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