[Pixman] Op. when compositing
Eric Nicolas
erik.nicolas at gmail.com
Wed Jun 11 13:53:05 PDT 2014
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 ?
Thanks.
#include <stdlib.h>
#include <stdio.h>
union C {
uint32_t value;
struct RGBA8888 {
uint8_t a;
uint8_t b;
uint8_t g;
uint8_t r;
} rgba;
};
void testPixmapOps()
{
// create target image full with r=0x20 g=0x20 b=0x80 a=0xFF
size_t w = 100; // multiple of 4 for alignment
size_t h = 100;
C *target = (C*)malloc(w * h * sizeof(C));
for(size_t i = 0; i < w * h; ++i)
target[i].value = 0x202080FF;
printf("in: r=%02X g=%02X b=%02X a=%02X\n",
target[0].rgba.r, target[0].rgba.g, target[0].rgba.b, target[0].rgba
.a);
// connect target to pixman image
pixman_image_t *ptarget = pixman_image_create_bits(PIXMAN_r8g8b8a8, w,
h, (uint32_t*)target, w * sizeof(uint32_t));
// create fill
pixman_color_t cfill;
cfill.red = uint16_t(0xFF) << 8;
cfill.green = uint16_t(0xFF) << 8;
cfill.blue = uint16_t(0xFF) << 8;
cfill.alpha = uint16_t(0xFF) << 8;
pixman_image_t *pfill = pixman_image_create_solid_fill(&cfill);
// create mask with a=0x80
uint8_t *mask = (uint8_t*)malloc(w * h);
for(size_t i = 0; i < w * h; ++i)
mask[i] = 0x80;
pixman_image_t *pmask = pixman_image_create_bits(PIXMAN_a8, w, h, (
uint32_t*)mask, w);
// do compositing
pixman_image_composite(
PIXMAN_OP_OVER,
pfill, pmask, ptarget,
// src_x, src_y
0, 0,
// mask_x, mask_y
0, 0,
// dest_x, dest_y, width, height
0, 0, w, h);
// display one pixel of target
printf("out: r=%02X g=%02X b=%02X a=%02X\n",
target[0].rgba.r, target[0].rgba.g, target[0].rgba.b, target[0].rgba
.a);
}
2014-06-11 21:49 GMT+02:00 Søren Sandmann <soren.sandmann at gmail.com>:
> Eric Nicolas <erik.nicolas at gmail.com> writes:
>
> > Hello,
> >
> > I have a question about the OP modes when compositing with Pixman. I had
> a look at the source code, but this part of the code is quite complex, so I
> couldn’t find the answer there.
> >
> > What I would like to do is :
> > - Use a plain color via a pixman_image_create_solid_fill on a
> RGBA color ;
> > - Use a PIXMAN_a8 mask ;
> > - Modify a target PIXMAN_r8g8b8a8 image.
> > So I do a pixman_image_composite(OP, fill, mask, target, …).
> >
> > My problem is that I cannot find an OP which would allow me to blend
> fill and mask together into target. I mean if ‘fill’ color has an alpha
> (for instance 0x80), mask is also an alpha (for instance 0x80), I expect
> the target to be blent with the color modified with an alpha of 0x40 (full
> fill color x mask alpha => blent to target).
> >
> > The closest I found is PIXMAN_OP_ATOP, but it always use the RGB from
> > the fill color and the A from the mask, it never blends the color with
> > the mask before compositing onto the target.
>
> The PIXMAN_OP_OVER operator used with a solid color, a PIXMAN_a8 mask
> and a PIXMAN_r8g8b8a8 target will multiply the fill color with the pixel
> from the a8 mask and then blend the result onto the target image.
>
> But maybe this is not what you want to do. If not, it might be helpful
> if you could post images showing what you would like to get, and what
> you are getting.
>
>
> Søren
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/pixman/attachments/20140611/4b9b7665/attachment.html>
More information about the Pixman
mailing list