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