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 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 format of the image, without actually reading the image
824 contents. The format describes the image format \l QImageReader::read()
825 returns, not the format of the actual image.
826
827 If the image format does not support this feature, this function returns
828 an invalid format.
829
830 \sa QImageIOHandler::ImageOption, QImageIOHandler::option(), QImageIOHandler::supportsOption()
831*/
832QImage::Format QImageReader::imageFormat() const
833{
834 if (supportsOption(QImageIOHandler::ImageFormat))
835 return (QImage::Format)d->handler->option(QImageIOHandler::ImageFormat).toInt();
836
837 return QImage::Format_Invalid;
838}
839
840/*!
841 Returns the text keys for this image. You can use
842 these keys with text() to list the image text for
843 a certain key.
844
845 Support for this option is implemented through
846 QImageIOHandler::Description.
847
848 \sa text(), QImageWriter::setText(), QImage::textKeys()
849*/
850QStringList QImageReader::textKeys() const
851{
852 d->getText();
853 return d->text.keys();
854}
855
856/*!
857 Returns the image text associated with \a key.
858
859 Support for this option is implemented through
860 QImageIOHandler::Description.
861
862 \sa textKeys(), QImageWriter::setText()
863*/
864QString QImageReader::text(const QString &key) const
865{
866 d->getText();
867 return d->text.value(key);
868}
869
870/*!
871 Sets the image clip rect (also known as the ROI, or Region Of
872 Interest) to \a rect. The coordinates of \a rect are relative to
873 the untransformed image size, as returned by size().
874
875 \sa clipRect(), setScaledSize(), setScaledClipRect()
876*/
877void QImageReader::setClipRect(const QRect &rect)
878{
879 d->clipRect = rect;
880}
881
882/*!
883 Returns the clip rect (also known as the ROI, or Region Of
884 Interest) of the image. If no clip rect has been set, an invalid
885 QRect is returned.
886
887 \sa setClipRect()
888*/
889QRect QImageReader::clipRect() const
890{
891 return d->clipRect;
892}
893
894/*!
895 Sets the scaled size of the image to \a size. The scaling is
896 performed after the initial clip rect, but before the scaled clip
897 rect is applied. The algorithm used for scaling depends on the
898 image format. By default (i.e., if the image format does not
899 support scaling), QImageReader will use QImage::scale() with
900 Qt::SmoothScaling.
901
902 If only one dimension is set in \a size, the other one will be
903 computed from the image's \l {size()} {natural size} so as to
904 maintain the aspect ratio.
905
906 \sa scaledSize(), setClipRect(), setScaledClipRect()
907*/
908void QImageReader::setScaledSize(const QSize &size)
909{
910 d->scaledSize = size;
911}
912
913/*!
914 Returns the scaled size of the image.
915
916 \sa setScaledSize()
917*/
918QSize QImageReader::scaledSize() const
919{
920 return d->scaledSize;
921}
922
923/*!
924 Sets the scaled clip rect to \a rect. The scaled clip rect is the
925 clip rect (also known as ROI, or Region Of Interest) that is
926 applied after the image has been scaled.
927
928 \sa scaledClipRect(), setScaledSize()
929*/
930void QImageReader::setScaledClipRect(const QRect &rect)
931{
932 d->scaledClipRect = rect;
933}
934
935/*!
936 Returns the scaled clip rect of the image.
937
938 \sa setScaledClipRect()
939*/
940QRect QImageReader::scaledClipRect() const
941{
942 return d->scaledClipRect;
943}
944
945/*!
946 Sets the background color to \a color.
947 Image formats that support this operation are expected to
948 initialize the background to \a color before reading an image.
949
950 \sa backgroundColor(), read()
951*/
952void QImageReader::setBackgroundColor(const QColor &color)
953{
954 if (supportsOption(QImageIOHandler::BackgroundColor))
955 d->handler->setOption(QImageIOHandler::BackgroundColor, color);
956}
957
958/*!
959 Returns the background color that's used when reading an image.
960 If the image format does not support setting the background color
961 an invalid color is returned.
962
963 \sa setBackgroundColor(), read()
964*/
965QColor QImageReader::backgroundColor() const
966{
967 if (supportsOption(QImageIOHandler::BackgroundColor))
968 return qvariant_cast<QColor>(d->handler->option(QImageIOHandler::BackgroundColor));
969 return QColor();
970}
971
972/*!
973 Returns \c true if the image format supports animation;
974 otherwise, false is returned.
975
976 \sa QMovie::supportedFormats()
977*/
978bool QImageReader::supportsAnimation() const
979{
980 if (supportsOption(QImageIOHandler::Animation))
981 return d->handler->option(QImageIOHandler::Animation).toBool();
982 return false;
983}
984
985/*!
986 \since 5.4
987
988 Returns the subtype of the image.
989*/
990QByteArray QImageReader::subType() const
991{
992 if (supportsOption(QImageIOHandler::SubType))
993 return d->handler->option(QImageIOHandler::SubType).toByteArray();
994 return QByteArray();
995}
996
997/*!
998 \since 5.4
999
1000 Returns the list of subtypes supported by an image.
1001*/
1002QList<QByteArray> QImageReader::supportedSubTypes() const
1003{
1004 if (supportsOption(QImageIOHandler::SupportedSubTypes))
1005 return qvariant_cast<QList<QByteArray> >(d->handler->option(QImageIOHandler::SupportedSubTypes));
1006 return QList<QByteArray>();
1007}
1008
1009/*!
1010 \since 5.5
1011
1012 Returns the transformation metadata of the image, including image orientation. If the format
1013 does not support transformation metadata, QImageIOHandler::TransformationNone is returned.
1014
1015 \sa setAutoTransform(), autoTransform()
1016*/
1017QImageIOHandler::Transformations QImageReader::transformation() const
1018{
1019 int option = QImageIOHandler::TransformationNone;
1020 if (supportsOption(QImageIOHandler::ImageTransformation))
1021 option = d->handler->option(QImageIOHandler::ImageTransformation).toInt();
1022 return QImageIOHandler::Transformations(option);
1023}
1024
1025/*!
1026 \since 5.5
1027
1028 Determines that images returned by read() should have transformation metadata automatically
1029 applied if \a enabled is \c true.
1030
1031 \sa autoTransform(), transformation(), read()
1032*/
1033void QImageReader::setAutoTransform(bool enabled)
1034{
1035 d->autoTransform = enabled ? QImageReaderPrivate::ApplyTransform
1036 : QImageReaderPrivate::DoNotApplyTransform;
1037}
1038
1039/*!
1040 \since 5.5
1041
1042 Returns \c true if the image handler will apply transformation metadata on read().
1043
1044 \sa setAutoTransform(), transformation(), read()
1045*/
1046bool QImageReader::autoTransform() const
1047{
1048 switch (d->autoTransform) {
1049 case QImageReaderPrivate::ApplyTransform:
1050 return true;
1051 case QImageReaderPrivate::DoNotApplyTransform:
1052 return false;
1053 case QImageReaderPrivate::UsePluginDefault:
1054 Q_FALLTHROUGH();
1055 default:
1056 break;
1057 }
1058 return false;
1059}
1060
1061/*!
1062 Returns \c true if an image can be read for the device (i.e., the
1063 image format is supported, and the device seems to contain valid
1064 data); otherwise returns \c false.
1065
1066 canRead() is a lightweight function that only does a quick test to
1067 see if the image data is valid. read() may still return false
1068 after canRead() returns \c true, if the image data is corrupt.
1069
1070 \note A QMimeDatabase lookup is normally a better approach than this
1071 function for identifying potentially non-image files or data.
1072
1073 For images that support animation, canRead() returns \c false when
1074 all frames have been read.
1075
1076 \sa read(), supportedImageFormats(), QMimeDatabase
1077*/
1078bool QImageReader::canRead() const
1079{
1080 if (!d->initHandler())
1081 return false;
1082
1083 return d->handler->canRead();
1084}
1085
1086/*!
1087 Reads an image from the device. On success, the image that was
1088 read is returned; otherwise, a null QImage is returned. You can
1089 then call error() to find the type of error that occurred, or
1090 errorString() to get a human readable description of the error.
1091
1092 For image formats that support animation, calling read()
1093 repeatedly will return the next frame. When all frames have been
1094 read, a null image will be returned.
1095
1096 \sa canRead(), supportedImageFormats(), supportsAnimation(), QMovie
1097*/
1098QImage QImageReader::read()
1099{
1100 // Because failed image reading might have side effects, we explicitly
1101 // return a null image instead of the image we've just created.
1102 QImage image;
1103 return read(&image) ? image : QImage();
1104}
1105
1106extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient);
1107
1108/*!
1109 \overload
1110
1111 Reads an image from the device into \a image, which must point to a
1112 QImage. Returns \c true on success; otherwise, returns \c false.
1113
1114 If \a image has same format and size as the image data that is about to be
1115 read, this function may not need to allocate a new image before
1116 reading. Because of this, it can be faster than the other read() overload,
1117 which always constructs a new image; especially when reading several
1118 images with the same format and size.
1119
1120 \snippet code/src_gui_image_qimagereader.cpp 2
1121
1122 For image formats that support animation, calling read() repeatedly will
1123 return the next frame. When all frames have been read, a null image will
1124 be returned.
1125
1126 \sa canRead(), supportedImageFormats(), supportsAnimation(), QMovie
1127*/
1128bool QImageReader::read(QImage *image)
1129{
1130 if (!image) {
1131 qWarning("QImageReader::read: cannot read into null pointer");
1132 return false;
1133 }
1134
1135 if (!d->initHandler())
1136 return false;
1137
1138 QSize scaledSize = d->scaledSize;
1139 if ((scaledSize.width() <= 0 && scaledSize.height() > 0) ||
1140 (scaledSize.height() <= 0 && scaledSize.width() > 0)) {
1141 // if only one dimension is given, let's try to calculate the second one
1142 // based on the original image size and maintaining the aspect ratio
1143 if (const QSize originalSize = size(); !originalSize.isEmpty()) {
1144 if (scaledSize.width() <= 0) {
1145 const auto ratio = qreal(scaledSize.height()) / originalSize.height();
1146 scaledSize.setWidth(qRound(originalSize.width() * ratio));
1147 } else {
1148 const auto ratio = qreal(scaledSize.width()) / originalSize.width();
1149 scaledSize.setHeight(qRound(originalSize.height() * ratio));
1150 }
1151 }
1152 }
1153
1154 const bool supportScaledSize = supportsOption(QImageIOHandler::ScaledSize) && scaledSize.isValid();
1155 const bool supportClipRect = supportsOption(QImageIOHandler::ClipRect) && !d->clipRect.isNull();
1156 const bool supportScaledClipRect = supportsOption(QImageIOHandler::ScaledClipRect) && !d->scaledClipRect.isNull();
1157
1158 // set the handler specific options.
1159 if (supportScaledSize) {
1160 if (supportClipRect || d->clipRect.isNull()) {
1161 // Only enable the ScaledSize option if there is no clip rect, or
1162 // if the handler also supports ClipRect.
1163 d->handler->setOption(QImageIOHandler::ScaledSize, scaledSize);
1164 }
1165 }
1166 if (supportClipRect)
1167 d->handler->setOption(QImageIOHandler::ClipRect, d->clipRect);
1168 if (supportScaledClipRect)
1169 d->handler->setOption(QImageIOHandler::ScaledClipRect, d->scaledClipRect);
1170 if (supportsOption(QImageIOHandler::Quality))
1171 d->handler->setOption(QImageIOHandler::Quality, d->quality);
1172
1173 // read the image
1174 QString filename = fileName();
1175 if (Q_TRACE_ENABLED(QImageReader_read_before_reading)) {
1176 Q_TRACE(QImageReader_read_before_reading, this, filename.isEmpty() ? u"unknown"_s : filename);
1177 }
1178
1179 const bool result = d->handler->read(image);
1180
1181 Q_TRACE(QImageReader_read_after_reading, this, result);
1182
1183 if (!result) {
1184 d->imageReaderError = InvalidDataError;
1185 d->errorString = QImageReader::tr("Unable to read image data");
1186 return false;
1187 }
1188
1189 // provide default implementations for any unsupported image
1190 // options
1191 if (supportClipRect) {
1192 if (supportScaledSize) {
1193 if (supportScaledClipRect) {
1194 // all features are supported by the handler; nothing to do.
1195 } else {
1196 // the image is already scaled, so apply scaled clipping.
1197 if (!d->scaledClipRect.isNull())
1198 *image = image->copy(d->scaledClipRect);
1199 }
1200 } else {
1201 if (supportScaledClipRect) {
1202 // supports scaled clipping but not scaling, most
1203 // likely a broken handler.
1204 } else {
1205 if (scaledSize.isValid()) {
1206 *image = image->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1207 }
1208 if (d->scaledClipRect.isValid()) {
1209 *image = image->copy(d->scaledClipRect);
1210 }
1211 }
1212 }
1213 } else {
1214 if (supportScaledSize && d->clipRect.isNull()) {
1215 if (supportScaledClipRect) {
1216 // nothing to do (ClipRect is ignored!)
1217 } else {
1218 // provide all workarounds.
1219 if (d->scaledClipRect.isValid()) {
1220 *image = image->copy(d->scaledClipRect);
1221 }
1222 }
1223 } else {
1224 if (supportScaledClipRect) {
1225 // this makes no sense; a handler that supports
1226 // ScaledClipRect but not ScaledSize is broken, and we
1227 // can't work around it.
1228 } else {
1229 // provide all workarounds.
1230 if (d->clipRect.isValid())
1231 *image = image->copy(d->clipRect);
1232 if (scaledSize.isValid())
1233 *image = image->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1234 if (d->scaledClipRect.isValid())
1235 *image = image->copy(d->scaledClipRect);
1236 }
1237 }
1238 }
1239
1240 // successful read; check for "@Nx" file name suffix and set device pixel ratio.
1241 static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
1242 if (!disableNxImageLoading) {
1243 const QByteArray suffix = QFileInfo(filename).baseName().right(3).toLatin1();
1244 if (suffix.size() == 3 && suffix[0] == '@' && suffix[1] >= '2' && suffix[1] <= '9' && suffix[2] == 'x')
1245 image->setDevicePixelRatio(suffix[1] - '0');
1246 }
1247 if (autoTransform())
1248 qt_imageTransform(*image, transformation());
1249
1250 return true;
1251}
1252
1253/*!
1254 For image formats that support animation, this function steps over the
1255 current image, returning true if successful or false if there is no
1256 following image in the animation.
1257
1258 The default implementation calls read(), then discards the resulting
1259 image, but the image handler may have a more efficient way of implementing
1260 this operation.
1261
1262 \sa jumpToImage(), QImageIOHandler::jumpToNextImage()
1263*/
1264bool QImageReader::jumpToNextImage()
1265{
1266 if (!d->initHandler())
1267 return false;
1268 return d->handler->jumpToNextImage();
1269}
1270
1271/*!
1272 For image formats that support animation, this function skips to the image
1273 whose sequence number is \a imageNumber, returning true if successful
1274 or false if the corresponding image cannot be found.
1275
1276 The next call to read() will attempt to read this image.
1277
1278 \sa jumpToNextImage(), QImageIOHandler::jumpToImage()
1279*/
1280bool QImageReader::jumpToImage(int imageNumber)
1281{
1282 if (!d->initHandler())
1283 return false;
1284 return d->handler->jumpToImage(imageNumber);
1285}
1286
1287/*!
1288 For image formats that support animation, this function returns the number
1289 of times the animation should loop. If this function returns -1, it can
1290 either mean the animation should loop forever, or that an error occurred.
1291 If an error occurred, canRead() will return false.
1292
1293 \sa supportsAnimation(), QImageIOHandler::loopCount(), canRead()
1294*/
1295int QImageReader::loopCount() const
1296{
1297 if (!d->initHandler())
1298 return -1;
1299 return d->handler->loopCount();
1300}
1301
1302/*!
1303 For image formats that support animation, this function returns the total
1304 number of images in the animation. If the format does not support
1305 animation, 0 is returned.
1306
1307 This function returns -1 if an error occurred.
1308
1309 \sa supportsAnimation(), QImageIOHandler::imageCount(), canRead()
1310*/
1311int QImageReader::imageCount() const
1312{
1313 if (!d->initHandler())
1314 return -1;
1315 return d->handler->imageCount();
1316}
1317
1318/*!
1319 For image formats that support animation, this function returns the number
1320 of milliseconds to wait until displaying the next frame in the animation.
1321 If the image format doesn't support animation, 0 is returned.
1322
1323 This function returns -1 if an error occurred.
1324
1325 \sa supportsAnimation(), QImageIOHandler::nextImageDelay(), canRead()
1326*/
1327int QImageReader::nextImageDelay() const
1328{
1329 if (!d->initHandler())
1330 return -1;
1331 return d->handler->nextImageDelay();
1332}
1333
1334/*!
1335 For image formats that support animation, this function returns the
1336 sequence number of the current frame. If the image format doesn't support
1337 animation, 0 is returned.
1338
1339 This function returns -1 if an error occurred.
1340
1341 \sa supportsAnimation(), QImageIOHandler::currentImageNumber(), canRead()
1342*/
1343int QImageReader::currentImageNumber() const
1344{
1345 if (!d->initHandler())
1346 return -1;
1347 return d->handler->currentImageNumber();
1348}
1349
1350/*!
1351 For image formats that support animation, this function returns
1352 the rect for the current frame. Otherwise, a null rect is returned.
1353
1354 \sa supportsAnimation(), QImageIOHandler::currentImageRect()
1355*/
1356QRect QImageReader::currentImageRect() const
1357{
1358 if (!d->initHandler())
1359 return QRect();
1360 return d->handler->currentImageRect();
1361}
1362
1363/*!
1364 Returns the type of error that occurred last.
1365
1366 \sa ImageReaderError, errorString()
1367*/
1368QImageReader::ImageReaderError QImageReader::error() const
1369{
1370 return d->imageReaderError;
1371}
1372
1373/*!
1374 Returns a human readable description of the last error that
1375 occurred.
1376
1377 \sa error()
1378*/
1379QString QImageReader::errorString() const
1380{
1381 if (d->errorString.isEmpty())
1382 return QImageReader::tr("Unknown error");
1383 return d->errorString;
1384}
1385
1386/*!
1387 Returns \c true if the reader supports \a option; otherwise returns
1388 false.
1389
1390 Different image formats support different options. Call this function to
1391 determine whether a certain option is supported by the current format. For
1392 example, the PNG format allows you to embed text into the image's metadata
1393 (see text()), and the BMP format allows you to determine the image's size
1394 without loading the whole image into memory (see size()).
1395
1396 \snippet code/src_gui_image_qimagereader.cpp 3
1397
1398 \sa QImageWriter::supportsOption()
1399*/
1400bool QImageReader::supportsOption(QImageIOHandler::ImageOption option) const
1401{
1402 if (!d->initHandler())
1403 return false;
1404 return d->handler->supportsOption(option);
1405}
1406
1407/*!
1408 If supported, this function returns the image format of the file
1409 \a fileName. Otherwise, an empty string is returned.
1410*/
1411QByteArray QImageReader::imageFormat(const QString &fileName)
1412{
1413 QFile file(fileName);
1414 if (!file.open(QFile::ReadOnly))
1415 return QByteArray();
1416
1417 return imageFormat(&file);
1418}
1419
1420/*!
1421 If supported, this function returns the image format of the device
1422 \a device. Otherwise, an empty string is returned.
1423
1424 \sa QImageReader::autoDetectImageFormat()
1425*/
1426QByteArray QImageReader::imageFormat(QIODevice *device)
1427{
1428 QByteArray format;
1429 QImageIOHandler *handler = createReadHandlerHelper(device, format, /* autoDetectImageFormat = */ true, false);
1430 if (handler) {
1431 if (handler->canRead())
1432 format = handler->format();
1433 delete handler;
1434 }
1435 return format;
1436}
1437
1438/*!
1439 Returns the list of image formats supported by QImageReader.
1440
1441 By default, Qt can read the following formats:
1442
1443 \table
1444 \header \li Format \li MIME type \li Description
1445 \row \li BMP \li image/bmp \li Windows Bitmap
1446 \row \li GIF \li image/gif \li Graphic Interchange Format (optional)
1447 \row \li JPG \li image/jpeg \li Joint Photographic Experts Group
1448 \row \li PNG \li image/png \li Portable Network Graphics
1449 \row \li PBM \li image/x-portable-bitmap \li Portable Bitmap
1450 \row \li PGM \li image/x-portable-graymap \li Portable Graymap
1451 \row \li PPM \li image/x-portable-pixmap \li Portable Pixmap
1452 \row \li XBM \li image/x-xbitmap \li X11 Bitmap
1453 \row \li XPM \li image/x-xpixmap \li X11 Pixmap
1454 \row \li SVG \li image/svg+xml \li Scalable Vector Graphics
1455 \endtable
1456
1457 Reading and writing SVG files is supported through the \l{Qt SVG} module.
1458 The \l{Qt Image Formats} module provides support for additional image formats.
1459
1460 Note that the QCoreApplication instance must be created before this function is
1461 called.
1462
1463 \sa setFormat(), QImageWriter::supportedImageFormats(), QImageIOPlugin
1464*/
1465
1466QList<QByteArray> QImageReader::supportedImageFormats()
1467{
1468 return QImageReaderWriterHelpers::supportedImageFormats(QImageReaderWriterHelpers::CanRead);
1469}
1470
1471/*!
1472 Returns the list of MIME types supported by QImageReader.
1473
1474 Note that the QApplication instance must be created before this function is
1475 called.
1476
1477 \sa supportedImageFormats(), QImageWriter::supportedMimeTypes()
1478*/
1479
1480QList<QByteArray> QImageReader::supportedMimeTypes()
1481{
1482 return QImageReaderWriterHelpers::supportedMimeTypes(QImageReaderWriterHelpers::CanRead);
1483}
1484
1485/*!
1486 \since 5.12
1487
1488 Returns the list of image formats corresponding to \a mimeType.
1489
1490 Note that the QGuiApplication instance must be created before this function is
1491 called.
1492
1493 \sa supportedImageFormats(), supportedMimeTypes()
1494*/
1495
1496QList<QByteArray> QImageReader::imageFormatsForMimeType(const QByteArray &mimeType)
1497{
1498 return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType,
1499 QImageReaderWriterHelpers::CanRead);
1500}
1501
1502/*!
1503 \since 6.0
1504
1505 Returns the current allocation limit, in megabytes.
1506
1507 \sa setAllocationLimit()
1508*/
1509int QImageReader::allocationLimit()
1510{
1511 static int envLimit = []() {
1512 bool ok = false;
1513 int res = qEnvironmentVariableIntValue("QT_IMAGEIO_MAXALLOC", &ok);
1514 return ok ? res : -1;
1515 }();
1516
1517 return envLimit >= 0 ? envLimit : QImageReaderPrivate::maxAlloc;
1518}
1519
1520/*!
1521 \since 6.0
1522
1523 Sets the allocation limit to \a mbLimit megabytes. Images that would
1524 require a QImage memory allocation above this limit will be rejected.
1525 If \a mbLimit is 0, the allocation size check will be disabled.
1526
1527 This limit helps applications avoid unexpectedly large memory usage from
1528 loading corrupt image files. It is normally not needed to change it. The
1529 default limit is large enough for all commonly used image sizes.
1530
1531 At runtime, this value may be overridden by the environment variable \c QT_IMAGEIO_MAXALLOC.
1532
1533 \note The memory requirements are calculated for a minimum of 32 bits per pixel, since Qt will
1534 typically convert an image to that depth when it is used in GUI. This means that the effective
1535 allocation limit is significantly smaller than \a mbLimit when reading 1 bpp and 8 bpp images.
1536
1537 \sa allocationLimit()
1538*/
1539void QImageReader::setAllocationLimit(int mbLimit)
1540{
1541 if (mbLimit >= 0)
1542 QImageReaderPrivate::maxAlloc = mbLimit;
1543}
1544
1545QT_END_NAMESPACE
QImageIOHandler * handler
QMap< QString, QString > text
QImageReaderPrivate(QImageReader *qq)
Definition qlist.h:80
Definition qcompare.h:76
Q_GUI_EXPORT void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient)
Definition qimage.cpp:6516
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,...)