Premultiplication methods produce slightly incorrect results
Categories
(Core :: Graphics, defect, P2)
Tracking
()
People
(Reporter: aosmond, Assigned: aosmond)
Details
Currently to premultiply the alpha to the RB components, we use the following algorithm:
rb = rb*a + 255
rb += rb >> 8
This was intended to be distilled from GFX_DIVIDE_BY_255 and gfxPremultiply which maps to, where v = individual color component:
(va << 8 + va + 255) >> 16
This requires at least 24-bits for our integers which isn't directly workable with SSE2 given we are using 16-bit integers. However with slight manipulation, we go to:
(va + (va + 255) >> 8) >> 8
va maximum is 255 * 255, which fits in 16-bits.
va + 255 maximum is 255 * 255 + 255, or 256 * 255 which also fits in 16-bits.
Mapping this back to the accelerated premultiplication methods, I would expect to see:
rb = rb*a
rb += (rb + 255) >> 8
This produces the correct result for me, and allows us to remove all sorts of fuzz I added as well as produce the actual correct results :).
| Assignee | ||
Comment 1•6 years ago
|
||
Discussing further with Jeff, it appears neither is what we would expect. Things are written with the expectation of integer truncation, but Jeff's assertion is that we should be rounding. This boils down to just changing the 255 in the original algorithm to 128:
rb = rb*a + 128
rb += rb >> 8
| Assignee | ||
Comment 2•6 years ago
|
||
Updated•3 years ago
|
Description
•