diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-05-06 14:23:57 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-06-03 12:01:26 +0000 |
commit | 8f760808e0fe0fe6dd89d561f118b19ed8085e7a (patch) | |
tree | 8cc259b6098d83b91b6ec8ac22745546947860c7 /src/gui/painting/qdrawhelper_p.h | |
parent | 754efa57d89c62d1796e01b407e9222e67450f52 (diff) |
Fix premul conversion from ARGB32 to A2RGB30 formats.
When a premultiplied alpha changes value because it is rounded to fewer
bits the premultiplied colors may need to be recalculated with the new
value. Otherwise the color will both be wrong and potentially invalid.
Change-Id: I9ec74a22aac73cd7ffab04e180cf2bf35bb4c315
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Diffstat (limited to 'src/gui/painting/qdrawhelper_p.h')
-rw-r--r-- | src/gui/painting/qdrawhelper_p.h | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 66ef5949d9..73ff21812a 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -847,9 +847,25 @@ template<enum QtPixelOrder> inline uint qConvertRgb32ToRgb30(QRgb); template<enum QtPixelOrder> inline QRgb qConvertA2rgb30ToArgb32(uint c); +// A combined unpremultiply and premultiply with new simplified alpha. +// Needed when alpha loses precision relative to other colors during conversion (ARGB32 -> A2RGB30). +template<unsigned int Shift> +inline QRgb qRepremultiply(QRgb p) +{ + const uint alpha = qAlpha(p); + if (alpha == 255 || alpha == 0) + return p; + p = qUnpremultiply(p); + Q_CONSTEXPR uint mult = 255 / (255 >> Shift); + const uint newAlpha = mult * (alpha >> Shift); + p = (p & ~0xff000000) | (newAlpha<<24); + return qPremultiply(p); +} + template<> inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c) { + c = qRepremultiply<6>(c); return (c & 0xc0000000) | (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000)) | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) @@ -859,6 +875,7 @@ inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c) template<> inline uint qConvertArgb32ToA2rgb30<PixelOrderRGB>(QRgb c) { + c = qRepremultiply<6>(c); return (c & 0xc0000000) | (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000)) | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) |