1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40//#define QIMAGEREADER_DEBUG
41
42/*!
43 \class QImageReader
44 \brief The QImageReader class provides a format independent interface
45 for reading images from files or other devices.
46
47 \inmodule QtGui
48 \reentrant
49 \ingroup painting
50 \ingroup io
51
52 The most common way to read images is through QImage and QPixmap's
53 constructors, or by calling QImage::load() and
54 QPixmap::load(). QImageReader is a specialized class which gives
55 you more control when reading images. For example, you can read an
56 image into a specific size by calling setScaledSize(), and you can
57 select a clip rect, effectively loading only parts of an image, by
58 calling setClipRect(). Depending on the underlying support in the
59 image format, this can save memory and speed up loading of images.
60
61 To read an image, you start by constructing a QImageReader object.
62 Pass either a file name or a device pointer, and the image format
63 to QImageReader's constructor. You can then set several options,
64 such as the clip rect (by calling setClipRect()) and scaled size
65 (by calling setScaledSize()). canRead() returns the image if the
66 QImageReader can read the image (i.e., the image format is
67 supported and the device is open for reading). Call read() to read
68 the image.
69
70 If any error occurs when reading the image, read() will return a
71 null QImage. You can then call error() to find the type of error
72 that occurred, or errorString() to get a human readable
73 description of what went wrong.
74
75 \note QImageReader assumes exclusive control over the file or
76 device that is assigned. Any attempts to modify the assigned file
77 or device during the lifetime of the QImageReader object will
78 yield undefined results.
79
80 \section1 Formats
81
82 Call supportedImageFormats() for a list of formats that
83 QImageReader can read. QImageReader supports all built-in image
84 formats, in addition to any image format plugins that support
85 reading. Call supportedMimeTypes() to obtain a list of supported MIME
86 types, which for example can be passed to QFileDialog::setMimeTypeFilters().
87
88 QImageReader autodetects the image format by default, by looking at the
89 provided (optional) format string, the file name suffix, and the data
90 stream contents. You can enable or disable this feature, by calling
91 setAutoDetectImageFormat().
92
93 \section1 High Resolution Versions of Images
94
95 It is possible to provide high resolution versions of images should a scaling
96 between \e{device pixels} and \e{device independent pixels} be in effect.
97
98 The high resolution version is marked by the suffix \c @2x on the base name.
99 The image read will have its \e{device pixel ratio} set to a value of 2.
100
101 This can be disabled by setting the environment variable
102 \c QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING.
103
104 \sa QImageWriter, QImageIOHandler, QImageIOPlugin, QMimeDatabase, QColorSpace
105 \sa QImage::devicePixelRatio(), QPixmap::devicePixelRatio(), QIcon, QPainter::drawPixmap(), QPainter::drawImage(), Qt::AA_UseHighDpiPixmaps
106*/
107
108/*!
109 \enum QImageReader::ImageReaderError
110
111 This enum describes the different types of errors that can occur
112 when reading images with QImageReader.
113
114 \value FileNotFoundError QImageReader was used with a file name,
115 but not file was found with that name. This can also happen if the
116 file name contained no extension, and the file with the correct
117 extension is not supported by Qt.
118
119 \value DeviceError QImageReader encountered a device error when
120 reading the image. You can consult your particular device for more
121 details on what went wrong.
122
123 \value UnsupportedFormatError Qt does not support the requested
124 image format.
125
126 \value InvalidDataError The image data was invalid, and
127 QImageReader was unable to read an image from it. The can happen
128 if the image file is damaged.
129
130 \value UnknownError An unknown error occurred. If you get this
131 value after calling read(), it is most likely caused by a bug in
132 QImageReader.
133*/
134#include "qimagereader.h"
135
136#include <qbytearray.h>
137#ifdef QIMAGEREADER_DEBUG
138#include <qdebug.h>
139#endif
140#include <qfile.h>
141#include <qfileinfo.h>
142#include <qimage.h>
143#include <qimageiohandler.h>
144#include <qlist.h>
145#include <qrect.h>
146#include <qsize.h>
147#include <qcolor.h>
148#include <qvariant.h>
149
150// factory loader
151#include <qcoreapplication.h>
152#include <private/qfactoryloader_p.h>
153#include <QtCore/private/qlocking_p.h>
154
155// for qt_getImageText
156#include <private/qimage_p.h>
157
158// image handlers
159#include <private/qbmphandler_p.h>
160#include <private/qppmhandler_p.h>
161#include <private/qxbmhandler_p.h>
162#include <private/qxpmhandler_p.h>
163#ifndef QT_NO_IMAGEFORMAT_PNG
164#include <private/qpnghandler_p.h>
165#endif
166
167#include <private/qimagereaderwriterhelpers_p.h>
168#include <qtgui_tracepoints_p.h>
169
170#include <algorithm>
171
172QT_BEGIN_NAMESPACE
173
174using namespace QImageReaderWriterHelpers;
175
176static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
177 const QByteArray &format,
178 bool autoDetectImageFormat,
179 bool ignoresFormatAndExtension)
180{
181 if (!autoDetectImageFormat && format.isEmpty())
182 return nullptr;
183
184 QByteArray form = format.toLower();
185 QImageIOHandler *handler = nullptr;
186 QByteArray suffix;
187
188#ifndef QT_NO_IMAGEFORMATPLUGIN
189 static QBasicMutex mutex;
190 const auto locker = qt_scoped_lock(mutex);
191
192 typedef QMultiMap<int, QString> PluginKeyMap;
193
194 // check if we have plugins that support the image format
195 auto l = QImageReaderWriterHelpers::pluginLoader();
196 const PluginKeyMap keyMap = l->keyMap();
197
198#ifdef QIMAGEREADER_DEBUG
199 qDebug() << "QImageReader::createReadHandler( device =" << (void *)device << ", format =" << format << "),"
200 << keyMap.uniqueKeys().size() << "plugins available: " << keyMap;
201#endif
202
203 int suffixPluginIndex = -1;
204#endif // QT_NO_IMAGEFORMATPLUGIN
205
206 if (device && format.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) {
207 // if there's no format, see if \a device is a file, and if so, find
208 // the file suffix and find support for that format among our plugins.
209 // this allows plugins to override our built-in handlers.
210 if (QFile *file = qobject_cast<QFile *>(object: device)) {
211#ifdef QIMAGEREADER_DEBUG
212 qDebug() << "QImageReader::createReadHandler: device is a file:" << file->fileName();
213#endif
214 if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) {
215#ifndef QT_NO_IMAGEFORMATPLUGIN
216 const int index = keyMap.key(avalue: QString::fromLatin1(str: suffix), defaultKey: -1);
217 if (index != -1) {
218#ifdef QIMAGEREADER_DEBUG
219 qDebug() << "QImageReader::createReadHandler: suffix recognized; the"
220 << suffix << "plugin might be able to read this";
221#endif
222 suffixPluginIndex = index;
223 }
224#endif // QT_NO_IMAGEFORMATPLUGIN
225 }
226 }
227 }
228
229 QByteArray testFormat = !form.isEmpty() ? form : suffix;
230
231 if (ignoresFormatAndExtension)
232 testFormat = QByteArray();
233
234#ifndef QT_NO_IMAGEFORMATPLUGIN
235 if (suffixPluginIndex != -1) {
236 // check if the plugin that claims support for this format can load
237 // from this device with this format.
238 const qint64 pos = device ? device->pos() : 0;
239 const int index = keyMap.key(avalue: QString::fromLatin1(str: suffix), defaultKey: -1);
240 if (index != -1) {
241 QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(object: l->instance(index));
242 if (plugin && plugin->capabilities(device, format: testFormat) & QImageIOPlugin::CanRead) {
243 handler = plugin->create(device, format: testFormat);
244#ifdef QIMAGEREADER_DEBUG
245 qDebug() << "QImageReader::createReadHandler: using the" << suffix
246 << "plugin";
247#endif
248 }
249 }
250 if (device && !device->isSequential())
251 device->seek(pos);
252 }
253
254 if (!handler && !testFormat.isEmpty() && !ignoresFormatAndExtension) {
255 // check if any plugin supports the format (they are not allowed to
256 // read from the device yet).
257 const qint64 pos = device ? device->pos() : 0;
258
259 if (autoDetectImageFormat) {
260 const int keyCount = keyMap.size();
261 for (int i = 0; i < keyCount; ++i) {
262 if (i != suffixPluginIndex) {
263 QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(object: l->instance(index: i));
264 if (plugin && plugin->capabilities(device, format: testFormat) & QImageIOPlugin::CanRead) {
265#ifdef QIMAGEREADER_DEBUG
266 qDebug() << "QImageReader::createReadHandler: the" << keyMap.keys().at(i) << "plugin can read this format";
267#endif
268 handler = plugin->create(device, format: testFormat);
269 break;
270 }
271 }
272 }
273 } else {
274 const int testIndex = keyMap.key(avalue: QLatin1String(testFormat), defaultKey: -1);
275 if (testIndex != -1) {
276 QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(object: l->instance(index: testIndex));
277 if (plugin && plugin->capabilities(device, format: testFormat) & QImageIOPlugin::CanRead) {
278#ifdef QIMAGEREADER_DEBUG
279 qDebug() << "QImageReader::createReadHandler: the" << testFormat << "plugin can read this format";
280#endif
281 handler = plugin->create(device, format: testFormat);
282 }
283 }
284 }
285 if (device && !device->isSequential())
286 device->seek(pos);
287 }
288
289#endif // QT_NO_IMAGEFORMATPLUGIN
290
291 // if we don't have a handler yet, check if we have built-in support for
292 // the format
293 if (!handler && !testFormat.isEmpty()) {
294 if (false) {
295#ifndef QT_NO_IMAGEFORMAT_PNG
296 } else if (testFormat == "png") {
297 handler = new QPngHandler;
298#endif
299#ifndef QT_NO_IMAGEFORMAT_BMP
300 } else if (testFormat == "bmp") {
301 handler = new QBmpHandler;
302 } else if (testFormat == "dib") {
303 handler = new QBmpHandler(QBmpHandler::DibFormat);
304#endif
305#ifndef QT_NO_IMAGEFORMAT_XPM
306 } else if (testFormat == "xpm") {
307 handler = new QXpmHandler;
308#endif
309#ifndef QT_NO_IMAGEFORMAT_XBM
310 } else if (testFormat == "xbm") {
311 handler = new QXbmHandler;
312 handler->setOption(option: QImageIOHandler::SubType, value: testFormat);
313#endif
314#ifndef QT_NO_IMAGEFORMAT_PPM
315 } else if (testFormat == "pbm" || testFormat == "pbmraw" || testFormat == "pgm"
316 || testFormat == "pgmraw" || testFormat == "ppm" || testFormat == "ppmraw") {
317 handler = new QPpmHandler;
318 handler->setOption(option: QImageIOHandler::SubType, value: testFormat);
319#endif
320 }
321
322#ifdef QIMAGEREADER_DEBUG
323 if (handler)
324 qDebug() << "QImageReader::createReadHandler: using the built-in handler for" << testFormat;
325#endif
326 }
327
328 if (handler && device && !suffix.isEmpty()) {
329 Q_ASSERT(qobject_cast<QFile *>(device));
330 // We have a file claiming to be of a recognized format. Now confirm that
331 // the handler also recognizes the file contents.
332 const qint64 pos = device->pos();
333 handler->setDevice(device);
334 if (!form.isEmpty())
335 handler->setFormat(form);
336 bool canRead = handler->canRead();
337 device->seek(pos);
338 if (canRead) {
339 // ok, we're done.
340 return handler;
341 }
342#ifdef QIMAGEREADER_DEBUG
343 qDebug() << "QImageReader::createReadHandler: the" << suffix << "handler can not read this file";
344#endif
345 // File may still be valid, just with wrong suffix, so fall back to
346 // finding a handler based on contents, below.
347 delete handler;
348 handler = nullptr;
349 }
350
351#ifndef QT_NO_IMAGEFORMATPLUGIN
352 if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
353 // check if any of our plugins recognize the file from its contents.
354 const qint64 pos = device ? device->pos() : 0;
355 const int keyCount = keyMap.size();
356 for (int i = 0; i < keyCount; ++i) {
357 if (i != suffixPluginIndex) {
358 QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(object: l->instance(index: i));
359 if (plugin && plugin->capabilities(device, format: QByteArray()) & QImageIOPlugin::CanRead) {
360 handler = plugin->create(device, format: testFormat);
361#ifdef QIMAGEREADER_DEBUG
362 qDebug() << "QImageReader::createReadHandler: the" << keyMap.value(i) << "plugin can read this data";
363#endif
364 break;
365 }
366 }
367 }
368 if (device && !device->isSequential())
369 device->seek(pos);
370 }
371#endif // QT_NO_IMAGEFORMATPLUGIN
372
373 if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
374 // check if any of our built-in handlers recognize the file from its
375 // contents.
376 int currentFormat = 0;
377 if (!suffix.isEmpty()) {
378 // If reading from a file with a suffix, start testing our
379 // built-in handler for that suffix first.
380 for (int i = 0; i < _qt_NumFormats; ++i) {
381 if (_qt_BuiltInFormats[i].extension == suffix) {
382 currentFormat = i;
383 break;
384 }
385 }
386 }
387
388 QByteArray subType;
389 int numFormats = _qt_NumFormats;
390 while (device && numFormats >= 0) {
391 const qint64 pos = device->pos();
392 switch (currentFormat) {
393#ifndef QT_NO_IMAGEFORMAT_PNG
394 case _qt_PngFormat:
395 if (QPngHandler::canRead(device))
396 handler = new QPngHandler;
397 break;
398#endif
399#ifndef QT_NO_IMAGEFORMAT_BMP
400 case _qt_BmpFormat:
401 if (QBmpHandler::canRead(device))
402 handler = new QBmpHandler;
403 break;
404#endif
405#ifndef QT_NO_IMAGEFORMAT_XPM
406 case _qt_XpmFormat:
407 if (QXpmHandler::canRead(device))
408 handler = new QXpmHandler;
409 break;
410#endif
411#ifndef QT_NO_IMAGEFORMAT_PPM
412 case _qt_PbmFormat:
413 case _qt_PgmFormat:
414 case _qt_PpmFormat:
415 if (QPpmHandler::canRead(device, subType: &subType)) {
416 handler = new QPpmHandler;
417 handler->setOption(option: QImageIOHandler::SubType, value: subType);
418 }
419 break;
420#endif
421#ifndef QT_NO_IMAGEFORMAT_XBM
422 case _qt_XbmFormat:
423 if (QXbmHandler::canRead(device))
424 handler = new QXbmHandler;
425 break;
426#endif
427 default:
428 break;
429 }
430 if (!device->isSequential())
431 device->seek(pos);
432
433 if (handler) {
434#ifdef QIMAGEREADER_DEBUG
435 qDebug("QImageReader::createReadHandler: the %s built-in handler can read this data",
436 _qt_BuiltInFormats[currentFormat].extension);
437#endif
438 break;
439 }
440
441 --numFormats;
442 ++currentFormat;
443 if (currentFormat >= _qt_NumFormats)
444 currentFormat = 0;
445 }
446 }
447
448 if (!handler) {
449#ifdef QIMAGEREADER_DEBUG
450 qDebug("QImageReader::createReadHandler: no handlers found. giving up.");
451#endif
452 // no handler: give up.
453 return nullptr;
454 }
455
456 handler->setDevice(device);
457 if (!form.isEmpty())
458 handler->setFormat(form);
459 return handler;
460}
461
462class QImageReaderPrivate
463{
464public:
465 QImageReaderPrivate(QImageReader *qq);
466 ~QImageReaderPrivate();
467
468 // device
469 QByteArray format;
470 bool autoDetectImageFormat;
471 bool ignoresFormatAndExtension;
472 QIODevice *device;
473 bool deleteDevice;
474 QImageIOHandler *handler;
475 bool initHandler();
476
477 // image options
478 QRect clipRect;
479 QSize scaledSize;
480 QRect scaledClipRect;
481 int quality;
482 QMap<QString, QString> text;
483 void getText();
484 enum {
485 UsePluginDefault,
486 ApplyTransform,
487 DoNotApplyTransform
488 } autoTransform;
489
490 // error
491 QImageReader::ImageReaderError imageReaderError;
492 QString errorString;
493
494 QImageReader *q;
495};
496
497/*!
498 \internal
499*/
500QImageReaderPrivate::QImageReaderPrivate(QImageReader *qq)
501 : autoDetectImageFormat(true), ignoresFormatAndExtension(false)
502{
503 device = nullptr;
504 deleteDevice = false;
505 handler = nullptr;
506 quality = -1;
507 imageReaderError = QImageReader::UnknownError;
508 autoTransform = UsePluginDefault;
509
510 q = qq;
511}
512
513/*!
514 \internal
515*/
516QImageReaderPrivate::~QImageReaderPrivate()
517{
518 if (deleteDevice)
519 delete device;
520 delete handler;
521}
522
523/*!
524 \internal
525*/
526bool QImageReaderPrivate::initHandler()
527{
528 // check some preconditions
529 if (!device || (!deleteDevice && !device->isOpen() && !device->open(mode: QIODevice::ReadOnly))) {
530 imageReaderError = QImageReader::DeviceError;
531 errorString = QImageReader::tr(sourceText: "Invalid device");
532 return false;
533 }
534
535 // probe the file extension
536 if (deleteDevice && !device->isOpen() && !device->open(mode: QIODevice::ReadOnly) && autoDetectImageFormat) {
537 Q_ASSERT(qobject_cast<QFile*>(device) != 0); // future-proofing; for now this should always be the case, so...
538 QFile *file = static_cast<QFile *>(device);
539
540 if (file->error() == QFileDevice::ResourceError) {
541 // this is bad. we should abort the open attempt and note the failure.
542 imageReaderError = QImageReader::DeviceError;
543 errorString = file->errorString();
544 return false;
545 }
546
547 QList<QByteArray> extensions = QImageReader::supportedImageFormats();
548 if (!format.isEmpty()) {
549 // Try the most probable extension first
550 int currentFormatIndex = extensions.indexOf(t: format.toLower());
551 if (currentFormatIndex > 0)
552 extensions.swapItemsAt(i: 0, j: currentFormatIndex);
553 }
554
555 int currentExtension = 0;
556
557 QString fileName = file->fileName();
558
559 do {
560 file->setFileName(fileName + QLatin1Char('.')
561 + QLatin1String(extensions.at(i: currentExtension++).constData()));
562 file->open(flags: QIODevice::ReadOnly);
563 } while (!file->isOpen() && currentExtension < extensions.size());
564
565 if (!device->isOpen()) {
566 imageReaderError = QImageReader::FileNotFoundError;
567 errorString = QImageReader::tr(sourceText: "File not found");
568 file->setFileName(fileName); // restore the old file name
569 return false;
570 }
571 }
572
573 // assign a handler
574 if (!handler && (handler = createReadHandlerHelper(device, format, autoDetectImageFormat, ignoresFormatAndExtension)) == nullptr) {
575 imageReaderError = QImageReader::UnsupportedFormatError;
576 errorString = QImageReader::tr(sourceText: "Unsupported image format");
577 return false;
578 }
579 return true;
580}
581
582/*!
583 \internal
584*/
585void QImageReaderPrivate::getText()
586{
587 if (text.isEmpty() && (handler || initHandler()) && handler->supportsOption(option: QImageIOHandler::Description))
588 text = qt_getImageTextFromDescription(description: handler->option(option: QImageIOHandler::Description).toString());
589}
590
591/*!
592 Constructs an empty QImageReader object. Before reading an image,
593 call setDevice() or setFileName().
594*/
595QImageReader::QImageReader()
596 : d(new QImageReaderPrivate(this))
597{
598}
599
600/*!
601 Constructs a QImageReader object with the device \a device and the
602 image format \a format.
603*/
604QImageReader::QImageReader(QIODevice *device, const QByteArray &format)
605 : d(new QImageReaderPrivate(this))
606{
607 d->device = device;
608 d->format = format;
609}
610
611/*!
612 Constructs a QImageReader object with the file name \a fileName
613 and the image format \a format.
614
615 \sa setFileName()
616*/
617QImageReader::QImageReader(const QString &fileName, const QByteArray &format)
618 : QImageReader(new QFile(fileName), format)
619{
620 d->deleteDevice = true;
621}
622
623/*!
624 Destructs the QImageReader object.
625*/
626QImageReader::~QImageReader()
627{
628 delete d;
629}
630
631/*!
632 Sets the format QImageReader will use when reading images, to \a
633 format. \a format is a case insensitive text string. Example:
634
635 \snippet code/src_gui_image_qimagereader.cpp 0
636
637 You can call supportedImageFormats() for the full list of formats
638 QImageReader supports.
639
640 \sa format()
641*/
642void QImageReader::setFormat(const QByteArray &format)
643{
644 d->format = format;
645}
646
647/*!
648 Returns the format QImageReader uses for reading images.
649
650 You can call this function after assigning a device to the
651 reader to determine the format of the device. For example:
652
653 \snippet code/src_gui_image_qimagereader.cpp 1
654
655 If the reader cannot read any image from the device (e.g., there is no
656 image there, or the image has already been read), or if the format is
657 unsupported, this function returns an empty QByteArray().
658
659 \sa setFormat(), supportedImageFormats()
660*/
661QByteArray QImageReader::format() const
662{
663 if (d->format.isEmpty()) {
664 if (!d->initHandler())
665 return QByteArray();
666 return d->handler->canRead() ? d->handler->format() : QByteArray();
667 }
668
669 return d->format;
670}
671
672/*!
673 If \a enabled is true, image format autodetection is enabled; otherwise,
674 it is disabled. By default, autodetection is enabled.
675
676 QImageReader uses an extensive approach to detecting the image format;
677 firstly, if you pass a file name to QImageReader, it will attempt to
678 detect the file extension if the given file name does not point to an
679 existing file, by appending supported default extensions to the given file
680 name, one at a time. It then uses the following approach to detect the
681 image format:
682
683 \list
684
685 \li Image plugins are queried first, based on either the optional format
686 string, or the file name suffix (if the source device is a file). No
687 content detection is done at this stage. QImageReader will choose the
688 first plugin that supports reading for this format.
689
690 \li If no plugin supports the image format, Qt's built-in handlers are
691 checked based on either the optional format string, or the file name
692 suffix.
693
694 \li If no capable plugins or built-in handlers are found, each plugin is
695 tested by inspecting the content of the data stream.
696
697 \li If no plugins could detect the image format based on data contents,
698 each built-in image handler is tested by inspecting the contents.
699
700 \li Finally, if all above approaches fail, QImageReader will report failure
701 when trying to read the image.
702
703 \endlist
704
705 By disabling image format autodetection, QImageReader will only query the
706 plugins and built-in handlers based on the format string (i.e., no file
707 name extensions are tested).
708
709 \sa QImageIOHandler::canRead(), QImageIOPlugin::capabilities()
710*/
711void QImageReader::setAutoDetectImageFormat(bool enabled)
712{
713 d->autoDetectImageFormat = enabled;
714}
715
716/*!
717 Returns \c true if image format autodetection is enabled on this image
718 reader; otherwise returns \c false. By default, autodetection is enabled.
719
720 \sa setAutoDetectImageFormat()
721*/
722bool QImageReader::autoDetectImageFormat() const
723{
724 return d->autoDetectImageFormat;
725}
726
727
728/*!
729 If \a ignored is set to true, then the image reader will ignore
730 specified formats or file extensions and decide which plugin to
731 use only based on the contents in the datastream.
732
733 Setting this flag means that all image plugins gets loaded. Each
734 plugin will read the first bytes in the image data and decide if
735 the plugin is compatible or not.
736
737 This also disables auto detecting the image format.
738
739 \sa decideFormatFromContent()
740*/
741
742void QImageReader::setDecideFormatFromContent(bool ignored)
743{
744 d->ignoresFormatAndExtension = ignored;
745}
746
747
748/*!
749 Returns whether the image reader should decide which plugin to use
750 only based on the contents of the datastream rather than on the file
751 extension.
752
753 \sa setDecideFormatFromContent()
754*/
755
756bool QImageReader::decideFormatFromContent() const
757{
758 return d->ignoresFormatAndExtension;
759}
760
761
762/*!
763 Sets QImageReader's device to \a device. If a device has already
764 been set, the old device is removed from QImageReader and is
765 otherwise left unchanged.
766
767 If the device is not already open, QImageReader will attempt to
768 open the device in \l QIODevice::ReadOnly mode by calling
769 open(). Note that this does not work for certain devices, such as
770 QProcess, QTcpSocket and QUdpSocket, where more logic is required
771 to open the device.
772
773 \sa device(), setFileName()
774*/
775void QImageReader::setDevice(QIODevice *device)
776{
777 if (d->device && d->deleteDevice)
778 delete d->device;
779 d->device = device;
780 d->deleteDevice = false;
781 delete d->handler;
782 d->handler = nullptr;
783 d->text.clear();
784}
785
786/*!
787 Returns the device currently assigned to QImageReader, or \nullptr
788 if no device has been assigned.
789*/
790QIODevice *QImageReader::device() const
791{
792 return d->device;
793}
794
795/*!
796 Sets the file name of QImageReader to \a fileName. Internally,
797 QImageReader will create a QFile object and open it in \l
798 QIODevice::ReadOnly mode, and use this when reading images.
799
800 If \a fileName does not include a file extension (e.g., .png or .bmp),
801 QImageReader will cycle through all supported extensions until it finds
802 a matching file.
803
804 \sa fileName(), setDevice(), supportedImageFormats()
805*/
806void QImageReader::setFileName(const QString &fileName)
807{
808 setDevice(new QFile(fileName));
809 d->deleteDevice = true;
810}
811
812/*!
813 If the currently assigned device is a QFile, or if setFileName()
814 has been called, this function returns the name of the file
815 QImageReader reads from. Otherwise (i.e., if no device has been
816 assigned or the device is not a QFile), an empty QString is
817 returned.
818
819 \sa setFileName(), setDevice()
820*/
821QString QImageReader::fileName() const
822{
823 QFile *file = qobject_cast<QFile *>(object: d->device);
824 return file ? file->fileName() : QString();
825}
826
827/*!
828 \since 4.2
829
830 Sets the quality setting of the image format to \a quality.
831
832 Some image formats, in particular lossy ones, entail a tradeoff between a)
833 visual quality of the resulting image, and b) decoding execution time.
834 This function sets the level of that tradeoff for image formats that
835 support it.
836
837 In case of scaled image reading, the quality setting may also influence the
838 tradeoff level between visual quality and execution speed of the scaling
839 algorithm.
840
841 The value range of \a quality depends on the image format. For example,
842 the "jpeg" format supports a quality range from 0 (low visual quality) to
843 100 (high visual quality).
844
845 \sa quality() setScaledSize()
846*/
847void QImageReader::setQuality(int quality)
848{
849 d->quality = quality;
850}
851
852/*!
853 \since 4.2
854
855 Returns the quality setting of the image format.
856
857 \sa setQuality()
858*/
859int QImageReader::quality() const
860{
861 return d->quality;
862}
863
864
865/*!
866 Returns the size of the image, without actually reading the image
867 contents.
868
869 If the image format does not support this feature, this function returns
870 an invalid size. Qt's built-in image handlers all support this feature,
871 but custom image format plugins are not required to do so.
872
873 \sa QImageIOHandler::ImageOption, QImageIOHandler::option(), QImageIOHandler::supportsOption()
874*/
875QSize QImageReader::size() const
876{
877 if (!d->initHandler())
878 return QSize();
879
880 if (d->handler->supportsOption(option: QImageIOHandler::Size))
881 return d->handler->option(option: QImageIOHandler::Size).toSize();
882
883 return QSize();
884}
885
886/*!
887 \since 4.5
888
889 Returns the format of the image, without actually reading the image
890 contents. The format describes the image format \l QImageReader::read()
891 returns, not the format of the actual image.
892
893 If the image format does not support this feature, this function returns
894 an invalid format.
895
896 \sa QImageIOHandler::ImageOption, QImageIOHandler::option(), QImageIOHandler::supportsOption()
897*/
898QImage::Format QImageReader::imageFormat() const
899{
900 if (!d->initHandler())
901 return QImage::Format_Invalid;
902
903 if (d->handler->supportsOption(option: QImageIOHandler::ImageFormat))
904 return (QImage::Format)d->handler->option(option: QImageIOHandler::ImageFormat).toInt();
905
906 return QImage::Format_Invalid;
907}
908
909/*!
910 \since 4.1
911
912 Returns the text keys for this image. You can use
913 these keys with text() to list the image text for
914 a certain key.
915
916 Support for this option is implemented through
917 QImageIOHandler::Description.
918
919 \sa text(), QImageWriter::setText(), QImage::textKeys()
920*/
921QStringList QImageReader::textKeys() const
922{
923 d->getText();
924 return d->text.keys();
925}
926
927/*!
928 \since 4.1
929
930 Returns the image text associated with \a key.
931
932 Support for this option is implemented through
933 QImageIOHandler::Description.
934
935 \sa textKeys(), QImageWriter::setText()
936*/
937QString QImageReader::text(const QString &key) const
938{
939 d->getText();
940 return d->text.value(akey: key);
941}
942
943/*!
944 Sets the image clip rect (also known as the ROI, or Region Of
945 Interest) to \a rect. The coordinates of \a rect are relative to
946 the untransformed image size, as returned by size().
947
948 \sa clipRect(), setScaledSize(), setScaledClipRect()
949*/
950void QImageReader::setClipRect(const QRect &rect)
951{
952 d->clipRect = rect;
953}
954
955/*!
956 Returns the clip rect (also known as the ROI, or Region Of
957 Interest) of the image. If no clip rect has been set, an invalid
958 QRect is returned.
959
960 \sa setClipRect()
961*/
962QRect QImageReader::clipRect() const
963{
964 return d->clipRect;
965}
966
967/*!
968 Sets the scaled size of the image to \a size. The scaling is
969 performed after the initial clip rect, but before the scaled clip
970 rect is applied. The algorithm used for scaling depends on the
971 image format. By default (i.e., if the image format does not
972 support scaling), QImageReader will use QImage::scale() with
973 Qt::SmoothScaling.
974
975 \sa scaledSize(), setClipRect(), setScaledClipRect()
976*/
977void QImageReader::setScaledSize(const QSize &size)
978{
979 d->scaledSize = size;
980}
981
982/*!
983 Returns the scaled size of the image.
984
985 \sa setScaledSize()
986*/
987QSize QImageReader::scaledSize() const
988{
989 return d->scaledSize;
990}
991
992/*!
993 Sets the scaled clip rect to \a rect. The scaled clip rect is the
994 clip rect (also known as ROI, or Region Of Interest) that is
995 applied after the image has been scaled.
996
997 \sa scaledClipRect(), setScaledSize()
998*/
999void QImageReader::setScaledClipRect(const QRect &rect)
1000{
1001 d->scaledClipRect = rect;
1002}
1003
1004/*!
1005 Returns the scaled clip rect of the image.
1006
1007 \sa setScaledClipRect()
1008*/
1009QRect QImageReader::scaledClipRect() const
1010{
1011 return d->scaledClipRect;
1012}
1013
1014/*!
1015 \since 4.1
1016
1017 Sets the background color to \a color.
1018 Image formats that support this operation are expected to
1019 initialize the background to \a color before reading an image.
1020
1021 \sa backgroundColor(), read()
1022*/
1023void QImageReader::setBackgroundColor(const QColor &color)
1024{
1025 if (!d->initHandler())
1026 return;
1027 if (d->handler->supportsOption(option: QImageIOHandler::BackgroundColor))
1028 d->handler->setOption(option: QImageIOHandler::BackgroundColor, value: color);
1029}
1030
1031/*!
1032 \since 4.1
1033
1034 Returns the background color that's used when reading an image.
1035 If the image format does not support setting the background color
1036 an invalid color is returned.
1037
1038 \sa setBackgroundColor(), read()
1039*/
1040QColor QImageReader::backgroundColor() const
1041{
1042 if (!d->initHandler())
1043 return QColor();
1044 if (d->handler->supportsOption(option: QImageIOHandler::BackgroundColor))
1045 return qvariant_cast<QColor>(v: d->handler->option(option: QImageIOHandler::BackgroundColor));
1046 return QColor();
1047}
1048
1049/*!
1050 \since 4.1
1051
1052 Returns \c true if the image format supports animation;
1053 otherwise, false is returned.
1054
1055 \sa QMovie::supportedFormats()
1056*/
1057bool QImageReader::supportsAnimation() const
1058{
1059 if (!d->initHandler())
1060 return false;
1061 if (d->handler->supportsOption(option: QImageIOHandler::Animation))
1062 return d->handler->option(option: QImageIOHandler::Animation).toBool();
1063 return false;
1064}
1065
1066/*!
1067 \since 5.4
1068
1069 Returns the subtype of the image.
1070*/
1071QByteArray QImageReader::subType() const
1072{
1073 if (!d->initHandler())
1074 return QByteArray();
1075
1076 if (d->handler->supportsOption(option: QImageIOHandler::SubType))
1077 return d->handler->option(option: QImageIOHandler::SubType).toByteArray();
1078 return QByteArray();
1079}
1080
1081/*!
1082 \since 5.4
1083
1084 Returns the list of subtypes supported by an image.
1085*/
1086QList<QByteArray> QImageReader::supportedSubTypes() const
1087{
1088 if (!d->initHandler())
1089 return QList<QByteArray>();
1090
1091 if (d->handler->supportsOption(option: QImageIOHandler::SupportedSubTypes))
1092 return qvariant_cast<QList<QByteArray> >(v: d->handler->option(option: QImageIOHandler::SupportedSubTypes));
1093 return QList<QByteArray>();
1094}
1095
1096/*!
1097 \since 5.5
1098
1099 Returns the transformation metadata of the image, including image orientation. If the format
1100 does not support transformation metadata, QImageIOHandler::TransformationNone is returned.
1101
1102 \sa setAutoTransform(), autoTransform()
1103*/
1104QImageIOHandler::Transformations QImageReader::transformation() const
1105{
1106 int option = QImageIOHandler::TransformationNone;
1107 if (d->initHandler() && d->handler->supportsOption(option: QImageIOHandler::ImageTransformation))
1108 option = d->handler->option(option: QImageIOHandler::ImageTransformation).toInt();
1109 return QImageIOHandler::Transformations(option);
1110}
1111
1112/*!
1113 \since 5.5
1114
1115 Determines that images returned by read() should have transformation metadata automatically
1116 applied if \a enabled is \c true.
1117
1118 \sa autoTransform(), transformation(), read()
1119*/
1120void QImageReader::setAutoTransform(bool enabled)
1121{
1122 d->autoTransform = enabled ? QImageReaderPrivate::ApplyTransform
1123 : QImageReaderPrivate::DoNotApplyTransform;
1124}
1125
1126/*!
1127 \since 5.5
1128
1129 Returns \c true if the image handler will apply transformation metadata on read().
1130
1131 \sa setAutoTransform(), transformation(), read()
1132*/
1133bool QImageReader::autoTransform() const
1134{
1135 switch (d->autoTransform) {
1136 case QImageReaderPrivate::ApplyTransform:
1137 return true;
1138 case QImageReaderPrivate::DoNotApplyTransform:
1139 return false;
1140 case QImageReaderPrivate::UsePluginDefault:
1141#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1142 if (d->initHandler())
1143 return d->handler->supportsOption(option: QImageIOHandler::TransformedByDefault);
1144#endif
1145 Q_FALLTHROUGH();
1146 default:
1147 break;
1148 }
1149 return false;
1150}
1151
1152#if QT_DEPRECATED_SINCE(5, 15)
1153/*!
1154 \since 5.6
1155 \obsolete Use QColorSpace conversion on the QImage instead.
1156
1157 This is an image format specific function that forces images with
1158 gamma information to be gamma corrected to \a gamma. For image formats
1159 that do not support gamma correction, this value is ignored.
1160
1161 To gamma correct to a standard PC color-space, set gamma to \c 1/2.2.
1162
1163 \sa gamma()
1164*/
1165void QImageReader::setGamma(float gamma)
1166{
1167 if (d->initHandler() && d->handler->supportsOption(option: QImageIOHandler::Gamma))
1168 d->handler->setOption(option: QImageIOHandler::Gamma, value: gamma);
1169}
1170
1171/*!
1172 \since 5.6
1173 \obsolete Use QImage::colorSpace() and QColorSpace::gamma() instead.
1174
1175 Returns the gamma level of the decoded image. If setGamma() has been
1176 called and gamma correction is supported it will return the gamma set.
1177 If gamma level is not supported by the image format, \c 0.0 is returned.
1178
1179 \sa setGamma()
1180*/
1181float QImageReader::gamma() const
1182{
1183 if (d->initHandler() && d->handler->supportsOption(option: QImageIOHandler::Gamma))
1184 return d->handler->option(option: QImageIOHandler::Gamma).toFloat();
1185 return 0.0;
1186}
1187#endif
1188
1189/*!
1190 Returns \c true if an image can be read for the device (i.e., the
1191 image format is supported, and the device seems to contain valid
1192 data); otherwise returns \c false.
1193
1194 canRead() is a lightweight function that only does a quick test to
1195 see if the image data is valid. read() may still return false
1196 after canRead() returns \c true, if the image data is corrupt.
1197
1198 \note A QMimeDatabase lookup is normally a better approach than this
1199 function for identifying potentially non-image files or data.
1200
1201 For images that support animation, canRead() returns \c false when
1202 all frames have been read.
1203
1204 \sa read(), supportedImageFormats(), QMimeDatabase
1205*/
1206bool QImageReader::canRead() const
1207{
1208 if (!d->initHandler())
1209 return false;
1210
1211 return d->handler->canRead();
1212}
1213
1214/*!
1215 Reads an image from the device. On success, the image that was
1216 read is returned; otherwise, a null QImage is returned. You can
1217 then call error() to find the type of error that occurred, or
1218 errorString() to get a human readable description of the error.
1219
1220 For image formats that support animation, calling read()
1221 repeatedly will return the next frame. When all frames have been
1222 read, a null image will be returned.
1223
1224 \sa canRead(), supportedImageFormats(), supportsAnimation(), QMovie
1225*/
1226QImage QImageReader::read()
1227{
1228 // Because failed image reading might have side effects, we explicitly
1229 // return a null image instead of the image we've just created.
1230 QImage image;
1231 return read(image: &image) ? image : QImage();
1232}
1233
1234extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient);
1235
1236/*!
1237 \overload
1238
1239 Reads an image from the device into \a image, which must point to a
1240 QImage. Returns \c true on success; otherwise, returns \c false.
1241
1242 If \a image has same format and size as the image data that is about to be
1243 read, this function may not need to allocate a new image before
1244 reading. Because of this, it can be faster than the other read() overload,
1245 which always constructs a new image; especially when reading several
1246 images with the same format and size.
1247
1248 \snippet code/src_gui_image_qimagereader.cpp 2
1249
1250 For image formats that support animation, calling read() repeatedly will
1251 return the next frame. When all frames have been read, a null image will
1252 be returned.
1253
1254 \sa canRead(), supportedImageFormats(), supportsAnimation(), QMovie
1255*/
1256bool QImageReader::read(QImage *image)
1257{
1258 if (!image) {
1259 qWarning(msg: "QImageReader::read: cannot read into null pointer");
1260 return false;
1261 }
1262
1263 if (!d->handler && !d->initHandler())
1264 return false;
1265
1266 // set the handler specific options.
1267 if (d->handler->supportsOption(option: QImageIOHandler::ScaledSize) && d->scaledSize.isValid()) {
1268 if ((d->handler->supportsOption(option: QImageIOHandler::ClipRect) && !d->clipRect.isNull())
1269 || d->clipRect.isNull()) {
1270 // Only enable the ScaledSize option if there is no clip rect, or
1271 // if the handler also supports ClipRect.
1272 d->handler->setOption(option: QImageIOHandler::ScaledSize, value: d->scaledSize);
1273 }
1274 }
1275 if (d->handler->supportsOption(option: QImageIOHandler::ClipRect) && !d->clipRect.isNull())
1276 d->handler->setOption(option: QImageIOHandler::ClipRect, value: d->clipRect);
1277 if (d->handler->supportsOption(option: QImageIOHandler::ScaledClipRect) && !d->scaledClipRect.isNull())
1278 d->handler->setOption(option: QImageIOHandler::ScaledClipRect, value: d->scaledClipRect);
1279 if (d->handler->supportsOption(option: QImageIOHandler::Quality))
1280 d->handler->setOption(option: QImageIOHandler::Quality, value: d->quality);
1281
1282 // read the image
1283 if (Q_TRACE_ENABLED(QImageReader_read_before_reading)) {
1284 QString fileName = QStringLiteral("unknown");
1285 if (QFile *file = qobject_cast<QFile *>(object: d->device))
1286 fileName = file->fileName();
1287 Q_TRACE(QImageReader_read_before_reading, this, fileName);
1288 }
1289
1290 const bool result = d->handler->read(image);
1291
1292 Q_TRACE(QImageReader_read_after_reading, this, result);
1293
1294 if (!result) {
1295 d->imageReaderError = InvalidDataError;
1296 d->errorString = QImageReader::tr(sourceText: "Unable to read image data");
1297 return false;
1298 }
1299
1300 // provide default implementations for any unsupported image
1301 // options
1302 if (d->handler->supportsOption(option: QImageIOHandler::ClipRect) && !d->clipRect.isNull()) {
1303 if (d->handler->supportsOption(option: QImageIOHandler::ScaledSize) && d->scaledSize.isValid()) {
1304 if (d->handler->supportsOption(option: QImageIOHandler::ScaledClipRect) && !d->scaledClipRect.isNull()) {
1305 // all features are supported by the handler; nothing to do.
1306 } else {
1307 // the image is already scaled, so apply scaled clipping.
1308 if (!d->scaledClipRect.isNull())
1309 *image = image->copy(rect: d->scaledClipRect);
1310 }
1311 } else {
1312 if (d->handler->supportsOption(option: QImageIOHandler::ScaledClipRect) && !d->scaledClipRect.isNull()) {
1313 // supports scaled clipping but not scaling, most
1314 // likely a broken handler.
1315 } else {
1316 if (d->scaledSize.isValid()) {
1317 *image = image->scaled(s: d->scaledSize, aspectMode: Qt::IgnoreAspectRatio, mode: Qt::SmoothTransformation);
1318 }
1319 if (d->scaledClipRect.isValid()) {
1320 *image = image->copy(rect: d->scaledClipRect);
1321 }
1322 }
1323 }
1324 } else {
1325 if (d->handler->supportsOption(option: QImageIOHandler::ScaledSize) && d->scaledSize.isValid() && d->clipRect.isNull()) {
1326 if (d->handler->supportsOption(option: QImageIOHandler::ScaledClipRect) && !d->scaledClipRect.isNull()) {
1327 // nothing to do (ClipRect is ignored!)
1328 } else {
1329 // provide all workarounds.
1330 if (d->scaledClipRect.isValid()) {
1331 *image = image->copy(rect: d->scaledClipRect);
1332 }
1333 }
1334 } else {
1335 if (d->handler->supportsOption(option: QImageIOHandler::ScaledClipRect) && !d->scaledClipRect.isNull()) {
1336 // this makes no sense; a handler that supports
1337 // ScaledClipRect but not ScaledSize is broken, and we
1338 // can't work around it.
1339 } else {
1340 // provide all workarounds.
1341 if (d->clipRect.isValid())
1342 *image = image->copy(rect: d->clipRect);
1343 if (d->scaledSize.isValid())
1344 *image = image->scaled(s: d->scaledSize, aspectMode: Qt::IgnoreAspectRatio, mode: Qt::SmoothTransformation);
1345 if (d->scaledClipRect.isValid())
1346 *image = image->copy(rect: d->scaledClipRect);
1347 }
1348 }
1349 }
1350
1351 // successful read; check for "@Nx" file name suffix and set device pixel ratio.
1352 static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty(varName: "QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
1353 if (!disableNxImageLoading) {
1354 const QByteArray suffix = QFileInfo(fileName()).baseName().right(n: 3).toLatin1();
1355 if (suffix.length() == 3 && suffix[0] == '@' && suffix[1] >= '2' && suffix[1] <= '9' && suffix[2] == 'x')
1356 image->setDevicePixelRatio(suffix[1] - '0');
1357 }
1358 if (autoTransform())
1359 qt_imageTransform(src&: *image, orient: transformation());
1360
1361 return true;
1362}
1363
1364/*!
1365 For image formats that support animation, this function steps over the
1366 current image, returning true if successful or false if there is no
1367 following image in the animation.
1368
1369 The default implementation calls read(), then discards the resulting
1370 image, but the image handler may have a more efficient way of implementing
1371 this operation.
1372
1373 \sa jumpToImage(), QImageIOHandler::jumpToNextImage()
1374*/
1375bool QImageReader::jumpToNextImage()
1376{
1377 if (!d->initHandler())
1378 return false;
1379 return d->handler->jumpToNextImage();
1380}
1381
1382/*!
1383 For image formats that support animation, this function skips to the image
1384 whose sequence number is \a imageNumber, returning true if successful
1385 or false if the corresponding image cannot be found.
1386
1387 The next call to read() will attempt to read this image.
1388
1389 \sa jumpToNextImage(), QImageIOHandler::jumpToImage()
1390*/
1391bool QImageReader::jumpToImage(int imageNumber)
1392{
1393 if (!d->initHandler())
1394 return false;
1395 return d->handler->jumpToImage(imageNumber);
1396}
1397
1398/*!
1399 For image formats that support animation, this function returns the number
1400 of times the animation should loop. If this function returns -1, it can
1401 either mean the animation should loop forever, or that an error occurred.
1402 If an error occurred, canRead() will return false.
1403
1404 \sa supportsAnimation(), QImageIOHandler::loopCount(), canRead()
1405*/
1406int QImageReader::loopCount() const
1407{
1408 if (!d->initHandler())
1409 return -1;
1410 return d->handler->loopCount();
1411}
1412
1413/*!
1414 For image formats that support animation, this function returns the total
1415 number of images in the animation. If the format does not support
1416 animation, 0 is returned.
1417
1418 This function returns -1 if an error occurred.
1419
1420 \sa supportsAnimation(), QImageIOHandler::imageCount(), canRead()
1421*/
1422int QImageReader::imageCount() const
1423{
1424 if (!d->initHandler())
1425 return -1;
1426 return d->handler->imageCount();
1427}
1428
1429/*!
1430 For image formats that support animation, this function returns the number
1431 of milliseconds to wait until displaying the next frame in the animation.
1432 If the image format doesn't support animation, 0 is returned.
1433
1434 This function returns -1 if an error occurred.
1435
1436 \sa supportsAnimation(), QImageIOHandler::nextImageDelay(), canRead()
1437*/
1438int QImageReader::nextImageDelay() const
1439{
1440 if (!d->initHandler())
1441 return -1;
1442 return d->handler->nextImageDelay();
1443}
1444
1445/*!
1446 For image formats that support animation, this function returns the
1447 sequence number of the current frame. If the image format doesn't support
1448 animation, 0 is returned.
1449
1450 This function returns -1 if an error occurred.
1451
1452 \sa supportsAnimation(), QImageIOHandler::currentImageNumber(), canRead()
1453*/
1454int QImageReader::currentImageNumber() const
1455{
1456 if (!d->initHandler())
1457 return -1;
1458 return d->handler->currentImageNumber();
1459}
1460
1461/*!
1462 For image formats that support animation, this function returns
1463 the rect for the current frame. Otherwise, a null rect is returned.
1464
1465 \sa supportsAnimation(), QImageIOHandler::currentImageRect()
1466*/
1467QRect QImageReader::currentImageRect() const
1468{
1469 if (!d->initHandler())
1470 return QRect();
1471 return d->handler->currentImageRect();
1472}
1473
1474/*!
1475 Returns the type of error that occurred last.
1476
1477 \sa ImageReaderError, errorString()
1478*/
1479QImageReader::ImageReaderError QImageReader::error() const
1480{
1481 return d->imageReaderError;
1482}
1483
1484/*!
1485 Returns a human readable description of the last error that
1486 occurred.
1487
1488 \sa error()
1489*/
1490QString QImageReader::errorString() const
1491{
1492 if (d->errorString.isEmpty())
1493 return QImageReader::tr(sourceText: "Unknown error");
1494 return d->errorString;
1495}
1496
1497/*!
1498 \since 4.2
1499
1500 Returns \c true if the reader supports \a option; otherwise returns
1501 false.
1502
1503 Different image formats support different options. Call this function to
1504 determine whether a certain option is supported by the current format. For
1505 example, the PNG format allows you to embed text into the image's metadata
1506 (see text()), and the BMP format allows you to determine the image's size
1507 without loading the whole image into memory (see size()).
1508
1509 \snippet code/src_gui_image_qimagereader.cpp 3
1510
1511 \sa QImageWriter::supportsOption()
1512*/
1513bool QImageReader::supportsOption(QImageIOHandler::ImageOption option) const
1514{
1515 if (!d->initHandler())
1516 return false;
1517 return d->handler->supportsOption(option);
1518}
1519
1520/*!
1521 If supported, this function returns the image format of the file
1522 \a fileName. Otherwise, an empty string is returned.
1523*/
1524QByteArray QImageReader::imageFormat(const QString &fileName)
1525{
1526 QFile file(fileName);
1527 if (!file.open(flags: QFile::ReadOnly))
1528 return QByteArray();
1529
1530 return imageFormat(device: &file);
1531}
1532
1533/*!
1534 If supported, this function returns the image format of the device
1535 \a device. Otherwise, an empty string is returned.
1536
1537 \sa QImageReader::autoDetectImageFormat()
1538*/
1539QByteArray QImageReader::imageFormat(QIODevice *device)
1540{
1541 QByteArray format;
1542 QImageIOHandler *handler = createReadHandlerHelper(device, format, /* autoDetectImageFormat = */ true, ignoresFormatAndExtension: false);
1543 if (handler) {
1544 if (handler->canRead())
1545 format = handler->format();
1546 delete handler;
1547 }
1548 return format;
1549}
1550
1551/*!
1552 Returns the list of image formats supported by QImageReader.
1553
1554 By default, Qt can read the following formats:
1555
1556 \table
1557 \header \li Format \li MIME type \li Description
1558 \row \li BMP \li image/bmp \li Windows Bitmap
1559 \row \li GIF \li image/gif \li Graphic Interchange Format (optional)
1560 \row \li JPG \li image/jpeg \li Joint Photographic Experts Group
1561 \row \li PNG \li image/png \li Portable Network Graphics
1562 \row \li PBM \li image/x-portable-bitmap \li Portable Bitmap
1563 \row \li PGM \li image/x-portable-graymap \li Portable Graymap
1564 \row \li PPM \li image/x-portable-pixmap \li Portable Pixmap
1565 \row \li XBM \li image/x-xbitmap \li X11 Bitmap
1566 \row \li XPM \li image/x-xpixmap \li X11 Pixmap
1567 \row \li SVG \li image/svg+xml \li Scalable Vector Graphics
1568 \endtable
1569
1570 Reading and writing SVG files is supported through the \l{Qt SVG} module.
1571 The \l{Qt Image Formats} module provides support for additional image formats.
1572
1573 Note that the QApplication instance must be created before this function is
1574 called.
1575
1576 \sa setFormat(), QImageWriter::supportedImageFormats(), QImageIOPlugin
1577*/
1578
1579QList<QByteArray> QImageReader::supportedImageFormats()
1580{
1581 return QImageReaderWriterHelpers::supportedImageFormats(cap: QImageReaderWriterHelpers::CanRead);
1582}
1583
1584/*!
1585 Returns the list of MIME types supported by QImageReader.
1586
1587 Note that the QApplication instance must be created before this function is
1588 called.
1589
1590 \sa supportedImageFormats(), QImageWriter::supportedMimeTypes()
1591*/
1592
1593QList<QByteArray> QImageReader::supportedMimeTypes()
1594{
1595 return QImageReaderWriterHelpers::supportedMimeTypes(cap: QImageReaderWriterHelpers::CanRead);
1596}
1597
1598/*!
1599 \since 5.12
1600
1601 Returns the list of image formats corresponding to \a mimeType.
1602
1603 Note that the QGuiApplication instance must be created before this function is
1604 called.
1605
1606 \sa supportedImageFormats(), supportedMimeTypes()
1607*/
1608
1609QList<QByteArray> QImageReader::imageFormatsForMimeType(const QByteArray &mimeType)
1610{
1611 return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType,
1612 cap: QImageReaderWriterHelpers::CanRead);
1613}
1614
1615QT_END_NAMESPACE
1616

source code of qtbase/src/gui/image/qimagereader.cpp