Coverage Report

Created: 2026-03-12 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/image/qimagewriter.cpp
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
/*!
5
    \class QImageWriter
6
    \brief The QImageWriter class provides a format independent interface
7
    for writing images to files or other devices.
8
9
    \inmodule QtGui
10
    \reentrant
11
    \ingroup painting
12
13
    QImageWriter supports setting format specific options, such as
14
    compression level and quality, prior to storing the
15
    image. If you do not need such options, you can use QImage::save()
16
    or QPixmap::save() instead.
17
18
    To store an image, you start by constructing a QImageWriter
19
    object.  Pass either a file name or a device pointer, and the
20
    image format to QImageWriter's constructor. You can then set
21
    several options, such as quality (by calling setQuality()).
22
    canWrite() returns \c true if QImageWriter can write the image
23
    (i.e., the image format is supported and the device is open for
24
    writing). Call write() to write the image to the device.
25
26
    If any error occurs when writing the image, write() will return
27
    false. You can then call error() to find the type of error that
28
    occurred, or errorString() to get a human readable description of
29
    what went wrong.
30
31
    Call supportedImageFormats() for a list of formats that
32
    QImageWriter can write. QImageWriter supports all built-in image
33
    formats, in addition to any image format plugins that support
34
    writing.
35
36
    \note QImageWriter assumes exclusive control over the file or
37
    device that is assigned. Any attempts to modify the assigned file
38
    or device during the lifetime of the QImageWriter object will
39
    yield undefined results. If immediate access to a resource is
40
    desired, the use of a scope is the recommended method.
41
42
    For example:
43
44
    \snippet qimagewriter/main.cpp 0
45
46
    \sa QImageReader, QImageIOHandler, QImageIOPlugin, QColorSpace
47
*/
48
49
/*!
50
    \enum QImageWriter::ImageWriterError
51
52
    This enum describes errors that can occur when writing images with
53
    QImageWriter.
54
55
    \value DeviceError QImageWriter encountered a device error when
56
    writing the image data. Consult your device for more details on
57
    what went wrong.
58
59
    \value UnsupportedFormatError Qt does not support the requested
60
    image format.
61
62
    \value InvalidImageError An attempt was made to write an invalid QImage. An
63
    example of an invalid image would be a null QImage.
64
65
    \value UnknownError An unknown error occurred. If you get this
66
    value after calling write(), it is most likely caused by a bug in
67
    QImageWriter.
68
*/
69
70
#include "qimagewriter.h"
71
72
#include <qbytearray.h>
73
#include <qfile.h>
74
#include <qfileinfo.h>
75
#include <qimage.h>
76
#include <qimageiohandler.h>
77
#include <qset.h>
78
#include <qvariant.h>
79
#include <qloggingcategory.h>
80
81
// factory loader
82
#include <qcoreapplication.h>
83
#include <private/qfactoryloader_p.h>
84
85
// image handlers
86
#include <private/qbmphandler_p.h>
87
#include <private/qppmhandler_p.h>
88
#include <private/qxbmhandler_p.h>
89
#include <private/qxpmhandler_p.h>
90
#ifndef QT_NO_IMAGEFORMAT_PNG
91
#include <private/qpnghandler_p.h>
92
#endif
93
94
#include <private/qimagereaderwriterhelpers_p.h>
95
96
#include <algorithm>
97
98
QT_BEGIN_NAMESPACE
99
100
Q_STATIC_LOGGING_CATEGORY(lcImageWriter, "qt.gui.imageio.writer")
101
102
using namespace Qt::StringLiterals;
103
104
static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
105
    const QByteArray &format)
106
0
{
107
0
    QByteArray form = format.toLower();
108
0
    QByteArray suffix;
109
0
    QImageIOHandler *handler = nullptr;
110
111
0
    qCDebug(lcImageWriter) << "Finding write handler for" << device << "and format" << format;
112
113
0
#ifndef QT_NO_IMAGEFORMATPLUGIN
114
0
    typedef QMultiMap<int, QString> PluginKeyMap;
115
116
    // check if any plugins can write the image
117
0
    auto l = QImageReaderWriterHelpers::pluginLoader();
118
0
    const PluginKeyMap keyMap = l->keyMap();
119
0
    int suffixPluginIndex = -1;
120
121
0
    qCDebug(lcImageWriter) << keyMap.uniqueKeys().size() << "plugins available:" << keyMap.values();
122
0
#endif
123
124
0
    if (device && format.isEmpty()) {
125
        // if there's no format, see if \a device is a file, and if so, find
126
        // the file suffix and find support for that format among our plugins.
127
        // this allows plugins to override our built-in handlers.
128
0
        if (QFileDevice *file = qobject_cast<QFileDevice *>(device)) {
129
0
            if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) {
130
0
                qCDebug(lcImageWriter) << "Resolved format" << suffix << "from file name suffix";
131
0
#ifndef QT_NO_IMAGEFORMATPLUGIN
132
0
                const int index = keyMap.key(QString::fromLatin1(suffix), -1);
133
0
                if (index != -1)
134
0
                    suffixPluginIndex = index;
135
0
#endif
136
0
            }
137
0
        }
138
0
    }
139
140
0
    QByteArray testFormat = !form.isEmpty() ? form : suffix;
141
142
0
#ifndef QT_NO_IMAGEFORMATPLUGIN
143
0
    if (suffixPluginIndex != -1) {
144
        // when format is missing, check if we can find a plugin for the
145
        // suffix.
146
0
        qCDebug(lcImageWriter) << "Checking if any plugins have explicitly declared support"
147
0
                               << "for the format" << testFormat;
148
0
        const int index = keyMap.key(QString::fromLatin1(suffix), -1);
149
0
        if (index != -1) {
150
0
            QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(index));
151
0
            if (plugin && (plugin->capabilities(device, suffix) & QImageIOPlugin::CanWrite)) {
152
0
                handler = plugin->create(device, suffix);
153
0
                qCDebug(lcImageWriter) << plugin << "can write the format" << testFormat;
154
0
            }
155
0
        }
156
0
    }
157
0
#endif // QT_NO_IMAGEFORMATPLUGIN
158
159
    // check if any built-in handlers can write the image
160
0
    if (!handler && !testFormat.isEmpty()) {
161
0
        qCDebug(lcImageWriter) << "Checking if any built in handlers recognize the format"
162
0
                               << testFormat;
163
0
        if (false) {
164
0
#ifndef QT_NO_IMAGEFORMAT_PNG
165
0
        } else if (testFormat == "png") {
166
0
            handler = new QPngHandler;
167
0
#endif
168
0
#ifndef QT_NO_IMAGEFORMAT_BMP
169
0
        } else if (testFormat == "bmp") {
170
0
            handler = new QBmpHandler;
171
0
        } else if (testFormat == "dib") {
172
0
            handler = new QBmpHandler(QBmpHandler::DibFormat);
173
0
#endif
174
0
#ifndef QT_NO_IMAGEFORMAT_XPM
175
0
        } else if (testFormat == "xpm") {
176
0
            handler = new QXpmHandler;
177
0
#endif
178
0
#ifndef QT_NO_IMAGEFORMAT_XBM
179
0
        } else if (testFormat == "xbm") {
180
0
            handler = new QXbmHandler;
181
0
            handler->setOption(QImageIOHandler::SubType, testFormat);
182
0
#endif
183
0
#ifndef QT_NO_IMAGEFORMAT_PPM
184
0
        } else if (testFormat == "pbm" || testFormat == "pbmraw" || testFormat == "pgm"
185
0
                 || testFormat == "pgmraw" || testFormat == "ppm" || testFormat == "ppmraw") {
186
0
            handler = new QPpmHandler;
187
0
            handler->setOption(QImageIOHandler::SubType, testFormat);
188
0
#endif
189
0
        }
190
191
0
        if (handler)
192
0
            qCDebug(lcImageWriter) << "Using the built-in handler for format" << testFormat;
193
0
    }
194
195
0
#ifndef QT_NO_IMAGEFORMATPLUGIN
196
0
    if (!handler && !testFormat.isEmpty()) {
197
0
        qCDebug(lcImageWriter) << "Checking if any plugins recognize the format" << testFormat;
198
0
        const int keyCount = keyMap.size();
199
0
        for (int i = 0; i < keyCount; ++i) {
200
0
            QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i));
201
0
            if (plugin && (plugin->capabilities(device, testFormat) & QImageIOPlugin::CanWrite)) {
202
0
                handler = plugin->create(device, testFormat);
203
0
                qCDebug(lcImageWriter) << plugin << "can write the format" << testFormat;
204
0
                break;
205
0
            }
206
0
        }
207
0
    }
208
0
#endif // QT_NO_IMAGEFORMATPLUGIN
209
210
0
    if (!handler) {
211
0
        qCDebug(lcImageWriter, "No handlers found. Giving up.");
212
0
        return nullptr;
213
0
    }
214
215
0
    handler->setDevice(device);
216
0
    if (!testFormat.isEmpty())
217
0
        handler->setFormat(testFormat);
218
0
    return handler;
219
0
}
220
221
class QImageWriterPrivate
222
{
223
public:
224
    QImageWriterPrivate(QImageWriter *qq);
225
226
    bool canWriteHelper();
227
228
    // device
229
    QByteArray format;
230
    QIODevice *device;
231
    bool deleteDevice;
232
    QImageIOHandler *handler;
233
234
    // image options
235
    int quality;
236
    int compression;
237
    float gamma;
238
    QString description;
239
    QString text;
240
    QByteArray subType;
241
    bool optimizedWrite;
242
    bool progressiveScanWrite;
243
    QImageIOHandler::Transformations transformation;
244
245
    // error
246
    QImageWriter::ImageWriterError imageWriterError;
247
    QString errorString;
248
249
    QImageWriter *q;
250
};
251
252
/*!
253
    \internal
254
*/
255
QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq)
256
0
{
257
0
    device = nullptr;
258
0
    deleteDevice = false;
259
0
    handler = nullptr;
260
0
    quality = -1;
261
0
    compression = -1;
262
0
    gamma = 0.0;
263
0
    optimizedWrite = false;
264
0
    progressiveScanWrite = false;
265
0
    imageWriterError = QImageWriter::UnknownError;
266
0
    errorString = QImageWriter::tr("Unknown error");
267
0
    transformation = QImageIOHandler::TransformationNone;
268
269
0
    q = qq;
270
0
}
271
272
bool QImageWriterPrivate::canWriteHelper()
273
0
{
274
0
    if (!device) {
275
0
        imageWriterError = QImageWriter::DeviceError;
276
0
        errorString = QImageWriter::tr("Device is not set");
277
0
        return false;
278
0
    }
279
0
    if (!device->isOpen()) {
280
0
        if (!device->open(QIODevice::WriteOnly)) {
281
0
            imageWriterError = QImageWriter::DeviceError;
282
0
            errorString = QImageWriter::tr("Cannot open device for writing: %1").arg(device->errorString());
283
0
            return false;
284
0
        }
285
0
    }
286
0
    if (!device->isWritable()) {
287
0
        imageWriterError = QImageWriter::DeviceError;
288
0
        errorString = QImageWriter::tr("Device not writable");
289
0
        return false;
290
0
    }
291
0
    if (!handler && (handler = createWriteHandlerHelper(device, format)) == nullptr) {
292
0
        imageWriterError = QImageWriter::UnsupportedFormatError;
293
0
        errorString = QImageWriter::tr("Unsupported image format");
294
0
        return false;
295
0
    }
296
0
    return true;
297
0
}
298
299
/*!
300
    Constructs an empty QImageWriter object. Before writing, you must
301
    call setFormat() to set an image format, then setDevice() or
302
    setFileName().
303
*/
304
QImageWriter::QImageWriter()
305
0
    : d(new QImageWriterPrivate(this))
306
0
{
307
0
}
308
309
/*!
310
    Constructs a QImageWriter object using the device \a device and
311
    image format \a format.
312
*/
313
QImageWriter::QImageWriter(QIODevice *device, const QByteArray &format)
314
0
    : d(new QImageWriterPrivate(this))
315
0
{
316
0
    d->device = device;
317
0
    d->format = format;
318
0
}
319
320
/*!
321
    Constructs a QImageWriter objects that will write to a file with
322
    the name \a fileName, using the image format \a format. If \a
323
    format is not provided, QImageWriter will detect the image format
324
    by inspecting the extension of \a fileName.
325
*/
326
QImageWriter::QImageWriter(const QString &fileName, const QByteArray &format)
327
0
    : QImageWriter(new QFile(fileName), format)
328
0
{
329
0
    d->deleteDevice = true;
330
0
}
331
332
/*!
333
    Destructs the QImageWriter object.
334
*/
335
QImageWriter::~QImageWriter()
336
0
{
337
0
    delete d->handler;
338
0
    if (d->deleteDevice)
339
0
        delete d->device;
340
0
    delete d;
341
0
}
342
343
/*!
344
    Sets the format QImageWriter will use when writing images, to \a
345
    format. \a format is a case insensitive text string. Example:
346
347
    \snippet code/src_gui_image_qimagewriter.cpp 0
348
349
    You can call supportedImageFormats() for the full list of formats
350
    QImageWriter supports.
351
352
    \sa format()
353
*/
354
void QImageWriter::setFormat(const QByteArray &format)
355
0
{
356
0
    d->format = format;
357
0
}
358
359
/*!
360
    Returns the format QImageWriter uses for writing images.
361
362
    \sa setFormat()
363
*/
364
QByteArray QImageWriter::format() const
365
0
{
366
0
    return d->format;
367
0
}
368
369
/*!
370
    Sets QImageWriter's device to \a device. If a device has already
371
    been set, the old device is removed from QImageWriter and is
372
    otherwise left unchanged.
373
374
    If the device is not already open, QImageWriter will attempt to
375
    open the device in \l QIODeviceBase::WriteOnly mode by calling
376
    open(). Note that this does not work for certain devices, such as
377
    QProcess, QTcpSocket and QUdpSocket, where more logic is required
378
    to open the device.
379
380
    \sa device(), setFileName()
381
*/
382
void QImageWriter::setDevice(QIODevice *device)
383
0
{
384
0
    delete d->handler;
385
0
    d->handler = nullptr;
386
0
    if (d->device && d->deleteDevice)
387
0
        delete d->device;
388
389
0
    d->device = device;
390
0
    d->deleteDevice = false;
391
0
}
392
393
/*!
394
    Returns the device currently assigned to QImageWriter, or \nullptr
395
    if no device has been assigned.
396
*/
397
QIODevice *QImageWriter::device() const
398
0
{
399
0
    return d->device;
400
0
}
401
402
/*!
403
    Sets the file name of QImageWriter to \a fileName. Internally,
404
    QImageWriter will create a QFile and open it in \l
405
    QIODevice::WriteOnly mode, and use this file when writing images.
406
407
    \sa fileName(), setDevice()
408
*/
409
void QImageWriter::setFileName(const QString &fileName)
410
0
{
411
0
    setDevice(new QFile(fileName));
412
0
    d->deleteDevice = true;
413
0
}
414
415
/*!
416
    If the currently assigned device is a file, or if setFileName()
417
    has been called, this function returns the name of the file
418
    QImageWriter writes to. Otherwise (i.e., if no device has been
419
    assigned or the device is not a file), an empty QString is
420
    returned.
421
422
    \sa setFileName(), setDevice()
423
*/
424
QString QImageWriter::fileName() const
425
0
{
426
0
    QFileDevice *file = qobject_cast<QFileDevice *>(d->device);
427
0
    return file ? file->fileName() : QString();
428
0
}
429
430
/*!
431
    Sets the quality setting of the image format to \a quality.
432
433
    Some image formats, in particular lossy ones, entail a tradeoff between a)
434
    visual quality of the resulting image, and b) encoding execution time and
435
    compression level. This function sets the level of that tradeoff for image
436
    formats that support it. For other formats, this value is ignored.
437
438
    The value range of \a quality depends on the image format. For example,
439
    the "jpeg" format supports a quality range from 0 (low visual quality, high
440
    compression) to 100 (high visual quality, low compression).
441
442
    \sa quality()
443
*/
444
void QImageWriter::setQuality(int quality)
445
0
{
446
0
    d->quality = quality;
447
0
}
448
449
/*!
450
    Returns the quality setting of the image format.
451
452
    \sa setQuality()
453
*/
454
int QImageWriter::quality() const
455
0
{
456
0
    return d->quality;
457
0
}
458
459
/*!
460
    This is an image format specific function that set the compression
461
    of an image. For image formats that do not support setting the
462
    compression, this value is ignored.
463
464
    The value range of \a compression depends on the image format:
465
    \table
466
    \header
467
        \li Image Format
468
        \li Supported Values
469
    \row
470
        \li PNG
471
        \li Values in the range from 0 (no compression) to 100 (low visual
472
            quality, maximum compression). This value is the inverse to
473
            \e quality in setQuality. The two options are mutually exclusive.
474
    \row
475
        \li TGA
476
        \li
477
        0 - No compression \br
478
        1 - RLE compression
479
    \row
480
        \li TIFF
481
        \li
482
        0 - No compression \br
483
        1 - LZW compression \br
484
        2 - RLE compression \br
485
        3 - CCITT Group 3 fax encoding \br
486
        4 - CCITT Group 4 fax encoding \br
487
        5 - JPEG compression
488
    \endtable
489
490
    \sa compression(), setQuality()
491
*/
492
void QImageWriter::setCompression(int compression)
493
0
{
494
0
    d->compression = compression;
495
0
}
496
497
/*!
498
    Returns the compression of the image.
499
500
    \sa setCompression()
501
*/
502
int QImageWriter::compression() const
503
0
{
504
0
    return d->compression;
505
0
}
506
507
/*!
508
    \since 5.4
509
510
    This is an image format specific function that sets the
511
    subtype of the image to \a type. Subtype can be used by
512
    a handler to determine which format it should use while
513
    saving the image.
514
515
    For example, saving an image in DDS format with A8R8G8R8 subtype:
516
517
    \snippet code/src_gui_image_qimagewriter.cpp 3
518
*/
519
void QImageWriter::setSubType(const QByteArray &type)
520
0
{
521
0
    d->subType = type;
522
0
}
523
524
/*!
525
    \since 5.4
526
527
    Returns the subtype of the image.
528
529
    \sa setSubType()
530
*/
531
QByteArray QImageWriter::subType() const
532
0
{
533
0
    return d->subType;
534
0
}
535
536
/*!
537
    \since 5.4
538
539
    Returns the list of subtypes supported by an image.
540
*/
541
QList<QByteArray> QImageWriter::supportedSubTypes() const
542
0
{
543
0
    if (!supportsOption(QImageIOHandler::SupportedSubTypes))
544
0
        return QList<QByteArray>();
545
0
    return qvariant_cast<QList<QByteArray> >(d->handler->option(QImageIOHandler::SupportedSubTypes));
546
0
}
547
548
/*!
549
    \since 5.5
550
551
    This is an image format-specific function which sets the \a optimize flags when
552
    writing images. For image formats that do not support setting an \a optimize flag,
553
    this value is ignored.
554
555
    The default is false.
556
557
    \sa optimizedWrite()
558
*/
559
void QImageWriter::setOptimizedWrite(bool optimize)
560
0
{
561
0
    d->optimizedWrite = optimize;
562
0
}
563
564
/*!
565
    \since 5.5
566
567
    Returns whether optimization has been turned on for writing the image.
568
569
    \sa setOptimizedWrite()
570
*/
571
bool QImageWriter::optimizedWrite() const
572
0
{
573
0
    return d->optimizedWrite;
574
0
}
575
576
/*!
577
    \since 5.5
578
579
    This is an image format-specific function which turns on \a progressive scanning
580
    when writing images. For image formats that do not support setting a \a progressive
581
    scan flag, this value is ignored.
582
583
    The default is false.
584
585
    \sa progressiveScanWrite()
586
*/
587
588
void QImageWriter::setProgressiveScanWrite(bool progressive)
589
0
{
590
0
    d->progressiveScanWrite = progressive;
591
0
}
592
593
/*!
594
    \since 5.5
595
596
    Returns whether the image should be written as a progressive image.
597
598
    \sa setProgressiveScanWrite()
599
*/
600
bool QImageWriter::progressiveScanWrite() const
601
0
{
602
0
    return d->progressiveScanWrite;
603
0
}
604
605
/*!
606
    \since 5.5
607
608
    Sets the image transformations metadata including orientation to \a transform.
609
610
    If transformation metadata is not supported by the image format,
611
    the transform is applied before writing.
612
613
    \sa transformation(), write()
614
*/
615
void QImageWriter::setTransformation(QImageIOHandler::Transformations transform)
616
0
{
617
0
    d->transformation = transform;
618
0
}
619
620
/*!
621
    \since 5.5
622
623
    Returns the transformation and orientation the image has been set to written with.
624
625
    \sa setTransformation()
626
*/
627
QImageIOHandler::Transformations QImageWriter::transformation() const
628
0
{
629
0
    return d->transformation;
630
0
}
631
632
/*!
633
    Sets the image text associated with the key \a key to
634
    \a text. This is useful for storing copyright information
635
    or other information about the image. Example:
636
637
    \snippet code/src_gui_image_qimagewriter.cpp 1
638
639
    If you want to store a single block of data
640
    (e.g., a comment), you can pass an empty key, or use
641
    a generic key like "Description".
642
643
    The key and text will be embedded into the
644
    image data after calling write().
645
646
    Support for this option is implemented through
647
    QImageIOHandler::Description.
648
649
    \sa QImage::setText(), QImageReader::text()
650
*/
651
void QImageWriter::setText(const QString &key, const QString &text)
652
0
{
653
0
    if (!d->description.isEmpty())
654
0
        d->description += "\n\n"_L1;
655
0
    d->description += key.simplified() + ": "_L1 + text.simplified();
656
0
}
657
658
/*!
659
    Returns \c true if QImageWriter can write the image; i.e., the image
660
    format is supported and the assigned device is open for reading.
661
662
    \sa write(), setDevice(), setFormat()
663
*/
664
bool QImageWriter::canWrite() const
665
0
{
666
0
    if (QFile *file = qobject_cast<QFile *>(d->device)) {
667
0
        const bool remove = !file->isOpen() && !file->exists();
668
0
        const bool result = d->canWriteHelper();
669
670
        // This looks strange (why remove if it doesn't exist?) but the issue
671
        // here is that canWriteHelper will create the file in the process of
672
        // checking if the write can succeed. If it subsequently fails, we
673
        // should remove that empty file.
674
0
        if (!result && remove)
675
0
            file->remove();
676
0
        return result;
677
0
    }
678
679
0
    return d->canWriteHelper();
680
0
}
681
682
extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient);
683
684
/*!
685
    Writes the image \a image to the assigned device or file
686
    name. Returns \c true on success; otherwise returns \c false. If the
687
    operation fails, you can call error() to find the type of error
688
    that occurred, or errorString() to get a human readable
689
    description of the error.
690
691
    \sa canWrite(), error(), errorString()
692
*/
693
bool QImageWriter::write(const QImage &image)
694
0
{
695
    // Do this before canWrite, so it doesn't create a file if this fails.
696
0
    if (Q_UNLIKELY(image.isNull())) {
697
0
        d->imageWriterError = QImageWriter::InvalidImageError;
698
0
        d->errorString = QImageWriter::tr("Image is empty");
699
0
        return false;
700
0
    }
701
702
0
    if (!canWrite())
703
0
        return false;
704
705
0
    QImage img = image;
706
0
    if (d->handler->supportsOption(QImageIOHandler::Quality))
707
0
        d->handler->setOption(QImageIOHandler::Quality, d->quality);
708
0
    if (d->handler->supportsOption(QImageIOHandler::CompressionRatio))
709
0
        d->handler->setOption(QImageIOHandler::CompressionRatio, d->compression);
710
0
    if (d->handler->supportsOption(QImageIOHandler::Gamma))
711
0
        d->handler->setOption(QImageIOHandler::Gamma, d->gamma);
712
0
    if (!d->description.isEmpty() && d->handler->supportsOption(QImageIOHandler::Description))
713
0
        d->handler->setOption(QImageIOHandler::Description, d->description);
714
0
    if (!d->subType.isEmpty() && d->handler->supportsOption(QImageIOHandler::SubType))
715
0
        d->handler->setOption(QImageIOHandler::SubType, d->subType);
716
0
    if (d->handler->supportsOption(QImageIOHandler::OptimizedWrite))
717
0
        d->handler->setOption(QImageIOHandler::OptimizedWrite, d->optimizedWrite);
718
0
    if (d->handler->supportsOption(QImageIOHandler::ProgressiveScanWrite))
719
0
        d->handler->setOption(QImageIOHandler::ProgressiveScanWrite, d->progressiveScanWrite);
720
0
    if (d->handler->supportsOption(QImageIOHandler::ImageTransformation))
721
0
        d->handler->setOption(QImageIOHandler::ImageTransformation, int(d->transformation));
722
0
    else
723
0
        qt_imageTransform(img, d->transformation);
724
725
0
    if (!d->handler->write(img))
726
0
        return false;
727
0
    if (QFileDevice *file = qobject_cast<QFileDevice *>(d->device))
728
0
        file->flush();
729
0
    return true;
730
0
}
731
732
/*!
733
    Returns the type of error that last occurred.
734
735
    \sa ImageWriterError, errorString()
736
*/
737
QImageWriter::ImageWriterError QImageWriter::error() const
738
0
{
739
0
    return d->imageWriterError;
740
0
}
741
742
/*!
743
    Returns a human readable description of the last error that occurred.
744
745
    \sa error()
746
*/
747
QString QImageWriter::errorString() const
748
0
{
749
0
    return d->errorString;
750
0
}
751
752
/*!
753
    Returns \c true if the writer supports \a option; otherwise returns
754
    false.
755
756
    Different image formats support different options. Call this function to
757
    determine whether a certain option is supported by the current format. For
758
    example, the PNG format allows you to embed text into the image's metadata
759
    (see text()).
760
761
    \snippet code/src_gui_image_qimagewriter.cpp 2
762
763
    Options can be tested after the writer has been associated with a format.
764
765
    \sa QImageReader::supportsOption(), setFormat()
766
*/
767
bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const
768
0
{
769
0
    if (!d->handler && (d->handler = createWriteHandlerHelper(d->device, d->format)) == nullptr) {
770
0
        d->imageWriterError = QImageWriter::UnsupportedFormatError;
771
0
        d->errorString = QImageWriter::tr("Unsupported image format");
772
0
        return false;
773
0
    }
774
775
0
    return d->handler->supportsOption(option);
776
0
}
777
778
/*!
779
    Returns the list of image formats supported by QImageWriter.
780
781
    By default, Qt can write the following formats:
782
783
    \table
784
    \header \li Format \li MIME type                    \li Description
785
    \row    \li BMP    \li image/bmp                    \li Windows Bitmap
786
    \row    \li JPG    \li image/jpeg                   \li Joint Photographic Experts Group
787
    \row    \li PNG    \li image/png                    \li Portable Network Graphics
788
    \row    \li PBM    \li image/x-portable-bitmap      \li Portable Bitmap
789
    \row    \li PGM    \li image/x-portable-graymap     \li Portable Graymap
790
    \row    \li PPM    \li image/x-portable-pixmap      \li Portable Pixmap
791
    \row    \li XBM    \li image/x-xbitmap              \li X11 Bitmap
792
    \row    \li XPM    \li image/x-xpixmap              \li X11 Pixmap
793
    \endtable
794
795
    Reading and writing SVG files is supported through the \l{Qt SVG} module.
796
    The \l{Qt Image Formats} module provides support for additional image formats.
797
798
    Note that the QApplication instance must be created before this function is
799
    called.
800
801
    \sa setFormat(), QImageReader::supportedImageFormats(), QImageIOPlugin
802
*/
803
QList<QByteArray> QImageWriter::supportedImageFormats()
804
0
{
805
0
    return QImageReaderWriterHelpers::supportedImageFormats(QImageReaderWriterHelpers::CanWrite);
806
0
}
807
808
/*!
809
    Returns the list of MIME types supported by QImageWriter.
810
811
    Note that the QApplication instance must be created before this function is
812
    called.
813
814
    \sa supportedImageFormats(), QImageReader::supportedMimeTypes()
815
*/
816
QList<QByteArray> QImageWriter::supportedMimeTypes()
817
0
{
818
0
    return QImageReaderWriterHelpers::supportedMimeTypes(QImageReaderWriterHelpers::CanWrite);
819
0
}
820
821
/*!
822
    \since 5.12
823
824
    Returns the list of image formats corresponding to \a mimeType.
825
826
    Note that the QGuiApplication instance must be created before this function is
827
    called.
828
829
    \sa supportedImageFormats(), supportedMimeTypes()
830
*/
831
832
QList<QByteArray> QImageWriter::imageFormatsForMimeType(const QByteArray &mimeType)
833
0
{
834
0
    return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType,
835
0
                                                              QImageReaderWriterHelpers::CanWrite);
836
0
}
837
838
QT_END_NAMESPACE