diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-01-23 16:09:20 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-29 08:54:55 +0100 |
commit | 0226795cf33363a872c777034e0d8934ffaa3819 (patch) | |
tree | e65b5dac925c965754ac03928e54ec566504ec2b /src/gui/painting/qdrawhelper_p.h | |
parent | fa83803119296c2224cf1c7fb7474057a77aa51b (diff) |
Round evenly in INV_PREMUL
Currently INV_PREMUL rounds strictly down. While PREMUL rounds evenly.
This patch adds 0x8000 to the intermediate results in INV_PREMUL before
right shifting, thereby achieving even rounding.
The rounding also makes PREMUL(INV_PREMUL()) into an identify operation,
which means we can safely convert ARGB32PM to ARGB32 and back without
ever losing color details. A test is added to verify this.
Change-Id: I1267e109caddcff0c01d726cb5c1c1e9fa5f7996
Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
Diffstat (limited to 'src/gui/painting/qdrawhelper_p.h')
-rw-r--r-- | src/gui/painting/qdrawhelper_p.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 3c945338a6..0f98b07229 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -699,7 +699,8 @@ static Q_ALWAYS_INLINE uint INV_PREMUL(uint p) { return 0; // (p*(0x00ff00ff/alpha)) >> 16 == (p*255)/alpha for all p and alpha <= 256. const uint invAlpha = 0x00ff00ffU / alpha; - return qRgba((qRed(p)*invAlpha)>>16, (qGreen(p)*invAlpha)>>16, (qBlue(p)*invAlpha)>>16, alpha); + // We add 0x8000 to get even rounding. The rounding also ensures that PREMUL(INV_PREMUL(p)) == p for all p. + return qRgba((qRed(p)*invAlpha + 0x8000)>>16, (qGreen(p)*invAlpha + 0x8000)>>16, (qBlue(p)*invAlpha + 0x8000)>>16, alpha); } struct quint24 { |