kimageio.cpp
00001 00011 #include"config.h" 00012 00013 #include <tqdir.h> 00014 #include <tdeapplication.h> 00015 #include <kstandarddirs.h> 00016 #include <tqstring.h> 00017 #include <tqregexp.h> 00018 #include <tqvaluelist.h> 00019 00020 #include <ltdl.h> 00021 #include "kimageio.h" 00022 #include "kimageiofactory.h" 00023 #include <tdelocale.h> 00024 #include <klibloader.h> 00025 #include <tdeglobal.h> 00026 #include <kmimetype.h> 00027 #include <tdesycocaentry.h> 00028 #include <tdesycoca.h> 00029 #include <kdebug.h> 00030 #include <kstaticdeleter.h> 00031 00032 #include <tqimage.h> 00033 00034 KImageIOFormat::KImageIOFormat( const TQString &path) 00035 : KSycocaEntry(path) 00036 { 00037 bLibLoaded = false; 00038 mReadFunc = 0; 00039 mWriteFunc = 0; 00040 TDEConfig 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( TQDataStream& _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( TQDataStream& _str) 00070 { 00071 TQ_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( TQDataStream& _str) 00087 { 00088 KSycocaEntry::save( _str ); 00089 TQ_INT8 iRead = bRead ? 1 : 0; 00090 TQ_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, TQImageIO *iio) 00098 { 00099 if (!bLibLoaded) 00100 { 00101 if (mLib.isEmpty()) 00102 { 00103 iio->setStatus(1); // Error 00104 return; 00105 } 00106 TQString libpath = KLibLoader::findLibrary(mLib.ascii()); 00107 if ( libpath.isEmpty()) 00108 { 00109 iio->setStatus(1); // Error 00110 return; 00111 } 00112 lt_dlhandle libhandle = lt_dlopen( TQFile::encodeName(libpath) ); 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 TQString 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 (*)(TQImageIO *))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 (*)(TQImageIO *))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(TQStringList::Iterator it = rPath.begin(); 00177 it != rPath.end(); ++it) 00178 lt_dladdsearchdir( TQFile::encodeName(*it) ); 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 TQString 00197 KImageIOFactory::createPattern( KImageIO::Mode _mode) 00198 { 00199 TQStringList patterns; 00200 TQString allPatterns; 00201 TQString wildCard("*."); 00202 TQString 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 TQString pattern; 00212 TQStringList suffices = format->mSuffices; 00213 for( TQStringList::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 TQString pattern = patterns.join(TQString::fromLatin1("\n")); 00236 return pattern; 00237 } 00238 00239 void 00240 KImageIOFactory::readImage( TQImageIO *iio) 00241 { 00242 (void) self(); // Make sure we exist 00243 const char *fm = iio->format(); 00244 if (!fm) 00245 fm = TQImageIO::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( TQImageIO *iio) 00268 { 00269 (void) self(); // Make sure we exist 00270 const char *fm = iio->format(); 00271 if (!fm) 00272 fm = TQImageIO::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)(TQImageIO *); 00325 void (*writeFunc)(TQImageIO *); 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 TQImageIO::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 TQDataStream *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 TQString 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 TQString& 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 TQString& 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 TQStringList KImageIO::types(Mode _mode ) { 00431 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; 00432 TQStringList 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 TQString KImageIO::suffix(const TQString& 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 TQString::null; 00467 } 00468 00469 TQString KImageIO::typeForMime(const TQString& 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 TQString::null; 00486 } 00487 00488 TQString KImageIO::type(const TQString& filename) 00489 { 00490 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; 00491 TQString 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 TQString::null; 00509 } 00510 00511 TQStringList KImageIO::mimeTypes( Mode _mode ) 00512 { 00513 KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; 00514 TQStringList 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 TQString& _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 TQString KImageIO::mimeType( const TQString& _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