summaryrefslogtreecommitdiffstats
path: root/src/gui/image
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image')
-rw-r--r--src/gui/image/qbitmap.h2
-rw-r--r--src/gui/image/qicon.cpp108
-rw-r--r--src/gui/image/qicon.h12
-rw-r--r--src/gui/image/qicon_p.h1
-rw-r--r--src/gui/image/qiconengine.cpp7
-rw-r--r--src/gui/image/qiconengine.h1
-rw-r--r--src/gui/image/qiconengineplugin.h2
-rw-r--r--src/gui/image/qiconloader.cpp11
-rw-r--r--src/gui/image/qiconloader_p.h2
-rw-r--r--src/gui/image/qimage.cpp166
-rw-r--r--src/gui/image/qimage.h37
-rw-r--r--src/gui/image/qimage_conversions.cpp38
-rw-r--r--src/gui/image/qimage_neon.cpp30
-rw-r--r--src/gui/image/qimage_p.h37
-rw-r--r--src/gui/image/qimageiohandler.h2
-rw-r--r--src/gui/image/qimagereader.cpp42
-rw-r--r--src/gui/image/qimagereader.h3
-rw-r--r--src/gui/image/qimagewriter.cpp4
-rw-r--r--src/gui/image/qjpeghandler.cpp4
-rw-r--r--src/gui/image/qmovie.h6
-rw-r--r--src/gui/image/qpaintengine_pic.cpp1
-rw-r--r--src/gui/image/qpicture.cpp7
-rw-r--r--src/gui/image/qpicture.h8
-rw-r--r--src/gui/image/qpicture_p.h5
-rw-r--r--src/gui/image/qpictureformatplugin.h2
-rw-r--r--src/gui/image/qpixmap.cpp6
-rw-r--r--src/gui/image/qpixmap.h16
-rw-r--r--src/gui/image/qpixmap_blitter.cpp2
-rw-r--r--src/gui/image/qpixmap_raster.cpp30
-rw-r--r--src/gui/image/qpixmap_win.cpp28
-rw-r--r--src/gui/image/qpixmapcache.cpp43
-rw-r--r--src/gui/image/qpixmapcache.h12
-rw-r--r--src/gui/image/qpnghandler.cpp27
-rw-r--r--src/gui/image/qpnghandler.pri7
-rw-r--r--src/gui/image/qppmhandler.cpp16
35 files changed, 508 insertions, 217 deletions
diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h
index f3ad90be20..be693af1cf 100644
--- a/src/gui/image/qbitmap.h
+++ b/src/gui/image/qbitmap.h
@@ -48,7 +48,7 @@ public:
QBitmap(const QPixmap &);
QBitmap(int w, int h);
explicit QBitmap(const QSize &);
- explicit QBitmap(const QString &fileName, const char *format=0);
+ explicit QBitmap(const QString &fileName, const char *format = Q_NULLPTR);
~QBitmap();
QBitmap &operator=(const QPixmap &);
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index 66bb77795e..d9e1347e4b 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -45,11 +46,7 @@
#include "qcache.h"
#include "qdebug.h"
#include "qpalette.h"
-
-#ifdef Q_DEAD_CODE_FROM_QT4_MAC
-#include <private/qt_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
+#include "qmath.h"
#include "private/qhexstring_p.h"
#include "private/qguiapplication_p.h"
@@ -134,7 +131,8 @@ static qreal qt_effective_device_pixel_ratio(QWindow *window = 0)
QIconPrivate::QIconPrivate()
: engine(0), ref(1),
serialNum(serialNumCounter.fetchAndAddRelaxed(1)),
- detach_no(0)
+ detach_no(0),
+ is_mask(false)
{
}
@@ -362,7 +360,7 @@ static inline int origIcoDepth(const QImage &image)
return s.isEmpty() ? 32 : s.toInt();
}
-static inline int findBySize(const QList<QImage> &images, const QSize &size)
+static inline int findBySize(const QVector<QImage> &images, const QSize &size)
{
for (int i = 0; i < images.size(); ++i) {
if (images.at(i).size() == size)
@@ -426,7 +424,7 @@ void QPixmapIconEngine::addFile(const QString &fileName, const QSize &size, QIco
// these files may contain low-resolution images. As this information is lost,
// ICOReader sets the original format as an image text key value. Read all matching
// images into a list trying to find the highest quality per size.
- QList<QImage> icoImages;
+ QVector<QImage> icoImages;
while (imageReader.read(&image)) {
if (ignoreSize || image.size() == size) {
const int position = findBySize(icoImages, image.size());
@@ -599,6 +597,8 @@ QFactoryLoader *qt_iconEngineFactoryLoader()
\image icon.png QIcon
+ \note QIcon needs a QGuiApplication instance before the icon is created.
+
\sa {fowler}{GUI Design Handbook: Iconic Label}, {Icons Example}
*/
@@ -1028,19 +1028,13 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State
} else {
detach();
}
+
d->engine->addFile(fileName, size, mode, state);
- // Check if a "@2x" file exists and add it.
- static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
- if (!disable2xImageLoading && qApp->devicePixelRatio() > 1.0) {
- QString at2xfileName = fileName;
- int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
- if (dotIndex == -1) /* no dot */
- dotIndex = fileName.size(); /* append */
- at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
- if (QFile::exists(at2xfileName))
- d->engine->addFile(at2xfileName, size, mode, state);
- }
+ // Check if a "@Nx" file exists and add it.
+ QString atNxFileName = qt_findAtNxFile(fileName, qApp->devicePixelRatio());
+ if (atNxFileName != fileName)
+ d->engine->addFile(atNxFileName, size, mode, state);
}
/*!
@@ -1185,8 +1179,6 @@ QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
qtIconCache()->insert(name, cachedIcon);
}
- // Note the qapp check is to allow lazy loading of static icons
- // Supporting fallbacks will not work for this case.
if (qApp && icon.availableSizes().isEmpty())
return fallback;
@@ -1208,6 +1200,39 @@ bool QIcon::hasThemeIcon(const QString &name)
return icon.name() == name;
}
+/*!
+ \since 5.6
+
+ Indicate that this icon is a mask image, and hence can potentially
+ be modified based on where it's displayed.
+ \sa isMask()
+*/
+void QIcon::setIsMask(bool isMask)
+{
+ if (!d) {
+ d = new QIconPrivate;
+ d->engine = new QPixmapIconEngine;
+ } else {
+ detach();
+ }
+ d->is_mask = isMask;
+}
+
+/*!
+ \since 5.6
+
+ Returns \c true if this icon has been marked as a mask image.
+ Certain platforms render mask icons differently (for example,
+ menu icons on OS X).
+
+ \sa setIsMask()
+*/
+bool QIcon::isMask() const
+{
+ if (!d)
+ return false;
+ return d->is_mask;
+}
/*****************************************************************************
QIcon stream functions
@@ -1354,5 +1379,46 @@ QDebug operator<<(QDebug dbg, const QIcon &i)
\internal
*/
+/*!
+ \internal
+ \since 5.6
+ Attempts to find a suitable @Nx file for the given \a targetDevicePixelRatio
+ Returns the the \a baseFileName if no such file was found.
+
+ Given base foo.png and a target dpr of 2.5, this function will look for
+ foo@3x.png, then foo@2x, then fall back to foo.png if not found.
+
+ \a sourceDevicePixelRatio will be set to the value of N if the argument is
+ a non-null pointer
+*/
+QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio,
+ qreal *sourceDevicePixelRatio)
+{
+ if (targetDevicePixelRatio <= 1.0)
+ return baseFileName;
+
+ static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
+ if (disableNxImageLoading)
+ return baseFileName;
+
+ int dotIndex = baseFileName.lastIndexOf(QLatin1Char('.'));
+ if (dotIndex == -1) /* no dot */
+ dotIndex = baseFileName.size(); /* append */
+
+ QString atNxfileName = baseFileName;
+ atNxfileName.insert(dotIndex, QLatin1String("@2x"));
+ // Check for @Nx, ..., @3x, @2x file versions,
+ for (int n = qMin(qCeil(targetDevicePixelRatio), 9); n > 1; --n) {
+ atNxfileName[dotIndex + 1] = QLatin1Char('0' + n);
+ if (QFile::exists(atNxfileName)) {
+ if (sourceDevicePixelRatio)
+ *sourceDevicePixelRatio = n;
+ return atNxfileName;
+ }
+ }
+
+ return baseFileName;
+}
+
QT_END_NAMESPACE
#endif //QT_NO_ICON
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 63e77eef99..9ed7336502 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -56,8 +56,8 @@ public:
QIcon(const QIcon &other);
#ifdef Q_COMPILER_RVALUE_REFS
QIcon(QIcon &&other) Q_DECL_NOEXCEPT
- : d(0)
- { qSwap(d, other.d); }
+ : d(other.d)
+ { other.d = Q_NULLPTR; }
#endif
explicit QIcon(const QString &fileName); // file or resource name
explicit QIcon(QIconEngine *engine);
@@ -65,7 +65,7 @@ public:
QIcon &operator=(const QIcon &other);
#ifdef Q_COMPILER_RVALUE_REFS
inline QIcon &operator=(QIcon &&other) Q_DECL_NOEXCEPT
- { qSwap(d, other.d); return *this; }
+ { swap(other); return *this; }
#endif
inline void swap(QIcon &other) Q_DECL_NOEXCEPT
{ qSwap(d, other.d); }
@@ -102,6 +102,9 @@ public:
QList<QSize> availableSizes(Mode mode = Normal, State state = Off) const;
+ void setIsMask(bool isMask);
+ bool isMask() const;
+
static QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon());
static bool hasThemeIcon(const QString &name);
@@ -136,6 +139,9 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &);
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QIcon &);
#endif
+Q_GUI_EXPORT QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio,
+ qreal *sourceDevicePixelRatio = Q_NULLPTR);
+
QT_END_NAMESPACE
#endif // QICON_H
diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h
index 8b42e770fa..2a4f584a0d 100644
--- a/src/gui/image/qicon_p.h
+++ b/src/gui/image/qicon_p.h
@@ -71,6 +71,7 @@ public:
QAtomicInt ref;
int serialNum;
int detach_no;
+ bool is_mask;
};
diff --git a/src/gui/image/qiconengine.cpp b/src/gui/image/qiconengine.cpp
index a25b216432..c09933d45f 100644
--- a/src/gui/image/qiconengine.cpp
+++ b/src/gui/image/qiconengine.cpp
@@ -77,6 +77,13 @@ QSize QIconEngine::actualSize(const QSize &size, QIcon::Mode /*mode*/, QIcon::St
return size;
}
+/*!
+ \since 5.6
+ Constructs the icon engine.
+ */
+QIconEngine::QIconEngine()
+{
+}
/*!
Destroys the icon engine.
diff --git a/src/gui/image/qiconengine.h b/src/gui/image/qiconengine.h
index 735da863fd..9977113054 100644
--- a/src/gui/image/qiconengine.h
+++ b/src/gui/image/qiconengine.h
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QIconEngine
{
public:
+ QIconEngine();
virtual ~QIconEngine();
virtual void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0;
virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
diff --git a/src/gui/image/qiconengineplugin.h b/src/gui/image/qiconengineplugin.h
index 66684c871d..b05969f283 100644
--- a/src/gui/image/qiconengineplugin.h
+++ b/src/gui/image/qiconengineplugin.h
@@ -48,7 +48,7 @@ class Q_GUI_EXPORT QIconEnginePlugin : public QObject
{
Q_OBJECT
public:
- QIconEnginePlugin(QObject *parent = 0);
+ QIconEnginePlugin(QObject *parent = Q_NULLPTR);
~QIconEnginePlugin();
virtual QIconEngine *create(const QString &filename = QString()) = 0;
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index fa14c84e83..3ead72dfbb 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -42,15 +42,10 @@
#include <QtGui/QIconEngine>
#include <QtGui/QPalette>
#include <QtCore/QList>
-#include <QtCore/QHash>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtGui/QPainter>
-#ifdef Q_DEAD_CODE_FROM_QT4_MAC
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
-
#include <private/qhexstring_p.h>
QT_BEGIN_NAMESPACE
@@ -73,9 +68,6 @@ QIconLoader::QIconLoader() :
{
}
-// We lazily initialize the loader to make static icons
-// work. Though we do not officially support this.
-
static inline QString systemThemeName()
{
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
@@ -398,9 +390,6 @@ void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect,
QIcon::Mode mode, QIcon::State state)
{
QSize pixmapSize = rect.size();
-#if defined(Q_DEAD_CODE_FROM_QT4_MAC)
- pixmapSize *= qt_mac_get_scalefactor();
-#endif
painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
}
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
index 5b0362e218..ccf0a9d438 100644
--- a/src/gui/image/qiconloader_p.h
+++ b/src/gui/image/qiconloader_p.h
@@ -76,7 +76,7 @@ struct QIconDirInfo
short maxSize;
short minSize;
short threshold;
- Type type : 4;
+ Type type;
};
Q_DECLARE_TYPEINFO(QIconDirInfo, Q_MOVABLE_TYPE);
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 01cacad630..667b65431e 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -491,6 +491,10 @@ bool QImageData::checkForAlphaPixels() const
\snippet code/src_gui_image_qimage.cpp 1
\endtable
+ For images with more than 8-bit per color-channel. The methods
+ setPixelColor() and pixelColor() can be used to set and get
+ with QColor values.
+
QImage also provide the scanLine() function which returns a
pointer to the pixel data at the scanline with the given index,
and the bits() function which returns a pointer to the first pixel
@@ -1785,11 +1789,11 @@ void QImage::fill(const QColor &color)
break;
case QImage::Format_BGR30:
case QImage::Format_A2BGR30_Premultiplied:
- fill(qConvertArgb32ToA2rgb30<PixelOrderBGR>(color.rgba()));
+ fill(qConvertRgb64ToRgb30<PixelOrderBGR>(color.rgba64()));
break;
case QImage::Format_RGB30:
case QImage::Format_A2RGB30_Premultiplied:
- fill(qConvertArgb32ToA2rgb30<PixelOrderRGB>(color.rgba()));
+ fill(qConvertRgb64ToRgb30<PixelOrderRGB>(color.rgba64()));
break;
case QImage::Format_RGB16:
fill((uint) qConvertRgb32To16(color.rgba()));
@@ -2206,9 +2210,10 @@ int QImage::pixelIndex(int x, int y) const
If the \a position is not valid, the results are undefined.
\warning This function is expensive when used for massive pixel
- manipulations.
+ manipulations. Use constBits() or constScanLine() when many
+ pixels needs to be read.
- \sa setPixel(), valid(), {QImage#Pixel Manipulation}{Pixel
+ \sa setPixel(), valid(), constBits(), constScanLine(), {QImage#Pixel Manipulation}{Pixel
Manipulation}
*/
@@ -2219,12 +2224,12 @@ int QImage::pixelIndex(int x, int y) const
*/
QRgb QImage::pixel(int x, int y) const
{
- if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
+ if (!d || x < 0 || x >= d->width || y < 0 || y >= d->height) {
qWarning("QImage::pixel: coordinate (%d,%d) out of range", x, y);
return 12345;
}
- const uchar * s = constScanLine(y);
+ const uchar *s = d->data + y * d->bytes_per_line;
switch(d->format) {
case Format_Mono:
return d->colortable.at((*(s + (x >> 3)) >> (~x & 7)) & 1);
@@ -2258,25 +2263,23 @@ QRgb QImage::pixel(int x, int y) const
return *layout->convertToARGB32PM(&result, ptr, 1, layout, 0);
}
-
/*!
\fn void QImage::setPixel(const QPoint &position, uint index_or_rgb)
Sets the pixel index or color at the given \a position to \a
index_or_rgb.
- If the image's format is either monochrome or 8-bit, the given \a
+ If the image's format is either monochrome or paletted, the given \a
index_or_rgb value must be an index in the image's color table,
otherwise the parameter must be a QRgb value.
If \a position is not a valid coordinate pair in the image, or if
\a index_or_rgb >= colorCount() in the case of monochrome and
- 8-bit images, the result is undefined.
+ paletted images, the result is undefined.
\warning This function is expensive due to the call of the internal
\c{detach()} function called within; if performance is a concern, we
- recommend the use of \l{QImage::}{scanLine()} to access pixel data
- directly.
+ recommend the use of scanLine() or bits() to access pixel data directly.
\sa pixel(), {QImage#Pixel Manipulation}{Pixel Manipulation}
*/
@@ -2364,6 +2367,116 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
}
/*!
+ \fn QColor QImage::pixelColor(const QPoint &position) const
+ \since 5.6
+
+ Returns the color of the pixel at the given \a position as a QColor.
+
+ If the \a position is not valid, an invalid QColor is returned.
+
+ \warning This function is expensive when used for massive pixel
+ manipulations. Use constBits() or constScanLine() when many
+ pixels needs to be read.
+
+ \sa setPixel(), valid(), constBits(), constScanLine(), {QImage#Pixel Manipulation}{Pixel
+ Manipulation}
+*/
+
+/*!
+ \overload
+ \since 5.6
+
+ Returns the color of the pixel at coordinates (\a x, \a y) as a QColor.
+*/
+QColor QImage::pixelColor(int x, int y) const
+{
+ if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
+ qWarning("QImage::pixelColor: coordinate (%d,%d) out of range", x, y);
+ return QColor();
+ }
+
+ QRgba64 c;
+ const uchar * s = constScanLine(y);
+ switch (d->format) {
+ case Format_BGR30:
+ case Format_A2BGR30_Premultiplied:
+ c = qConvertA2rgb30ToRgb64<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]);
+ break;
+ case Format_RGB30:
+ case Format_A2RGB30_Premultiplied:
+ c = qConvertA2rgb30ToRgb64<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
+ break;
+ default:
+ c = QRgba64::fromArgb32(pixel(x, y));
+ break;
+ }
+ // QColor is always unpremultiplied
+ if (hasAlphaChannel() && qPixelLayouts[d->format].premultiplied)
+ c = c.unpremultiplied();
+ return QColor(c);
+}
+
+/*!
+ \fn void QImage::setPixelColor(const QPoint &position, const QColor &color)
+ \since 5.6
+
+ Sets the color at the given \a position to \a color.
+
+ If \a position is not a valid coordinate pair in the image, or
+ the image's format is either monochrome or paletted, the result is undefined.
+
+ \warning This function is expensive due to the call of the internal
+ \c{detach()} function called within; if performance is a concern, we
+ recommend the use of scanLine() or bits() to access pixel data directly.
+
+ \sa pixel(), bits(), scanLine(), {QImage#Pixel Manipulation}{Pixel Manipulation}
+*/
+
+/*!
+ \overload
+ \since 5.6
+
+ Sets the pixel color at (\a x, \a y) to \a color.
+*/
+void QImage::setPixelColor(int x, int y, const QColor &color)
+{
+ if (!d || x < 0 || x >= width() || y < 0 || y >= height() || !color.isValid()) {
+ qWarning("QImage::setPixelColor: coordinate (%d,%d) out of range", x, y);
+ return;
+ }
+ // QColor is always unpremultiplied
+ QRgba64 c = color.rgba64();
+ if (!hasAlphaChannel())
+ c.setAlpha(65535);
+ else if (qPixelLayouts[d->format].premultiplied)
+ c = c.premultiplied();
+ // detach is called from within scanLine
+ uchar * s = scanLine(y);
+ switch (d->format) {
+ case Format_Mono:
+ case Format_MonoLSB:
+ case Format_Indexed8:
+ qWarning("QImage::setPixelColor: called on monochrome or indexed format");
+ return;
+ case Format_BGR30:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c) | 0xc0000000;
+ return;
+ case Format_A2BGR30_Premultiplied:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c);
+ return;
+ case Format_RGB30:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c) | 0xc0000000;
+ return;
+ case Format_A2RGB30_Premultiplied:
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c);
+ return;
+ default:
+ setPixel(x, y, c.toArgb32());
+ return;
+ }
+}
+
+/*!
Returns \c true if all the colors in the image are shades of gray
(i.e. their red, green and blue components are equal); otherwise
false.
@@ -3808,6 +3921,10 @@ int QImage::metric(PaintDeviceMetric metric) const
return d->devicePixelRatio;
break;
+ case PdmDevicePixelRatioScaled:
+ return d->devicePixelRatio * QPaintDevice::devicePixelRatioFScale();
+ break;
+
default:
qWarning("QImage::metric(): Unhandled metric type %d", metric);
break;
@@ -4521,32 +4638,7 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
if (complex_xform || mode == Qt::SmoothTransformation) {
if (d->format < QImage::Format_RGB32 || !hasAlphaChannel()) {
- switch(d->format) {
- case QImage::Format_RGB16:
- target_format = Format_ARGB8565_Premultiplied;
- break;
- case QImage::Format_RGB555:
- target_format = Format_ARGB8555_Premultiplied;
- break;
- case QImage::Format_RGB666:
- target_format = Format_ARGB6666_Premultiplied;
- break;
- case QImage::Format_RGB444:
- target_format = Format_ARGB4444_Premultiplied;
- break;
- case QImage::Format_RGBX8888:
- target_format = Format_RGBA8888_Premultiplied;
- break;
- case QImage::Format_BGR30:
- target_format = Format_A2BGR30_Premultiplied;
- break;
- case QImage::Format_RGB30:
- target_format = Format_A2RGB30_Premultiplied;
- break;
- default:
- target_format = Format_ARGB32_Premultiplied;
- break;
- }
+ target_format = qt_alphaVersion(d->format);
}
}
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 26057f366c..888c7beb32 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -34,10 +34,11 @@
#ifndef QIMAGE_H
#define QIMAGE_H
-#include <QtGui/qtransform.h>
-#include <QtGui/qpaintdevice.h>
+#include <QtGui/qcolor.h>
#include <QtGui/qrgb.h>
+#include <QtGui/qpaintdevice.h>
#include <QtGui/qpixelformat.h>
+#include <QtGui/qtransform.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qrect.h>
#include <QtCore/qstring.h>
@@ -124,15 +125,15 @@ public:
QImage() Q_DECL_NOEXCEPT;
QImage(const QSize &size, Format format);
QImage(int width, int height, Format format);
- QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0);
- QImage(const uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0);
- QImage(uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0);
- QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0);
+ QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR);
+ QImage(const uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR);
+ QImage(uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR);
+ QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR);
#ifndef QT_NO_IMAGEFORMAT_XPM
explicit QImage(const char * const xpm[]);
#endif
- explicit QImage(const QString &fileName, const char *format = 0);
+ explicit QImage(const QString &fileName, const char *format = Q_NULLPTR);
QImage(const QImage &);
#ifdef Q_COMPILER_RVALUE_REFS
@@ -220,6 +221,12 @@ public:
void setPixel(int x, int y, uint index_or_rgb);
void setPixel(const QPoint &pt, uint index_or_rgb);
+ QColor pixelColor(int x, int y) const;
+ QColor pixelColor(const QPoint &pt) const;
+
+ void setPixelColor(int x, int y, const QColor &c);
+ void setPixelColor(const QPoint &pt, const QColor &c);
+
QVector<QRgb> colorTable() const;
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
void setColorTable(const QVector<QRgb> &colors);
@@ -272,16 +279,16 @@ public:
bool load(QIODevice *device, const char* format);
- bool load(const QString &fileName, const char* format=0);
- bool loadFromData(const uchar *buf, int len, const char *format = 0);
- inline bool loadFromData(const QByteArray &data, const char* aformat=0)
+ bool load(const QString &fileName, const char *format = Q_NULLPTR);
+ bool loadFromData(const uchar *buf, int len, const char *format = Q_NULLPTR);
+ inline bool loadFromData(const QByteArray &data, const char *aformat = Q_NULLPTR)
{ return loadFromData(reinterpret_cast<const uchar *>(data.constData()), data.size(), aformat); }
- bool save(const QString &fileName, const char* format=0, int quality=-1) const;
- bool save(QIODevice *device, const char* format=0, int quality=-1) const;
+ bool save(const QString &fileName, const char *format = Q_NULLPTR, int quality = -1) const;
+ bool save(QIODevice *device, const char *format = Q_NULLPTR, int quality = -1) const;
- static QImage fromData(const uchar *data, int size, const char *format = 0);
- inline static QImage fromData(const QByteArray &data, const char *format = 0)
+ static QImage fromData(const uchar *data, int size, const char *format = Q_NULLPTR);
+ inline static QImage fromData(const QByteArray &data, const char *format = Q_NULLPTR)
{ return fromData(reinterpret_cast<const uchar *>(data.constData()), data.size(), format); }
#if QT_DEPRECATED_SINCE(5, 0)
@@ -352,6 +359,8 @@ inline bool QImage::valid(const QPoint &pt) const { return valid(pt.x(), pt.y())
inline int QImage::pixelIndex(const QPoint &pt) const { return pixelIndex(pt.x(), pt.y());}
inline QRgb QImage::pixel(const QPoint &pt) const { return pixel(pt.x(), pt.y()); }
inline void QImage::setPixel(const QPoint &pt, uint index_or_rgb) { setPixel(pt.x(), pt.y(), index_or_rgb); }
+inline QColor QImage::pixelColor(const QPoint &pt) const { return pixelColor(pt.x(), pt.y()); }
+inline void QImage::setPixelColor(const QPoint &pt, const QColor &c) { setPixelColor(pt.x(), pt.y(), c); }
#if QT_DEPRECATED_SINCE(5, 0)
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 02f32aa34b..cc79e73534 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -375,7 +375,32 @@ static void convert_RGB888_to_RGB(QImageData *dest, const QImageData *src, Qt::I
}
}
+#ifdef __SSE2__
extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
+#else
+static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data,Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = qPremultiply(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+
+ if (data->format == QImage::Format_ARGB32)
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ else
+ data->format = QImage::Format_RGBA8888_Premultiplied;
+ return true;
+}
+#endif
static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
@@ -2592,7 +2617,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
#ifdef __SSE2__
convert_ARGB_to_ARGB_PM_inplace_sse2,
#else
- 0,
+ convert_ARGB_to_ARGB_PM_inplace,
#endif
0,
0,
@@ -2705,12 +2730,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
mask_alpha_converter_rgbx_inplace,
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && __SSE2__
0,
+#ifdef __SSE2__
convert_ARGB_to_ARGB_PM_inplace_sse2,
+#elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ convert_ARGB_to_ARGB_PM_inplace,
#else
0,
- 0,
#endif
0, 0, 0, 0, 0, 0
}, // Format_RGBA8888
@@ -2894,7 +2920,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
} // Format_Grayscale8
};
-void qInitImageConversions()
+static void qInitImageConversions()
{
#if defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSSE3)
if (qCpuHasFeature(SSSE3)) {
@@ -2921,7 +2947,7 @@ void qInitImageConversions()
}
#endif
-#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#if defined(__ARM_NEON__)
extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
@@ -2941,4 +2967,6 @@ void qInitImageConversions()
#endif
}
+Q_CONSTRUCTOR_FUNCTION(qInitImageConversions);
+
QT_END_NAMESPACE
diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp
index b51c43aa9d..5853510ee1 100644
--- a/src/gui/image/qimage_neon.cpp
+++ b/src/gui/image/qimage_neon.cpp
@@ -35,7 +35,7 @@
#include <private/qimage_p.h>
#include <private/qsimd_p.h>
-#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#if defined(__ARM_NEON__)
QT_BEGIN_NAMESPACE
@@ -55,6 +55,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
if ((len - offsetToAlignOn8Bytes) >= 8) {
const quint32 *const simdEnd = end - 7;
+#if !defined(Q_PROCESSOR_ARM_64)
register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff);
do {
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
@@ -76,6 +77,31 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
);
#endif
} while (dst < simdEnd);
+#else
+ register uint8x8_t fullVector asm ("v3") = vdup_n_u8(0xff);
+ do {
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ asm volatile (
+ "ld3 { v4.8b, v5.8b, v6.8b }, [%[SRC]], #24 \n\t"
+ "st4 { v3.8b, v4.8b, v5.8b, v6.8b }, [%[DST]], #32 \n\t"
+ : [DST]"+r" (dst), [SRC]"+r" (src)
+ : "w"(fullVector)
+ : "memory", "v4", "v5", "v6"
+ );
+#else
+ asm volatile (
+ "ld3 { v0.8b, v1.8b, v2.8b }, [%[SRC]], #24 \n\t"
+ "mov v4.8b, v2.8b\n\t"
+ "mov v2.8b, v0.8b\n\t"
+ "mov v0.8b, v4.8b\n\t"
+ "st4 { v0.8b, v1.8b, v2.8b, v3.8b }, [%[DST]], #32 \n\t"
+ : [DST]"+r" (dst), [SRC]"+r" (src)
+ : "w"(fullVector)
+ : "memory", "v0", "v1", "v2", "v4"
+ );
+#endif
+ } while (dst < simdEnd);
+#endif
}
while (dst != end) {
@@ -103,4 +129,4 @@ void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::I
QT_END_NAMESPACE
-#endif // defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#endif // defined(__ARM_NEON__)
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index feeab60abd..f9ad6c0ac0 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -111,8 +111,6 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
void dither_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags, bool fromalpha);
-void qInitImageConversions();
-
const uchar *qt_get_bitflip_array();
Q_GUI_EXPORT void qGamma_correct_back_to_linear_cs(QImage *image);
@@ -163,10 +161,45 @@ inline int qt_depthForFormat(QImage::Format format)
}
return depth;
}
+
#if defined(_M_ARM)
#pragma optimize("", on)
#endif
+inline QImage::Format qt_alphaVersion(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_RGB16:
+ return QImage::Format_ARGB8565_Premultiplied;
+ case QImage::Format_RGB555:
+ return QImage::Format_ARGB8555_Premultiplied;
+ case QImage::Format_RGB666:
+ return QImage::Format_ARGB6666_Premultiplied;
+ case QImage::Format_RGB444:
+ return QImage::Format_ARGB4444_Premultiplied;
+ case QImage::Format_RGBX8888:
+ return QImage::Format_RGBA8888_Premultiplied;
+ case QImage::Format_BGR30:
+ return QImage::Format_A2BGR30_Premultiplied;
+ case QImage::Format_RGB30:
+ return QImage::Format_A2RGB30_Premultiplied;
+ default:
+ break;
+ }
+ return QImage::Format_ARGB32_Premultiplied;
+}
+
+inline QImage::Format qt_alphaVersionForPainting(QImage::Format format)
+{
+ QImage::Format toFormat = qt_alphaVersion(format);
+#if defined(__ARM_NEON__) || defined(__SSE2__)
+ // If we are switching depth anyway and we have optimized ARGB32PM routines, upgrade to that.
+ if (qt_depthForFormat(format) != qt_depthForFormat(toFormat))
+ toFormat = QImage::Format_ARGB32_Premultiplied;
+#endif
+ return toFormat;
+}
+
QT_END_NAMESPACE
#endif // QIMAGE_P_H
diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h
index 80cd87c4c3..47a8a2b7c6 100644
--- a/src/gui/image/qimageiohandler.h
+++ b/src/gui/image/qimageiohandler.h
@@ -133,7 +133,7 @@ class Q_GUI_EXPORT QImageIOPlugin : public QObject
{
Q_OBJECT
public:
- explicit QImageIOPlugin(QObject *parent = 0);
+ explicit QImageIOPlugin(QObject *parent = Q_NULLPTR);
virtual ~QImageIOPlugin();
enum Capability {
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index a35442308f..0ef587f333 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -252,7 +252,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
#ifdef QIMAGEREADER_DEBUG
qDebug() << "QImageReader::createReadHandler( device =" << (void *)device << ", format =" << format << "),"
- << keyMap.values().size() << "plugins available: " << keyMap.values();
+ << keyMap.size() << "plugins available: " << keyMap.values();
#endif
int suffixPluginIndex = -1;
@@ -312,7 +312,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
const qint64 pos = device ? device->pos() : 0;
if (autoDetectImageFormat) {
- const int keyCount = keyMap.keys().size();
+ const int keyCount = keyMap.size();
for (int i = 0; i < keyCount; ++i) {
if (i != suffixPluginIndex) {
QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i));
@@ -392,7 +392,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
// check if any of our plugins recognize the file from its contents.
const qint64 pos = device ? device->pos() : 0;
- const int keyCount = keyMap.keys().size();
+ const int keyCount = keyMap.size();
for (int i = 0; i < keyCount; ++i) {
if (i != suffixPluginIndex) {
QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(i));
@@ -1168,7 +1168,8 @@ QImageIOHandler::Transformations QImageReader::transformation() const
/*!
\since 5.5
- Sets if images returned by read() should have transformation metadata automatically applied.
+ Determines that images returned by read() should have transformation metadata automatically
+ applied if \a enabled is \c true.
\sa autoTransform(), transformation(), read()
*/
@@ -1203,6 +1204,39 @@ bool QImageReader::autoTransform() const
}
/*!
+ \since 5.6
+
+ This is an image format specific function that forces images with
+ gamma information to be gamma corrected to \a gamma. For image formats
+ that do not support gamma correction, this value is ignored.
+
+ To gamma correct to a standard PC color-space, set gamma to \c 1/2.2.
+
+ \sa gamma()
+*/
+void QImageReader::setGamma(float gamma)
+{
+ if (d->initHandler() && d->handler->supportsOption(QImageIOHandler::Gamma))
+ d->handler->setOption(QImageIOHandler::Gamma, gamma);
+}
+
+/*!
+ \since 5.6
+
+ Returns the gamma level of the decoded image. If setGamma() has been
+ called and gamma correction is supported it will return the gamma set.
+ If gamma level is not supported by the image format, \c 0.0 is returned.
+
+ \sa setGamma()
+*/
+float QImageReader::gamma() const
+{
+ if (d->initHandler() && d->handler->supportsOption(QImageIOHandler::Gamma))
+ return d->handler->option(QImageIOHandler::Gamma).toFloat();
+ return 0.0;
+}
+
+/*!
Returns \c true if an image can be read for the device (i.e., the
image format is supported, and the device seems to contain valid
data); otherwise returns \c false.
diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h
index 27a29bed49..6745c55b97 100644
--- a/src/gui/image/qimagereader.h
+++ b/src/gui/image/qimagereader.h
@@ -110,6 +110,9 @@ public:
void setAutoTransform(bool enabled);
bool autoTransform() const;
+ void setGamma(float gamma);
+ float gamma() const;
+
QByteArray subType() const;
QList<QByteArray> supportedSubTypes() const;
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index e9de1db4b2..1cf75d8688 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -212,7 +212,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
#ifndef QT_NO_IMAGEFORMATPLUGIN
if (!testFormat.isEmpty()) {
- const int keyCount = keyMap.keys().size();
+ 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)) {
@@ -621,7 +621,7 @@ bool QImageWriter::progressiveScanWrite() const
/*!
\since 5.5
- Sets the image transformations metadata including orientation.
+ 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.
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index e29f9783a6..68709b708d 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -68,6 +68,7 @@ extern "C" {
}
QT_BEGIN_NAMESPACE
+QT_WARNING_DISABLE_GCC("-Wclobbered")
Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dst, const uchar *src, int len);
typedef void (QT_FASTCALL *Rgb888ToRgb32Converter)(quint32 *dst, const uchar *src, int len);
@@ -977,9 +978,8 @@ extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(quint32 *dst, const uc
QJpegHandler::QJpegHandler()
: d(new QJpegHandlerPrivate(this))
{
-#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
+#if defined(__ARM_NEON__)
// from qimage_neon.cpp
-
if (qCpuHasFeature(NEON))
d->rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon;
#endif
diff --git a/src/gui/image/qmovie.h b/src/gui/image/qmovie.h
index 13bc381f8e..a750e4a9fc 100644
--- a/src/gui/image/qmovie.h
+++ b/src/gui/image/qmovie.h
@@ -73,9 +73,9 @@ public:
};
Q_ENUM(CacheMode)
- explicit QMovie(QObject *parent = 0);
- explicit QMovie(QIODevice *device, const QByteArray &format = QByteArray(), QObject *parent = 0);
- explicit QMovie(const QString &fileName, const QByteArray &format = QByteArray(), QObject *parent = 0);
+ explicit QMovie(QObject *parent = Q_NULLPTR);
+ explicit QMovie(QIODevice *device, const QByteArray &format = QByteArray(), QObject *parent = Q_NULLPTR);
+ explicit QMovie(const QString &fileName, const QByteArray &format = QByteArray(), QObject *parent = Q_NULLPTR);
~QMovie();
static QList<QByteArray> supportedFormats();
diff --git a/src/gui/image/qpaintengine_pic.cpp b/src/gui/image/qpaintengine_pic.cpp
index 9ab1e2c30b..47480ebbae 100644
--- a/src/gui/image/qpaintengine_pic.cpp
+++ b/src/gui/image/qpaintengine_pic.cpp
@@ -398,6 +398,7 @@ void QPicturePaintEngine::drawPolygon(const QPointF *points, int numPoints, Poly
int pos;
QPolygonF polygon;
+ polygon.reserve(numPoints);
for (int i=0; i<numPoints; ++i)
polygon << points[i];
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index b63be19153..2b184466f4 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -961,6 +961,9 @@ int QPicture::metric(PaintDeviceMetric m) const
case PdmDevicePixelRatio:
val = 1;
break;
+ case PdmDevicePixelRatioScaled:
+ val = 1 * QPaintDevice::devicePixelRatioFScale();
+ break;
default:
val = 0;
qWarning("QPicture::metric: Invalid metric command");
@@ -1216,7 +1219,9 @@ QList<QByteArray> QPicture::inputFormats()
static QStringList qToStringList(const QList<QByteArray> &arr)
{
QStringList list;
- for (int i = 0; i < arr.count(); ++i)
+ const int count = arr.count();
+ list.reserve(count);
+ for (int i = 0; i < count; ++i)
list.append(QString::fromLatin1(arr.at(i)));
return list;
}
diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h
index c3897a1935..a71d1deb02 100644
--- a/src/gui/image/qpicture.h
+++ b/src/gui/image/qpicture.h
@@ -62,10 +62,10 @@ public:
bool play(QPainter *p);
- bool load(QIODevice *dev, const char *format = 0);
- bool load(const QString &fileName, const char *format = 0);
- bool save(QIODevice *dev, const char *format = 0);
- bool save(const QString &fileName, const char *format = 0);
+ bool load(QIODevice *dev, const char *format = Q_NULLPTR);
+ bool load(const QString &fileName, const char *format = Q_NULLPTR);
+ bool save(QIODevice *dev, const char *format = Q_NULLPTR);
+ bool save(const QString &fileName, const char *format = Q_NULLPTR);
QRect boundingRect() const;
void setBoundingRect(const QRect &r);
diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h
index 56e6e1249c..a414a122f1 100644
--- a/src/gui/image/qpicture_p.h
+++ b/src/gui/image/qpicture_p.h
@@ -48,6 +48,7 @@
#include "QtCore/qatomic.h"
#include "QtCore/qbuffer.h"
#include "QtCore/qobjectdefs.h"
+#include "QtCore/qvector.h"
#include "QtGui/qpicture.h"
#include "QtGui/qpixmap.h"
#include "QtGui/qpen.h"
@@ -150,8 +151,8 @@ public:
QRect override_rect;
QScopedPointer<QPaintEngine> paintEngine;
bool in_memory_only;
- QList<QImage> image_list;
- QList<QPixmap> pixmap_list;
+ QVector<QImage> image_list;
+ QVector<QPixmap> pixmap_list;
QList<QBrush> brush_list;
QList<QPen> pen_list;
};
diff --git a/src/gui/image/qpictureformatplugin.h b/src/gui/image/qpictureformatplugin.h
index 773c0180d3..9ad938fa79 100644
--- a/src/gui/image/qpictureformatplugin.h
+++ b/src/gui/image/qpictureformatplugin.h
@@ -53,7 +53,7 @@ class Q_GUI_EXPORT QPictureFormatPlugin : public QObject
{
Q_OBJECT
public:
- explicit QPictureFormatPlugin(QObject *parent = 0);
+ explicit QPictureFormatPlugin(QObject *parent = Q_NULLPTR);
~QPictureFormatPlugin();
virtual bool loadPicture(const QString &format, const QString &filename, QPicture *pic);
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index e53af8038f..fb62889e40 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -907,7 +907,7 @@ void QPixmap::fill(const QPaintDevice *device, const QPoint &p)
{
Q_UNUSED(device)
Q_UNUSED(p)
- qWarning("%s is deprecated, ignored", Q_FUNC_INFO);
+ qWarning("this function is deprecated, ignored");
}
@@ -1703,8 +1703,8 @@ QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionF
QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
{
- qWarning("%s is deprecated, use QScreen::grabWindow() instead."
- " Defaulting to primary screen.", Q_FUNC_INFO);
+ qWarning("this function is deprecated, use QScreen::grabWindow() instead."
+ " Defaulting to primary screen.");
return QGuiApplication::primaryScreen()->grabWindow(window, x, y, w, h);
}
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index 51b02acfcf..48db7a3840 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -58,7 +58,7 @@ public:
explicit QPixmap(QPlatformPixmap *data);
QPixmap(int w, int h);
explicit QPixmap(const QSize &);
- QPixmap(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ QPixmap(const QString& fileName, const char *format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor);
#ifndef QT_NO_IMAGEFORMAT_XPM
explicit QPixmap(const char * const xpm[]);
#endif
@@ -131,19 +131,19 @@ public:
}
#endif
- bool load(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
- bool loadFromData(const uchar *buf, uint len, const char* format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
- inline bool loadFromData(const QByteArray &data, const char* format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
- bool save(const QString& fileName, const char* format = 0, int quality = -1) const;
- bool save(QIODevice* device, const char* format = 0, int quality = -1) const;
+ bool load(const QString& fileName, const char *format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ bool loadFromData(const uchar *buf, uint len, const char* format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ inline bool loadFromData(const QByteArray &data, const char* format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ bool save(const QString& fileName, const char* format = Q_NULLPTR, int quality = -1) const;
+ bool save(QIODevice* device, const char* format = Q_NULLPTR, int quality = -1) const;
bool convertFromImage(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor);
inline QPixmap copy(int x, int y, int width, int height) const;
QPixmap copy(const QRect &rect = QRect()) const;
- inline void scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed = 0);
- void scroll(int dx, int dy, const QRect &rect, QRegion *exposed = 0);
+ inline void scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed = Q_NULLPTR);
+ void scroll(int dx, int dy, const QRect &rect, QRegion *exposed = Q_NULLPTR);
#if QT_DEPRECATED_SINCE(5, 0)
QT_DEPRECATED inline int serialNumber() const { return cacheKey() >> 32; }
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index f24cbc3db9..b254c5a2af 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -115,6 +115,8 @@ int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) con
return qt_defaultDpiY();
case QPaintDevice::PdmDevicePixelRatio:
return devicePixelRatio();
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return devicePixelRatio() * QPaintDevice::devicePixelRatioFScale();
default:
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 9c8835a7a0..bbdf77355e 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -178,20 +178,7 @@ void QRasterPlatformPixmap::fill(const QColor &color)
int alpha = color.alpha();
if (alpha != 255) {
if (!image.hasAlphaChannel()) {
- QImage::Format toFormat;
-#if !(defined(__ARM_NEON__) || defined(__SSE2__))
- if (image.format() == QImage::Format_RGB16)
- toFormat = QImage::Format_ARGB8565_Premultiplied;
- else if (image.format() == QImage::Format_RGB666)
- toFormat = QImage::Format_ARGB6666_Premultiplied;
- else if (image.format() == QImage::Format_RGB555)
- toFormat = QImage::Format_ARGB8555_Premultiplied;
- else if (image.format() == QImage::Format_RGB444)
- toFormat = QImage::Format_ARGB4444_Premultiplied;
- else
-#endif
- toFormat = QImage::Format_ARGB32_Premultiplied;
-
+ QImage::Format toFormat = qt_alphaVersionForPainting(image.format());
if (!image.isNull() && qt_depthForFormat(image.format()) == qt_depthForFormat(toFormat)) {
image.detach();
image.d->format = toFormat;
@@ -288,6 +275,9 @@ int QRasterPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
return qt_defaultDpiY();
case QPaintDevice::PdmDevicePixelRatio:
return image.devicePixelRatio();
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return image.devicePixelRatio() * QPaintDevice::devicePixelRatioFScale();
+
default:
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
@@ -311,17 +301,7 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC
: QImage::Format_RGB32;
} else {
QImage::Format opaqueFormat = QNativeImage::systemFormat();
- QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
-
-#if !defined(__ARM_NEON__) && !defined(__SSE2__)
- switch (opaqueFormat) {
- case QImage::Format_RGB16:
- alphaFormat = QImage::Format_ARGB8565_Premultiplied;
- break;
- default: // We don't care about the others...
- break;
- }
-#endif
+ QImage::Format alphaFormat = qt_alphaVersionForPainting(opaqueFormat);
if (!sourceImage.hasAlphaChannel()) {
format = opaqueFormat;
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index 12e19440dc..a7a9b375ff 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -345,9 +345,22 @@ static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
return image;
}
+static inline bool hasAlpha(const QImage &image)
+{
+ const int w = image.width();
+ const int h = image.height();
+ for (int y = 0; y < h; ++y) {
+ const QRgb *scanLine = reinterpret_cast<const QRgb *>(image.scanLine(y));
+ for (int x = 0; x < w; ++x) {
+ if (qAlpha(scanLine[x]) != 0)
+ return true;
+ }
+ }
+ return false;
+}
+
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
{
- bool foundAlpha = false;
HDC screenDevice = GetDC(0);
HDC hdc = CreateCompatibleDC(screenDevice);
ReleaseDC(0, screenDevice);
@@ -356,6 +369,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
if (!result) {
qErrnoWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
+ DeleteDC(hdc);
return QPixmap();
}
@@ -371,17 +385,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
- for (int y = 0 ; y < h && !foundAlpha ; y++) {
- const QRgb *scanLine= reinterpret_cast<const QRgb *>(image.scanLine(y));
- for (int x = 0; x < w ; x++) {
- if (qAlpha(scanLine[x]) != 0) {
- foundAlpha = true;
- break;
- }
- }
- }
- if (!foundAlpha) {
- //If no alpha was found, we use the mask to set alpha values
+ if (!image.isNull() && !hasAlpha(image)) { //If no alpha was found, we use the mask to set alpha values
DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 3836976975..d29ddcf978 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
memory.
The \e{Qt Quarterly} article
- \l{http://doc.qt.digia.com/qq/qq12-qpixmapcache.html}{Optimizing
+ \l{http://doc.qt.io/archives/qq/qq12-qpixmapcache.html}{Optimizing
with QPixmapCache} explains how to use QPixmapCache to speed up
applications by caching the results of painting.
@@ -138,6 +138,24 @@ bool QPixmapCache::Key::operator ==(const Key &key) const
*/
/*!
+ \fn QPixmapCache::Key::Key(Key &&)
+ \internal
+ \since 5.6
+*/
+
+/*!
+ \fn QPixmapCache::Key &QPixmapCache::Key::operator=(Key &&)
+ \internal
+ \since 5.6
+*/
+
+/*!
+ \fn void QPixmapCache::Key::swap(Key &)
+ \internal
+ \since 5.6
+*/
+
+/*!
\internal
*/
QPixmapCache::Key &QPixmapCache::Key::operator =(const Key &other)
@@ -179,7 +197,6 @@ public:
static QPixmapCache::KeyData* getKeyData(QPixmapCache::Key *key);
- QList< QPair<QString,QPixmap> > allPixmaps() const;
bool flushDetachedPixmaps(bool nt);
private:
@@ -423,20 +440,6 @@ QPixmapCache::KeyData* QPMCache::getKeyData(QPixmapCache::Key *key)
return key->d;
}
-QList< QPair<QString,QPixmap> > QPMCache::allPixmaps() const
-{
- QList< QPair<QString,QPixmap> > r;
- QHash<QString, QPixmapCache::Key>::const_iterator it = cacheKeys.begin();
- while (it != cacheKeys.end()) {
- QPixmap *ptr = QCache<QPixmapCache::Key, QPixmapCacheEntry>::object(it.value());
- if (ptr)
- r.append(QPair<QString,QPixmap>(it.key(),*ptr));
- ++it;
- }
- return r;
-}
-
-
Q_GLOBAL_STATIC(QPMCache, pm_cache)
int Q_AUTOTEST_EXPORT q_QPixmapCache_keyHashSize()
@@ -639,7 +642,8 @@ void QPixmapCache::remove(const Key &key)
void QPixmapCache::clear()
{
QT_TRY {
- pm_cache()->clear();
+ if (pm_cache.exists())
+ pm_cache->clear();
} QT_CATCH(const std::bad_alloc &) {
// if we ran out of memory during pm_cache(), it's no leak,
// so just ignore it.
@@ -656,10 +660,6 @@ int QPixmapCache::totalUsed()
return (pm_cache()->totalCost()+1023) / 1024;
}
-QList< QPair<QString,QPixmap> > QPixmapCache::allPixmaps()
-{
- return pm_cache()->allPixmaps();
-}
/*!
\fn QPixmapCache::KeyData::KeyData()
@@ -667,7 +667,6 @@ QList< QPair<QString,QPixmap> > QPixmapCache::allPixmaps()
*/
/*!
\fn QPixmapCache::KeyData::KeyData(const KeyData &other)
-
\internal
*/
/*!
diff --git a/src/gui/image/qpixmapcache.h b/src/gui/image/qpixmapcache.h
index 345389e987..37a0588e06 100644
--- a/src/gui/image/qpixmapcache.h
+++ b/src/gui/image/qpixmapcache.h
@@ -36,10 +36,6 @@
#include <QtGui/qpixmap.h>
-#ifdef Q_TEST_QPIXMAPCACHE
-#include <QtCore/qpair.h>
-#endif
-
QT_BEGIN_NAMESPACE
@@ -52,12 +48,18 @@ public:
public:
Key();
Key(const Key &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ Key(Key &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Q_NULLPTR; }
+ Key &operator =(Key &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
~Key();
bool operator ==(const Key &key) const;
inline bool operator !=(const Key &key) const
{ return !operator==(key); }
Key &operator =(const Key &other);
+ void swap(Key &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
private:
KeyData *d;
friend class QPMCache;
@@ -80,9 +82,9 @@ public:
#ifdef Q_TEST_QPIXMAPCACHE
static void flushDetachedPixmaps();
static int totalUsed();
- static QList< QPair<QString,QPixmap> > allPixmaps();
#endif
};
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QPixmapCache::Key)
QT_END_NAMESPACE
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 7fbd24787e..e9944e1750 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -43,13 +43,8 @@
#include <qvariant.h>
#include <qvector.h>
-#ifdef QT_USE_BUNDLED_LIBPNG
-#include <../../3rdparty/libpng/png.h>
-#include <../../3rdparty/libpng/pngconf.h>
-#else
#include <png.h>
#include <pngconf.h>
-#endif
#if PNG_LIBPNG_VER >= 10400 && PNG_LIBPNG_VER <= 10502 \
&& defined(PNG_PEDANTIC_WARNINGS_SUPPORTED)
@@ -108,10 +103,11 @@ public:
};
QPngHandlerPrivate(QPngHandler *qq)
- : gamma(0.0), quality(2), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq)
+ : gamma(0.0), fileGamma(0.0), quality(2), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq)
{ }
float gamma;
+ float fileGamma;
int quality;
QString description;
QSize scaledSize;
@@ -234,13 +230,10 @@ void CALLBACK_CALL_TYPE qpiw_flush_fn(png_structp /* png_ptr */)
}
static
-void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0)
+void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0, float file_gamma=0.0)
{
- if (screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
- double file_gamma;
- png_get_gAMA(png_ptr, info_ptr, &file_gamma);
- png_set_gamma(png_ptr, screen_gamma, file_gamma);
- }
+ if (screen_gamma != 0.0 && file_gamma != 0.0)
+ png_set_gamma(png_ptr, 1.0f / screen_gamma, file_gamma);
png_uint_32 width;
png_uint_32 height;
@@ -557,6 +550,12 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngHeader()
readPngTexts(info_ptr);
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
+ double file_gamma = 0.0;
+ png_get_gAMA(png_ptr, info_ptr, &file_gamma);
+ fileGamma = file_gamma;
+ }
+
state = ReadHeader;
return true;
}
@@ -580,7 +579,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage)
}
bool doScaledRead = false;
- setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead, gamma);
+ setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead, gamma, fileGamma);
if (outImage->isNull()) {
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
@@ -1063,7 +1062,7 @@ QVariant QPngHandler::option(ImageOption option) const
return QVariant();
if (option == Gamma)
- return d->gamma;
+ return d->gamma == 0.0 ? d->fileGamma : d->gamma;
else if (option == Quality)
return d->quality;
else if (option == Description)
diff --git a/src/gui/image/qpnghandler.pri b/src/gui/image/qpnghandler.pri
index 9ab175d628..505d214130 100644
--- a/src/gui/image/qpnghandler.pri
+++ b/src/gui/image/qpnghandler.pri
@@ -1,9 +1,4 @@
HEADERS += $$PWD/qpnghandler_p.h
SOURCES += $$PWD/qpnghandler.cpp
-contains(QT_CONFIG, system-png) {
- if(unix|mingw): LIBS_PRIVATE += -lpng
- else:win32: LIBS += libpng.lib
-} else {
- include($$PWD/../../3rdparty/libpng.pri)
-}
+include($$PWD/../../3rdparty/png_dependency.pri)
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index f460431c2b..7f23656c02 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -46,13 +46,21 @@ QT_BEGIN_NAMESPACE
PBM/PGM/PPM (ASCII and RAW) image read/write functions
*****************************************************************************/
+static void discard_pbm_line(QIODevice *d)
+{
+ const int buflen = 100;
+ char buf[buflen];
+ int res = 0;
+ do {
+ res = d->readLine(buf, buflen);
+ } while (res > 0 && buf[res-1] != '\n');
+}
+
static int read_pbm_int(QIODevice *d)
{
char c;
int val = -1;
bool digit;
- const int buflen = 100;
- char buf[buflen];
for (;;) {
if (!d->getChar(&c)) // end of file
break;
@@ -63,7 +71,7 @@ static int read_pbm_int(QIODevice *d)
continue;
} else {
if (c == '#') // comment
- d->readLine(buf, buflen);
+ discard_pbm_line(d);
break;
}
}
@@ -72,7 +80,7 @@ static int read_pbm_int(QIODevice *d)
else if (isspace((uchar) c))
continue;
else if (c == '#')
- (void)d->readLine(buf, buflen);
+ discard_pbm_line(d);
else
break;
}