Correct use of qt_div_255

qt_div_255 does a fast rounded division, the form of rounding is however
only valid for positive integers.

Correct one case where it was used incorrectly and add it one place
it would be valid, and adds a comment to the function.

We were using the optimization (x*a + y*(255-a))/255 ==
(x-y)*a/255 + y but that makes the division by 255 potentially
negative.

Change-Id: Ie53aa82b66ef801f5d43f8d2ec48880cb4972f69
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Allan Sandfeld Jensen 2016-08-24 15:19:43 +02:00 committed by Allan Sandfeld Jensen
parent 882f344964
commit 68c2bf1a1a
2 changed files with 7 additions and 6 deletions

View File

@ -5754,9 +5754,9 @@ static inline void rgbBlendPixel(quint32 *dst, int coverage, int sr, int sg, int
dg = gamma[dg];
db = gamma[db];
int nr = qt_div_255((sr - dr) * mr) + dr;
int ng = qt_div_255((sg - dg) * mg) + dg;
int nb = qt_div_255((sb - db) * mb) + db;
int nr = qt_div_255(sr * mr + dr * (255 - mr));
int ng = qt_div_255(sg * mg + dg * (255 - mg));
int nb = qt_div_255(sb * mb + db * (255 - mb));
nr = invgamma[nr];
ng = invgamma[ng];
@ -5781,9 +5781,9 @@ static inline void grayBlendPixel(quint32 *dst, int coverage, int sr, int sg, in
int alpha = coverage;
int ialpha = 255 - alpha;
int nr = (sr * alpha + ialpha * dr) / 255;
int ng = (sg * alpha + ialpha * dg) / 255;
int nb = (sb * alpha + ialpha * db) / 255;
int nr = qt_div_255(sr * alpha + dr * ialpha);
int ng = qt_div_255(sg * alpha + dg * ialpha);
int nb = qt_div_255(sb * alpha + db * ialpha);
nr = invgamma[nr];
ng = invgamma[ng];

View File

@ -705,6 +705,7 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) {
return t;
}
// qt_div_255 is a fast rounded division by 255 using an approximation that is accurate for all positive 16-bit integers
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; }