kio Library API Documentation

kimageio.cpp

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); // Latin1 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); // Error 00104 return; 00105 } 00106 QString libpath = KLibLoader::findLibrary(mLib.ascii()); 00107 if ( libpath.isEmpty()) 00108 { 00109 iio->setStatus(1); // Error 00110 return; 00111 } 00112 lt_dlhandle libhandle = lt_dlopen( libpath.ascii() ); 00113 if (libhandle == 0) { 00114 iio->setStatus(1); // error 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); // error 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); // error 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); // Error 00149 else 00150 if (mWriteFunc) 00151 mWriteFunc(iio); 00152 else 00153 iio->setStatus(1); // Error 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 // read from database 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(); // Do this only once! 00175 // Add rPaths. 00176 for(QStringList::Iterator it = rPath.begin(); 00177 it != rPath.end(); ++it) 00178 lt_dladdsearchdir( (*it).ascii()); 00179 } 00180 load(); 00181 } 00182 else 00183 if (KSycoca::self()->isBuilding()) 00184 { 00185 // Build database 00186 if (!formatList) 00187 { 00188 formatList = new KImageIOFormatList(); 00189 } 00190 } else 00191 { 00192 // We have no database at all.. uh-oh 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(); // Make sure we exist 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); // error 00260 return; 00261 } 00262 00263 format->callLibFunc( true, iio); 00264 } 00265 00266 void 00267 KImageIOFactory::writeImage( QImageIO *iio) 00268 { 00269 (void) self(); // Make sure we exist 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); // error 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 // Since Qt doesn't allow us to unregister image formats 00305 // we have to make sure not to add them a second time. 00306 // This typically happens when the sycoca database was updated 00307 // we need to reread it. 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 // Already in list 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 // We would like to: 00348 // * Free all KImageIOFormats. 00349 // * Unload libs 00350 // * Remove Qt IO handlers. 00351 // But we can't remove IO handlers, so we better keep all KImageIOFormats 00352 // in memory so that we can make sure not register IO handlers again whenever 00353 // the sycoca database updates (Such event deletes this factory) 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
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 8 11:14:57 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003