kio
kimageio.cpp
Go to the documentation of this file.00001
00011 #include"config.h"
00012
00013 #include <qdir.h>
00014 #include <kapplication.h>
00015 #include <kstandarddirs.h>
00016 #include <qstring.h>
00017 #include <qregexp.h>
00018 #include <qvaluelist.h>
00019
00020 #include <ltdl.h>
00021 #include "kimageio.h"
00022 #include "kimageiofactory.h"
00023 #include <klocale.h>
00024 #include <klibloader.h>
00025 #include <kglobal.h>
00026 #include <kmimetype.h>
00027 #include <ksycocaentry.h>
00028 #include <ksycoca.h>
00029 #include <kdebug.h>
00030 #include <kstaticdeleter.h>
00031
00032 #include <qimage.h>
00033
00034 KImageIOFormat::KImageIOFormat( const QString &path)
00035 : KSycocaEntry(path)
00036 {
00037 bLibLoaded = false;
00038 mReadFunc = 0;
00039 mWriteFunc = 0;
00040 KConfig config(path, true, false);
00041
00042 config.setGroup("Image Format");
00043 mType = config.readEntry("Type");
00044 mHeader = KURL::decode_string(config.readEntry("Header"), 4);
00045 mFlags = config.readEntry("Flags");
00046 bRead = config.readBoolEntry("Read");
00047 bWrite = config.readBoolEntry("Write");
00048 mSuffices = config.readListEntry("Suffices");
00049 mPattern = config.readEntry("Name");
00050 mMimetype = config.readEntry("Mimetype");
00051 mLib = config.readPathEntry("Library");
00052 rPaths = config.readPathListEntry("rPaths");
00053 }
00054
00055 KImageIOFormat::KImageIOFormat( QDataStream& _str, int offset) :
00056 KSycocaEntry( _str, offset)
00057 {
00058 bLibLoaded = false;
00059 mReadFunc = 0;
00060 mWriteFunc = 0;
00061 load( _str );
00062 }
00063
00064 KImageIOFormat::~KImageIOFormat()
00065 {
00066 }
00067
00068 void
00069 KImageIOFormat::load( QDataStream& _str)
00070 {
00071 Q_INT8 iRead, iWrite;
00072 KSycocaEntry::read(_str, mType);
00073 KSycocaEntry::read(_str, mHeader);
00074 KSycocaEntry::read(_str, mFlags);
00075 _str >> iRead >> iWrite;
00076 KSycocaEntry::read(_str, mSuffices);
00077 KSycocaEntry::read(_str, mMimetype);
00078 KSycocaEntry::read(_str, mLib);
00079 KSycocaEntry::read(_str, mPattern);
00080 KSycocaEntry::read(_str, rPaths);
00081 bRead = (iRead != 0);
00082 bWrite = (iWrite != 0);
00083 }
00084
00085 void
00086 KImageIOFormat::save( QDataStream& _str)
00087 {
00088 KSycocaEntry::save( _str );
00089 Q_INT8 iRead = bRead ? 1 : 0;
00090 Q_INT8 iWrite = bWrite ? 1 : 0;
00091
00092 _str << mType << mHeader << mFlags << iRead << iWrite
00093 << mSuffices << mMimetype << mLib << mPattern << rPaths;
00094 }
00095
00096 void
00097 KImageIOFormat::callLibFunc( bool read, QImageIO *iio)
00098 {
00099 if (!bLibLoaded)
00100 {
00101 if (mLib.isEmpty())
00102 {
00103 iio->setStatus(1);
00104 return;
00105 }
00106 QString libpath = KLibLoader::findLibrary(mLib.ascii());
00107 if ( libpath.isEmpty())
00108 {
00109 iio->setStatus(1);
00110 return;
00111 }
00112 lt_dlhandle libhandle = lt_dlopen( QFile::encodeName(libpath) );
00113 if (libhandle == 0) {
00114 iio->setStatus(1);
00115 kdWarning() << "KImageIOFormat::callLibFunc: couldn't dlopen " << mLib << "(" << lt_dlerror() << ")" << endl;
00116 return;
00117 }
00118 bLibLoaded = true;
00119 QString funcName;
00120 if (bRead)
00121 {
00122 funcName = "kimgio_"+mType.lower()+"_read";
00123 lt_ptr func = lt_dlsym(libhandle, funcName.ascii());
00124
00125 if (func == NULL) {
00126 iio->setStatus(1);
00127 kdWarning() << "couln't find " << funcName << " (" << lt_dlerror() << ")" << endl;
00128 }
00129 mReadFunc = (void (*)(QImageIO *))func;
00130 }
00131 if (bWrite)
00132 {
00133 funcName = "kimgio_"+mType.lower()+"_write";
00134 lt_ptr func = lt_dlsym(libhandle, funcName.ascii());
00135
00136 if (func == NULL) {
00137 iio->setStatus(1);
00138 kdWarning() << "couln't find " << funcName << " (" << lt_dlerror() << ")" << endl;
00139 }
00140 mWriteFunc = (void (*)(QImageIO *))func;
00141 }
00142
00143 }
00144 if (read)
00145 if (mReadFunc)
00146 mReadFunc(iio);
00147 else
00148 iio->setStatus(1);
00149 else
00150 if (mWriteFunc)
00151 mWriteFunc(iio);
00152 else
00153 iio->setStatus(1);
00154 }
00155
00156
00157 KImageIOFactory *KImageIOFactory::_self = 0;
00158 KImageIOFormatList *KImageIOFactory::formatList = 0;
00159
00160 static KStaticDeleter<KImageIOFormatList> kiioflsd;
00161
00162 KImageIOFactory::KImageIOFactory() : KSycocaFactory( KST_KImageIO )
00163 {
00164 _self = this;
00165 if (m_str)
00166 {
00167
00168 KSycocaEntry::read(*m_str, mReadPattern);
00169 KSycocaEntry::read(*m_str, mWritePattern);
00170 KSycocaEntry::read(*m_str, rPath);
00171 if (!formatList)
00172 {
00173 kiioflsd.setObject( formatList, new KImageIOFormatList());
00174 lt_dlinit();
00175
00176 for(QStringList::Iterator it = rPath.begin();
00177 it != rPath.end(); ++it)
00178 lt_dladdsearchdir( QFile::encodeName(*it) );
00179 }
00180 load();
00181 }
00182 else
00183 if (KSycoca::self()->isBuilding())
00184 {
00185
00186 if (!formatList)
00187 {
00188 formatList = new KImageIOFormatList();
00189 }
00190 } else
00191 {
00192
00193 }
00194 }
00195
00196 QString
00197 KImageIOFactory::createPattern( KImageIO::Mode _mode)
00198 {
00199 QStringList patterns;
00200 QString allPatterns;
00201 QString wildCard("*.");
00202 QString separator("|");
00203 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00204 it != formatList->end();
00205 ++it )
00206 {
00207 KImageIOFormat *format = (*it);
00208 if (((_mode == KImageIO::Reading) && format->bRead) ||
00209 ((_mode == KImageIO::Writing) && format->bWrite))
00210 {
00211 QString pattern;
00212 QStringList suffices = format->mSuffices;
00213 for( QStringList::ConstIterator it = suffices.begin();
00214 it != suffices.end();
00215 ++it)
00216 {
00217 if (!pattern.isEmpty())
00218 pattern += " ";
00219 pattern = pattern + wildCard+(*it);
00220 if (!allPatterns.isEmpty())
00221 allPatterns += " ";
00222 allPatterns = allPatterns + wildCard +(*it);
00223 }
00224 if (!pattern.isEmpty())
00225 {
00226 pattern = pattern + separator + format->mPattern;
00227 patterns.append(pattern);
00228 }
00229 }
00230 }
00231 allPatterns = allPatterns + separator + i18n("All Pictures");
00232 patterns.sort();
00233 patterns.prepend(allPatterns);
00234
00235 QString pattern = patterns.join(QString::fromLatin1("\n"));
00236 return pattern;
00237 }
00238
00239 void
00240 KImageIOFactory::readImage( QImageIO *iio)
00241 {
00242 (void) self();
00243 const char *fm = iio->format();
00244 if (!fm)
00245 fm = QImageIO::imageFormat( iio->ioDevice());
00246 kdDebug() << "KImageIO: readImage() format = " << fm << endl;
00247
00248 KImageIOFormat *format = 0;
00249 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00250 it != formatList->end();
00251 ++it )
00252 {
00253 format = (*it);
00254 if (format->mType == fm)
00255 break;
00256 }
00257 if (!format || !format->bRead)
00258 {
00259 iio->setStatus(1);
00260 return;
00261 }
00262
00263 format->callLibFunc( true, iio);
00264 }
00265
00266 void
00267 KImageIOFactory::writeImage( QImageIO *iio)
00268 {
00269 (void) self();
00270 const char *fm = iio->format();
00271 if (!fm)
00272 fm = QImageIO::imageFormat( iio->ioDevice());
00273 kdDebug () << "KImageIO: writeImage() format = "<< fm << endl;
00274
00275 KImageIOFormat *format = 0;
00276 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00277 it != formatList->end();
00278 ++it )
00279 {
00280 format = (*it);
00281 if (format->mType == fm)
00282 break;
00283 }
00284 if (!format || !format->bWrite)
00285 {
00286 iio->setStatus(1);
00287 return;
00288 }
00289
00290 format->callLibFunc( false, iio);
00291 }
00292
00293 void
00294 KImageIOFactory::load()
00295 {
00296 KSycocaEntry::List list = allEntries();
00297 for( KSycocaEntry::List::Iterator it = list.begin();
00298 it != list.end();
00299 ++it)
00300 {
00301 KSycocaEntry *entry = static_cast<KSycocaEntry *>(*it);
00302 KImageIOFormat *format = static_cast<KImageIOFormat *>(entry);
00303
00304
00305
00306
00307
00308 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00309 it != formatList->end();
00310 ++it )
00311 {
00312 KImageIOFormat *_format = (*it);
00313 if (format->mType == _format->mType)
00314 {
00315
00316 format = 0;
00317 break;
00318 }
00319 }
00320 if (!format)
00321 continue;
00322 if (!format->mHeader.isEmpty() && !format->mLib.isEmpty())
00323 {
00324 void (*readFunc)(QImageIO *);
00325 void (*writeFunc)(QImageIO *);
00326 if (format->bRead)
00327 readFunc = readImage;
00328 else
00329 readFunc = 0;
00330 if (format->bWrite)
00331 writeFunc = writeImage;
00332 else
00333 writeFunc = 0;
00334 QImageIO::defineIOHandler( format->mType.ascii(),
00335 format->mHeader.ascii(),
00336 format->mFlags.ascii(),
00337 readFunc, writeFunc);
00338 }
00339 formatList->append( format );
00340 }
00341 }
00342
00343 KImageIOFactory::~KImageIOFactory()
00344 {
00345 _self = 0;
00346
00347
00348
00349
00350
00351
00352
00353
00354 }
00355
00356 KSycocaEntry*
00357 KImageIOFactory::createEntry(int offset)
00358 {
00359 KImageIOFormat *format = 0;
00360 KSycocaType type;
00361 QDataStream *str = KSycoca::self()->findEntry(offset, type);
00362 switch (type)
00363 {
00364 case KST_KImageIOFormat:
00365 format = new KImageIOFormat(*str, offset);
00366 break;
00367 default:
00368 return 0;
00369 }
00370 if (!format->isValid())
00371 {
00372 delete format;
00373 format = 0;
00374 }
00375 return format;
00376 }
00377
00378 void KImageIO::registerFormats()
00379 {
00380 (void) KImageIOFactory::self();
00381 }
00382
00383 QString
00384 KImageIO::pattern(Mode _mode)
00385 {
00386 if (_mode == Reading)
00387 return KImageIOFactory::self()->mReadPattern;
00388 else
00389 return KImageIOFactory::self()->mWritePattern;
00390 }
00391
00392 bool KImageIO::canWrite(const QString& type)
00393 {
00394 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList;
00395
00396 if(formatList)
00397 {
00398 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00399 it != formatList->end();
00400 ++it )
00401 {
00402 KImageIOFormat *format = (*it);
00403 if (format->mType == type)
00404 return format->bWrite;
00405 }
00406 }
00407
00408 return false;
00409 }
00410
00411 bool KImageIO::canRead(const QString& type)
00412 {
00413 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList;
00414
00415 if(formatList)
00416 {
00417 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00418 it != formatList->end();
00419 ++it )
00420 {
00421 KImageIOFormat *format = (*it);
00422 if (format->mType == type)
00423 return format->bRead;
00424 }
00425 }
00426
00427 return false;
00428 }
00429
00430 QStringList KImageIO::types(Mode _mode ) {
00431 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList;
00432 QStringList types;
00433
00434 if(formatList)
00435 {
00436 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00437 it != formatList->end();
00438 ++it )
00439 {
00440 KImageIOFormat *format = (*it);
00441 if (((_mode == Reading) && format->bRead) ||
00442 ((_mode == Writing) && format->bWrite))
00443 types.append(format->mType);
00444 }
00445 }
00446
00447 return types;
00448 }
00449
00450 QString KImageIO::suffix(const QString& type)
00451 {
00452 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList;
00453
00454 if(formatList)
00455 {
00456 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00457 it != formatList->end();
00458 ++it )
00459 {
00460 KImageIOFormat *format = (*it);
00461 if (format->mType == type)
00462 return format->mSuffices[0];
00463 }
00464 }
00465
00466 return QString::null;
00467 }
00468
00469 QString KImageIO::typeForMime(const QString& mimeType)
00470 {
00471 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList;
00472
00473 if(formatList)
00474 {
00475 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00476 it != formatList->end();
00477 ++it )
00478 {
00479 KImageIOFormat *format = (*it);
00480 if (format->mMimetype == mimeType)
00481 return format->mType;
00482 }
00483 }
00484
00485 return QString::null;
00486 }
00487
00488 QString KImageIO::type(const QString& filename)
00489 {
00490 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList;
00491 QString suffix = filename;
00492 int dot = suffix.findRev('.');
00493 if (dot >= 0)
00494 suffix = suffix.mid(dot + 1);
00495
00496 if(formatList)
00497 {
00498 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00499 it != formatList->end();
00500 ++it )
00501 {
00502 KImageIOFormat *format = (*it);
00503 if (format->mSuffices.contains(suffix))
00504 return format->mType;
00505 }
00506 }
00507
00508 return QString::null;
00509 }
00510
00511 QStringList KImageIO::mimeTypes( Mode _mode )
00512 {
00513 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList;
00514 QStringList mimeList;
00515
00516 if(formatList)
00517 {
00518 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00519 it != formatList->end();
00520 ++it )
00521 {
00522 KImageIOFormat *format = (*it);
00523 if (((_mode == Reading) && format->bRead) ||
00524 ((_mode == Writing) && format->bWrite))
00525 if ( !format->mMimetype.isEmpty() )
00526 mimeList.append ( format->mMimetype );
00527 }
00528 }
00529
00530 return mimeList;
00531 }
00532
00533 bool KImageIO::isSupported( const QString& _mimeType, Mode _mode )
00534 {
00535 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList;
00536
00537 if(formatList)
00538 {
00539 for( KImageIOFormatList::ConstIterator it = formatList->begin();
00540 it != formatList->end();
00541 ++it )
00542 {
00543 KImageIOFormat *format = (*it);
00544 if (format->mMimetype == _mimeType)
00545 {
00546 if (((_mode == Reading) && format->bRead) ||
00547 ((_mode == Writing) && format->bWrite))
00548 return true;
00549 }
00550 }
00551 }
00552
00553 return false;
00554 }
00555
00556 QString KImageIO::mimeType( const QString& _filename )
00557 {
00558 return KMimeType::findByURL( KURL( _filename ) )->name();
00559 }
00560
00561 void KImageIOFormat::virtual_hook( int id, void* data )
00562 { KSycocaEntry::virtual_hook( id, data ); }
00563
00564 void KImageIOFactory::virtual_hook( int id, void* data )
00565 { KSycocaFactory::virtual_hook( id, data ); }
00566