summaryrefslogtreecommitdiffstats
path: root/src/gui/image
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image')
-rw-r--r--src/gui/image/qbmphandler.cpp4
-rw-r--r--src/gui/image/qgifhandler_p.h22
-rw-r--r--src/gui/image/qicon.cpp6
-rw-r--r--src/gui/image/qicon_p.h22
-rw-r--r--src/gui/image/qiconloader.cpp128
-rw-r--r--src/gui/image/qiconloader_p.h20
-rw-r--r--src/gui/image/qimage.cpp99
-rw-r--r--src/gui/image/qimage.h38
-rw-r--r--src/gui/image/qimage_conversions.cpp365
-rw-r--r--src/gui/image/qimage_p.h2
-rw-r--r--src/gui/image/qimageiohandler.cpp6
-rw-r--r--src/gui/image/qimageiohandler.h4
-rw-r--r--src/gui/image/qimagereader.cpp2
-rw-r--r--src/gui/image/qimagewriter.cpp65
-rw-r--r--src/gui/image/qimagewriter.h6
-rw-r--r--src/gui/image/qjpeghandler.cpp71
-rw-r--r--src/gui/image/qjpeghandler_p.h14
-rw-r--r--src/gui/image/qmovie.h3
-rw-r--r--src/gui/image/qpaintengine_pic_p.h27
-rw-r--r--src/gui/image/qpicture.cpp4
-rw-r--r--src/gui/image/qpicture.h6
-rw-r--r--src/gui/image/qpixmap.h6
-rw-r--r--src/gui/image/qpixmap_blitter_p.h22
-rw-r--r--src/gui/image/qpixmap_raster.cpp9
-rw-r--r--src/gui/image/qpixmap_raster_p.h38
-rw-r--r--src/gui/image/qpixmapcache.cpp2
-rw-r--r--src/gui/image/qpnghandler.cpp25
-rw-r--r--src/gui/image/qppmhandler.cpp108
28 files changed, 792 insertions, 332 deletions
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 21c1a2f813..bf3563932d 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -791,6 +791,10 @@ bool QBmpHandler::write(const QImage &img)
case QImage::Format_ARGB32:
image = img;
break;
+ case QImage::Format_Alpha8:
+ case QImage::Format_Grayscale8:
+ image = img.convertToFormat(QImage::Format_Indexed8);
+ break;
default:
if (img.hasAlphaChannel())
image = img.convertToFormat(QImage::Format_ARGB32);
diff --git a/src/gui/image/qgifhandler_p.h b/src/gui/image/qgifhandler_p.h
index 40bff19e7a..08910bf111 100644
--- a/src/gui/image/qgifhandler_p.h
+++ b/src/gui/image/qgifhandler_p.h
@@ -63,22 +63,22 @@ public:
QGifHandler();
~QGifHandler();
- bool canRead() const;
- bool read(QImage *image);
- bool write(const QImage &image);
+ bool canRead() const Q_DECL_OVERRIDE;
+ bool read(QImage *image) Q_DECL_OVERRIDE;
+ bool write(const QImage &image) Q_DECL_OVERRIDE;
- QByteArray name() const;
+ QByteArray name() const Q_DECL_OVERRIDE;
static bool canRead(QIODevice *device);
- QVariant option(ImageOption option) const;
- void setOption(ImageOption option, const QVariant &value);
- bool supportsOption(ImageOption option) const;
+ QVariant option(ImageOption option) const Q_DECL_OVERRIDE;
+ void setOption(ImageOption option, const QVariant &value) Q_DECL_OVERRIDE;
+ bool supportsOption(ImageOption option) const Q_DECL_OVERRIDE;
- int imageCount() const;
- int loopCount() const;
- int nextImageDelay() const;
- int currentImageNumber() const;
+ int imageCount() const Q_DECL_OVERRIDE;
+ int loopCount() const Q_DECL_OVERRIDE;
+ int nextImageDelay() const Q_DECL_OVERRIDE;
+ int currentImageNumber() const Q_DECL_OVERRIDE;
private:
bool imageIsComing() const;
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index 86d9c02c6e..3e27ba3efa 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -46,7 +46,7 @@
#include "qdebug.h"
#include "qpalette.h"
-#ifdef Q_WS_MAC
+#ifdef Q_DEAD_CODE_FROM_QT4_MAC
#include <private/qt_mac_p.h>
#include <private/qt_cocoa_helpers_mac_p.h>
#endif
@@ -1024,7 +1024,7 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State
d->engine->addFile(fileName, size, mode, state);
// Check if a "@2x" file exists and add it.
- static bool disable2xImageLoading = !qgetenv("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING").isEmpty();
+ static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
if (!disable2xImageLoading && qApp->devicePixelRatio() > 1.0) {
QString at2xfileName = fileName;
int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
@@ -1197,7 +1197,7 @@ bool QIcon::hasThemeIcon(const QString &name)
{
QIcon icon = fromTheme(name);
- return !icon.isNull();
+ return icon.name() == name;
}
diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h
index 4896aa89c0..e5ae8ec431 100644
--- a/src/gui/image/qicon_p.h
+++ b/src/gui/image/qicon_p.h
@@ -104,18 +104,18 @@ public:
QPixmapIconEngine();
QPixmapIconEngine(const QPixmapIconEngine &);
~QPixmapIconEngine();
- void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
- QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE;
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE;
QPixmapIconEngineEntry *bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly);
- QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
- void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state);
- void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state);
-
- QString key() const;
- QIconEngine *clone() const;
- bool read(QDataStream &in);
- bool write(QDataStream &out) const;
- void virtual_hook(int id, void *data);
+ QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE;
+ void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE;
+ void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE;
+
+ QString key() const Q_DECL_OVERRIDE;
+ QIconEngine *clone() const Q_DECL_OVERRIDE;
+ bool read(QDataStream &in) Q_DECL_OVERRIDE;
+ bool write(QDataStream &out) const Q_DECL_OVERRIDE;
+ void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
private:
QPixmapIconEngineEntry *tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state);
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 06491f1155..c7a08a7938 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -47,7 +47,7 @@
#include <QtCore/QSettings>
#include <QtGui/QPainter>
-#ifdef Q_WS_MAC
+#ifdef Q_DEAD_CODE_FROM_QT4_MAC
#include <private/qt_cocoa_helpers_mac_p.h>
#endif
@@ -172,11 +172,15 @@ QIconTheme::QIconTheme(const QString &themeName)
for ( int i = 0 ; i < iconDirs.size() ; ++i) {
QDir iconDir(iconDirs[i]);
QString themeDir = iconDir.path() + QLatin1Char('/') + themeName;
- themeIndex.setFileName(themeDir + QLatin1String("/index.theme"));
- if (themeIndex.exists()) {
- m_contentDir = themeDir;
- m_valid = true;
- break;
+ QFileInfo themeDirInfo(themeDir);
+
+ if (themeDirInfo.isDir())
+ m_contentDirs << themeDir;
+
+ if (!m_valid) {
+ themeIndex.setFileName(themeDir + QLatin1String("/index.theme"));
+ if (themeIndex.exists())
+ m_valid = true;
}
}
#ifndef QT_NO_SETTINGS
@@ -239,11 +243,11 @@ QIconTheme::QIconTheme(const QString &themeName)
#endif //QT_NO_SETTINGS
}
-QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName,
- const QString &iconName,
- QStringList &visited) const
+QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName,
+ const QString &iconName,
+ QStringList &visited) const
{
- QThemeIconEntries entries;
+ QThemeIconInfo info;
Q_ASSERT(!themeName.isEmpty());
QPixmap pixmap;
@@ -260,34 +264,54 @@ QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName,
themeList.insert(themeName, theme);
}
- QString contentDir = theme.contentDir() + QLatin1Char('/');
+ const QStringList contentDirs = theme.contentDirs();
const QVector<QIconDirInfo> subDirs = theme.keyList();
- const QString svgext(QLatin1String(".svg"));
- const QString pngext(QLatin1String(".png"));
-
- // Add all relevant files
- for (int i = 0; i < subDirs.size() ; ++i) {
- const QIconDirInfo &dirInfo = subDirs.at(i);
- QString subdir = dirInfo.path;
- QDir currentDir(contentDir + subdir);
- if (currentDir.exists(iconName + pngext)) {
- PixmapEntry *iconEntry = new PixmapEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + pngext);
- // Notice we ensure that pixmap entries always come before
- // scalable to preserve search order afterwards
- entries.prepend(iconEntry);
- } else if (m_supportsSvg &&
- currentDir.exists(iconName + svgext)) {
- ScalableEntry *iconEntry = new ScalableEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + svgext);
- entries.append(iconEntry);
+ QString iconNameFallback = iconName;
+
+ // Iterate through all icon's fallbacks in current theme
+ while (info.entries.isEmpty()) {
+ const QString svgIconName = iconNameFallback + QLatin1String(".svg");
+ const QString pngIconName = iconNameFallback + QLatin1String(".png");
+
+ // Add all relevant files
+ for (int i = 0; i < contentDirs.size(); ++i) {
+ QString contentDir = contentDirs.at(i) + QLatin1Char('/');
+ for (int j = 0; j < subDirs.size() ; ++j) {
+ const QIconDirInfo &dirInfo = subDirs.at(j);
+ QString subdir = dirInfo.path;
+ QDir currentDir(contentDir + subdir);
+ if (currentDir.exists(pngIconName)) {
+ PixmapEntry *iconEntry = new PixmapEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(pngIconName);
+ // Notice we ensure that pixmap entries always come before
+ // scalable to preserve search order afterwards
+ info.entries.prepend(iconEntry);
+ } else if (m_supportsSvg &&
+ currentDir.exists(svgIconName)) {
+ ScalableEntry *iconEntry = new ScalableEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(svgIconName);
+ info.entries.append(iconEntry);
+ }
+ }
+ }
+
+ if (!info.entries.isEmpty()) {
+ info.iconName = iconNameFallback;
+ break;
}
+
+ // If it's possible - find next fallback for the icon
+ const int indexOfDash = iconNameFallback.lastIndexOf(QLatin1Char('-'));
+ if (indexOfDash == -1)
+ break;
+
+ iconNameFallback.truncate(indexOfDash);
}
- if (entries.isEmpty()) {
+ if (info.entries.isEmpty()) {
const QStringList parents = theme.parents();
// Search recursively through inherited themes
for (int i = 0 ; i < parents.size() ; ++i) {
@@ -295,23 +319,23 @@ QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName,
const QString parentTheme = parents.at(i).trimmed();
if (!visited.contains(parentTheme)) // guard against recursion
- entries = findIconHelper(parentTheme, iconName, visited);
+ info = findIconHelper(parentTheme, iconName, visited);
- if (!entries.isEmpty()) // success
+ if (!info.entries.isEmpty()) // success
break;
}
}
- return entries;
+ return info;
}
-QThemeIconEntries QIconLoader::loadIcon(const QString &name) const
+QThemeIconInfo QIconLoader::loadIcon(const QString &name) const
{
if (!themeName().isEmpty()) {
QStringList visited;
return findIconHelper(themeName(), name, visited);
}
- return QThemeIconEntries();
+ return QThemeIconInfo();
}
@@ -325,7 +349,7 @@ QIconLoaderEngine::QIconLoaderEngine(const QString& iconName)
QIconLoaderEngine::~QIconLoaderEngine()
{
- qDeleteAll(m_entries);
+ qDeleteAll(m_info.entries);
}
QIconLoaderEngine::QIconLoaderEngine(const QIconLoaderEngine &other)
@@ -353,17 +377,19 @@ bool QIconLoaderEngine::write(QDataStream &out) const
bool QIconLoaderEngine::hasIcon() const
{
- return !(m_entries.isEmpty());
+ return !(m_info.entries.isEmpty());
}
// Lazily load the icon
void QIconLoaderEngine::ensureLoaded()
{
if (!(QIconLoader::instance()->themeKey() == m_key)) {
+ qDeleteAll(m_info.entries);
+ m_info.entries.clear();
+ m_info.iconName.clear();
- qDeleteAll(m_entries);
-
- m_entries = QIconLoader::instance()->loadIcon(m_iconName);
+ Q_ASSERT(m_info.entries.size() == 0);
+ m_info = QIconLoader::instance()->loadIcon(m_iconName);
m_key = QIconLoader::instance()->themeKey();
}
}
@@ -372,7 +398,7 @@ void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect,
QIcon::Mode mode, QIcon::State state)
{
QSize pixmapSize = rect.size();
-#if defined(Q_WS_MAC)
+#if defined(Q_DEAD_CODE_FROM_QT4_MAC)
pixmapSize *= qt_mac_get_scalefactor();
#endif
painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
@@ -433,14 +459,14 @@ QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size)
{
int iconsize = qMin(size.width(), size.height());
- // Note that m_entries are sorted so that png-files
+ // Note that m_info.entries are sorted so that png-files
// come first
- const int numEntries = m_entries.size();
+ const int numEntries = m_info.entries.size();
// Search for exact matches first
for (int i = 0; i < numEntries; ++i) {
- QIconLoaderEngineEntry *entry = m_entries.at(i);
+ QIconLoaderEngineEntry *entry = m_info.entries.at(i);
if (directoryMatchesSize(entry->dir, iconsize)) {
return entry;
}
@@ -450,7 +476,7 @@ QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size)
int minimalSize = INT_MAX;
QIconLoaderEngineEntry *closestMatch = 0;
for (int i = 0; i < numEntries; ++i) {
- QIconLoaderEngineEntry *entry = m_entries.at(i);
+ QIconLoaderEngineEntry *entry = m_info.entries.at(i);
int distance = directorySizeDistance(entry->dir, iconsize);
if (distance < minimalSize) {
minimalSize = distance;
@@ -554,13 +580,13 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
{
QIconEngine::AvailableSizesArgument &arg
= *reinterpret_cast<QIconEngine::AvailableSizesArgument*>(data);
- const int N = m_entries.size();
+ const int N = m_info.entries.size();
QList<QSize> sizes;
sizes.reserve(N);
// Gets all sizes from the DirectoryInfo entries
for (int i = 0; i < N; ++i) {
- int size = m_entries.at(i)->dir.size;
+ int size = m_info.entries.at(i)->dir.size;
sizes.append(QSize(size, size));
}
arg.sizes.swap(sizes); // commit
@@ -569,7 +595,7 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
case QIconEngine::IconNameHook:
{
QString &name = *reinterpret_cast<QString*>(data);
- name = m_iconName;
+ name = m_info.iconName;
}
break;
default:
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
index 50a6e6d3a7..8ee730f307 100644
--- a/src/gui/image/qiconloader_p.h
+++ b/src/gui/image/qiconloader_p.h
@@ -106,6 +106,12 @@ struct PixmapEntry : public QIconLoaderEngineEntry
typedef QList<QIconLoaderEngineEntry*> QThemeIconEntries;
+struct QThemeIconInfo
+{
+ QThemeIconEntries entries;
+ QString iconName;
+};
+
class QIconLoaderEngine : public QIconEngine
{
public:
@@ -126,7 +132,7 @@ private:
void virtual_hook(int id, void *data);
QIconLoaderEngineEntry *entryForSize(const QSize &size);
QIconLoaderEngine(const QIconLoaderEngine &other);
- QThemeIconEntries m_entries;
+ QThemeIconInfo m_info;
QString m_iconName;
uint m_key;
@@ -140,11 +146,11 @@ public:
QIconTheme() : m_valid(false) {}
QStringList parents() { return m_parents; }
QVector<QIconDirInfo> keyList() { return m_keyList; }
- QString contentDir() { return m_contentDir; }
+ QStringList contentDirs() { return m_contentDirs; }
bool isValid() { return m_valid; }
private:
- QString m_contentDir;
+ QStringList m_contentDirs;
QVector<QIconDirInfo> m_keyList;
QStringList m_parents;
bool m_valid;
@@ -154,7 +160,7 @@ class Q_GUI_EXPORT QIconLoader
{
public:
QIconLoader();
- QThemeIconEntries loadIcon(const QString &iconName) const;
+ QThemeIconInfo loadIcon(const QString &iconName) const;
uint themeKey() const { return m_themeKey; }
QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; }
@@ -169,9 +175,9 @@ public:
void ensureInitialized();
private:
- QThemeIconEntries findIconHelper(const QString &themeName,
- const QString &iconName,
- QStringList &visited) const;
+ QThemeIconInfo findIconHelper(const QString &themeName,
+ const QString &iconName,
+ QStringList &visited) const;
uint m_themeKey;
bool m_supportsSvg;
bool m_initialized;
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 887a7c29eb..ade30b9d77 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -47,7 +47,6 @@
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
-#include <math.h>
#include <qpa/qplatformpixmap.h>
#include <private/qdrawhelper_p.h>
#include <private/qmemrotate_p.h>
@@ -653,7 +652,8 @@ bool QImageData::checkForAlphaPixels() const
The following image formats are available in Qt. Values from Format_ARGB8565_Premultiplied
to Format_ARGB4444_Premultiplied were added in Qt 4.4. Values Format_RGBX8888, Format_RGBA8888
and Format_RGBA8888_Premultiplied were added in Qt 5.2. Values Format_BGR30, Format_A2BGR30_Premultiplied,
- Format_RGB30, Format_A2RGB30_Premultiplied were added in Qt 5.4.
+ Format_RGB30, Format_A2RGB30_Premultiplied were added in Qt 5.4. Format_Alpha8 and Format_Grayscale8
+ were added in Qt 5.5.
See the notes after the table.
\value Format_Invalid The image is invalid.
@@ -709,6 +709,8 @@ bool QImageData::checkForAlphaPixels() const
\value Format_A2BGR30_Premultiplied The image is stored using a 32-bit premultiplied ABGR format (2-10-10-10).
\value Format_RGB30 The image is stored using a 32-bit RGB format (x-10-10-10).
\value Format_A2RGB30_Premultiplied The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10).
+ \value Format_Alpha8 The image is stored using an 8-bit alpha only format.
+ \value Format_Grayscale8 The image is stored using an 8-bit grayscale format.
\note Drawing into a QImage with QImage::Format_Indexed8 is not
supported.
@@ -2352,6 +2354,10 @@ bool QImage::allGray() const
return false;
}
return true;
+ case Format_Alpha8:
+ return false;
+ case Format_Grayscale8:
+ return true;
case Format_RGB32:
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
@@ -2405,9 +2411,9 @@ bool QImage::allGray() const
/*!
For 32-bit images, this function is equivalent to allGray().
- For 8-bpp images, this function returns \c true if color(i) is
- QRgb(i, i, i) for all indexes of the color table; otherwise
- returns \c false.
+ For color indexed images, this function returns \c true if
+ color(i) is QRgb(i, i, i) for all indexes of the color table;
+ otherwise returns \c false.
\sa allGray(), {QImage#Image Formats}{Image Formats}
*/
@@ -2416,12 +2422,19 @@ bool QImage::isGrayscale() const
if (!d)
return false;
+ if (d->format == QImage::Format_Alpha8)
+ return false;
+
+ if (d->format == QImage::Format_Grayscale8)
+ return true;
+
switch (depth()) {
case 32:
case 24:
case 16:
return allGray();
case 8: {
+ Q_ASSERT(d->format == QImage::Format_Indexed8);
for (int i = 0; i < colorCount(); i++)
if (d->colortable.at(i) != qRgb(i,i,i))
return false;
@@ -2998,6 +3011,9 @@ QImage QImage::rgbSwapped_helper() const
case NImageFormats:
Q_ASSERT(false);
break;
+ case Format_Alpha8:
+ case Format_Grayscale8:
+ return *this;
case Format_Mono:
case Format_MonoLSB:
case Format_Indexed8:
@@ -3084,6 +3100,9 @@ void QImage::rgbSwapped_inplace()
case NImageFormats:
Q_ASSERT(false);
break;
+ case Format_Alpha8:
+ case Format_Grayscale8:
+ return;
case Format_Mono:
case Format_MonoLSB:
case Format_Indexed8:
@@ -4017,7 +4036,7 @@ void QImage::setAlphaChannel(const QImage &alphaChannel)
return;
// Slight optimization since alphachannels are returned as 8-bit grays.
- if (alphaChannel.d->depth == 8 && alphaChannel.isGrayscale()) {
+ if (alphaChannel.format() == QImage::Format_Alpha8 ||( alphaChannel.d->depth == 8 && alphaChannel.isGrayscale())) {
const uchar *src_data = alphaChannel.d->data;
const uchar *dest_data = d->data;
for (int y=0; y<h; ++y) {
@@ -4075,9 +4094,13 @@ void QImage::setAlphaChannel(const QImage &alphaChannel)
Most usecases for this function can be replaced with QPainter and
using composition modes.
+ Note this returns a color-indexed image if you want the alpha channel in
+ the alpha8 format instead use convertToFormat(Format_Alpha8) on the source
+ image.
+
\warning This is an expensive function.
- \sa setAlphaChannel(), hasAlphaChannel(),
+ \sa setAlphaChannel(), hasAlphaChannel(), convertToFormat(),
{QPixmap#Pixmap Information}{Pixmap},
{QImage#Image Transformations}{Image Transformations}
*/
@@ -4087,6 +4110,9 @@ QImage QImage::alphaChannel() const
if (!d)
return QImage();
+ if (d->format == QImage::Format_Alpha8)
+ return *this;
+
int w = d->width;
int h = d->height;
@@ -4264,6 +4290,8 @@ static QImage rotated90(const QImage &image) {
reinterpret_cast<quint16*>(out.bits()),
out.bytesPerLine());
break;
+ case QImage::Format_Alpha8:
+ case QImage::Format_Grayscale8:
case QImage::Format_Indexed8:
qt_memrotate270(reinterpret_cast<const quint8*>(image.bits()),
w, h, image.bytesPerLine(),
@@ -4330,6 +4358,8 @@ static QImage rotated270(const QImage &image) {
reinterpret_cast<quint16*>(out.bits()),
out.bytesPerLine());
break;
+ case QImage::Format_Alpha8:
+ case QImage::Format_Grayscale8:
case QImage::Format_Indexed8:
qt_memrotate90(reinterpret_cast<const quint8*>(image.bits()),
w, h, image.bytesPerLine(),
@@ -4481,24 +4511,17 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
dImage.d->dpmx = dotsPerMeterX();
dImage.d->dpmy = dotsPerMeterY();
- switch (bpp) {
- // initizialize the data
- case 8:
- if (dImage.d->colortable.size() < 256) {
- // colors are left in the color table, so pick that one as transparent
- dImage.d->colortable.append(0x0);
- memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.byteCount());
- } else {
- memset(dImage.bits(), 0, dImage.byteCount());
- }
- break;
- case 1:
- case 16:
- case 24:
- case 32:
- memset(dImage.bits(), 0x00, dImage.byteCount());
- break;
- }
+ // initizialize the data
+ if (d->format == QImage::Format_Indexed8) {
+ if (dImage.d->colortable.size() < 256) {
+ // colors are left in the color table, so pick that one as transparent
+ dImage.d->colortable.append(0x0);
+ memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.byteCount());
+ } else {
+ memset(dImage.bits(), 0, dImage.byteCount());
+ }
+ } else
+ memset(dImage.bits(), 0x00, dImage.byteCount());
if (target_format >= QImage::Format_RGB32) {
// Prevent QPainter from applying devicePixelRatio corrections
@@ -4942,6 +4965,32 @@ static Q_CONSTEXPR QPixelFormat pixelformats[] = {
/*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
/*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
/*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
+ //QImage::Format_Alpha8:
+ QPixelFormat(QPixelFormat::Alpha,
+ /*First*/ 0,
+ /*SECOND*/ 0,
+ /*THIRD*/ 0,
+ /*FOURTH*/ 0,
+ /*FIFTH*/ 0,
+ /*ALPHA*/ 8,
+ /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
+ /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
+ /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
+ /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
+ /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
+ //QImage::Format_Grayscale8:
+ QPixelFormat(QPixelFormat::Grayscale,
+ /*GRAY*/ 8,
+ /*SECOND*/ 0,
+ /*THIRD*/ 0,
+ /*FOURTH*/ 0,
+ /*FIFTH*/ 0,
+ /*ALPHA*/ 0,
+ /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
+ /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
+ /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
+ /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
+ /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
};
Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats);
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 55b8690c77..8984af12d1 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -106,20 +106,16 @@ public:
Format_RGBX8888,
Format_RGBA8888,
Format_RGBA8888_Premultiplied,
-#if 0
- // reserved for future use
- Format_RGB15,
- Format_Grayscale16,
- Format_Grayscale8,
- Format_Grayscale4,
- Format_Grayscale4LSB,
- Format_Grayscale2,
- Format_Grayscale2LSB
-#endif
Format_BGR30,
Format_A2BGR30_Premultiplied,
Format_RGB30,
Format_A2RGB30_Premultiplied,
+ Format_Alpha8,
+ Format_Grayscale8,
+#if 0
+ // reserved for future use
+ Format_Grayscale16,
+#endif
#ifndef Q_QDOC
NImageFormats
#endif
@@ -155,7 +151,7 @@ public:
bool isNull() const;
- int devType() const;
+ int devType() const Q_DECL_OVERRIDE;
bool operator==(const QImage &) const;
bool operator!=(const QImage &) const;
@@ -288,7 +284,7 @@ public:
#endif
qint64 cacheKey() const;
- QPaintEngine *paintEngine() const;
+ QPaintEngine *paintEngine() const Q_DECL_OVERRIDE;
// Auxiliary data
int dotsPerMeterX() const;
@@ -321,7 +317,7 @@ public:
#endif
protected:
- virtual int metric(PaintDeviceMetric metric) const;
+ virtual int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
QImage mirrored_helper(bool horizontal, bool vertical) const;
QImage rgbSwapped_helper() const;
void mirrored_inplace(bool horizontal, bool vertical);
@@ -353,13 +349,9 @@ inline void QImage::setPixel(const QPoint &pt, uint index_or_rgb) { setPixel(pt.
#if QT_DEPRECATED_SINCE(5, 0)
-#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#elif defined(Q_CC_MSVC)
-# pragma warning(push)
-# pragma warning(disable: 4996)
-#endif
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations")
+QT_WARNING_DISABLE_MSVC(4996)
inline QString QImage::text(const char* key, const char* lang) const
{
@@ -431,11 +423,7 @@ inline void QImage::setText(const char* key, const char* lang, const QString &s)
setText(k, s);
}
-#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
-# pragma GCC diagnostic pop
-#elif defined(Q_CC_MSVC)
-# pragma warning(pop)
-#endif
+QT_WARNING_POP
inline int QImage::numColors() const
{
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index b2681f4261..0a4bf47c82 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -195,7 +195,7 @@ static bool convert_passthrough_inplace(QImageData *data, Qt::ImageConversionFla
return true;
}
-static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+static inline void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
@@ -219,6 +219,15 @@ static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt:
}
}
+#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__)
+QT_FUNCTION_TARGET(SSE4_1)
+static void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ // Twice as fast autovectorized due to SSE4.1 PMULLD instructions.
+ convert_ARGB_to_ARGB_PM(dest, src, flags);
+}
+#endif
+
extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
#ifndef __SSE2__
@@ -232,7 +241,7 @@ static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversio
for (int i = 0; i < data->height; ++i) {
const QRgb *end = rgb_data + data->width;
while (rgb_data < end) {
- *rgb_data = PREMUL(*rgb_data);
+ *rgb_data = qPremultiply(*rgb_data);
++rgb_data;
}
rgb_data += pad;
@@ -312,7 +321,7 @@ static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFl
return true;
}
-static void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+static inline void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_ARGB32);
Q_ASSERT(dest->format == QImage::Format_RGBA8888_Premultiplied);
@@ -336,6 +345,15 @@ static void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt:
}
}
+#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__)
+QT_FUNCTION_TARGET(SSE4_1)
+static void convert_ARGB_to_RGBA_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ // Twice as fast autovectorized due to SSE4.1 PMULLD instructions.
+ convert_ARGB_to_RGBA_PM(dest, src, flags);
+}
+#endif
+
static void convert_RGBA_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBA8888_Premultiplied);
@@ -1861,11 +1879,154 @@ static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt
}
}
+static void convert_Indexed8_to_Alpha8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Indexed8);
+ Q_ASSERT(dest->format == QImage::Format_Alpha8);
+
+ uchar translate[256];
+ const QVector<QRgb> &colors = src->colortable;
+ bool simpleCase = (colors.size() == 256);
+ for (int i = 0; i < colors.size(); ++i) {
+ uchar alpha = qAlpha(colors[i]);
+ translate[i] = alpha;
+ simpleCase = simpleCase && (alpha == i);
+ }
+
+ if (simpleCase)
+ memcpy(dest->data, src->data, src->bytes_per_line * src->height);
+ else {
+ int size = src->bytes_per_line * src->height;
+ for (int i = 0; i < size; ++i) {
+ dest->data[i] = translate[src->data[i]];
+ }
+ }
+}
+
+static void convert_Indexed8_to_Grayscale8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Indexed8);
+ Q_ASSERT(dest->format == QImage::Format_Grayscale8);
+
+ uchar translate[256];
+ const QVector<QRgb> &colors = src->colortable;
+ bool simpleCase = (colors.size() == 256);
+ for (int i = 0; i < colors.size(); ++i) {
+ uchar gray = qGray(colors[i]);
+ translate[i] = gray;
+ simpleCase = simpleCase && (gray == i);
+ }
+
+ if (simpleCase)
+ memcpy(dest->data, src->data, src->bytes_per_line * src->height);
+ else {
+ int size = src->bytes_per_line * src->height;
+ for (int i = 0; i < size; ++i) {
+ dest->data[i] = translate[src->data[i]];
+ }
+ }
+}
+
+static bool convert_Indexed8_to_Alpha8_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+
+ // Just check if this is an Alpha8 in Indexed8 disguise.
+ const QVector<QRgb> &colors = data->colortable;
+ if (colors.size() != 256)
+ return false;
+ for (int i = 0; i < colors.size(); ++i) {
+ if (i != qAlpha(colors[i]))
+ return false;
+ }
+
+ data->colortable.clear();
+ data->format = QImage::Format_Alpha8;
+
+ return true;
+}
+
+static bool convert_Indexed8_to_Grayscale8_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+
+ // Just check if this is a Grayscale8 in Indexed8 disguise.
+ const QVector<QRgb> &colors = data->colortable;
+ if (colors.size() != 256)
+ return false;
+ for (int i = 0; i < colors.size(); ++i) {
+ if (i != qGray(colors[i]))
+ return false;
+ }
+
+ data->colortable.clear();
+ data->format = QImage::Format_Grayscale8;
+
+ return true;
+}
+
+static void convert_Alpha8_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Alpha8);
+ Q_ASSERT(dest->format == QImage::Format_Indexed8);
+
+ memcpy(dest->data, src->data, src->bytes_per_line * src->height);
+
+ QVector<QRgb> colors(256);
+ for (int i=0; i<256; ++i)
+ colors[i] = qRgba(0, 0, 0, i);
+
+ dest->colortable = colors;
+}
+
+static void convert_Grayscale8_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Grayscale8);
+ Q_ASSERT(dest->format == QImage::Format_Indexed8);
+
+ memcpy(dest->data, src->data, src->bytes_per_line * src->height);
+
+ QVector<QRgb> colors(256);
+ for (int i=0; i<256; ++i)
+ colors[i] = qRgb(i, i, i);
+
+ dest->colortable = colors;
+}
+
+static bool convert_Alpha8_to_Indexed8_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Alpha8);
+
+ QVector<QRgb> colors(256);
+ for (int i=0; i<256; ++i)
+ colors[i] = qRgba(0, 0, 0, i);
+
+ data->colortable = colors;
+ data->format = QImage::Format_Indexed8;
+
+ return true;
+}
+
+static bool convert_Grayscale8_to_Indexed8_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Grayscale8);
+
+ QVector<QRgb> colors(256);
+ for (int i=0; i<256; ++i)
+ colors[i] = qRgb(i, i, i);
+
+ data->colortable = colors;
+ data->format = QImage::Format_Indexed8;
+
+ return true;
+}
+
+
// first index source, second dest
Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
0,
@@ -1886,7 +2047,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
@@ -1908,7 +2069,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
@@ -1930,7 +2091,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0,
+ convert_Indexed8_to_Alpha8,
+ convert_Indexed8_to_Grayscale8,
}, // Format_Indexed8
{
@@ -1957,6 +2120,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB_to_RGB30<PixelOrderBGR>,
convert_RGB_to_RGB30<PixelOrderRGB>,
convert_RGB_to_RGB30<PixelOrderRGB>,
+ 0, 0
}, // Format_RGB32
{
@@ -1983,6 +2147,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
convert_RGB_to_RGB30<PixelOrderRGB>,
0,
+ 0, 0
}, // Format_ARGB32
{
@@ -2009,6 +2174,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_ARGB_to_A2RGB30<PixelOrderBGR>,
convert_ARGB_PM_to_RGB30<PixelOrderRGB>,
convert_ARGB_to_A2RGB30<PixelOrderRGB>,
+ 0, 0
}, // Format_ARGB32_Premultiplied
{
@@ -2030,7 +2196,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
@@ -2052,7 +2218,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
@@ -2074,7 +2240,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
@@ -2096,7 +2262,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
@@ -2118,7 +2284,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
@@ -2140,7 +2306,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
@@ -2162,7 +2328,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB888
{
@@ -2184,7 +2350,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
@@ -2205,7 +2371,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB4444_Premultiplied
{
0,
@@ -2227,7 +2393,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
mask_alpha_converter_RGBx,
mask_alpha_converter_RGBx,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
}, // Format_RGBX8888
{
0,
@@ -2254,7 +2420,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
#endif
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888
{
@@ -2283,7 +2449,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
#endif
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888_Premultiplied
{
@@ -2309,7 +2475,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
convert_passthrough,
convert_BGR30_to_RGB30,
- convert_BGR30_to_RGB30
+ convert_BGR30_to_RGB30,
+ 0, 0
}, // Format_BGR30
{
0,
@@ -2334,7 +2501,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_RGB30,
0,
0,
- convert_BGR30_to_RGB30
+ convert_BGR30_to_RGB30,
+ 0, 0
}, // Format_BGR30A2_Premultiplied
{
0,
@@ -2360,6 +2528,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
convert_passthrough,
+ 0, 0
}, // Format_RGB30
{
0,
@@ -2385,19 +2554,61 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_BGR30_to_RGB30,
convert_A2RGB30_PM_to_RGB30,
0,
+ 0,
+ 0,
}, // Format_RGB30A2_Premultiplied
+ {
+ 0,
+ 0,
+ 0,
+ convert_Alpha8_to_Indexed8,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0, 0, 0, 0
+ }, // Format_Alpha8
+ {
+ 0,
+ 0,
+ 0,
+ convert_Grayscale8_to_Indexed8,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0, 0, 0, 0
+ } // Format_Grayscale8
};
InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
0,
@@ -2418,7 +2629,9 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0,
+ convert_Indexed8_to_Alpha8_inplace,
+ convert_Indexed8_to_Grayscale8_inplace,
}, // Format_Indexed8
{
0,
@@ -2439,7 +2652,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB32
{
0,
@@ -2464,7 +2677,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
convert_ARGB_to_RGBA_inplace,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB32
{
0,
@@ -2486,34 +2699,34 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
convert_ARGB_to_RGBA_inplace,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
}, // Format_ARGB32_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB888
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB4444_Premultiplied
{
0,
@@ -2535,7 +2748,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
convert_passthrough_inplace<QImage::Format_RGBA8888>,
convert_passthrough_inplace<QImage::Format_RGBA8888_Premultiplied>,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
}, // Format_RGBX8888
{
0,
@@ -2557,7 +2770,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888
{
0,
@@ -2579,7 +2792,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888_Premultiplied
{
0,
@@ -2604,7 +2817,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>,
convert_BGR30_to_RGB30_inplace,
- convert_BGR30_to_RGB30_inplace
+ convert_BGR30_to_RGB30_inplace,
+ 0, 0
}, // Format_BGR30
{
0,
@@ -2629,7 +2843,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_A2RGB30_PM_to_RGB30_inplace,
0,
0,
- convert_BGR30_to_RGB30_inplace
+ convert_BGR30_to_RGB30_inplace,
+ 0, 0
}, // Format_BGR30A2_Premultiplied
{
0,
@@ -2654,7 +2869,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_BGR30_to_RGB30_inplace,
convert_BGR30_to_RGB30_inplace,
0,
- convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>
+ convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>,
+ 0, 0
}, // Format_RGB30
{
0,
@@ -2679,8 +2895,61 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
convert_BGR30_to_RGB30_inplace,
convert_A2RGB30_PM_to_RGB30_inplace,
- 0
+ 0,
+ 0, 0
}, // Format_RGB30A2_Premultiplied
+ {
+ 0,
+ 0,
+ 0,
+ convert_Alpha8_to_Indexed8_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, 0
+ }, // Format_Alpha8
+ {
+ 0,
+ 0,
+ 0,
+ convert_Grayscale8_to_Indexed8_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, 0
+ } // Format_Grayscale8
};
void qInitImageConversions()
@@ -2694,6 +2963,14 @@ void qInitImageConversions()
}
#endif
+#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__)
+ if (qCpuHasFeature(SSE4_1)) {
+ qimage_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4;
+ qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4;
+ qimage_converter_map[QImage::Format_ARGB32][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_RGBA_PM_sse4;
+ }
+#endif
+
#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
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;
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 7e2d4305ef..47e68b14a5 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -131,6 +131,8 @@ inline int qt_depthForFormat(QImage::Format format)
depth = 1;
break;
case QImage::Format_Indexed8:
+ case QImage::Format_Alpha8:
+ case QImage::Format_Grayscale8:
depth = 8;
break;
case QImage::Format_RGB32:
diff --git a/src/gui/image/qimageiohandler.cpp b/src/gui/image/qimageiohandler.cpp
index 1ecf445d57..7e7f3295e9 100644
--- a/src/gui/image/qimageiohandler.cpp
+++ b/src/gui/image/qimageiohandler.cpp
@@ -153,6 +153,12 @@
\value SupportedSubTypes Image formats that support different saving
variants should return a list of supported variant names
(QList<QByteArray>) in this option.
+
+ \value OptimizedWrite. A handler which supports this option
+ is expected to turn on optimization flags when writing.
+
+ \value ProgressiveScanWrite. A handler which supports
+ this option is expected to write the image as a progressive scan image.
*/
/*!
diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h
index 3b3c410e0c..1c906436fe 100644
--- a/src/gui/image/qimageiohandler.h
+++ b/src/gui/image/qimageiohandler.h
@@ -84,7 +84,9 @@ public:
Animation,
BackgroundColor,
ImageFormat,
- SupportedSubTypes
+ SupportedSubTypes,
+ OptimizedWrite,
+ ProgressiveScanWrite
};
virtual QVariant option(ImageOption option) const;
virtual void setOption(ImageOption option, const QVariant &value);
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index a7a08a6fee..ad84b0a091 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -1290,7 +1290,7 @@ bool QImageReader::read(QImage *image)
}
// successful read; check for "@2x" file name suffix and set device pixel ratio.
- static bool disable2xImageLoading = !qgetenv("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING").isEmpty();
+ static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
if (!disable2xImageLoading && QFileInfo(fileName()).baseName().endsWith(QLatin1String("@2x"))) {
image->setDevicePixelRatio(2.0);
}
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index fa261df1a5..0e03c9b215 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -252,6 +252,8 @@ public:
QString description;
QString text;
QByteArray subType;
+ bool optimizedWrite;
+ bool progressiveScanWrite;
// error
QImageWriter::ImageWriterError imageWriterError;
@@ -271,6 +273,8 @@ QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq)
quality = -1;
compression = 0;
gamma = 0.0;
+ optimizedWrite = false;
+ progressiveScanWrite = false;
imageWriterError = QImageWriter::UnknownError;
errorString = QImageWriter::tr("Unknown error");
@@ -555,6 +559,63 @@ QList<QByteArray> QImageWriter::supportedSubTypes() const
}
/*!
+ \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;
+}
+
+/*!
\obsolete
Use setText() instead.
@@ -657,6 +718,10 @@ bool QImageWriter::write(const QImage &image)
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->write(image))
return false;
diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h
index f458a259aa..e070d3b3d6 100644
--- a/src/gui/image/qimagewriter.h
+++ b/src/gui/image/qimagewriter.h
@@ -83,6 +83,12 @@ public:
QByteArray subType() const;
QList<QByteArray> supportedSubTypes() const;
+ void setOptimizedWrite(bool optimize);
+ bool optimizedWrite() const;
+
+ void setProgressiveScanWrite(bool progressive);
+ bool progressiveScanWrite() const;
+
// Obsolete as of 4.1
void setDescription(const QString &description);
QString description() const;
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index 9cf9947b6c..b07e1e28d3 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -86,9 +86,7 @@ struct my_error_mgr : public jpeg_error_mgr {
jmp_buf setjmp_buffer;
};
-#if defined(Q_C_CALLBACKS)
extern "C" {
-#endif
static void my_error_exit (j_common_ptr cinfo)
{
@@ -106,9 +104,7 @@ static void my_output_message(j_common_ptr cinfo)
qWarning("%s", buffer);
}
-#if defined(Q_C_CALLBACKS)
}
-#endif
static const int max_buf = 4096;
@@ -123,9 +119,7 @@ public:
my_jpeg_source_mgr(QIODevice *device);
};
-#if defined(Q_C_CALLBACKS)
extern "C" {
-#endif
static void qt_init_source(j_decompress_ptr)
{
@@ -185,9 +179,7 @@ static void qt_term_source(j_decompress_ptr cinfo)
src->device->seek(src->device->pos() - src->bytes_in_buffer);
}
-#if defined(Q_C_CALLBACKS)
}
-#endif
inline my_jpeg_source_mgr::my_jpeg_source_mgr(QIODevice *device)
{
@@ -220,7 +212,7 @@ inline static bool read_jpeg_format(QImage::Format &format, j_decompress_ptr cin
bool result = true;
switch (cinfo->output_components) {
case 1:
- format = QImage::Format_Indexed8;
+ format = QImage::Format_Grayscale8;
break;
case 3:
case 4:
@@ -240,7 +232,7 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
QImage::Format format;
switch (info->output_components) {
case 1:
- format = QImage::Format_Indexed8;
+ format = QImage::Format_Grayscale8;
break;
case 3:
case 4:
@@ -250,16 +242,9 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
return false; // unsupported format
}
- if (dest->size() != size || dest->format() != format) {
+ if (dest->size() != size || dest->format() != format)
*dest = QImage(size, format);
- if (format == QImage::Format_Indexed8) {
- dest->setColorCount(256);
- for (int i = 0; i < 256; i++)
- dest->setColor(i, qRgb(i,i,i));
- }
- }
-
return !dest->isNull();
}
@@ -465,9 +450,7 @@ public:
};
-#if defined(Q_C_CALLBACKS)
extern "C" {
-#endif
static void qt_init_destination(j_compress_ptr)
{
@@ -497,9 +480,7 @@ static void qt_term_destination(j_compress_ptr cinfo)
(*cinfo->err->error_exit)((j_common_ptr)cinfo);
}
-#if defined(Q_C_CALLBACKS)
}
-#endif
inline my_jpeg_destination_mgr::my_jpeg_destination_mgr(QIODevice *device)
{
@@ -545,11 +526,14 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt
}
}
-static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description)
+static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive)
{
bool success = false;
const QVector<QRgb> cmap = image.colorTable();
+ if (image.format() == QImage::Format_Invalid || image.format() == QImage::Format_Alpha8)
+ return false;
+
struct jpeg_compress_struct cinfo;
JSAMPROW row_pointer[1];
row_pointer[0] = 0;
@@ -573,19 +557,23 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
cinfo.image_width = image.width();
cinfo.image_height = image.height();
- bool gray=false;
+ bool gray = false;
switch (image.format()) {
case QImage::Format_Mono:
case QImage::Format_MonoLSB:
case QImage::Format_Indexed8:
gray = true;
- for (int i = image.colorCount(); gray && i--;) {
- gray = gray & (qRed(cmap[i]) == qGreen(cmap[i]) &&
- qRed(cmap[i]) == qBlue(cmap[i]));
+ for (int i = image.colorCount(); gray && i; i--) {
+ gray = gray & qIsGray(cmap[i-1]);
}
cinfo.input_components = gray ? 1 : 3;
cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;
break;
+ case QImage::Format_Grayscale8:
+ gray = true;
+ cinfo.input_components = 1;
+ cinfo.in_color_space = JCS_GRAYSCALE;
+ break;
default:
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
@@ -607,6 +595,11 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
cinfo.Y_density = (image.dotsPerMeterY()+50) / 100;
}
+ if (optimize)
+ cinfo.optimize_coding = true;
+
+ if (progressive)
+ jpeg_simple_progression(&cinfo);
int quality = sourceQuality >= 0 ? qMin(int(sourceQuality),100) : 75;
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
@@ -670,6 +663,9 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
}
}
break;
+ case QImage::Format_Grayscale8:
+ memcpy(row, image.constScanLine(cinfo.next_scanline), w);
+ break;
case QImage::Format_RGB888:
memcpy(row, image.constScanLine(cinfo.next_scanline), w * 3);
break;
@@ -726,7 +722,7 @@ public:
};
QJpegHandlerPrivate(QJpegHandler *qq)
- : quality(75), exifOrientation(1), iod_src(0), state(Ready), q(qq)
+ : quality(75), exifOrientation(1), iod_src(0), state(Ready), optimize(false), progressive(false), q(qq)
{}
~QJpegHandlerPrivate()
@@ -759,6 +755,9 @@ public:
State state;
+ bool optimize;
+ bool progressive;
+
QJpegHandler *q;
};
@@ -1063,7 +1062,7 @@ bool QJpegHandler::read(QImage *image)
bool QJpegHandler::write(const QImage &image)
{
- return write_jpeg_image(image, device(), d->quality, d->description);
+ return write_jpeg_image(image, device(), d->quality, d->description, d->optimize, d->progressive);
}
bool QJpegHandler::supportsOption(ImageOption option) const
@@ -1074,7 +1073,9 @@ bool QJpegHandler::supportsOption(ImageOption option) const
|| option == ClipRect
|| option == Description
|| option == Size
- || option == ImageFormat;
+ || option == ImageFormat
+ || option == OptimizedWrite
+ || option == ProgressiveScanWrite;
}
QVariant QJpegHandler::option(ImageOption option) const
@@ -1097,6 +1098,10 @@ QVariant QJpegHandler::option(ImageOption option) const
case ImageFormat:
d->readJpegHeader(device());
return d->format;
+ case OptimizedWrite:
+ return d->optimize;
+ case ProgressiveScanWrite:
+ return d->progressive;
default:
break;
}
@@ -1122,6 +1127,12 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value)
case Description:
d->description = value.toString();
break;
+ case OptimizedWrite:
+ d->optimize = value.toBool();
+ break;
+ case ProgressiveScanWrite:
+ d->progressive = value.toBool();
+ break;
default:
break;
}
diff --git a/src/gui/image/qjpeghandler_p.h b/src/gui/image/qjpeghandler_p.h
index 85b903bf44..12f2553f92 100644
--- a/src/gui/image/qjpeghandler_p.h
+++ b/src/gui/image/qjpeghandler_p.h
@@ -58,17 +58,17 @@ public:
QJpegHandler();
~QJpegHandler();
- bool canRead() const;
- bool read(QImage *image);
- bool write(const QImage &image);
+ bool canRead() const Q_DECL_OVERRIDE;
+ bool read(QImage *image) Q_DECL_OVERRIDE;
+ bool write(const QImage &image) Q_DECL_OVERRIDE;
- QByteArray name() const;
+ QByteArray name() const Q_DECL_OVERRIDE;
static bool canRead(QIODevice *device);
- QVariant option(ImageOption option) const;
- void setOption(ImageOption option, const QVariant &value);
- bool supportsOption(ImageOption option) const;
+ QVariant option(ImageOption option) const Q_DECL_OVERRIDE;
+ void setOption(ImageOption option, const QVariant &value) Q_DECL_OVERRIDE;
+ bool supportsOption(ImageOption option) const Q_DECL_OVERRIDE;
private:
QJpegHandlerPrivate *d;
diff --git a/src/gui/image/qmovie.h b/src/gui/image/qmovie.h
index c1560fdab6..60078f9e98 100644
--- a/src/gui/image/qmovie.h
+++ b/src/gui/image/qmovie.h
@@ -58,7 +58,6 @@ class Q_GUI_EXPORT QMovie : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QMovie)
- Q_ENUMS(MovieState CacheMode)
Q_PROPERTY(int speed READ speed WRITE setSpeed)
Q_PROPERTY(CacheMode cacheMode READ cacheMode WRITE setCacheMode)
public:
@@ -67,10 +66,12 @@ public:
Paused,
Running
};
+ Q_ENUM(MovieState)
enum CacheMode {
CacheNone,
CacheAll
};
+ Q_ENUM(CacheMode)
explicit QMovie(QObject *parent = 0);
explicit QMovie(QIODevice *device, const QByteArray &format = QByteArray(), QObject *parent = 0);
diff --git a/src/gui/image/qpaintengine_pic_p.h b/src/gui/image/qpaintengine_pic_p.h
index ef8b5643d1..168be55927 100644
--- a/src/gui/image/qpaintengine_pic_p.h
+++ b/src/gui/image/qpaintengine_pic_p.h
@@ -62,10 +62,10 @@ public:
QPicturePaintEngine();
~QPicturePaintEngine();
- bool begin(QPaintDevice *pdev);
- bool end();
+ bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE;
+ bool end() Q_DECL_OVERRIDE;
- void updateState(const QPaintEngineState &state);
+ void updateState(const QPaintEngineState &state) Q_DECL_OVERRIDE;
void updatePen(const QPen &pen);
void updateBrush(const QBrush &brush);
@@ -80,23 +80,18 @@ public:
void updateClipEnabled(bool enabled);
void updateOpacity(qreal opacity);
- void drawEllipse(const QRectF &rect);
- void drawPath(const QPainterPath &path);
- void drawPolygon(const QPointF *points, int numPoints, PolygonDrawMode mode);
-#ifdef Q_NO_USING_KEYWORD
- inline void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
- { QPaintEngine::drawPolygon(points, pointCount, mode); }
-#else
+ void drawEllipse(const QRectF &rect) Q_DECL_OVERRIDE;
+ void drawPath(const QPainterPath &path) Q_DECL_OVERRIDE;
+ void drawPolygon(const QPointF *points, int numPoints, PolygonDrawMode mode) Q_DECL_OVERRIDE;
using QPaintEngine::drawPolygon;
-#endif
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE;
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) Q_DECL_OVERRIDE;
void drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor);
- void drawTextItem(const QPointF &p, const QTextItem &ti);
+ Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
+ void drawTextItem(const QPointF &p, const QTextItem &ti) Q_DECL_OVERRIDE;
- Type type() const { return Picture; }
+ Type type() const Q_DECL_OVERRIDE { return Picture; }
protected:
QPicturePaintEngine(QPaintEnginePrivate &dptr);
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index bb37461b4f..bdfb987567 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -450,8 +450,8 @@ public:
QFakeDevice() { dpi_x = qt_defaultDpiX(); dpi_y = qt_defaultDpiY(); }
void setDpiX(int dpi) { dpi_x = dpi; }
void setDpiY(int dpi) { dpi_y = dpi; }
- QPaintEngine *paintEngine() const { return 0; }
- int metric(PaintDeviceMetric m) const
+ QPaintEngine *paintEngine() const Q_DECL_OVERRIDE { return 0; }
+ int metric(PaintDeviceMetric m) const Q_DECL_OVERRIDE
{
switch(m) {
case PdmPhysicalDpiX:
diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h
index 1ad20a4e70..2ce8b3b75e 100644
--- a/src/gui/image/qpicture.h
+++ b/src/gui/image/qpicture.h
@@ -55,7 +55,7 @@ public:
bool isNull() const;
- int devType() const;
+ int devType() const Q_DECL_OVERRIDE;
uint size() const;
const char* data() const;
virtual void setData(const char* data, uint size);
@@ -88,12 +88,12 @@ public:
static QStringList inputFormatList();
static QStringList outputFormatList();
- QPaintEngine *paintEngine() const;
+ QPaintEngine *paintEngine() const Q_DECL_OVERRIDE;
protected:
QPicture(QPicturePrivate &data);
- int metric(PaintDeviceMetric m) const;
+ int metric(PaintDeviceMetric m) const Q_DECL_OVERRIDE;
private:
bool exec(QPainter *p, QDataStream &ds, int i);
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index dce64bd2dd..ce3a42abc4 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -75,7 +75,7 @@ public:
operator QVariant() const;
bool isNull() const;
- int devType() const;
+ int devType() const Q_DECL_OVERRIDE;
int width() const;
int height() const;
@@ -154,7 +154,7 @@ public:
bool isQBitmap() const;
- QPaintEngine *paintEngine() const;
+ QPaintEngine *paintEngine() const Q_DECL_OVERRIDE;
inline bool operator!() const { return isNull(); }
@@ -164,7 +164,7 @@ public:
#endif
protected:
- int metric(PaintDeviceMetric) const;
+ int metric(PaintDeviceMetric) const Q_DECL_OVERRIDE;
static QPixmap fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor);
private:
diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h
index ec6c1eb8e5..069efbf593 100644
--- a/src/gui/image/qpixmap_blitter_p.h
+++ b/src/gui/image/qpixmap_blitter_p.h
@@ -62,17 +62,17 @@ public:
QBlittable *blittable() const;
void setBlittable(QBlittable *blittable);
- void resize(int width, int height);
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
- void fill(const QColor &color);
- QImage *buffer();
- QImage toImage() const;
- bool hasAlphaChannel() const;
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- qreal devicePixelRatio() const;
- void setDevicePixelRatio(qreal scaleFactor);
-
- QPaintEngine *paintEngine() const;
+ void resize(int width, int height) Q_DECL_OVERRIDE;
+ int metric(QPaintDevice::PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
+ void fill(const QColor &color) Q_DECL_OVERRIDE;
+ QImage *buffer() Q_DECL_OVERRIDE;
+ QImage toImage() const Q_DECL_OVERRIDE;
+ bool hasAlphaChannel() const Q_DECL_OVERRIDE;
+ void fromImage(const QImage &image, Qt::ImageConversionFlags flags) Q_DECL_OVERRIDE;
+ qreal devicePixelRatio() const Q_DECL_OVERRIDE;
+ void setDevicePixelRatio(qreal scaleFactor) Q_DECL_OVERRIDE;
+
+ QPaintEngine *paintEngine() const Q_DECL_OVERRIDE;
void markRasterOverlay(const QRectF &);
void markRasterOverlay(const QPointF &, const QTextItem &);
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 65e7fb0096..9c9db1c9c1 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -203,9 +203,14 @@ void QRasterPlatformPixmap::fill(const QColor &color)
pixel = qPremultiply(color.rgba());
const QPixelLayout *layout = &qPixelLayouts[image.format()];
layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);
- } else {
+ } else if (image.format() == QImage::Format_Alpha8) {
+ pixel = qAlpha(color.rgba());
+ } else if (image.format() == QImage::Format_Grayscale8) {
+ pixel = qGray(color.rgba());
+ } else
+ {
pixel = 0;
- // ### what about 8 bits
+ // ### what about 8 bit indexed?
}
image.fill(pixel);
diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h
index ffb4b591de..cbbd681314 100644
--- a/src/gui/image/qpixmap_raster_p.h
+++ b/src/gui/image/qpixmap_raster_p.h
@@ -56,28 +56,28 @@ public:
QRasterPlatformPixmap(PixelType type);
~QRasterPlatformPixmap();
- QPlatformPixmap *createCompatiblePlatformPixmap() const;
-
- void resize(int width, int height);
- bool fromData(const uchar *buffer, uint len, const char *format, Qt::ImageConversionFlags flags);
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- void fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags);
- void fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags);
-
- void copy(const QPlatformPixmap *data, const QRect &rect);
- bool scroll(int dx, int dy, const QRect &rect);
- void fill(const QColor &color);
- bool hasAlphaChannel() const;
- QImage toImage() const;
- QImage toImage(const QRect &rect) const;
- QPaintEngine* paintEngine() const;
- QImage* buffer();
- qreal devicePixelRatio() const;
- void setDevicePixelRatio(qreal scaleFactor);
+ QPlatformPixmap *createCompatiblePlatformPixmap() const Q_DECL_OVERRIDE;
+
+ void resize(int width, int height) Q_DECL_OVERRIDE;
+ bool fromData(const uchar *buffer, uint len, const char *format, Qt::ImageConversionFlags flags) Q_DECL_OVERRIDE;
+ void fromImage(const QImage &image, Qt::ImageConversionFlags flags) Q_DECL_OVERRIDE;
+ void fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags) Q_DECL_OVERRIDE;
+ void fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags) Q_DECL_OVERRIDE;
+
+ void copy(const QPlatformPixmap *data, const QRect &rect) Q_DECL_OVERRIDE;
+ bool scroll(int dx, int dy, const QRect &rect) Q_DECL_OVERRIDE;
+ void fill(const QColor &color) Q_DECL_OVERRIDE;
+ bool hasAlphaChannel() const Q_DECL_OVERRIDE;
+ QImage toImage() const Q_DECL_OVERRIDE;
+ QImage toImage(const QRect &rect) const Q_DECL_OVERRIDE;
+ QPaintEngine* paintEngine() const Q_DECL_OVERRIDE;
+ QImage* buffer() Q_DECL_OVERRIDE;
+ qreal devicePixelRatio() const Q_DECL_OVERRIDE;
+ void setDevicePixelRatio(qreal scaleFactor) Q_DECL_OVERRIDE;
protected:
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
+ int metric(QPaintDevice::PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
void createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace);
void setImage(const QImage &image);
QImage image;
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 170a295cf8..d4b5cee74c 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -159,7 +159,7 @@ public:
QPMCache();
~QPMCache();
- void timerEvent(QTimerEvent *);
+ void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
bool insert(const QString& key, const QPixmap &pixmap, int cost);
QPixmapCache::Key insert(const QPixmap &pixmap, int cost);
bool replace(const QPixmapCache::Key &key, const QPixmap &pixmap, int cost);
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 17a0dd3eb9..c19bc52a97 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -157,10 +157,6 @@ public:
};
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
class QPNGImageWriter {
public:
explicit QPNGImageWriter(QIODevice*);
@@ -190,6 +186,7 @@ private:
float gamma;
};
+extern "C" {
static
void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
{
@@ -234,9 +231,7 @@ void CALLBACK_CALL_TYPE qpiw_flush_fn(png_structp /* png_ptr */)
{
}
-#if defined(Q_C_CALLBACKS)
}
-#endif
static
void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0)
@@ -295,6 +290,15 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
png_set_swap_alpha(png_ptr);
png_read_update_info(png_ptr, info_ptr);
+ } else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ png_set_expand(png_ptr);
+ if (image.size() != QSize(width, height) || image.format() != QImage::Format_Grayscale8) {
+ image = QImage(width, height, QImage::Format_Grayscale8);
+ if (image.isNull())
+ return;
+ }
+
+ png_read_update_info(png_ptr, info_ptr);
} else {
if (bit_depth == 16)
png_set_strip_16(png_ptr);
@@ -483,17 +487,13 @@ static void read_image_scaled(QImage *outImage, png_structp png_ptr, png_infop i
}
-#if defined(Q_C_CALLBACKS)
extern "C" {
-#endif
static void CALLBACK_CALL_TYPE qt_png_warning(png_structp /*png_ptr*/, png_const_charp message)
{
qWarning("libpng warning: %s", message);
}
-#if defined(Q_C_CALLBACKS)
}
-#endif
void Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngTexts(png_info *info)
@@ -666,6 +666,8 @@ QImage::Format QPngHandlerPrivate::readImageFormat()
format = QImage::Format_Mono;
} else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
format = QImage::Format_ARGB32;
+ } else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ format = QImage::Format_Grayscale8;
} else {
format = QImage::Format_Indexed8;
}
@@ -857,6 +859,8 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo
else
color_type = PNG_COLOR_TYPE_PALETTE;
}
+ else if (image.format() == QImage::Format_Grayscale8)
+ color_type = PNG_COLOR_TYPE_GRAY;
else if (image.hasAlphaChannel())
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
else
@@ -955,6 +959,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo
case QImage::Format_Mono:
case QImage::Format_MonoLSB:
case QImage::Format_Indexed8:
+ case QImage::Format_Grayscale8:
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_RGB888:
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 314abca9f0..e1c76cce7f 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -122,7 +122,7 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
case '2': // ascii PGM
case '5': // raw PGM
nbits = 8;
- format = QImage::Format_Indexed8;
+ format = QImage::Format_Grayscale8;
break;
case '3': // ascii PPM
case '6': // raw PPM
@@ -200,13 +200,13 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
*p++ = b;
}
} else if (nbits == 8) {
- if (mcc == maxc) {
+ if (mcc == 255) {
while (n--) {
*p++ = read_pbm_int(device);
}
} else {
while (n--) {
- *p++ = read_pbm_int(device) * maxc / mcc;
+ *p++ = read_pbm_int(device) * 255 / mcc;
}
}
} else { // 32 bits
@@ -233,14 +233,10 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
}
}
- if (nbits == 1) { // bitmap
+ if (format == QImage::Format_Mono) {
outImage->setColorCount(2);
- outImage->setColor(0, qRgb(255,255,255)); // white
- outImage->setColor(1, qRgb(0,0,0)); // black
- } else if (nbits == 8) { // graymap
- outImage->setColorCount(maxc+1);
- for (int i=0; i<=maxc; i++)
- outImage->setColor(i, qRgb(i*255/maxc,i*255/maxc,i*255/maxc));
+ outImage->setColor(0, qRgb(255,255,255)); // white
+ outImage->setColor(1, qRgb(0,0,0)); // black
}
return true;
@@ -257,6 +253,8 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
if (format == "pbm") {
image = image.convertToFormat(QImage::Format_Mono);
+ } else if (gray) {
+ image = image.convertToFormat(QImage::Format_Grayscale8);
} else {
switch (image.format()) {
case QImage::Format_Mono:
@@ -317,63 +315,77 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
str.append("255\n");
if (out->write(str, str.length()) != str.length())
return false;
- QVector<QRgb> color = image.colorTable();
- uint bpl = w*(gray ? 1 : 3);
- uchar *buf = new uchar[bpl];
- for (uint y=0; y<h; y++) {
- uchar *b = image.scanLine(y);
- uchar *p = buf;
- uchar *end = buf+bpl;
- if (gray) {
- while (p < end) {
- uchar g = (uchar)qGray(color[*b++]);
- *p++ = g;
+ uint bpl = w * (gray ? 1 : 3);
+ uchar *buf = new uchar[bpl];
+ if (image.format() == QImage::Format_Indexed8) {
+ QVector<QRgb> color = image.colorTable();
+ for (uint y=0; y<h; y++) {
+ uchar *b = image.scanLine(y);
+ uchar *p = buf;
+ uchar *end = buf+bpl;
+ if (gray) {
+ while (p < end) {
+ uchar g = (uchar)qGray(color[*b++]);
+ *p++ = g;
+ }
+ } else {
+ while (p < end) {
+ QRgb rgb = color[*b++];
+ *p++ = qRed(rgb);
+ *p++ = qGreen(rgb);
+ *p++ = qBlue(rgb);
+ }
}
- } else {
- while (p < end) {
- QRgb rgb = color[*b++];
- *p++ = qRed(rgb);
- *p++ = qGreen(rgb);
- *p++ = qBlue(rgb);
+ if (bpl != (uint)out->write((char*)buf, bpl))
+ return false;
+ }
+ } else {
+ for (uint y=0; y<h; y++) {
+ uchar *b = image.scanLine(y);
+ uchar *p = buf;
+ uchar *end = buf + bpl;
+ if (gray) {
+ while (p < end)
+ *p++ = *b++;
+ } else {
+ while (p < end) {
+ uchar color = *b++;
+ *p++ = color;
+ *p++ = color;
+ *p++ = color;
+ }
}
+ if (bpl != (uint)out->write((char*)buf, bpl))
+ return false;
}
- if (bpl != (uint)out->write((char*)buf, bpl))
- return false;
}
delete [] buf;
- }
break;
+ }
case 32: {
- str.insert(1, gray ? '5' : '6');
+ str.insert(1, '6');
str.append("255\n");
if (out->write(str, str.length()) != str.length())
return false;
- uint bpl = w*(gray ? 1 : 3);
+ uint bpl = w * 3;
uchar *buf = new uchar[bpl];
for (uint y=0; y<h; y++) {
QRgb *b = (QRgb*)image.scanLine(y);
uchar *p = buf;
uchar *end = buf+bpl;
- if (gray) {
- while (p < end) {
- uchar g = (uchar)qGray(*b++);
- *p++ = g;
- }
- } else {
- while (p < end) {
- QRgb rgb = *b++;
- *p++ = qRed(rgb);
- *p++ = qGreen(rgb);
- *p++ = qBlue(rgb);
- }
+ while (p < end) {
+ QRgb rgb = *b++;
+ *p++ = qRed(rgb);
+ *p++ = qGreen(rgb);
+ *p++ = qBlue(rgb);
}
if (bpl != (uint)out->write((char*)buf, bpl))
return false;
}
delete [] buf;
- }
break;
+ }
default:
return false;
@@ -488,11 +500,11 @@ QVariant QPpmHandler::option(ImageOption option) const
switch (type) {
case '1': // ascii PBM
case '4': // raw PBM
- format = QImage::Format_Mono;
- break;
+ format = QImage::Format_Mono;
+ break;
case '2': // ascii PGM
case '5': // raw PGM
- format = QImage::Format_Indexed8;
+ format = QImage::Format_Grayscale8;
break;
case '3': // ascii PPM
case '6': // raw PPM