Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++
++ /*!
++ \class QImageWriter
++ \brief The QImageWriter class provides a format independent interface
++ for writing images to files or other devices.
++
++ \inmodule QtGui
++ \reentrant
++ \ingroup painting
++
++ QImageWriter supports setting format specific options, such as
++ compression level and quality, prior to storing the
++ image. If you do not need such options, you can use QImage::save()
++ or QPixmap::save() instead.
++
++ To store an image, you start by constructing a QImageWriter
++ object. Pass either a file name or a device pointer, and the
++ image format to QImageWriter's constructor. You can then set
++ several options, such as quality (by calling setQuality()).
++ canWrite() returns \c true if QImageWriter can write the image
++ (i.e., the image format is supported and the device is open for
++ writing). Call write() to write the image to the device.
++
++ If any error occurs when writing the image, write() will return
++ false. You can then call error() to find the type of error that
++ occurred, or errorString() to get a human readable description of
++ what went wrong.
++
++ Call supportedImageFormats() for a list of formats that
++ QImageWriter can write. QImageWriter supports all built-in image
++ formats, in addition to any image format plugins that support
++ writing.
++
++ \note QImageWriter assumes exclusive control over the file or
++ device that is assigned. Any attempts to modify the assigned file
++ or device during the lifetime of the QImageWriter object will
++ yield undefined results. If immediate access to a resource is
++ desired, the use of a scope is the recommended method.
++
++ For example:
++
++ \snippet qimagewriter/main.cpp 0
++
++ \sa QImageReader, QImageIOHandler, QImageIOPlugin, QColorSpace
++ */
++
++ /*!
++ \enum QImageWriter::ImageWriterError
++
++ This enum describes errors that can occur when writing images with
++ QImageWriter.
++
++ \value DeviceError QImageWriter encountered a device error when
++ writing the image data. Consult your device for more details on
++ what went wrong.
++
++ \value UnsupportedFormatError Qt does not support the requested
++ image format.
++
++ \value InvalidImageError An attempt was made to write an invalid QImage. An
++ example of an invalid image would be a null QImage.
++
++ \value UnknownError An unknown error occurred. If you get this
++ value after calling write(), it is most likely caused by a bug in
++ QImageWriter.
++ */
++ // Qt-Security score:significant reason:default
++
++ #include "qimagewriter.h"
++
++ #include <qbytearray.h>
++ #include <qfile.h>
++ #include <qfileinfo.h>
++ #include <qimage.h>
++ #include <qimageiohandler.h>
++ #include <qset.h>
++ #include <qvariant.h>
++ #include <qloggingcategory.h>
++
++ // factory loader
++ #include <qcoreapplication.h>
++ #include <private/qfactoryloader_p.h>
++
++ // image handlers
++ #include <private/qbmphandler_p.h>
++ #include <private/qppmhandler_p.h>
++ #include <private/qxbmhandler_p.h>
++ #include <private/qxpmhandler_p.h>
++ #ifndef QT_NO_IMAGEFORMAT_PNG
++ #include <private/qpnghandler_p.h>
++ #endif
++
++ #include <private/qimagereaderwriterhelpers_p.h>
++
++ #include <algorithm>
++
++ QT_BEGIN_NAMESPACE
++
++ Q_STATIC_LOGGING_CATEGORY(lcImageWriter, "qt.gui.imageio.writer")
++
++ using namespace Qt::StringLiterals;
++
++ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
++ const QByteArray &format)
++ {
++ QByteArray form = format.toLower();
++ QByteArray suffix;
++ QImageIOHandler *handler = nullptr;
++
++ qCDebug(lcImageWriter) << "Finding write handler for" << device << "and format" << format;
++
++ #ifndef QT_NO_IMAGEFORMATPLUGIN
++ typedef QMultiMap<int, QString> PluginKeyMap;
++
++ // check if any plugins can write the image
++ auto l = QImageReaderWriterHelpers::pluginLoader();
++ const PluginKeyMap keyMap = l->keyMap();
++ int suffixPluginIndex = -1;
++
++ qCDebug(lcImageWriter) << keyMap.uniqueKeys().size() << "plugins available:" << keyMap.values();
++ #endif
++
++ if (device && format.isEmpty()) {
++ // if there's no format, see if \a device is a file, and if so, find
++ // the file suffix and find support for that format among our plugins.
++ // this allows plugins to override our built-in handlers.
++ if (QFileDevice *file = qobject_cast<QFileDevice *>(device)) {
++ if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) {
++ qCDebug(lcImageWriter) << "Resolved format" << suffix << "from file name suffix";
++ #ifndef QT_NO_IMAGEFORMATPLUGIN
++ const int index = keyMap.key(QString::fromLatin1(suffix), -1);
++ if (index != -1)
++ suffixPluginIndex = index;
++ #endif
++ }
++ }
++ }
++
++ QByteArray testFormat = !form.isEmpty() ? form : suffix;
++
++ #ifndef QT_NO_IMAGEFORMATPLUGIN
++ if (suffixPluginIndex != -1) {
++ // when format is missing, check if we can find a plugin for the
++ // suffix.
++ qCDebug(lcImageWriter) << "Checking if any plugins have explicitly declared support"
++ << "for the format" << testFormat;
++ const int index = keyMap.key(QString::fromLatin1(suffix), -1);
++ if (index != -1) {
++ QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(index));
++ if (plugin && (plugin->capabilities(device, suffix) & QImageIOPlugin::CanWrite)) {
++ handler = plugin->create(device, suffix);
++ qCDebug(lcImageWriter) << plugin << "can write the format" << testFormat;
++ }
++ }
++ }
++ #endif // QT_NO_IMAGEFORMATPLUGIN
++
++ // check if any built-in handlers can write the image
++ if (!handler && !testFormat.isEmpty()) {
++ qCDebug(lcImageWriter) << "Checking if any built in handlers recognize the format"
++ << testFormat;
++ if (false) {
++ #ifndef QT_NO_IMAGEFORMAT_PNG
++ } else if (testFormat == "png") {
++ handler = new QPngHandler;
++ #endif
++ #ifndef QT_NO_IMAGEFORMAT_BMP
++ } else if (testFormat == "bmp") {
++ handler = new QBmpHandler;
++ } else if (testFormat == "dib") {
++ handler = new QBmpHandler(QBmpHandler::DibFormat);
++ #endif
++ #ifndef QT_NO_IMAGEFORMAT_XPM
++ } else if (testFormat == "xpm") {
++ handler = new QXpmHandler;
++ #endif
++ #ifndef QT_NO_IMAGEFORMAT_XBM
++ } else if (testFormat == "xbm") {
++ handler = new QXbmHandler;
++ handler->setOption(QImageIOHandler::SubType, testFormat);
++ #endif
++ #ifndef QT_NO_IMAGEFORMAT_PPM
++ } else if (testFormat == "pbm" || testFormat == "pbmraw" || testFormat == "pgm"
++ || testFormat == "pgmraw" || testFormat == "ppm" || testFormat == "ppmraw") {
++ handler = new QPpmHandler;
++ handler->setOption(QImageIOHandler::SubType, testFormat);
++ #endif
++ }
++
++ if (handler)
++ qCDebug(lcImageWriter) << "Using the built-in handler for format" << testFormat;
++ }
++
++ #ifndef QT_NO_IMAGEFORMATPLUGIN
++ if (!handler && !testFormat.isEmpty()) {
++ qCDebug(lcImageWriter) << "Checking if any plugins recognize the format" << testFormat;
++ const int keyCount = keyMap.size();
++ for (int i = 0; i < keyCount; ++i) {
++ QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i));
++ if (plugin && (plugin->capabilities(device, testFormat) & QImageIOPlugin::CanWrite)) {
++ handler = plugin->create(device, testFormat);
++ qCDebug(lcImageWriter) << plugin << "can write the format" << testFormat;
++ break;
++ }
++ }
++ }
++ #endif // QT_NO_IMAGEFORMATPLUGIN
++
++ if (!handler) {
++ qCDebug(lcImageWriter, "No handlers found. Giving up.");
++ return nullptr;
++ }
++
++ handler->setDevice(device);
++ if (!testFormat.isEmpty())
++ handler->setFormat(testFormat);
++ return handler;
++ }
++
++ class QImageWriterPrivate
++ {
++ public:
++ QImageWriterPrivate(QImageWriter *qq);
++
++ bool canWriteHelper();
++
++ // device
++ QByteArray format;
++ QIODevice *device;
++ bool deleteDevice;
++ QImageIOHandler *handler;
++
++ // image options
++ int quality;
++ int compression;
++ float gamma;
++ QString description;
++ QString text;
++ QByteArray subType;
++ bool optimizedWrite;
++ bool progressiveScanWrite;
++ QImageIOHandler::Transformations transformation;
++
++ // error
++ QImageWriter::ImageWriterError imageWriterError;
++ QString errorString;
++
++ QImageWriter *q;
++ };
++
++ /*!
++ \internal
++ */
++ QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq)
++ {
++ device = nullptr;
++ deleteDevice = false;
++ handler = nullptr;
++ quality = -1;
++ compression = -1;
++ gamma = 0.0;
++ optimizedWrite = false;
++ progressiveScanWrite = false;
++ imageWriterError = QImageWriter::UnknownError;
++ errorString = QImageWriter::tr("Unknown error");
++ transformation = QImageIOHandler::TransformationNone;
++
++ q = qq;
++ }
++
++ bool QImageWriterPrivate::canWriteHelper()
++ {
++ if (!device) {
++ imageWriterError = QImageWriter::DeviceError;
++ errorString = QImageWriter::tr("Device is not set");
++ return false;
++ }
++ if (!device->isOpen()) {
++ if (!device->open(QIODevice::WriteOnly)) {
++ imageWriterError = QImageWriter::DeviceError;
++ errorString = QImageWriter::tr("Cannot open device for writing: %1").arg(device->errorString());
++ return false;
++ }
++ }
++ if (!device->isWritable()) {
++ imageWriterError = QImageWriter::DeviceError;
++ errorString = QImageWriter::tr("Device not writable");
++ return false;
++ }
++ if (!handler && (handler = createWriteHandlerHelper(device, format)) == nullptr) {
++ imageWriterError = QImageWriter::UnsupportedFormatError;
++ errorString = QImageWriter::tr("Unsupported image format");
++ return false;
++ }
++ return true;
++ }
++
++ /*!
++ Constructs an empty QImageWriter object. Before writing, you must
++ call setFormat() to set an image format, then setDevice() or
++ setFileName().
++ */
++ QImageWriter::QImageWriter()
++ : d(new QImageWriterPrivate(this))
++ {
++ }
++
++ /*!
++ Constructs a QImageWriter object using the device \a device and
++ image format \a format.
++ */
++ QImageWriter::QImageWriter(QIODevice *device, const QByteArray &format)
++ : d(new QImageWriterPrivate(this))
++ {
++ d->device = device;
++ d->format = format;
++ }
++
++ /*!
++ Constructs a QImageWriter objects that will write to a file with
++ the name \a fileName, using the image format \a format. If \a
++ format is not provided, QImageWriter will detect the image format
++ by inspecting the extension of \a fileName.
++ */
++ QImageWriter::QImageWriter(const QString &fileName, const QByteArray &format)
++ : QImageWriter(new QFile(fileName), format)
++ {
++ d->deleteDevice = true;
++ }
++
++ /*!
++ Destructs the QImageWriter object.
++ */
++ QImageWriter::~QImageWriter()
++ {
++ delete d->handler;
++ if (d->deleteDevice)
++ delete d->device;
++ delete d;
++ }
++
++ /*!
++ Sets the format QImageWriter will use when writing images, to \a
++ format. \a format is a case insensitive text string. Example:
++
++ \snippet code/src_gui_image_qimagewriter.cpp 0
++
++ You can call supportedImageFormats() for the full list of formats
++ QImageWriter supports.
++
++ \sa format()
++ */
++ void QImageWriter::setFormat(const QByteArray &format)
++ {
++ d->format = format;
++ }
++
++ /*!
++ Returns the format QImageWriter uses for writing images.
++
++ \sa setFormat()
++ */
++ QByteArray QImageWriter::format() const
++ {
++ return d->format;
++ }
++
++ /*!
++ Sets QImageWriter's device to \a device. If a device has already
++ been set, the old device is removed from QImageWriter and is
++ otherwise left unchanged.
++
++ If the device is not already open, QImageWriter will attempt to
++ open the device in \l QIODeviceBase::WriteOnly mode by calling
++ open(). Note that this does not work for certain devices, such as
++ QProcess, QTcpSocket and QUdpSocket, where more logic is required
++ to open the device.
++
++ \sa device(), setFileName()
++ */
++ void QImageWriter::setDevice(QIODevice *device)
++ {
++ delete d->handler;
++ d->handler = nullptr;
++ if (d->device && d->deleteDevice)
++ delete d->device;
++
++ d->device = device;
++ d->deleteDevice = false;
++ }
++
++ /*!
++ Returns the device currently assigned to QImageWriter, or \nullptr
++ if no device has been assigned.
++ */
++ QIODevice *QImageWriter::device() const
++ {
++ return d->device;
++ }
++
++ /*!
++ Sets the file name of QImageWriter to \a fileName. Internally,
++ QImageWriter will create a QFile and open it in \l
++ QIODevice::WriteOnly mode, and use this file when writing images.
++
++ \sa fileName(), setDevice()
++ */
++ void QImageWriter::setFileName(const QString &fileName)
++ {
++ setDevice(new QFile(fileName));
++ d->deleteDevice = true;
++ }
++
++ /*!
++ If the currently assigned device is a file, or if setFileName()
++ has been called, this function returns the name of the file
++ QImageWriter writes to. Otherwise (i.e., if no device has been
++ assigned or the device is not a file), an empty QString is
++ returned.
++
++ \sa setFileName(), setDevice()
++ */
++ QString QImageWriter::fileName() const
++ {
++ QFileDevice *file = qobject_cast<QFileDevice *>(d->device);
++ return file ? file->fileName() : QString();
++ }
++
++ /*!
++ Sets the quality setting of the image format to \a quality.
++
++ Some image formats, in particular lossy ones, entail a tradeoff between a)
++ visual quality of the resulting image, and b) encoding execution time and
++ compression level. This function sets the level of that tradeoff for image
++ formats that support it. For other formats, this value is ignored.
++
++ The value range of \a quality depends on the image format. For example,
++ the "jpeg" format supports a quality range from 0 (low visual quality, high
++ compression) to 100 (high visual quality, low compression).
++
++ \sa quality()
++ */
++ void QImageWriter::setQuality(int quality)
++ {
++ d->quality = quality;
++ }
++
++ /*!
++ Returns the quality setting of the image format.
++
++ \sa setQuality()
++ */
++ int QImageWriter::quality() const
++ {
++ return d->quality;
++ }
++
++ /*!
++ This is an image format specific function that set the compression
++ of an image. For image formats that do not support setting the
++ compression, this value is ignored.
++
++ The value range of \a compression depends on the image format:
++ \table
++ \header
++ \li Image Format
++ \li Supported Values
++ \row
++ \li PNG
++ \li Values in the range from 0 (no compression) to 100 (low visual
++ quality, maximum compression). This value is the inverse to
++ \e quality in setQuality. The two options are mutually exclusive.
++ \row
++ \li TGA
++ \li
++ 0 - No compression \br
++ 1 - RLE compression
++ \row
++ \li TIFF
++ \li
++ 0 - No compression \br
++ 1 - LZW compression \br
++ 2 - RLE compression \br
++ 3 - CCITT Group 3 fax encoding \br
++ 4 - CCITT Group 4 fax encoding \br
++ 5 - JPEG compression
++ \endtable
++
++ \sa compression(), setQuality()
++ */
++ void QImageWriter::setCompression(int compression)
++ {
++ d->compression = compression;
++ }
++
++ /*!
++ Returns the compression of the image.
++
++ \sa setCompression()
++ */
++ int QImageWriter::compression() const
++ {
++ return d->compression;
++ }
++
++ /*!
++ \since 5.4
++
++ This is an image format specific function that sets the
++ subtype of the image to \a type. Subtype can be used by
++ a handler to determine which format it should use while
++ saving the image.
++
++ For example, saving an image in DDS format with A8R8G8R8 subtype:
++
++ \snippet code/src_gui_image_qimagewriter.cpp 3
++ */
++ void QImageWriter::setSubType(const QByteArray &type)
++ {
++ d->subType = type;
++ }
++
++ /*!
++ \since 5.4
++
++ Returns the subtype of the image.
++
++ \sa setSubType()
++ */
++ QByteArray QImageWriter::subType() const
++ {
++ return d->subType;
++ }
++
++ /*!
++ \since 5.4
++
++ Returns the list of subtypes supported by an image.
++ */
++ QList<QByteArray> QImageWriter::supportedSubTypes() const
++ {
++ if (!supportsOption(QImageIOHandler::SupportedSubTypes))
++ return QList<QByteArray>();
++ return qvariant_cast<QList<QByteArray> >(d->handler->option(QImageIOHandler::SupportedSubTypes));
++ }
++
++ /*!
++ \since 5.5
++
++ This is an image format-specific function which sets the \a optimize flags when
++ writing images. For image formats that do not support setting an \a optimize flag,
++ this value is ignored.
++
++ The default is false.
++
++ \sa optimizedWrite()
++ */
++ void QImageWriter::setOptimizedWrite(bool optimize)
++ {
++ d->optimizedWrite = optimize;
++ }
++
++ /*!
++ \since 5.5
++
++ Returns whether optimization has been turned on for writing the image.
++
++ \sa setOptimizedWrite()
++ */
++ bool QImageWriter::optimizedWrite() const
++ {
++ return d->optimizedWrite;
++ }
++
++ /*!
++ \since 5.5
++
++ This is an image format-specific function which turns on \a progressive scanning
++ when writing images. For image formats that do not support setting a \a progressive
++ scan flag, this value is ignored.
++
++ The default is false.
++
++ \sa progressiveScanWrite()
++ */
++
++ void QImageWriter::setProgressiveScanWrite(bool progressive)
++ {
++ d->progressiveScanWrite = progressive;
++ }
++
++ /*!
++ \since 5.5
++
++ Returns whether the image should be written as a progressive image.
++
++ \sa setProgressiveScanWrite()
++ */
++ bool QImageWriter::progressiveScanWrite() const
++ {
++ return d->progressiveScanWrite;
++ }
++
++ /*!
++ \since 5.5
++
++ Sets the image transformations metadata including orientation to \a transform.
++
++ If transformation metadata is not supported by the image format,
++ the transform is applied before writing.
++
++ \sa transformation(), write()
++ */
++ void QImageWriter::setTransformation(QImageIOHandler::Transformations transform)
++ {
++ d->transformation = transform;
++ }
++
++ /*!
++ \since 5.5
++
++ Returns the transformation and orientation the image has been set to written with.
++
++ \sa setTransformation()
++ */
++ QImageIOHandler::Transformations QImageWriter::transformation() const
++ {
++ return d->transformation;
++ }
++
++ /*!
++ Sets the image text associated with the key \a key to
++ \a text. This is useful for storing copyright information
++ or other information about the image. Example:
++
++ \snippet code/src_gui_image_qimagewriter.cpp 1
++
++ If you want to store a single block of data
++ (e.g., a comment), you can pass an empty key, or use
++ a generic key like "Description".
++
++ The key and text will be embedded into the
++ image data after calling write().
++
++ Support for this option is implemented through
++ QImageIOHandler::Description.
++
++ \sa QImage::setText(), QImageReader::text()
++ */
++ void QImageWriter::setText(const QString &key, const QString &text)
++ {
++ if (!d->description.isEmpty())
++ d->description += "\n\n"_L1;
++ d->description += key.simplified() + ": "_L1 + text.simplified();
++ }
++
++ /*!
++ Returns \c true if QImageWriter can write the image; i.e., the image
++ format is supported and the assigned device is open for reading.
++
++ \sa write(), setDevice(), setFormat()
++ */
++ bool QImageWriter::canWrite() const
++ {
++ if (QFile *file = qobject_cast<QFile *>(d->device)) {
++ const bool remove = !file->isOpen() && !file->exists();
++ const bool result = d->canWriteHelper();
++
++ // This looks strange (why remove if it doesn't exist?) but the issue
++ // here is that canWriteHelper will create the file in the process of
++ // checking if the write can succeed. If it subsequently fails, we
++ // should remove that empty file.
++ if (!result && remove)
++ file->remove();
++ return result;
++ }
++
++ return d->canWriteHelper();
++ }
++
++ extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient);
++
++ /*!
++ Writes the image \a image to the assigned device or file
++ name. Returns \c true on success; otherwise returns \c false. If the
++ operation fails, you can call error() to find the type of error
++ that occurred, or errorString() to get a human readable
++ description of the error.
++
++ \sa canWrite(), error(), errorString()
++ */
++ bool QImageWriter::write(const QImage &image)
++ {
++ // Do this before canWrite, so it doesn't create a file if this fails.
++ if (Q_UNLIKELY(image.isNull())) {
++ d->imageWriterError = QImageWriter::InvalidImageError;
++ d->errorString = QImageWriter::tr("Image is empty");
++ return false;
++ }
++
++ if (!canWrite())
++ return false;
++
++ QImage img = image;
++ if (d->handler->supportsOption(QImageIOHandler::Quality))
++ d->handler->setOption(QImageIOHandler::Quality, d->quality);
++ if (d->handler->supportsOption(QImageIOHandler::CompressionRatio))
++ d->handler->setOption(QImageIOHandler::CompressionRatio, d->compression);
++ if (d->handler->supportsOption(QImageIOHandler::Gamma))
++ d->handler->setOption(QImageIOHandler::Gamma, d->gamma);
++ if (!d->description.isEmpty() && d->handler->supportsOption(QImageIOHandler::Description))
++ d->handler->setOption(QImageIOHandler::Description, d->description);
++ if (!d->subType.isEmpty() && d->handler->supportsOption(QImageIOHandler::SubType))
++ d->handler->setOption(QImageIOHandler::SubType, d->subType);
++ if (d->handler->supportsOption(QImageIOHandler::OptimizedWrite))
++ d->handler->setOption(QImageIOHandler::OptimizedWrite, d->optimizedWrite);
++ if (d->handler->supportsOption(QImageIOHandler::ProgressiveScanWrite))
++ d->handler->setOption(QImageIOHandler::ProgressiveScanWrite, d->progressiveScanWrite);
++ if (d->handler->supportsOption(QImageIOHandler::ImageTransformation))
++ d->handler->setOption(QImageIOHandler::ImageTransformation, int(d->transformation));
++ else
++ qt_imageTransform(img, d->transformation);
++
++ if (!d->handler->write(img))
++ return false;
++ if (QFileDevice *file = qobject_cast<QFileDevice *>(d->device))
++ file->flush();
++ return true;
++ }
++
++ /*!
++ Returns the type of error that last occurred.
++
++ \sa ImageWriterError, errorString()
++ */
++ QImageWriter::ImageWriterError QImageWriter::error() const
++ {
++ return d->imageWriterError;
++ }
++
++ /*!
++ Returns a human readable description of the last error that occurred.
++
++ \sa error()
++ */
++ QString QImageWriter::errorString() const
++ {
++ return d->errorString;
++ }
++
++ /*!
++ Returns \c true if the writer supports \a option; otherwise returns
++ false.
++
++ Different image formats support different options. Call this function to
++ determine whether a certain option is supported by the current format. For
++ example, the PNG format allows you to embed text into the image's metadata
++ (see text()).
++
++ \snippet code/src_gui_image_qimagewriter.cpp 2
++
++ Options can be tested after the writer has been associated with a format.
++
++ \sa QImageReader::supportsOption(), setFormat()
++ */
++ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const
++ {
++ if (!d->handler && (d->handler = createWriteHandlerHelper(d->device, d->format)) == nullptr) {
++ d->imageWriterError = QImageWriter::UnsupportedFormatError;
++ d->errorString = QImageWriter::tr("Unsupported image format");
++ return false;
++ }
++
++ return d->handler->supportsOption(option);
++ }
++
++ /*!
++ Returns the list of image formats supported by QImageWriter.
++
++ By default, Qt can write the following formats:
++
++ \table
++ \header \li Format \li MIME type \li Description
++ \row \li BMP \li image/bmp \li Windows Bitmap
++ \row \li JPG \li image/jpeg \li Joint Photographic Experts Group
++ \row \li PNG \li image/png \li Portable Network Graphics
++ \row \li PBM \li image/x-portable-bitmap \li Portable Bitmap
++ \row \li PGM \li image/x-portable-graymap \li Portable Graymap
++ \row \li PPM \li image/x-portable-pixmap \li Portable Pixmap
++ \row \li XBM \li image/x-xbitmap \li X11 Bitmap
++ \row \li XPM \li image/x-xpixmap \li X11 Pixmap
++ \endtable
++
++ Reading and writing SVG files is supported through the \l{Qt SVG} module.
++ The \l{Qt Image Formats} module provides support for additional image formats.
++
++ Note that the QApplication instance must be created before this function is
++ called.
++
++ \sa setFormat(), QImageReader::supportedImageFormats(), QImageIOPlugin
++ */
++ QList<QByteArray> QImageWriter::supportedImageFormats()
++ {
++ return QImageReaderWriterHelpers::supportedImageFormats(QImageReaderWriterHelpers::CanWrite);
++ }
++
++ /*!
++ Returns the list of MIME types supported by QImageWriter.
++
++ Note that the QApplication instance must be created before this function is
++ called.
++
++ \sa supportedImageFormats(), QImageReader::supportedMimeTypes()
++ */
++ QList<QByteArray> QImageWriter::supportedMimeTypes()
++ {
++ return QImageReaderWriterHelpers::supportedMimeTypes(QImageReaderWriterHelpers::CanWrite);
++ }
++
++ /*!
++ \since 5.12
++
++ Returns the list of image formats corresponding to \a mimeType.
++
++ Note that the QGuiApplication instance must be created before this function is
++ called.
++
++ \sa supportedImageFormats(), supportedMimeTypes()
++ */
++
++ QList<QByteArray> QImageWriter::imageFormatsForMimeType(const QByteArray &mimeType)
++ {
++ return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType,
++ QImageReaderWriterHelpers::CanWrite);
++ }
++
++ QT_END_NAMESPACE