Qt 4.8
Classes | Functions | Variables
qimagereader.cpp File Reference
#include "qimagereader.h"
#include <qbytearray.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qimage.h>
#include <qimageiohandler.h>
#include <qlist.h>
#include <qrect.h>
#include <qset.h>
#include <qsize.h>
#include <qcolor.h>
#include <qvariant.h>
#include <qcoreapplication.h>
#include <private/qfactoryloader_p.h>
#include <private/qbmphandler_p.h>
#include <private/qppmhandler_p.h>
#include <private/qxbmhandler_p.h>
#include <private/qxpmhandler_p.h>
#include <private/qpnghandler_p.h>
#include <private/qjpeghandler_p.h>
#include <private/qmnghandler_p.h>
#include <private/qtiffhandler_p.h>

Go to the source code of this file.

Classes

struct  _qt_BuiltInFormatStruct
 
class  QImageReaderPrivate
 

Functions

static QImageIOHandlercreateReadHandlerHelper (QIODevice *device, const QByteArray &format, bool autoDetectImageFormat, bool ignoresFormatAndExtension)
 
 Q_GLOBAL_STATIC_WITH_ARGS (QFactoryLoader, loader,(QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))) enum _qt_BuiltInFormatType
 

Variables

static const _qt_BuiltInFormatStruct _qt_BuiltInFormats []
 

Function Documentation

◆ createReadHandlerHelper()

static QImageIOHandler* createReadHandlerHelper ( QIODevice device,
const QByteArray format,
bool  autoDetectImageFormat,
bool  ignoresFormatAndExtension 
)
static

Definition at line 239 of file qimagereader.cpp.

Referenced by QImageReader::imageFormat(), and QImageReaderPrivate::initHandler().

243 {
244  if (!autoDetectImageFormat && format.isEmpty())
245  return 0;
246 
247  QByteArray form = format.toLower();
249 
250 #ifndef QT_NO_LIBRARY
251  // check if we have plugins that support the image format
252  QFactoryLoader *l = loader();
253  QStringList keys = l->keys();
254 #endif
256 
257 #ifdef QIMAGEREADER_DEBUG
258  qDebug() << "QImageReader::createReadHandler( device =" << (void *)device << ", format =" << format << "),"
259  << keys.size() << "plugins available: " << keys;
260 #endif
261 
262 #ifndef QT_NO_LIBRARY
263  int suffixPluginIndex = -1;
264  if (device && format.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) {
265  // if there's no format, see if \a device is a file, and if so, find
266  // the file suffix and find support for that format among our plugins.
267  // this allows plugins to override our built-in handlers.
268  if (QFile *file = qobject_cast<QFile *>(device)) {
269 #ifdef QIMAGEREADER_DEBUG
270  qDebug() << "QImageReader::createReadHandler: device is a file:" << file->fileName();
271 #endif
272  if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) {
273  int index = keys.indexOf(QString::fromLatin1(suffix));
274  if (index != -1) {
275 #ifdef QIMAGEREADER_DEBUG
276  qDebug() << "QImageReader::createReadHandler: suffix recognized; the"
277  << suffix << "plugin might be able to read this";
278 #endif
279  suffixPluginIndex = index;
280  }
281  }
282  }
283  }
284 #endif // QT_NO_LIBRARY
285 
286  QByteArray testFormat = !form.isEmpty() ? form : suffix;
287 
288  if (ignoresFormatAndExtension)
289  testFormat = QByteArray();
290 
291 #ifndef QT_NO_LIBRARY
292  if (suffixPluginIndex != -1) {
293  // check if the plugin that claims support for this format can load
294  // from this device with this format.
295  const qint64 pos = device ? device->pos() : 0;
297  if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) {
298  handler = plugin->create(device, testFormat);
299 #ifdef QIMAGEREADER_DEBUG
300  qDebug() << "QImageReader::createReadHandler: using the" << suffix
301  << "plugin";
302 #endif
303  }
304  if (device && !device->isSequential())
305  device->seek(pos);
306  }
307 
308  if (!handler && !testFormat.isEmpty() && !ignoresFormatAndExtension) {
309  // check if any plugin supports the format (they are not allowed to
310  // read from the device yet).
311  const qint64 pos = device ? device->pos() : 0;
312 
313  if (autoDetectImageFormat) {
314  for (int i = 0; i < keys.size(); ++i) {
315  if (i != suffixPluginIndex) {
316  QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
317  if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) {
318 #ifdef QIMAGEREADER_DEBUG
319  qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this format";
320 #endif
321  handler = plugin->create(device, testFormat);
322  break;
323  }
324  }
325  }
326  } else {
327  QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(QLatin1String(testFormat)));
328  if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) {
329 #ifdef QIMAGEREADER_DEBUG
330  qDebug() << "QImageReader::createReadHandler: the" << testFormat << "plugin can read this format";
331 #endif
332  handler = plugin->create(device, testFormat);
333  }
334  }
335  if (device && !device->isSequential())
336  device->seek(pos);
337  }
338 
339 #endif // QT_NO_LIBRARY
340 
341  // if we don't have a handler yet, check if we have built-in support for
342  // the format
343  if (!handler && !testFormat.isEmpty()) {
344  if (false) {
345 #ifndef QT_NO_IMAGEFORMAT_PNG
346  } else if (testFormat == "png") {
347  handler = new QPngHandler;
348 #endif
349 #ifndef QT_NO_IMAGEFORMAT_JPEG
350  } else if (testFormat == "jpg" || testFormat == "jpeg") {
351  handler = new QJpegHandler;
352 #endif
353 #ifndef QT_NO_IMAGEFORMAT_MNG
354  } else if (testFormat == "mng") {
355  handler = new QMngHandler;
356 #endif
357 #ifndef QT_NO_IMAGEFORMAT_TIFF
358  } else if (testFormat == "tif" || testFormat == "tiff") {
359  handler = new QTiffHandler;
360 #endif
361 #ifdef QT_BUILTIN_GIF_READER
362  } else if (testFormat == "gif") {
363  handler = new QGifHandler;
364 #endif
365 #ifndef QT_NO_IMAGEFORMAT_BMP
366  } else if (testFormat == "bmp") {
367  handler = new QBmpHandler;
368 #endif
369 #ifndef QT_NO_IMAGEFORMAT_XPM
370  } else if (testFormat == "xpm") {
371  handler = new QXpmHandler;
372 #endif
373 #ifndef QT_NO_IMAGEFORMAT_XBM
374  } else if (testFormat == "xbm") {
375  handler = new QXbmHandler;
376  handler->setOption(QImageIOHandler::SubType, testFormat);
377 #endif
378 #ifndef QT_NO_IMAGEFORMAT_PPM
379  } else if (testFormat == "pbm" || testFormat == "pbmraw" || testFormat == "pgm"
380  || testFormat == "pgmraw" || testFormat == "ppm" || testFormat == "ppmraw") {
381  handler = new QPpmHandler;
382  handler->setOption(QImageIOHandler::SubType, testFormat);
383 #endif
384  }
385 
386 #ifdef QIMAGEREADER_DEBUG
387  if (handler)
388  qDebug() << "QImageReader::createReadHandler: using the built-in handler for" << testFormat;
389 #endif
390  }
391 
392 #ifndef QT_NO_LIBRARY
393  if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
394  // check if any of our plugins recognize the file from its contents.
395  const qint64 pos = device ? device->pos() : 0;
396  for (int i = 0; i < keys.size(); ++i) {
397  if (i != suffixPluginIndex) {
398  QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
399  if (plugin && plugin->capabilities(device, QByteArray()) & QImageIOPlugin::CanRead) {
400  handler = plugin->create(device, testFormat);
401 #ifdef QIMAGEREADER_DEBUG
402  qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this data";
403 #endif
404  break;
405  }
406  }
407  }
408  if (device && !device->isSequential())
409  device->seek(pos);
410  }
411 #endif // QT_NO_LIBRARY
412 
413  if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
414  // check if any of our built-in handlers recognize the file from its
415  // contents.
416  int currentFormat = 0;
417  if (!suffix.isEmpty()) {
418  // If reading from a file with a suffix, start testing our
419  // built-in handler for that suffix first.
420  for (int i = 0; i < _qt_NumFormats; ++i) {
421  if (_qt_BuiltInFormats[i].extension == suffix) {
422  currentFormat = i;
423  break;
424  }
425  }
426  }
427 
428  QByteArray subType;
429  int numFormats = _qt_NumFormats;
430  while (device && numFormats >= 0) {
431  const _qt_BuiltInFormatStruct *formatStruct = &_qt_BuiltInFormats[currentFormat];
432 
433  const qint64 pos = device->pos();
434  switch (formatStruct->type) {
435 #ifndef QT_NO_IMAGEFORMAT_PNG
436  case _qt_PngFormat:
437  if (QPngHandler::canRead(device))
438  handler = new QPngHandler;
439  break;
440 #endif
441 #ifndef QT_NO_IMAGEFORMAT_JPEG
442  case _qt_JpgFormat:
443  if (QJpegHandler::canRead(device))
444  handler = new QJpegHandler;
445  break;
446 #endif
447 #ifndef QT_NO_IMAGEFORMAT_MNG
448  case _qt_MngFormat:
449  if (QMngHandler::canRead(device))
450  handler = new QMngHandler;
451  break;
452 #endif
453 #ifndef QT_NO_IMAGEFORMAT_TIFF
454  case _qt_TifFormat:
455  if (QTiffHandler::canRead(device))
456  handler = new QTiffHandler;
457  break;
458 #endif
459 #ifdef QT_BUILTIN_GIF_READER
460  case _qt_GifFormat:
461  if (QGifHandler::canRead(device))
462  handler = new QGifHandler;
463  break;
464 #endif
465 #ifndef QT_NO_IMAGEFORMAT_BMP
466  case _qt_BmpFormat:
467  if (QBmpHandler::canRead(device))
468  handler = new QBmpHandler;
469  break;
470 #endif
471 #ifndef QT_NO_IMAGEFORMAT_XPM
472  case _qt_XpmFormat:
473  if (QXpmHandler::canRead(device))
474  handler = new QXpmHandler;
475  break;
476 #endif
477 #ifndef QT_NO_IMAGEFORMAT_PPM
478  case _qt_PbmFormat:
479  case _qt_PgmFormat:
480  case _qt_PpmFormat:
481  if (QPpmHandler::canRead(device, &subType)) {
482  handler = new QPpmHandler;
483  handler->setOption(QImageIOHandler::SubType, subType);
484  }
485  break;
486 #endif
487 #ifndef QT_NO_IMAGEFORMAT_XBM
488  case _qt_XbmFormat:
489  if (QXbmHandler::canRead(device))
490  handler = new QXbmHandler;
491  break;
492 #endif
493  default:
494  break;
495  }
496  if (!device->isSequential())
497  device->seek(pos);
498 
499  if (handler) {
500 #ifdef QIMAGEREADER_DEBUG
501  qDebug() << "QImageReader::createReadHandler: the" << formatStruct->extension
502  << "built-in handler can read this data";
503 #endif
504  break;
505  }
506 
507  --numFormats;
508  ++currentFormat;
509  currentFormat %= _qt_NumFormats;
510  }
511  }
512 
513  if (!handler) {
514 #ifdef QIMAGEREADER_DEBUG
515  qDebug() << "QImageReader::createReadHandler: no handlers found. giving up.";
516 #endif
517  // no handler: give up.
518  return 0;
519  }
520 
521  handler->setDevice(device);
522  if (!form.isEmpty())
523  handler->setFormat(form);
524  return handler;
525 }
bool canRead() const
Returns true if an image can be read from the device (i.
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
virtual Capabilities capabilities(QIODevice *device, const QByteArray &format) const =0
Returns the capabilities on the plugin, based on the data in device and the format format...
int suffixPluginIndex
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from...
Definition: qiodevice.cpp:624
bool canRead() const
Returns true if an image can be read from the device (i.
QByteArray toLower() const
Returns a lowercase copy of the byte array.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
T * qobject_cast(QObject *object)
Definition: qobject.h:375
QStringList keys
Q_CORE_EXPORT void qDebug(const char *,...)
virtual void setOption(ImageOption option, const QVariant &value)
Sets the option option with the value value.
QStringList keys() const
int indexOf(const QRegExp &rx, int from=0) const
Returns the index position of the first exact match of rx in the list, searching forward from index p...
Definition: qstringlist.h:195
static bool isEmpty(const char *str)
bool canRead() const
Returns true if an image can be read from the device (i.
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
bool canRead() const
Returns true if an image can be read from the device (i.
__int64 qint64
Definition: qglobal.h:942
QByteArray testFormat
_qt_BuiltInFormatType type
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
Definition: qiodevice.cpp:454
virtual QImageIOHandler * create(QIODevice *device, const QByteArray &format=QByteArray()) const =0
Creates and returns a QImageIOHandler subclass, with device and format set.
void setDevice(QIODevice *device)
Sets the device of the QImageIOHandler to device.
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
bool canRead() const
Returns true if an image can be read from the device (i.
The QImageIOPlugin class defines an interface for writing an image format plugin. ...
The QImageIOHandler class defines the common image I/O interface for all image formats in Qt...
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
QObject * instance(const QString &key) const
QByteArray suffix
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
bool canRead() const
Returns true if an image can be read from the device (i.
QFactoryLoader * l
static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[]
quint16 index
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:60
QImageIOHandler * handler
bool canRead() const
Returns true if an image can be read from the device (i.
virtual bool canRead() const
Reimplemented Function
bool canRead() const
Returns true if an image can be read from the device (i.
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success...
Definition: qiodevice.cpp:659

◆ Q_GLOBAL_STATIC_WITH_ARGS()

Q_GLOBAL_STATIC_WITH_ARGS ( QFactoryLoader  ,
loader  ,
(QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))   
)

Definition at line 166 of file qimagereader.cpp.

170  {
171 #ifndef QT_NO_IMAGEFORMAT_PNG
172  _qt_PngFormat,
173 #endif
174 #ifndef QT_NO_IMAGEFORMAT_JPEG
175  _qt_JpgFormat,
176 #endif
177 #ifndef QT_NO_IMAGEFORMAT_MNG
178  _qt_MngFormat,
179 #endif
180 #ifndef QT_NO_IMAGEFORMAT_TIFF
181  _qt_TifFormat,
182 #endif
183 #ifdef QT_BUILTIN_GIF_READER
184  _qt_GifFormat,
185 #endif
186  _qt_BmpFormat,
187 #ifndef QT_NO_IMAGEFORMAT_PPM
188  _qt_PpmFormat,
189  _qt_PgmFormat,
190  _qt_PbmFormat,
191 #endif
192 #ifndef QT_NO_IMAGEFORMAT_XBM
193  _qt_XbmFormat,
194 #endif
195 #ifndef QT_NO_IMAGEFORMAT_XPM
196  _qt_XpmFormat,
197 #endif
198  _qt_NumFormats,
199  _qt_NoFormat = -1
200 };

Variable Documentation

◆ _qt_BuiltInFormats

const _qt_BuiltInFormatStruct _qt_BuiltInFormats[]
static
Initial value:
= {
{_qt_PngFormat, "png"},
{_qt_JpgFormat, "jpg"},
{_qt_MngFormat, "mng"},
{_qt_TifFormat, "tif"},
{_qt_BmpFormat, "bmp"},
{_qt_PpmFormat, "ppm"},
{_qt_PgmFormat, "pgm"},
{_qt_PbmFormat, "pbm"},
{_qt_XbmFormat, "xbm"},
{_qt_XpmFormat, "xpm"},
{_qt_NoFormat, ""}
}

Definition at line 208 of file qimagereader.cpp.