MIPS: DSPr2: Added mips_dspr2_blt and mips_dspr2_fill routines.
[profile/ivi/pixman.git] / test / alphamap.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "utils.h"
4
5 #define WIDTH 48
6 #define HEIGHT 48
7
8 static const pixman_format_code_t formats[] =
9 {
10     PIXMAN_a8r8g8b8,
11     PIXMAN_a2r10g10b10,
12     PIXMAN_a4r4g4b4,
13     PIXMAN_a8
14 };
15
16 static const pixman_format_code_t alpha_formats[] =
17 {
18     PIXMAN_null,
19     PIXMAN_a8,
20     PIXMAN_a2r10g10b10,
21     PIXMAN_a4r4g4b4
22 };
23
24 static const int origins[] =
25 {
26     0, 10, -100
27 };
28
29 static const char *
30 format_name (pixman_format_code_t format)
31 {
32     if (format == PIXMAN_a8)
33         return "a8";
34     else if (format == PIXMAN_a2r10g10b10)
35         return "a2r10g10b10";
36     else if (format == PIXMAN_a8r8g8b8)
37         return "a8r8g8b8";
38     else if (format == PIXMAN_a4r4g4b4)
39         return "a4r4g4b4";
40     else if (format == PIXMAN_null)
41         return "none";
42     else
43         assert (0);
44
45     return "<unknown - bug in alphamap.c>";
46 }
47
48 static void
49 on_destroy (pixman_image_t *image, void *data)
50 {
51     uint32_t *bits = pixman_image_get_data (image);
52
53     fence_free (bits);
54 }
55
56 static pixman_image_t *
57 make_image (pixman_format_code_t format)
58 {
59     uint32_t *bits;
60     uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8;
61     pixman_image_t *image;
62
63     bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
64
65     image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp);
66
67     if (image && bits)
68         pixman_image_set_destroy_function (image, on_destroy, NULL);
69
70     return image;
71 }
72
73 static uint8_t
74 get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
75 {
76     uint8_t *bits;
77     uint8_t r;
78
79     if (image->common.alpha_map)
80     {
81         if (x - orig_x >= 0 && x - orig_x < WIDTH &&
82             y - orig_y >= 0 && y - orig_y < HEIGHT)
83         {
84             image = (pixman_image_t *)image->common.alpha_map;
85
86             x -= orig_x;
87             y -= orig_y;
88         }
89         else
90         {
91             return 0;
92         }
93     }
94
95     bits = (uint8_t *)image->bits.bits;
96
97     if (image->bits.format == PIXMAN_a8)
98     {
99         r = bits[y * WIDTH + x];
100     }
101     else if (image->bits.format == PIXMAN_a2r10g10b10)
102     {
103         r = ((uint32_t *)bits)[y * WIDTH + x] >> 30;
104         r |= r << 2;
105         r |= r << 4;
106     }
107     else if (image->bits.format == PIXMAN_a8r8g8b8)
108     {
109         r = ((uint32_t *)bits)[y * WIDTH + x] >> 24;
110     }
111     else if (image->bits.format == PIXMAN_a4r4g4b4)
112     {
113         r = ((uint16_t *)bits)[y * WIDTH + x] >> 12;
114         r |= r << 4;
115     }
116     else
117     {
118         assert (0);
119     }
120
121     return r;
122 }
123
124 static uint16_t
125 get_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
126 {
127     uint8_t *bits;
128     uint16_t r;
129
130     bits = (uint8_t *)image->bits.bits;
131
132     if (image->bits.format == PIXMAN_a8)
133     {
134         r = 0x00;
135     }
136     else if (image->bits.format == PIXMAN_a2r10g10b10)
137     {
138         r = ((uint32_t *)bits)[y * WIDTH + x] >> 14;
139         r &= 0xffc0;
140         r |= (r >> 10);
141     }
142     else if (image->bits.format == PIXMAN_a8r8g8b8)
143     {
144         r = ((uint32_t *)bits)[y * WIDTH + x] >> 16;
145         r &= 0xff;
146         r |= r << 8;
147     }
148     else if (image->bits.format == PIXMAN_a4r4g4b4)
149     {
150         r = ((uint16_t *)bits)[y * WIDTH + x] >> 8;
151         r &= 0xf;
152         r |= r << 4;
153         r |= r << 8;
154     }
155     else
156     {
157         assert (0);
158     }
159
160     return r;
161 }
162
163 static int
164 run_test (int s, int d, int sa, int da, int soff, int doff)
165 {
166     pixman_format_code_t sf = formats[s];
167     pixman_format_code_t df = formats[d];
168     pixman_format_code_t saf = alpha_formats[sa];
169     pixman_format_code_t daf = alpha_formats[da];
170     pixman_image_t *src, *dst, *orig_dst, *alpha, *orig_alpha;
171     pixman_transform_t t1;
172     int j, k;
173     int n_alpha_bits, n_red_bits;
174
175     soff = origins[soff];
176     doff = origins[doff];
177
178     n_alpha_bits = PIXMAN_FORMAT_A (df);
179     if (daf != PIXMAN_null)
180         n_alpha_bits = PIXMAN_FORMAT_A (daf);
181
182     n_red_bits = PIXMAN_FORMAT_R (df);
183
184     /* Source */
185     src = make_image (sf);
186     if (saf != PIXMAN_null)
187     {
188         alpha = make_image (saf);
189         pixman_image_set_alpha_map (src, alpha, soff, soff);
190         pixman_image_unref (alpha);
191     }
192
193     /* Destination */
194     orig_dst = make_image (df);
195     dst = make_image (df);
196     pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst,
197                             0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
198
199     if (daf != PIXMAN_null)
200     {
201         orig_alpha = make_image (daf);
202         alpha = make_image (daf);
203
204         pixman_image_composite (PIXMAN_OP_SRC, orig_alpha, NULL, alpha,
205                                 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
206
207         pixman_image_set_alpha_map (orig_dst, orig_alpha, doff, doff);
208         pixman_image_set_alpha_map (dst, alpha, doff, doff);
209
210         pixman_image_unref (orig_alpha);
211         pixman_image_unref (alpha);
212     }
213
214     /* Transformations, repeats and filters on destinations should be ignored,
215      * so just set some random ones.
216      */
217     pixman_transform_init_identity (&t1);
218     pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11));
219     pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11));
220     pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17));
221
222     pixman_image_set_transform (dst, &t1);
223     pixman_image_set_filter (dst, PIXMAN_FILTER_BILINEAR, NULL, 0);
224     pixman_image_set_repeat (dst, PIXMAN_REPEAT_REFLECT);
225
226     pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst,
227                             0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
228
229     for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j)
230     {
231         for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k)
232         {
233             uint8_t sa, da, oda, refa;
234             uint16_t sr, dr, odr, refr;
235
236             sa = get_alpha (src, k, j, soff, soff);
237             da = get_alpha (dst, k, j, doff, doff);
238             oda = get_alpha (orig_dst, k, j, doff, doff);
239
240             if (sa + oda > 255)
241                 refa = 255;
242             else
243                 refa = sa + oda;
244
245             if (da >> (8 - n_alpha_bits) != refa >> (8 - n_alpha_bits))
246             {
247                 printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
248                         k, j, refa, da, sa, oda);
249
250                 printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
251                         format_name (sf),
252                         format_name (saf),
253                         soff, soff,
254                         format_name (df),
255                         format_name (daf),
256                         doff, doff);
257                 return 1;
258             }
259
260             /* There are cases where we go through the 8 bit compositing
261              * path even with 10bpc formats. This results in incorrect
262              * results here, so only do the red check for narrow formats
263              */
264             if (n_red_bits <= 8)
265             {
266                 sr = get_red (src, k, j, soff, soff);
267                 dr = get_red (dst, k, j, doff, doff);
268                 odr = get_red (orig_dst, k, j, doff, doff);
269
270                 if (sr + odr > 0xffff)
271                     refr = 0xffff;
272                 else
273                     refr = sr + odr;
274
275                 if (abs ((dr >> (16 - n_red_bits)) - (refr >> (16 - n_red_bits))) > 1)
276                 {
277                     printf ("%d red bits\n", n_red_bits);
278                     printf ("\nWrong red value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
279                             k, j, refr, dr, sr, odr);
280
281                     printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
282                             format_name (sf),
283                             format_name (saf),
284                             soff, soff,
285                             format_name (df),
286                             format_name (daf),
287                             doff, doff);
288                     return 1;
289                 }
290             }
291         }
292     }
293
294     pixman_image_set_alpha_map (src, NULL, 0, 0);
295     pixman_image_set_alpha_map (dst, NULL, 0, 0);
296     pixman_image_set_alpha_map (orig_dst, NULL, 0, 0);
297
298     pixman_image_unref (src);
299     pixman_image_unref (dst);
300     pixman_image_unref (orig_dst);
301
302     return 0;
303 }
304
305 int
306 main (int argc, char **argv)
307 {
308     int i, j, a, b, x, y;
309
310     for (i = 0; i < ARRAY_LENGTH (formats); ++i)
311     {
312         for (j = 0; j < ARRAY_LENGTH (formats); ++j)
313         {
314             for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a)
315             {
316                 for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b)
317                 {
318                     for (x = 0; x < ARRAY_LENGTH (origins); ++x)
319                     {
320                         for (y = 0; y < ARRAY_LENGTH (origins); ++y)
321                         {
322                             if (run_test (i, j, a, b, x, y) != 0)
323                                 return 1;
324                         }
325                     }
326                 }
327             }
328         }
329     }
330
331     return 0;
332 }