[cairo] On multiplying alpha

Behdad Esfahbod behdad at behdad.org
Fri Feb 1 18:00:27 PST 2008


On Fri, 2008-02-01 at 20:07 -0500, Jeff Muizelaar wrote:
> On Fri, Feb 01, 2008 at 07:26:16PM -0500, Behdad Esfahbod wrote:
> > I wrote some code about how to go from premultiplied alpha to multiplied
> > alpha formats.  Thought people here may be interested to review:
> > 
> >   http://bugzilla.gnome.org/show_bug.cgi?id=513812
> 
> Yeah, that code looks wrong. It should be:
> 
> t = a*c + 0x80;
> r = ((t>>8) + t) >> 8;
> 
> If you're interested in the derivation it's in the article:
> "Jim Blinn's Corner: Three wrongs make a right"
> 
> Furthermore, the standard way of multiplying a 32bit pixel by alpha is what FbByteMul does.
> It should be faster than the method you propose.
> 
> #define FbByteMul(x, a) do {     
>         uint32_t t = ((x & 0xff00ff) * a) + 0x800080;               \
>         t = (t + ((t >> 8) & 0xff00ff)) >> 8;                       \
>         t &= 0xff00ff;                                              \
>                                                                     \
>         x = (((x >> 8) & 0xff00ff) * a) + 0x800080;                 \
>         x = (x + ((x >> 8) & 0xff00ff));                            \
>         x &= 0xff00ff00;                                            \
>         x += t;

Nice trick.  Thanks!

So, on whole pixels that means:

  Fb: 2 mul, 15 add/shift/and

mine: 3 mul, 10 add/shift
  or: 4 mul,  6 add/shift

Interesting to see on which hardware which means what.  The best one in
a particular case also depends on how much packing/unpacking you'd need
to do too of course.

> -Jeff
-- 
behdad
http://behdad.org/

"Those who would give up Essential Liberty to purchase a little
 Temporary Safety, deserve neither Liberty nor Safety."
        -- Benjamin Franklin, 1759



More information about the cairo mailing list