kimageio.cpp Source File (kio Library)

| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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"));
    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 seperator("|");
    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 + seperator + format->mPattern;
    00227            patterns.append(pattern);
    00228         }
    00229      }
    00230   }
    00231   allPatterns = allPatterns + seperator + 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( _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

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:13:37 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001