summaryrefslogtreecommitdiffstats
path: root/src/gui/image
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image')
-rw-r--r--src/gui/image/image.pri2
-rw-r--r--src/gui/image/qbitmap.cpp52
-rw-r--r--src/gui/image/qbitmap.h1
-rw-r--r--src/gui/image/qimage.cpp19
-rw-r--r--src/gui/image/qimage_conversions.cpp10
-rw-r--r--src/gui/image/qimagereader.cpp117
-rw-r--r--src/gui/image/qimagereader.h1
-rw-r--r--src/gui/image/qimagereaderwriterhelpers.cpp180
-rw-r--r--src/gui/image/qimagereaderwriterhelpers_p.h139
-rw-r--r--src/gui/image/qimagewriter.cpp121
-rw-r--r--src/gui/image/qimagewriter.h1
-rw-r--r--src/gui/image/qpixmap.cpp10
-rw-r--r--src/gui/image/qxbmhandler.cpp2
-rw-r--r--src/gui/image/qxpmhandler.cpp4
14 files changed, 417 insertions, 242 deletions
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index 76aba944b2..b4942f06d4 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -9,6 +9,7 @@ HEADERS += \
image/qimage_p.h \
image/qimageiohandler.h \
image/qimagereader.h \
+ image/qimagereaderwriterhelpers_p.h \
image/qimagewriter.h \
image/qpaintengine_pic_p.h \
image/qpicture.h \
@@ -33,6 +34,7 @@ SOURCES += \
image/qimage_conversions.cpp \
image/qimageiohandler.cpp \
image/qimagereader.cpp \
+ image/qimagereaderwriterhelpers.cpp \
image/qimagewriter.cpp \
image/qpaintengine_pic.cpp \
image/qpicture.cpp \
diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp
index e8405a6d11..2453242fa8 100644
--- a/src/gui/image/qbitmap.cpp
+++ b/src/gui/image/qbitmap.cpp
@@ -189,9 +189,7 @@ QBitmap &QBitmap::operator=(const QPixmap &pixmap)
} else if (pixmap.depth() == 1) { // 1-bit pixmap
QPixmap::operator=(pixmap); // shallow assignment
} else { // n-bit depth pixmap
- QImage image;
- image = pixmap.toImage(); // convert pixmap to image
- *this = fromImage(image); // will dither image
+ *this = fromImage(pixmap.toImage()); // will dither image
}
return *this;
}
@@ -223,6 +221,24 @@ QBitmap::operator QVariant() const
return QVariant(QVariant::Bitmap, this);
}
+static QBitmap makeBitmap(QImage &&image, Qt::ImageConversionFlags flags)
+{
+ // make sure image.color(0) == Qt::color0 (white)
+ // and image.color(1) == Qt::color1 (black)
+ const QRgb c0 = QColor(Qt::black).rgb();
+ const QRgb c1 = QColor(Qt::white).rgb();
+ if (image.color(0) == c0 && image.color(1) == c1) {
+ image.invertPixels();
+ image.setColor(0, c1);
+ image.setColor(1, c0);
+ }
+
+ QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType));
+
+ data->fromImageInPlace(image, flags | Qt::MonoOnly);
+ return QPixmap(data.take());
+}
+
/*!
Returns a copy of the given \a image converted to a bitmap using
the specified image conversion \a flags.
@@ -234,22 +250,24 @@ QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
if (image.isNull())
return QBitmap();
- QImage img = image.convertToFormat(QImage::Format_MonoLSB, flags);
+ return makeBitmap(image.convertToFormat(QImage::Format_MonoLSB, flags), flags);
+}
- // make sure image.color(0) == Qt::color0 (white)
- // and image.color(1) == Qt::color1 (black)
- const QRgb c0 = QColor(Qt::black).rgb();
- const QRgb c1 = QColor(Qt::white).rgb();
- if (img.color(0) == c0 && img.color(1) == c1) {
- img.invertPixels();
- img.setColor(0, c1);
- img.setColor(1, c0);
- }
+/*!
+ \since 5.12
+ \overload
- QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType));
+ Returns a copy of the given \a image converted to a bitmap using
+ the specified image conversion \a flags.
- data->fromImage(img, flags | Qt::MonoOnly);
- return QPixmap(data.take());
+ \sa fromData()
+*/
+QBitmap QBitmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
+{
+ if (image.isNull())
+ return QBitmap();
+
+ return makeBitmap(std::move(image).convertToFormat(QImage::Format_MonoLSB, flags), flags);
}
/*!
@@ -277,7 +295,7 @@ QBitmap QBitmap::fromData(const QSize &size, const uchar *bits, QImage::Format m
int bytesPerLine = (size.width() + 7) / 8;
for (int y = 0; y < size.height(); ++y)
memcpy(image.scanLine(y), bits + bytesPerLine * y, bytesPerLine);
- return QBitmap::fromImage(image);
+ return QBitmap::fromImage(std::move(image));
}
/*!
diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h
index 6a8c8b3457..188064fccf 100644
--- a/src/gui/image/qbitmap.h
+++ b/src/gui/image/qbitmap.h
@@ -72,6 +72,7 @@ public:
inline void clear() { fill(Qt::color0); }
static QBitmap fromImage(const QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ static QBitmap fromImage(QImage &&image, Qt::ImageConversionFlags flags = Qt::AutoColor);
static QBitmap fromData(const QSize &size, const uchar *bits,
QImage::Format monoFormat = QImage::Format_MonoLSB);
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 7fcae12cbd..469ae8b97e 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -2582,15 +2582,14 @@ bool QImage::allGray() const
break;
}
- const int buffer_size = 2048;
- uint buffer[buffer_size];
+ uint buffer[BufferSize];
const QPixelLayout *layout = &qPixelLayouts[d->format];
FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
for (int j = 0; j < d->height; ++j) {
const uchar *b = constScanLine(j);
int x = 0;
while (x < d->width) {
- int l = qMin(d->width - x, buffer_size);
+ int l = qMin(d->width - x, BufferSize);
const uint *ptr = fetch(buffer, b, x, l);
ptr = layout->convertToARGB32PM(buffer, ptr, l, 0, 0);
for (int i = 0; i < l; ++i) {
@@ -3218,14 +3217,13 @@ inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage
const uint alphaGreenMask = (((1 << layout->alphaWidth) - 1) << layout->alphaShift)
| (((1 << layout->greenWidth) - 1) << layout->greenShift);
- const int buffer_size = 2048;
- uint buffer[buffer_size];
+ uint buffer[BufferSize];
for (int i = 0; i < height; ++i) {
uchar *q = dst->scanLine(i);
const uchar *p = src->constScanLine(i);
int x = 0;
while (x < width) {
- int l = qMin(width - x, buffer_size);
+ int l = qMin(width - x, BufferSize);
const uint *ptr = fetch(buffer, p, x, l);
for (int j = 0; j < l; ++j) {
uint red = (ptr[j] >> layout->redShift) & redBlueMask;
@@ -3457,8 +3455,7 @@ void QImage::rgbSwapped_inplace()
bool QImage::load(const QString &fileName, const char* format)
{
- QImage image = QImageReader(fileName, format).read();
- operator=(image);
+ *this = QImageReader(fileName, format).read();
return !isNull();
}
@@ -3471,8 +3468,7 @@ bool QImage::load(const QString &fileName, const char* format)
bool QImage::load(QIODevice* device, const char* format)
{
- QImage image = QImageReader(device, format).read();
- operator=(image);
+ *this = QImageReader(device, format).read();
return !isNull();
}
@@ -3492,8 +3488,7 @@ bool QImage::load(QIODevice* device, const char* format)
bool QImage::loadFromData(const uchar *data, int len, const char *format)
{
- QImage image = fromData(data, len, format);
- operator=(image);
+ *this = fromData(data, len, format);
return !isNull();
}
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 4eef617336..9a8cbf43c9 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -145,8 +145,7 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
// Cannot be used with indexed formats.
Q_ASSERT(dest->format > QImage::Format_Indexed8);
Q_ASSERT(src->format > QImage::Format_Indexed8);
- const int buffer_size = 2048;
- uint buf[buffer_size];
+ uint buf[BufferSize];
uint *buffer = buf;
const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
@@ -196,7 +195,7 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
if (destLayout->bpp == QPixelLayout::BPP32)
buffer = reinterpret_cast<uint *>(destData) + x;
else
- l = qMin(l, buffer_size);
+ l = qMin(l, BufferSize);
const uint *ptr = fetch(buffer, srcData, x, l);
ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr);
ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr);
@@ -217,8 +216,7 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
if (data->depth != qt_depthForFormat(dst_format))
return false;
- const int buffer_size = 2048;
- uint buffer[buffer_size];
+ uint buffer[BufferSize];
const QPixelLayout *srcLayout = &qPixelLayouts[data->format];
const QPixelLayout *destLayout = &qPixelLayouts[dst_format];
uchar *srcData = data->data;
@@ -261,7 +259,7 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
int x = 0;
while (x < data->width) {
dither.x = x;
- int l = qMin(data->width - x, buffer_size);
+ int l = qMin(data->width - x, BufferSize);
const uint *ptr = fetch(buffer, srcData, x, l);
ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr);
ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr);
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 7086e102ea..e77c6f019c 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -164,73 +164,13 @@
#include <private/qpnghandler_p.h>
#endif
+#include <private/qimagereaderwriterhelpers_p.h>
+
#include <algorithm>
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
-#endif
-
-enum _qt_BuiltInFormatType {
-#ifndef QT_NO_IMAGEFORMAT_PNG
- _qt_PngFormat,
-#endif
-#ifndef QT_NO_IMAGEFORMAT_BMP
- _qt_BmpFormat,
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PPM
- _qt_PpmFormat,
- _qt_PgmFormat,
- _qt_PbmFormat,
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XBM
- _qt_XbmFormat,
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XPM
- _qt_XpmFormat,
-#endif
- _qt_NumFormats,
- _qt_NoFormat = -1
-};
-
-#if !defined(QT_NO_IMAGEFORMAT_PPM)
-# define MAX_MT_SIZE 20
-#elif !defined(QT_NO_IMAGEFORMAT_XBM) || !defined(QT_NO_IMAGEFORMAT_XPM)
-# define MAX_MT_SIZE 10
-#else
-# define MAX_MT_SIZE 4
-#endif
-
-struct _qt_BuiltInFormatStruct
-{
- char extension[4];
- char mimeType[MAX_MT_SIZE];
-};
-
-#undef MAX_MT_SIZE
-
-static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = {
-#ifndef QT_NO_IMAGEFORMAT_PNG
- {"png", "png"},
-#endif
-#ifndef QT_NO_IMAGEFORMAT_BMP
- {"bmp", "bmp"},
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PPM
- {"ppm", "x-portable-pixmap"},
- {"pgm", "x-portable-graymap"},
- {"pbm", "x-portable-bitmap"},
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XBM
- {"xbm", "x-xbitmap"},
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XPM
- {"xpm", "x-xpixmap"},
-#endif
-};
-Q_STATIC_ASSERT(_qt_NumFormats == sizeof _qt_BuiltInFormats / sizeof *_qt_BuiltInFormats);
+using namespace QImageReaderWriterHelpers;
static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
const QByteArray &format,
@@ -251,7 +191,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
typedef QMultiMap<int, QString> PluginKeyMap;
// check if we have plugins that support the image format
- QFactoryLoader *l = loader();
+ auto l = QImageReaderWriterHelpers::pluginLoader();
const PluginKeyMap keyMap = l->keyMap();
#ifdef QIMAGEREADER_DEBUG
@@ -1565,16 +1505,6 @@ QByteArray QImageReader::imageFormat(QIODevice *device)
return format;
}
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-void supportedImageHandlerFormats(QFactoryLoader *loader,
- QImageIOPlugin::Capability cap,
- QList<QByteArray> *result);
-
-void supportedImageHandlerMimeTypes(QFactoryLoader *loader,
- QImageIOPlugin::Capability cap,
- QList<QByteArray> *result);
-#endif
-
/*!
Returns the list of image formats supported by QImageReader.
@@ -1605,18 +1535,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader,
QList<QByteArray> QImageReader::supportedImageFormats()
{
- QList<QByteArray> formats;
- formats.reserve(_qt_NumFormats);
- for (int i = 0; i < _qt_NumFormats; ++i)
- formats << _qt_BuiltInFormats[i].extension;
-
-#ifndef QT_NO_IMAGEFORMATPLUGIN
- supportedImageHandlerFormats(loader(), QImageIOPlugin::CanRead, &formats);
-#endif // QT_NO_IMAGEFORMATPLUGIN
-
- std::sort(formats.begin(), formats.end());
- formats.erase(std::unique(formats.begin(), formats.end()), formats.end());
- return formats;
+ return QImageReaderWriterHelpers::supportedImageFormats(QImageReaderWriterHelpers::CanRead);
}
/*!
@@ -1630,18 +1549,24 @@ QList<QByteArray> QImageReader::supportedImageFormats()
QList<QByteArray> QImageReader::supportedMimeTypes()
{
- QList<QByteArray> mimeTypes;
- mimeTypes.reserve(_qt_NumFormats);
- for (const auto &fmt : _qt_BuiltInFormats)
- mimeTypes.append(QByteArrayLiteral("image/") + fmt.mimeType);
+ return QImageReaderWriterHelpers::supportedMimeTypes(QImageReaderWriterHelpers::CanRead);
+}
-#ifndef QT_NO_IMAGEFORMATPLUGIN
- supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanRead, &mimeTypes);
-#endif // QT_NO_IMAGEFORMATPLUGIN
+/*!
+ \since 5.12
- std::sort(mimeTypes.begin(), mimeTypes.end());
- mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end());
- return mimeTypes;
+ Returns the list of image formats corresponding to \mimeType.
+
+ Note that the QGuiApplication instance must be created before this function is
+ called.
+
+ \sa supportedImageFormats(), supportedMimeTypes()
+*/
+
+QList<QByteArray> QImageReader::imageFormatsForMimeType(const QByteArray &mimeType)
+{
+ return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType,
+ QImageReaderWriterHelpers::CanRead);
}
QT_END_NAMESPACE
diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h
index 9d6c1e0b1e..4e9a08b6e6 100644
--- a/src/gui/image/qimagereader.h
+++ b/src/gui/image/qimagereader.h
@@ -144,6 +144,7 @@ public:
static QByteArray imageFormat(QIODevice *device);
static QList<QByteArray> supportedImageFormats();
static QList<QByteArray> supportedMimeTypes();
+ static QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType);
private:
Q_DISABLE_COPY(QImageReader)
diff --git a/src/gui/image/qimagereaderwriterhelpers.cpp b/src/gui/image/qimagereaderwriterhelpers.cpp
new file mode 100644
index 0000000000..a5b7fb6449
--- /dev/null
+++ b/src/gui/image/qimagereaderwriterhelpers.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qimagereaderwriterhelpers_p.h"
+
+#include <qjsonarray.h>
+#include <qmutex.h>
+#include <private/qfactoryloader_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QImageReaderWriterHelpers {
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
+Q_GLOBAL_STATIC(QMutex, loaderMutex)
+
+static void appendImagePluginFormats(QFactoryLoader *loader,
+ QImageIOPlugin::Capability cap,
+ QList<QByteArray> *result)
+{
+ typedef QMultiMap<int, QString> PluginKeyMap;
+ typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
+
+ const PluginKeyMap keyMap = loader->keyMap();
+ const PluginKeyMapConstIterator cend = keyMap.constEnd();
+ int i = -1;
+ QImageIOPlugin *plugin = 0;
+ result->reserve(result->size() + keyMap.size());
+ for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) {
+ if (it.key() != i) {
+ i = it.key();
+ plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i));
+ }
+ const QByteArray key = it.value().toLatin1();
+ if (plugin && (plugin->capabilities(0, key) & cap) != 0)
+ result->append(key);
+ }
+}
+
+static void appendImagePluginMimeTypes(QFactoryLoader *loader,
+ QImageIOPlugin::Capability cap,
+ QList<QByteArray> *result,
+ QList<QByteArray> *resultKeys = nullptr)
+{
+ QList<QJsonObject> metaDataList = loader->metaData();
+
+ const int pluginCount = metaDataList.size();
+ for (int i = 0; i < pluginCount; ++i) {
+ const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject();
+ const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray();
+ const QJsonArray mimeTypes = metaData.value(QLatin1String("MimeTypes")).toArray();
+ QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i));
+ const int keyCount = keys.size();
+ for (int k = 0; k < keyCount; ++k) {
+ const QByteArray key = keys.at(k).toString().toLatin1();
+ if (plugin && (plugin->capabilities(0, key) & cap) != 0) {
+ result->append(mimeTypes.at(k).toString().toLatin1());
+ if (resultKeys)
+ resultKeys->append(key);
+ }
+ }
+ }
+}
+
+QSharedPointer<QFactoryLoader> pluginLoader()
+{
+ loaderMutex()->lock();
+ return QSharedPointer<QFactoryLoader>(loader(), [](QFactoryLoader *) {
+ loaderMutex()->unlock();
+ });
+}
+
+static inline QImageIOPlugin::Capability pluginCapability(Capability cap)
+{
+ return cap == CanRead ? QImageIOPlugin::CanRead : QImageIOPlugin::CanWrite;
+}
+
+#endif // QT_NO_IMAGEFORMATPLUGIN
+
+QList<QByteArray> supportedImageFormats(Capability cap)
+{
+ QList<QByteArray> formats;
+ formats.reserve(_qt_NumFormats);
+ for (int i = 0; i < _qt_NumFormats; ++i)
+ formats << _qt_BuiltInFormats[i].extension;
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+ appendImagePluginFormats(loader(), pluginCapability(cap), &formats);
+#endif // QT_NO_IMAGEFORMATPLUGIN
+
+ std::sort(formats.begin(), formats.end());
+ formats.erase(std::unique(formats.begin(), formats.end()), formats.end());
+ return formats;
+}
+
+QList<QByteArray> supportedMimeTypes(Capability cap)
+{
+ QList<QByteArray> mimeTypes;
+ mimeTypes.reserve(_qt_NumFormats);
+ for (const auto &fmt : _qt_BuiltInFormats)
+ mimeTypes.append(QByteArrayLiteral("image/") + fmt.mimeType);
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+ appendImagePluginMimeTypes(loader(), pluginCapability(cap), &mimeTypes);
+#endif // QT_NO_IMAGEFORMATPLUGIN
+
+ std::sort(mimeTypes.begin(), mimeTypes.end());
+ mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end());
+ return mimeTypes;
+}
+
+QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType, Capability cap)
+{
+ QList<QByteArray> formats;
+ if (mimeType.startsWith("image/")) {
+ const QByteArray type = mimeType.mid(sizeof("image/") - 1);
+ for (const auto &fmt : _qt_BuiltInFormats) {
+ if (fmt.mimeType == type && !formats.contains(fmt.extension))
+ formats << fmt.extension;
+ }
+ }
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+ QList<QByteArray> mimeTypes;
+ QList<QByteArray> keys;
+ appendImagePluginMimeTypes(loader(), pluginCapability(cap), &mimeTypes, &keys);
+ for (int i = 0; i < mimeTypes.size(); ++i) {
+ if (mimeTypes.at(i) == mimeType) {
+ const auto &key = keys.at(i);
+ if (!formats.contains(key))
+ formats << key;
+ }
+ }
+#endif // QT_NO_IMAGEFORMATPLUGIN
+
+ return formats;
+}
+
+} // QImageReaderWriterHelpers
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qimagereaderwriterhelpers_p.h b/src/gui/image/qimagereaderwriterhelpers_p.h
new file mode 100644
index 0000000000..6fe418a8ab
--- /dev/null
+++ b/src/gui/image/qimagereaderwriterhelpers_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QIMAGEREADERWRITERHELPERS_P_H
+#define QIMAGEREADERWRITERHELPERS_P_H
+
+#include <QtGui/private/qtguiglobal_p.h>
+#include <qsharedpointer.h>
+#include "qimageiohandler.h"
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QFactoryLoader;
+
+namespace QImageReaderWriterHelpers {
+
+enum _qt_BuiltInFormatType {
+#ifndef QT_NO_IMAGEFORMAT_PNG
+ _qt_PngFormat,
+#endif
+#ifndef QT_NO_IMAGEFORMAT_BMP
+ _qt_BmpFormat,
+#endif
+#ifndef QT_NO_IMAGEFORMAT_PPM
+ _qt_PpmFormat,
+ _qt_PgmFormat,
+ _qt_PbmFormat,
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XBM
+ _qt_XbmFormat,
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ _qt_XpmFormat,
+#endif
+ _qt_NumFormats,
+ _qt_NoFormat = -1
+};
+
+#if !defined(QT_NO_IMAGEFORMAT_PPM)
+# define MAX_MT_SIZE 20
+#elif !defined(QT_NO_IMAGEFORMAT_XBM) || !defined(QT_NO_IMAGEFORMAT_XPM)
+# define MAX_MT_SIZE 10
+#else
+# define MAX_MT_SIZE 4
+#endif
+
+struct _qt_BuiltInFormatStruct
+{
+ char extension[4];
+ char mimeType[MAX_MT_SIZE];
+};
+
+#undef MAX_MT_SIZE
+
+static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = {
+#ifndef QT_NO_IMAGEFORMAT_PNG
+ {"png", "png"},
+#endif
+#ifndef QT_NO_IMAGEFORMAT_BMP
+ {"bmp", "bmp"},
+#endif
+#ifndef QT_NO_IMAGEFORMAT_PPM
+ {"ppm", "x-portable-pixmap"},
+ {"pgm", "x-portable-graymap"},
+ {"pbm", "x-portable-bitmap"},
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XBM
+ {"xbm", "x-xbitmap"},
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ {"xpm", "x-xpixmap"},
+#endif
+};
+Q_STATIC_ASSERT(_qt_NumFormats == sizeof _qt_BuiltInFormats / sizeof *_qt_BuiltInFormats);
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+QSharedPointer<QFactoryLoader> pluginLoader();
+#endif
+
+enum Capability {
+ CanRead,
+ CanWrite
+};
+QList<QByteArray> supportedImageFormats(Capability cap);
+QList<QByteArray> supportedMimeTypes(Capability cap);
+QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType, Capability cap);
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QIMAGEREADERWRITERHELPERS_P_H
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index a39d204677..30ec224158 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -102,7 +102,6 @@
#include <qfileinfo.h>
#include <qimage.h>
#include <qimageiohandler.h>
-#include <qjsonarray.h>
#include <qset.h>
#include <qvariant.h>
@@ -119,15 +118,12 @@
#include <private/qpnghandler_p.h>
#endif
+#include <private/qimagereaderwriterhelpers_p.h>
+
#include <algorithm>
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
-#endif
-
static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
const QByteArray &format)
{
@@ -139,7 +135,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
typedef QMultiMap<int, QString> PluginKeyMap;
// check if any plugins can write the image
- QFactoryLoader *l = loader();
+ auto l = QImageReaderWriterHelpers::pluginLoader();
const PluginKeyMap keyMap = l->keyMap();
int suffixPluginIndex = -1;
#endif
@@ -824,52 +820,6 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const
return d->handler->supportsOption(option);
}
-
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-void supportedImageHandlerFormats(QFactoryLoader *loader,
- QImageIOPlugin::Capability cap,
- QList<QByteArray> *result)
-{
- typedef QMultiMap<int, QString> PluginKeyMap;
- typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
-
- const PluginKeyMap keyMap = loader->keyMap();
- const PluginKeyMapConstIterator cend = keyMap.constEnd();
- int i = -1;
- QImageIOPlugin *plugin = 0;
- result->reserve(result->size() + keyMap.size());
- for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) {
- if (it.key() != i) {
- i = it.key();
- plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i));
- }
- const QByteArray key = it.value().toLatin1();
- if (plugin && (plugin->capabilities(0, key) & cap) != 0)
- result->append(key);
- }
-}
-
-void supportedImageHandlerMimeTypes(QFactoryLoader *loader,
- QImageIOPlugin::Capability cap,
- QList<QByteArray> *result)
-{
- QList<QJsonObject> metaDataList = loader->metaData();
-
- const int pluginCount = metaDataList.size();
- for (int i = 0; i < pluginCount; ++i) {
- const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject();
- const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray();
- const QJsonArray mimeTypes = metaData.value(QLatin1String("MimeTypes")).toArray();
- QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i));
- const int keyCount = keys.size();
- for (int k = 0; k < keyCount; ++k) {
- if (plugin && (plugin->capabilities(0, keys.at(k).toString().toLatin1()) & cap) != 0)
- result->append(mimeTypes.at(k).toString().toLatin1());
- }
- }
-}
-#endif // QT_NO_IMAGEFORMATPLUGIN
-
/*!
Returns the list of image formats supported by QImageWriter.
@@ -897,30 +847,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader,
*/
QList<QByteArray> QImageWriter::supportedImageFormats()
{
- QList<QByteArray> formats;
-#ifndef QT_NO_IMAGEFORMAT_BMP
- formats << "bmp";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PPM
- formats << "pbm" << "pgm" << "ppm";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XBM
- formats << "xbm";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XPM
- formats << "xpm";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PNG
- formats << "png";
-#endif
-
-#ifndef QT_NO_IMAGEFORMATPLUGIN
- supportedImageHandlerFormats(loader(), QImageIOPlugin::CanWrite, &formats);
-#endif // QT_NO_IMAGEFORMATPLUGIN
-
- std::sort(formats.begin(), formats.end());
- formats.erase(std::unique(formats.begin(), formats.end()), formats.end());
- return formats;
+ return QImageReaderWriterHelpers::supportedImageFormats(QImageReaderWriterHelpers::CanWrite);
}
/*!
@@ -933,32 +860,24 @@ QList<QByteArray> QImageWriter::supportedImageFormats()
*/
QList<QByteArray> QImageWriter::supportedMimeTypes()
{
- QList<QByteArray> mimeTypes;
-#ifndef QT_NO_IMAGEFORMAT_BMP
- mimeTypes << "image/bmp";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PPM
- mimeTypes << "image/x-portable-bitmap";
- mimeTypes << "image/x-portable-graymap";
- mimeTypes << "image/x-portable-pixmap";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XBM
- mimeTypes << "image/x-xbitmap";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XPM
- mimeTypes << "image/x-xpixmap";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PNG
- mimeTypes << "image/png";
-#endif
+ return QImageReaderWriterHelpers::supportedMimeTypes(QImageReaderWriterHelpers::CanWrite);
+}
-#ifndef QT_NO_IMAGEFORMATPLUGIN
- supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanWrite, &mimeTypes);
-#endif // QT_NO_IMAGEFORMATPLUGIN
+/*!
+ \since 5.12
- std::sort(mimeTypes.begin(), mimeTypes.end());
- mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end());
- return mimeTypes;
+ Returns the list of image formats corresponding to \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
diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h
index fd1fdd07e8..29c06ccdd2 100644
--- a/src/gui/image/qimagewriter.h
+++ b/src/gui/image/qimagewriter.h
@@ -116,6 +116,7 @@ public:
static QList<QByteArray> supportedImageFormats();
static QList<QByteArray> supportedMimeTypes();
+ static QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType);
private:
Q_DISABLE_COPY(QImageWriter)
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 5b3e3985a7..4cd8befc1b 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -248,9 +248,9 @@ QPixmap::QPixmap(const char * const xpm[])
QImage image(xpm);
if (!image.isNull()) {
if (data && data->pixelType() == QPlatformPixmap::BitmapType)
- *this = QBitmap::fromImage(image);
+ *this = QBitmap::fromImage(std::move(image));
else
- *this = fromImage(image);
+ *this = fromImage(std::move(image));
}
}
#endif
@@ -691,7 +691,7 @@ QBitmap QPixmap::createHeuristicMask(bool clipTight) const
QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const
{
QImage image = toImage().convertToFormat(QImage::Format_ARGB32);
- return QBitmap::fromImage(image.createMaskFromColor(maskColor.rgba(), mode));
+ return QBitmap::fromImage(std::move(image).createMaskFromColor(maskColor.rgba(), mode));
}
/*!
@@ -1018,9 +1018,9 @@ QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
if (image.isNull()) {
pixmap = QPixmap();
} else if (image.depth() == 1) {
- pixmap = QBitmap::fromImage(image);
+ pixmap = QBitmap::fromImage(std::move(image));
} else {
- pixmap = QPixmap::fromImage(image);
+ pixmap = QPixmap::fromImage(std::move(image));
}
return stream;
}
diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp
index 155a4f88b4..24d86e116d 100644
--- a/src/gui/image/qxbmhandler.cpp
+++ b/src/gui/image/qxbmhandler.cpp
@@ -241,7 +241,7 @@ static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const
}
}
}
-#if defined(_MSC_VER) && _MSC_VER >= 1400
+#ifdef Q_CC_MSVC
strcpy_s(p, sizeof(" };\n"), " };\n");
#else
strcpy(p, " };\n");
diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp
index 9c54b9ada4..17272ffe69 100644
--- a/src/gui/image/qxpmhandler.cpp
+++ b/src/gui/image/qxpmhandler.cpp
@@ -741,10 +741,6 @@ static const struct XPMRGBData {
{ QRGB(139,139, 0), "yellow4" },
{ QRGB(154,205, 50), "yellowgreen" } };
-#if defined(Q_CC_MSVC) && _MSC_VER < 1600
-inline bool operator<(const XPMRGBData &data1, const XPMRGBData &data2)
-{ return qstrcmp(data1.name, data2.name) < 0; }
-#endif
inline bool operator<(const char *name, const XPMRGBData &data)
{ return qstrcmp(name, data.name) < 0; }