summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-12-03 15:15:19 +0100
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-12-04 09:54:39 +0000
commitc04e7dead8bee51e11698fe1c625c76915a60753 (patch)
treee42259c20a7b33ca2558bbabc0998f758608e692
parent2366ecfb2dbf96eda8fa77d1f8cb484d80b52642 (diff)
QImage pixelColor and setPixelColor must use unpremultiplied QColor
QColor always uses unpremultiplied alpha, but the new QImage methods were based on the QRgb versions which might be either. This patches fixes the two new methods so they treat QColor alpha correctly. Change-Id: I78a5b875ad4e78ad7fde3b811c6187482b4f6d15 Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
-rw-r--r--src/gui/image/qimage.cpp30
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp18
2 files changed, 40 insertions, 8 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 798002224a..a992ad6fea 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -2380,17 +2380,25 @@ QColor QImage::pixelColor(int x, int y) const
return QColor();
}
+ QRgba64 c;
const uchar * s = constScanLine(y);
switch (d->format) {
case Format_BGR30:
case Format_A2BGR30_Premultiplied:
- return QColor(qConvertA2rgb30ToRgb64<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]));
+ c = qConvertA2rgb30ToRgb64<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]);
+ break;
case Format_RGB30:
case Format_A2RGB30_Premultiplied:
- return QColor(qConvertA2rgb30ToRgb64<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]));
+ c = qConvertA2rgb30ToRgb64<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
+ break;
default:
- return QColor(pixel(x, y));
+ c = QRgba64::fromArgb32(pixel(x, y));
+ break;
}
+ // QColor is always unpremultiplied
+ if (hasAlphaChannel() && qPixelLayouts[d->format].premultiplied)
+ c = c.unpremultiplied();
+ return QColor(c);
}
/*!
@@ -2421,6 +2429,12 @@ void QImage::setPixelColor(int x, int y, const QColor &color)
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) {
@@ -2430,19 +2444,19 @@ void QImage::setPixelColor(int x, int y, const QColor &color)
qWarning("QImage::setPixelColor: called on monochrome or indexed format");
return;
case Format_BGR30:
- ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(color.rgba64()) | 0xc0000000;
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c) | 0xc0000000;
return;
case Format_A2BGR30_Premultiplied:
- ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(color.rgba64());
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c);
return;
case Format_RGB30:
- ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(color.rgba64()) | 0xc0000000;
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c) | 0xc0000000;
return;
case Format_A2RGB30_Premultiplied:
- ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(color.rgba64());
+ ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c);
return;
default:
- setPixel(x, y, color.rgba());
+ setPixel(x, y, c.toArgb32());
return;
}
}
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 5574a92ad9..23ddfbdd58 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -196,6 +196,8 @@ private slots:
void metadataPassthrough();
+ void pixelColor();
+
private:
const QString m_prefix;
};
@@ -3020,5 +3022,21 @@ void tst_QImage::metadataPassthrough()
QCOMPARE(swapped.devicePixelRatio(), a.devicePixelRatio());
}
+void tst_QImage::pixelColor()
+{
+ QImage argb32(1, 1, QImage::Format_ARGB32);
+ QImage argb32pm(1, 1, QImage::Format_ARGB32_Premultiplied);
+
+ QColor c(Qt::red);
+ c.setAlpha(128);
+ argb32.setPixelColor(QPoint(0, 0), c);
+ argb32pm.setPixelColor(QPoint(0, 0), c);
+ QCOMPARE(argb32.pixelColor(QPoint(0, 0)), c);
+ QCOMPARE(argb32pm.pixelColor(QPoint(0, 0)), c);
+
+ QImage t = argb32.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ QCOMPARE(t.pixel(0,0), argb32pm.pixel(0,0));
+}
+
QTEST_GUILESS_MAIN(tst_QImage)
#include "tst_qimage.moc"