diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-06-30 13:26:25 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-08-11 09:33:06 +0000 |
commit | 55512950281260b85ea40c08239e459c76b696d2 (patch) | |
tree | 98faefc98c2d7e81b65517d36ccfecfed9a79240 /src/gui/painting/qdrawhelper_p.h | |
parent | 49ea02f435876d514898d587700a21e1a8972f09 (diff) |
Fix repremultiply from RGB64 to RGB30
Just like from RGB32 to RGB30 we must also repremultiply when converting
from RGB64 because the alpha channel loses more precision than the other
color channels.
Since this is not approximated accurately in the simple blending
functions and the functions are no longer needed now the main render
engine supports higher accuracy, the simple blending routines for RGB30
have been removed.
Change-Id: I2b7b8eb015e330a487848fc4370ad3a1e966be91
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 | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 2c222b97c2..0034bfdf91 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -712,18 +712,6 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) { static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; } static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; } -static Q_ALWAYS_INLINE uint BYTE_MUL_RGB30(uint x, uint a) { - uint xa = x >> 30; - uint xr = (x >> 20) & 0x3ff; - uint xg = (x >> 10) & 0x3ff; - uint xb = x & 0x3ff; - xa = qt_div_255(xa * a); - xr = qt_div_255(xr * a); - xg = qt_div_255(xg * a); - xb = qt_div_255(xb * a); - return (xa << 30) | (xr << 20) | (xg << 10) | xb; -} - static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c) { uint a = c >> 30; @@ -897,6 +885,18 @@ inline QRgb qRepremultiply(QRgb p) return qPremultiply(p); } +template<unsigned int Shift> +inline QRgba64 qRepremultiply(QRgba64 p) +{ + const uint alpha = p.alpha(); + if (alpha == 65535 || alpha == 0) + return p; + p = p.unpremultiplied(); + Q_CONSTEXPR uint mult = 65535 / (65535 >> Shift); + p.setAlpha(mult * (alpha >> Shift)); + return p.premultiplied(); +} + template<> inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c) { @@ -1000,6 +1000,7 @@ template<enum QtPixelOrder> inline unsigned int qConvertRgb64ToRgb30(QRgba64); template<> inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c) { + c = qRepremultiply<14>(c); const uint a = c.alpha() >> 14; const uint r = c.red() >> 6; const uint g = c.green() >> 6; @@ -1010,6 +1011,7 @@ inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c) template<> inline unsigned int qConvertRgb64ToRgb30<PixelOrderRGB>(QRgba64 c) { + c = qRepremultiply<14>(c); const uint a = c.alpha() >> 14; const uint r = c.red() >> 6; const uint g = c.green() >> 6; |