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