diff options
Diffstat (limited to 'tdeio/tdeio/kimageio.cpp')
-rw-r--r-- | tdeio/tdeio/kimageio.cpp | 566 |
1 files changed, 566 insertions, 0 deletions
diff --git a/tdeio/tdeio/kimageio.cpp b/tdeio/tdeio/kimageio.cpp new file mode 100644 index 000000000..e983cb945 --- /dev/null +++ b/tdeio/tdeio/kimageio.cpp @@ -0,0 +1,566 @@ + +/** +* kimgio.h -- Implementation of interface to the KDE Image IO library. +* Sirtaj Singh Kang <taj@kde.org>, 23 Sep 1998. +* +* $Id$ +* +* This library is distributed under the conditions of the GNU LGPL. +*/ + +#include"config.h" + +#include <tqdir.h> +#include <kapplication.h> +#include <kstandarddirs.h> +#include <tqstring.h> +#include <tqregexp.h> +#include <tqvaluelist.h> + +#include <ltdl.h> +#include "kimageio.h" +#include "kimageiofactory.h" +#include <klocale.h> +#include <klibloader.h> +#include <kglobal.h> +#include <kmimetype.h> +#include <tdesycocaentry.h> +#include <tdesycoca.h> +#include <kdebug.h> +#include <kstaticdeleter.h> + +#include <tqimage.h> + +KImageIOFormat::KImageIOFormat( const TQString &path) + : KSycocaEntry(path) +{ + bLibLoaded = false; + mReadFunc = 0; + mWriteFunc = 0; + TDEConfig config(path, true, false); + + config.setGroup("Image Format"); + mType = config.readEntry("Type"); + mHeader = KURL::decode_string(config.readEntry("Header"), 4); // Latin1 + mFlags = config.readEntry("Flags"); + bRead = config.readBoolEntry("Read"); + bWrite = config.readBoolEntry("Write"); + mSuffices = config.readListEntry("Suffices"); + mPattern = config.readEntry("Name"); + mMimetype = config.readEntry("Mimetype"); + mLib = config.readPathEntry("Library"); + rPaths = config.readPathListEntry("rPaths"); +} + +KImageIOFormat::KImageIOFormat( TQDataStream& _str, int offset) : + KSycocaEntry( _str, offset) +{ + bLibLoaded = false; + mReadFunc = 0; + mWriteFunc = 0; + load( _str ); +} + +KImageIOFormat::~KImageIOFormat() +{ +} + +void +KImageIOFormat::load( TQDataStream& _str) +{ + TQ_INT8 iRead, iWrite; + KSycocaEntry::read(_str, mType); + KSycocaEntry::read(_str, mHeader); + KSycocaEntry::read(_str, mFlags); + _str >> iRead >> iWrite; + KSycocaEntry::read(_str, mSuffices); + KSycocaEntry::read(_str, mMimetype); + KSycocaEntry::read(_str, mLib); + KSycocaEntry::read(_str, mPattern); + KSycocaEntry::read(_str, rPaths); + bRead = (iRead != 0); + bWrite = (iWrite != 0); +} + +void +KImageIOFormat::save( TQDataStream& _str) +{ + KSycocaEntry::save( _str ); + TQ_INT8 iRead = bRead ? 1 : 0; + TQ_INT8 iWrite = bWrite ? 1 : 0; + + _str << mType << mHeader << mFlags << iRead << iWrite + << mSuffices << mMimetype << mLib << mPattern << rPaths; +} + +void +KImageIOFormat::callLibFunc( bool read, TQImageIO *iio) +{ + if (!bLibLoaded) + { + if (mLib.isEmpty()) + { + iio->setStatus(1); // Error + return; + } + TQString libpath = KLibLoader::findLibrary(mLib.ascii()); + if ( libpath.isEmpty()) + { + iio->setStatus(1); // Error + return; + } + lt_dlhandle libhandle = lt_dlopen( TQFile::encodeName(libpath) ); + if (libhandle == 0) { + iio->setStatus(1); // error + kdWarning() << "KImageIOFormat::callLibFunc: couldn't dlopen " << mLib << "(" << lt_dlerror() << ")" << endl; + return; + } + bLibLoaded = true; + TQString funcName; + if (bRead) + { + funcName = "kimgio_"+mType.lower()+"_read"; + lt_ptr func = lt_dlsym(libhandle, funcName.ascii()); + + if (func == NULL) { + iio->setStatus(1); // error + kdWarning() << "couln't find " << funcName << " (" << lt_dlerror() << ")" << endl; + } + mReadFunc = (void (*)(TQImageIO *))func; + } + if (bWrite) + { + funcName = "kimgio_"+mType.lower()+"_write"; + lt_ptr func = lt_dlsym(libhandle, funcName.ascii()); + + if (func == NULL) { + iio->setStatus(1); // error + kdWarning() << "couln't find " << funcName << " (" << lt_dlerror() << ")" << endl; + } + mWriteFunc = (void (*)(TQImageIO *))func; + } + + } + if (read) + if (mReadFunc) + mReadFunc(iio); + else + iio->setStatus(1); // Error + else + if (mWriteFunc) + mWriteFunc(iio); + else + iio->setStatus(1); // Error +} + + +KImageIOFactory *KImageIOFactory::_self = 0; +KImageIOFormatList *KImageIOFactory::formatList = 0; + +static KStaticDeleter<KImageIOFormatList> kiioflsd; + +KImageIOFactory::KImageIOFactory() : KSycocaFactory( KST_KImageIO ) +{ + _self = this; + if (m_str) + { + // read from database + KSycocaEntry::read(*m_str, mReadPattern); + KSycocaEntry::read(*m_str, mWritePattern); + KSycocaEntry::read(*m_str, rPath); + if (!formatList) + { + kiioflsd.setObject( formatList, new KImageIOFormatList()); + lt_dlinit(); // Do this only once! + // Add rPaths. + for(TQStringList::Iterator it = rPath.begin(); + it != rPath.end(); ++it) + lt_dladdsearchdir( TQFile::encodeName(*it) ); + } + load(); + } + else + if (KSycoca::self()->isBuilding()) + { + // Build database + if (!formatList) + { + formatList = new KImageIOFormatList(); + } + } else + { + // We have no database at all.. uh-oh + } +} + +TQString +KImageIOFactory::createPattern( KImageIO::Mode _mode) +{ + TQStringList patterns; + TQString allPatterns; + TQString wildCard("*."); + TQString separator("|"); + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *format = (*it); + if (((_mode == KImageIO::Reading) && format->bRead) || + ((_mode == KImageIO::Writing) && format->bWrite)) + { + TQString pattern; + TQStringList suffices = format->mSuffices; + for( TQStringList::ConstIterator it = suffices.begin(); + it != suffices.end(); + ++it) + { + if (!pattern.isEmpty()) + pattern += " "; + pattern = pattern + wildCard+(*it); + if (!allPatterns.isEmpty()) + allPatterns += " "; + allPatterns = allPatterns + wildCard +(*it); + } + if (!pattern.isEmpty()) + { + pattern = pattern + separator + format->mPattern; + patterns.append(pattern); + } + } + } + allPatterns = allPatterns + separator + i18n("All Pictures"); + patterns.sort(); + patterns.prepend(allPatterns); + + TQString pattern = patterns.join(TQString::fromLatin1("\n")); + return pattern; +} + +void +KImageIOFactory::readImage( TQImageIO *iio) +{ + (void) self(); // Make sure we exist + const char *fm = iio->format(); + if (!fm) + fm = TQImageIO::imageFormat( iio->ioDevice()); + kdDebug() << "KImageIO: readImage() format = " << fm << endl; + + KImageIOFormat *format = 0; + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + format = (*it); + if (format->mType == fm) + break; + } + if (!format || !format->bRead) + { + iio->setStatus(1); // error + return; + } + + format->callLibFunc( true, iio); +} + +void +KImageIOFactory::writeImage( TQImageIO *iio) +{ + (void) self(); // Make sure we exist + const char *fm = iio->format(); + if (!fm) + fm = TQImageIO::imageFormat( iio->ioDevice()); + kdDebug () << "KImageIO: writeImage() format = "<< fm << endl; + + KImageIOFormat *format = 0; + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + format = (*it); + if (format->mType == fm) + break; + } + if (!format || !format->bWrite) + { + iio->setStatus(1); // error + return; + } + + format->callLibFunc( false, iio); +} + +void +KImageIOFactory::load() +{ + KSycocaEntry::List list = allEntries(); + for( KSycocaEntry::List::Iterator it = list.begin(); + it != list.end(); + ++it) + { + KSycocaEntry *entry = static_cast<KSycocaEntry *>(*it); + KImageIOFormat *format = static_cast<KImageIOFormat *>(entry); + + // Since Qt doesn't allow us to unregister image formats + // we have to make sure not to add them a second time. + // This typically happens when the sycoca database was updated + // we need to reread it. + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *_format = (*it); + if (format->mType == _format->mType) + { + // Already in list + format = 0; + break; + } + } + if (!format) + continue; + if (!format->mHeader.isEmpty() && !format->mLib.isEmpty()) + { + void (*readFunc)(TQImageIO *); + void (*writeFunc)(TQImageIO *); + if (format->bRead) + readFunc = readImage; + else + readFunc = 0; + if (format->bWrite) + writeFunc = writeImage; + else + writeFunc = 0; + TQImageIO::defineIOHandler( format->mType.ascii(), + format->mHeader.ascii(), + format->mFlags.ascii(), + readFunc, writeFunc); + } + formatList->append( format ); + } +} + +KImageIOFactory::~KImageIOFactory() +{ + _self = 0; + + // We would like to: + // * Free all KImageIOFormats. + // * Unload libs + // * Remove Qt IO handlers. + // But we can't remove IO handlers, so we better keep all KImageIOFormats + // in memory so that we can make sure not register IO handlers again whenever + // the sycoca database updates (Such event deletes this factory) +} + +KSycocaEntry* +KImageIOFactory::createEntry(int offset) +{ + KImageIOFormat *format = 0; + KSycocaType type; + TQDataStream *str = KSycoca::self()->findEntry(offset, type); + switch (type) + { + case KST_KImageIOFormat: + format = new KImageIOFormat(*str, offset); + break; + default: + return 0; + } + if (!format->isValid()) + { + delete format; + format = 0; + } + return format; +} + +void KImageIO::registerFormats() +{ + (void) KImageIOFactory::self(); +} + +TQString +KImageIO::pattern(Mode _mode) +{ + if (_mode == Reading) + return KImageIOFactory::self()->mReadPattern; + else + return KImageIOFactory::self()->mWritePattern; +} + +bool KImageIO::canWrite(const TQString& type) +{ + KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; + + if(formatList) + { + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *format = (*it); + if (format->mType == type) + return format->bWrite; + } + } + + return false; +} + +bool KImageIO::canRead(const TQString& type) +{ + KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; + + if(formatList) + { + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *format = (*it); + if (format->mType == type) + return format->bRead; + } + } + + return false; +} + +TQStringList KImageIO::types(Mode _mode ) { + KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; + TQStringList types; + + if(formatList) + { + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *format = (*it); + if (((_mode == Reading) && format->bRead) || + ((_mode == Writing) && format->bWrite)) + types.append(format->mType); + } + } + + return types; +} + +TQString KImageIO::suffix(const TQString& type) +{ + KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; + + if(formatList) + { + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *format = (*it); + if (format->mType == type) + return format->mSuffices[0]; + } + } + + return TQString::null; +} + +TQString KImageIO::typeForMime(const TQString& mimeType) +{ + KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; + + if(formatList) + { + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *format = (*it); + if (format->mMimetype == mimeType) + return format->mType; + } + } + + return TQString::null; +} + +TQString KImageIO::type(const TQString& filename) +{ + KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; + TQString suffix = filename; + int dot = suffix.findRev('.'); + if (dot >= 0) + suffix = suffix.mid(dot + 1); + + if(formatList) + { + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *format = (*it); + if (format->mSuffices.contains(suffix)) + return format->mType; + } + } + + return TQString::null; +} + +TQStringList KImageIO::mimeTypes( Mode _mode ) +{ + KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; + TQStringList mimeList; + + if(formatList) + { + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *format = (*it); + if (((_mode == Reading) && format->bRead) || + ((_mode == Writing) && format->bWrite)) + if ( !format->mMimetype.isEmpty() ) + mimeList.append ( format->mMimetype ); + } + } + + return mimeList; +} + +bool KImageIO::isSupported( const TQString& _mimeType, Mode _mode ) +{ + KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; + + if(formatList) + { + for( KImageIOFormatList::ConstIterator it = formatList->begin(); + it != formatList->end(); + ++it ) + { + KImageIOFormat *format = (*it); + if (format->mMimetype == _mimeType) + { + if (((_mode == Reading) && format->bRead) || + ((_mode == Writing) && format->bWrite)) + return true; + } + } + } + + return false; +} + +TQString KImageIO::mimeType( const TQString& _filename ) +{ + return KMimeType::findByURL( KURL( _filename ) )->name(); +} + +void KImageIOFormat::virtual_hook( int id, void* data ) +{ KSycocaEntry::virtual_hook( id, data ); } + +void KImageIOFactory::virtual_hook( int id, void* data ) +{ KSycocaFactory::virtual_hook( id, data ); } + |