Coverage Report

Created: 2025-07-16 07:53

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