1#include <math.h>
2
3#include "pixman.h"
4#include "gtk-utils.h"
5
6static uint32_t
7linear_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
21static float
22lin2srgb (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
30static uint32_t
31linear_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
45int
46main (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