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);
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);
00104
return;
00105 }
00106
QString libpath =
KLibLoader::findLibrary(mLib.ascii());
00107
if ( libpath.
isEmpty())
00108 {
00109 iio->
setStatus(1);
00110
return;
00111 }
00112 lt_dlhandle libhandle = lt_dlopen( libpath.
ascii() );
00113
if (libhandle == 0) {
00114 iio->
setStatus(1);
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);
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);
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);
00149
else
00150
if (mWriteFunc)
00151 mWriteFunc(iio);
00152
else
00153 iio->
setStatus(1);
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
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();
00175
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
00186
if (!formatList)
00187 {
00188 formatList =
new KImageIOFormatList();
00189 }
00190 }
else
00191 {
00192
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();
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);
00260
return;
00261 }
00262
00263 format->callLibFunc(
true, iio);
00264 }
00265
00266
void
00267 KImageIOFactory::writeImage(
QImageIO *iio)
00268 {
00269 (
void)
self();
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);
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
00305
00306
00307
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
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
00348
00349
00350
00351
00352
00353
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