1 #include <math.h>
2 
3 #include "pixman.h"
4 #include "gtk-utils.h"
5 
6 static uint32_t
linear_argb_to_premult_argb(float a,float r,float g,float b)7 linear_argb_to_premult_argb (float a,
8 			     float r,
9 			     float g,
10 			     float b)
11 {
12     r *= a;
13     g *= a;
14     b *= a;
15     return (uint32_t) (a * 255.0f + 0.5f) << 24
16 	 | (uint32_t) (r * 255.0f + 0.5f) << 16
17 	 | (uint32_t) (g * 255.0f + 0.5f) <<  8
18 	 | (uint32_t) (b * 255.0f + 0.5f) <<  0;
19 }
20 
21 static float
lin2srgb(float linear)22 lin2srgb (float linear)
23 {
24     if (linear < 0.0031308f)
25 	return linear * 12.92f;
26     else
27 	return 1.055f * powf (linear, 1.0f/2.4f) - 0.055f;
28 }
29 
30 static uint32_t
linear_argb_to_premult_srgb_argb(float a,float r,float g,float b)31 linear_argb_to_premult_srgb_argb (float a,
32 				  float r,
33 				  float g,
34 				  float b)
35 {
36     r = lin2srgb (r * a);
37     g = lin2srgb (g * a);
38     b = lin2srgb (b * a);
39     return (uint32_t) (a * 255.0f + 0.5f) << 24
40 	 | (uint32_t) (r * 255.0f + 0.5f) << 16
41 	 | (uint32_t) (g * 255.0f + 0.5f) <<  8
42 	 | (uint32_t) (b * 255.0f + 0.5f) <<  0;
43 }
44 
45 int
main(int argc,char ** argv)46 main (int argc, char **argv)
47 {
48 #define WIDTH 400
49 #define HEIGHT 200
50     int y, x, p;
51     float alpha;
52 
53     uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
54     uint32_t *src1 = malloc (WIDTH * HEIGHT * 4);
55     pixman_image_t *dest_img, *src1_img;
56 
57     dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8_sRGB,
58 					 WIDTH, HEIGHT,
59 					 dest,
60 					 WIDTH * 4);
61     src1_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
62 					 WIDTH, HEIGHT,
63 					 src1,
64 					 WIDTH * 4);
65 
66     for (y = 0; y < HEIGHT; y ++)
67     {
68 	p = WIDTH * y;
69 	for (x = 0; x < WIDTH; x ++)
70 	{
71 	     alpha = (float) x / WIDTH;
72 	     src1[p + x] = linear_argb_to_premult_argb (alpha, 1, 0, 1);
73 	     dest[p + x] = linear_argb_to_premult_srgb_argb (1-alpha, 0, 1, 0);
74 	}
75     }
76 
77     pixman_image_composite (PIXMAN_OP_ADD, src1_img, NULL, dest_img,
78 			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
79     pixman_image_unref (src1_img);
80     free (src1);
81 
82     show_image (dest_img);
83     pixman_image_unref (dest_img);
84     free (dest);
85 
86     return 0;
87 }
88