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