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

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