• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

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); // 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( QFile::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       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( QFile::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 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 

kio

Skip menu "kio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal