static QImageIOHandler *createReadHandlerHelper(QIODevice *device, const QByteArray &format, bool autoDetectImageFormat, bool ignoresFormatAndExtension) { if (!autoDetectImageFormat && format.isEmpty()) return 0; QByteArray form = format.toLower(); QImageIOHandler *handler = 0; QByteArray suffix; #ifndef QT_NO_IMAGEFORMATPLUGIN static QMutex mutex; QMutexLocker locker(&mutex); typedef QMultiMap<int, QString> PluginKeyMap; // check if we have plugins that support the image format QFactoryLoader *l = loader(); const PluginKeyMap keyMap = l->keyMap(); #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler( device =" << (void *)device << ", format =" << format << ")," << keyMap.values().size() << "plugins available: " << keyMap.values(); #endif int suffixPluginIndex = -1; #endif // QT_NO_IMAGEFORMATPLUGIN if (device && format.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) { // if there's no format, see if \a device is a file, and if so, find // the file suffix and find support for that format among our plugins. // this allows plugins to override our built-in handlers. if (QFile *file = qobject_cast<QFile *>(device)) { #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler: device is a file:" << file->fileName(); #endif if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) { #ifndef QT_NO_IMAGEFORMATPLUGIN const int index = keyMap.key(QString::fromLatin1(suffix), -1); if (index != -1) { #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler: suffix recognized; the" << suffix << "plugin might be able to read this"; #endif suffixPluginIndex = index; } #endif // QT_NO_IMAGEFORMATPLUGIN } } } QByteArray testFormat = !form.isEmpty() ? form : suffix; if (ignoresFormatAndExtension) testFormat = QByteArray(); #ifndef QT_NO_IMAGEFORMATPLUGIN if (suffixPluginIndex != -1) { // check if the plugin that claims support for this format can load // from this device with this format. const qint64 pos = device ? device->pos() : 0; const int index = keyMap.key(QString::fromLatin1(suffix), -1); if (index != -1) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(index)); if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) { handler = plugin->create(device, testFormat); #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler: using the" << suffix << "plugin"; #endif } } if (device && !device->isSequential()) device->seek(pos); } if (!handler && !testFormat.isEmpty() && !ignoresFormatAndExtension) { // check if any plugin supports the format (they are not allowed to // read from the device yet). const qint64 pos = device ? device->pos() : 0; if (autoDetectImageFormat) { const int keyCount = keyMap.keys().size(); for (int i = 0; i < keyCount; ++i) { if (i != suffixPluginIndex) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i)); if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) { #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler: the" << keyMap.keys().at(i) << "plugin can read this format"; #endif handler = plugin->create(device, testFormat); break; } } } } else { const int testIndex = keyMap.key(QLatin1String(testFormat), -1); if (testIndex != -1) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(testIndex)); if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) { #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler: the" << testFormat << "plugin can read this format"; #endif handler = plugin->create(device, testFormat); } } } if (device && !device->isSequential()) device->seek(pos); } #endif // QT_NO_IMAGEFORMATPLUGIN // if we don't have a handler yet, check if we have built-in support for // the format if (!handler && !testFormat.isEmpty()) { if (false) { #ifndef QT_NO_IMAGEFORMAT_PNG } else if (testFormat == "png") { handler = new QPngHandler; #endif #ifndef QT_NO_IMAGEFORMAT_JPEG } else if (testFormat == "jpg" || testFormat == "jpeg") { handler = new QJpegHandler; #endif #ifdef QT_BUILTIN_GIF_READER } else if (testFormat == "gif") { handler = new QGifHandler; #endif #ifndef QT_NO_IMAGEFORMAT_BMP } else if (testFormat == "bmp") { handler = new QBmpHandler; } else if (testFormat == "dib") { handler = new QBmpHandler(QBmpHandler::DibFormat); #endif #ifndef QT_NO_IMAGEFORMAT_XPM } else if (testFormat == "xpm") { handler = new QXpmHandler; #endif #ifndef QT_NO_IMAGEFORMAT_XBM } else if (testFormat == "xbm") { handler = new QXbmHandler; handler->setOption(QImageIOHandler::SubType, testFormat); #endif #ifndef QT_NO_IMAGEFORMAT_PPM } else if (testFormat == "pbm" || testFormat == "pbmraw" || testFormat == "pgm" || testFormat == "pgmraw" || testFormat == "ppm" || testFormat == "ppmraw") { handler = new QPpmHandler; handler->setOption(QImageIOHandler::SubType, testFormat); #endif } #ifdef QIMAGEREADER_DEBUG if (handler) qDebug() << "QImageReader::createReadHandler: using the built-in handler for" << testFormat; #endif } #ifndef QT_NO_IMAGEFORMATPLUGIN if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) { // check if any of our plugins recognize the file from its contents. const qint64 pos = device ? device->pos() : 0; const int keyCount = keyMap.keys().size(); for (int i = 0; i < keyCount; ++i) { if (i != suffixPluginIndex) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i)); if (plugin && plugin->capabilities(device, QByteArray()) & QImageIOPlugin::CanRead) { handler = plugin->create(device, testFormat); #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler: the" << keyMap.keys().at(i) << "plugin can read this data"; #endif break; } } } if (device && !device->isSequential()) device->seek(pos); } #endif // QT_NO_IMAGEFORMATPLUGIN if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) { // check if any of our built-in handlers recognize the file from its // contents. int currentFormat = 0; if (!suffix.isEmpty()) { // If reading from a file with a suffix, start testing our // built-in handler for that suffix first. for (int i = 0; i < _qt_NumFormats; ++i) { if (_qt_BuiltInFormats[i].extension == suffix) { currentFormat = i; break; } } } QByteArray subType; int numFormats = _qt_NumFormats; while (device && numFormats >= 0) { const _qt_BuiltInFormatStruct *formatStruct = &_qt_BuiltInFormats[currentFormat]; const qint64 pos = device->pos(); switch (formatStruct->type) { #ifndef QT_NO_IMAGEFORMAT_PNG case _qt_PngFormat: if (QPngHandler::canRead(device)) handler = new QPngHandler; break; #endif #ifndef QT_NO_IMAGEFORMAT_JPEG case _qt_JpgFormat: case _qt_JpegFormat: if (QJpegHandler::canRead(device)) handler = new QJpegHandler; break; #endif #ifdef QT_BUILTIN_GIF_READER case _qt_GifFormat: if (QGifHandler::canRead(device)) handler = new QGifHandler; break; #endif #ifndef QT_NO_IMAGEFORMAT_BMP case _qt_BmpFormat: if (QBmpHandler::canRead(device)) handler = new QBmpHandler; break; #endif #ifndef QT_NO_IMAGEFORMAT_XPM case _qt_XpmFormat: if (QXpmHandler::canRead(device)) handler = new QXpmHandler; break; #endif #ifndef QT_NO_IMAGEFORMAT_PPM case _qt_PbmFormat: case _qt_PgmFormat: case _qt_PpmFormat: if (QPpmHandler::canRead(device, &subType)) { handler = new QPpmHandler; handler->setOption(QImageIOHandler::SubType, subType); } break; #endif #ifndef QT_NO_IMAGEFORMAT_XBM case _qt_XbmFormat: if (QXbmHandler::canRead(device)) handler = new QXbmHandler; break; #endif default: break; } if (!device->isSequential()) device->seek(pos); if (handler) { #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler: the" << formatStruct->extension << "built-in handler can read this data"; #endif break; } --numFormats; ++currentFormat; currentFormat %= _qt_NumFormats; } } if (!handler) { #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler: no handlers found. giving up."; #endif // no handler: give up. return 0; } handler->setDevice(device); if (!form.isEmpty()) handler->setFormat(form); return handler; }
static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, const QByteArray &format) { QByteArray form = format.toLower(); QByteArray suffix; QImageIOHandler *handler = 0; #ifndef QT_NO_IMAGEFORMATPLUGIN typedef QMultiMap<int, QString> PluginKeyMap; // check if any plugins can write the image QFactoryLoader *l = loader(); const PluginKeyMap keyMap = l->keyMap(); int suffixPluginIndex = -1; #endif if (device && format.isEmpty()) { // if there's no format, see if \a device is a file, and if so, find // the file suffix and find support for that format among our plugins. // this allows plugins to override our built-in handlers. if (QFile *file = qobject_cast<QFile *>(device)) { if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) { #ifndef QT_NO_IMAGEFORMATPLUGIN const int index = keyMap.key(QString::fromLatin1(suffix), -1); if (index != -1) suffixPluginIndex = index; #endif } } } QByteArray testFormat = !form.isEmpty() ? form : suffix; #ifndef QT_NO_IMAGEFORMATPLUGIN if (suffixPluginIndex != -1) { // when format is missing, check if we can find a plugin for the // suffix. const int index = keyMap.key(QString::fromLatin1(suffix), -1); if (index != -1) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(index)); if (plugin && (plugin->capabilities(device, suffix) & QImageIOPlugin::CanWrite)) handler = plugin->create(device, suffix); } } #endif // QT_NO_IMAGEFORMATPLUGIN // check if any built-in handlers can write the image if (!handler && !testFormat.isEmpty()) { if (false) { #ifndef QT_NO_IMAGEFORMAT_PNG } else if (testFormat == "png") { handler = new QPngHandler; #endif #ifndef QT_NO_IMAGEFORMAT_JPEG } else if (testFormat == "jpg" || testFormat == "jpeg") { handler = new QJpegHandler; #endif #ifdef QT_BUILTIN_GIF_READER } else if (testFormat == "gif") { handler = new QGifHandler; #endif #ifndef QT_NO_IMAGEFORMAT_BMP } else if (testFormat == "bmp") { handler = new QBmpHandler; } else if (testFormat == "dib") { handler = new QBmpHandler(QBmpHandler::DibFormat); #endif #ifndef QT_NO_IMAGEFORMAT_XPM } else if (testFormat == "xpm") { handler = new QXpmHandler; #endif #ifndef QT_NO_IMAGEFORMAT_XBM } else if (testFormat == "xbm") { handler = new QXbmHandler; handler->setOption(QImageIOHandler::SubType, testFormat); #endif #ifndef QT_NO_IMAGEFORMAT_PPM } else if (testFormat == "pbm" || testFormat == "pbmraw" || testFormat == "pgm" || testFormat == "pgmraw" || testFormat == "ppm" || testFormat == "ppmraw") { handler = new QPpmHandler; handler->setOption(QImageIOHandler::SubType, testFormat); #endif } } #ifndef QT_NO_IMAGEFORMATPLUGIN if (!testFormat.isEmpty()) { const int keyCount = keyMap.keys().size(); for (int i = 0; i < keyCount; ++i) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i)); if (plugin && (plugin->capabilities(device, testFormat) & QImageIOPlugin::CanWrite)) { delete handler; handler = plugin->create(device, testFormat); break; } } } #endif // QT_NO_IMAGEFORMATPLUGIN if (!handler) return 0; handler->setDevice(device); if (!testFormat.isEmpty()) handler->setFormat(testFormat); return handler; }