[Pixman] Op. when compositing

Eric Nicolas erik.nicolas at gmail.com
Thu Jun 12 23:08:50 PDT 2014


Thanks so much. It works perfectly now. 
May I suggest the following modification in pixman.h so that it is clear for all users ?

/*
* Important note: pixman colors are alpha-premultiplied
* and must conform: red <= alpha ; green <= alpha ; blue <= alpha
* So that for instance pure white with 0x80 alpha should
 * be r=0x80, g=0x80, b=0x80, a=0x80
*/
struct pixman_color
{
    uint16_t          red;
    uint16_t    green;
    uint16_t    blue;
    uint16_t    alpha;
};

Thanks

> Le 12 juin 2014 à 17:01, soren.sandmann at gmail.com (Søren Sandmann) a écrit :
> 
> Eric Nicolas <erik.nicolas at gmail.com> writes:
> 
>> Hello, Thanks for your answer.
>> 
>> Below is a small test program (works on little endian machines).
>> 
>> As is the result is already strange to me :
>>     in: r=20 g=20 b=80 a=FF
>>     out: r=90 g=90 b=C0 a=FF
>> Where as I expected the fill color #FFFFFFFF x the mask 0x80 = #FFFFFF80
>> and so an output of #9090FFFF.
>> 
>> However, if I set the fill color to #FFFFFF80, the result seems really
>> wrong :
>> in: r=20 g=20 b=80 a=FF
>> out: r=98 g=98 b=E0 a=FF
>> 
>> I would expect fill x mask => #FFFFFF40 and thus out: #606060C0FF.
>> 
>> I especially do not understand how a lower alpha input color can end up in
>> a lighter output on the target image.
>> 
>> What I am doing wrong here ?
> 
> The thing you are missing is that Pixman works with premultiplied
> alpha. That is, if the rgb values are R, G, and B, and the alpha value
> is A, then pixman will assume that pixels are stored as
> 
>   R * A, G * A, B * A, A
> 
> and it will also generate pixels in this format. The reason for doing
> this is that it avoids divisions when compositing.
> 
> When you set the fill value to 0xffffff80 pixman will interprete it as 
> 
>     (1.0 / 0.5), (1.0 / 0.5), (1.0 / 0.5), 0.5
> 
>   = (2, 2, 2, 0.5)
> 
> ie., you get out-of-range color values, which is why the result will be
> lighter. Normally, the alpha value in premultiplied pixels should not be
> bigger than the color values, though it can occasionally be useful.
> 
> Premultiplied alpha also means that when applying an alpha mask, it must
> be applied to all four channels, so in this case you get
> 
>   0xffffff80 x 0x80 = 0x80808040
> 
> when applying the mask.
> 
> 
> Søren
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/pixman/attachments/20140613/34fa54bb/attachment.html>


More information about the Pixman mailing list