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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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