Offset rendering in pixman_composite_trapezoids() by (x_dst, y_dst)
[profile/ivi/pixman.git] / test / composite-traps-test.c
1 /* Based loosely on scaling-test */
2
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include "utils.h"
7
8 #define MAX_SRC_WIDTH  48
9 #define MAX_SRC_HEIGHT 48
10 #define MAX_DST_WIDTH  48
11 #define MAX_DST_HEIGHT 48
12 #define MAX_STRIDE     4
13
14 static pixman_format_code_t formats[] =
15 {
16     PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_r5g6b5, PIXMAN_a1, PIXMAN_a4
17 };
18
19 static pixman_format_code_t mask_formats[] =
20 {
21     PIXMAN_a1, PIXMAN_a4, PIXMAN_a8,
22 };
23
24 static pixman_op_t operators[] =
25 {
26     PIXMAN_OP_OVER, PIXMAN_OP_ADD, PIXMAN_OP_SRC, PIXMAN_OP_IN
27 };
28
29 #define RANDOM_ELT(array)                                               \
30     ((array)[lcg_rand_n(ARRAY_LENGTH((array)))])
31
32 static void
33 destroy_bits (pixman_image_t *image, void *data)
34 {
35     fence_free (data);
36 }
37
38 static pixman_fixed_t
39 random_fixed (int n)
40 {
41     return lcg_rand_N (n << 16);
42 }
43
44 /*
45  * Composite operation with pseudorandom images
46  */
47 uint32_t
48 test_composite (int      testnum,
49                 int      verbose)
50 {
51     int                i;
52     pixman_image_t *   src_img;
53     pixman_image_t *   dst_img;
54     pixman_region16_t  clip;
55     int                dst_width, dst_height;
56     int                dst_stride;
57     int                dst_x, dst_y;
58     int                dst_bpp;
59     pixman_op_t        op;
60     uint32_t *         dst_bits;
61     uint32_t           crc32;
62     pixman_format_code_t mask_format, dst_format;
63     pixman_trapezoid_t *traps;
64     int src_x, src_y;
65     int n_traps;
66
67     static pixman_color_t colors[] =
68     {
69         { 0xffff, 0xffff, 0xffff, 0xffff },
70         { 0x0000, 0x0000, 0x0000, 0x0000 },
71         { 0xabcd, 0xabcd, 0x0000, 0xabcd },
72         { 0x0000, 0x0000, 0x0000, 0xffff },
73         { 0x0101, 0x0101, 0x0101, 0x0101 },
74         { 0x7777, 0x6666, 0x5555, 0x9999 },
75     };
76     
77     FLOAT_REGS_CORRUPTION_DETECTOR_START ();
78
79     lcg_srand (testnum);
80
81     op = RANDOM_ELT (operators);
82     mask_format = RANDOM_ELT (mask_formats);
83
84     /* Create source image */
85     
86     if (lcg_rand_n (4) == 0)
87     {
88         src_img = pixman_image_create_solid_fill (
89             &(colors[lcg_rand_n (ARRAY_LENGTH (colors))]));
90
91         src_x = 10;
92         src_y = 234;
93     }
94     else
95     {
96         pixman_format_code_t src_format = RANDOM_ELT(formats);
97         int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8;
98         int src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
99         int src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
100         int src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
101         uint32_t *bits;
102
103         src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
104         src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
105
106         src_stride = (src_stride + 3) & ~3;
107         
108         bits = (uint32_t *)make_random_bytes (src_stride * src_height);
109
110         src_img = pixman_image_create_bits (
111             src_format, src_width, src_height, bits, src_stride);
112
113         pixman_image_set_destroy_function (src_img, destroy_bits, bits);
114
115         if (lcg_rand_n (8) == 0)
116         {
117             pixman_box16_t clip_boxes[2];
118             int            n = lcg_rand_n (2) + 1;
119             
120             for (i = 0; i < n; i++)
121             {
122                 clip_boxes[i].x1 = lcg_rand_n (src_width);
123                 clip_boxes[i].y1 = lcg_rand_n (src_height);
124                 clip_boxes[i].x2 =
125                     clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
126                 clip_boxes[i].y2 =
127                     clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);
128                 
129                 if (verbose)
130                 {
131                     printf ("source clip box: [%d,%d-%d,%d]\n",
132                             clip_boxes[i].x1, clip_boxes[i].y1,
133                             clip_boxes[i].x2, clip_boxes[i].y2);
134                 }
135             }
136             
137             pixman_region_init_rects (&clip, clip_boxes, n);
138             pixman_image_set_clip_region (src_img, &clip);
139             pixman_image_set_source_clipping (src_img, 1);
140             pixman_region_fini (&clip);
141         }
142
143         image_endian_swap (src_img);
144     }
145
146     /* Create destination image */
147     {
148         dst_format = RANDOM_ELT(formats);
149         dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8;
150         dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
151         dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
152         dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
153         dst_stride = (dst_stride + 3) & ~3;
154         
155         dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height);
156
157         dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
158         dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
159         
160         dst_img = pixman_image_create_bits (
161             dst_format, dst_width, dst_height, dst_bits, dst_stride);
162
163         image_endian_swap (dst_img);
164     }
165
166     /* Create traps */
167     {
168         int i;
169
170         n_traps = lcg_rand_n (25);
171         traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t));
172
173         for (i = 0; i < n_traps; ++i)
174         {
175             pixman_trapezoid_t *t = &(traps[i]);
176             
177             t->top = random_fixed (MAX_DST_HEIGHT) - MAX_DST_HEIGHT / 2;
178             t->bottom = t->top + random_fixed (MAX_DST_HEIGHT);
179             t->left.p1.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
180             t->left.p1.y = t->top - random_fixed (50);
181             t->left.p2.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
182             t->left.p2.y = t->bottom + random_fixed (50);
183             t->right.p1.x = t->left.p1.x + random_fixed (MAX_DST_WIDTH);
184             t->right.p1.y = t->top - random_fixed (50);
185             t->right.p2.x = t->left.p2.x + random_fixed (MAX_DST_WIDTH);
186             t->right.p2.y = t->bottom - random_fixed (50);
187         }
188     }
189     
190     if (lcg_rand_n (8) == 0)
191     {
192         pixman_box16_t clip_boxes[2];
193         int            n = lcg_rand_n (2) + 1;
194         for (i = 0; i < n; i++)
195         {
196             clip_boxes[i].x1 = lcg_rand_n (dst_width);
197             clip_boxes[i].y1 = lcg_rand_n (dst_height);
198             clip_boxes[i].x2 =
199                 clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
200             clip_boxes[i].y2 =
201                 clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);
202
203             if (verbose)
204             {
205                 printf ("destination clip box: [%d,%d-%d,%d]\n",
206                         clip_boxes[i].x1, clip_boxes[i].y1,
207                         clip_boxes[i].x2, clip_boxes[i].y2);
208             }
209         }
210         pixman_region_init_rects (&clip, clip_boxes, n);
211         pixman_image_set_clip_region (dst_img, &clip);
212         pixman_region_fini (&clip);
213     }
214
215     pixman_composite_trapezoids (op, src_img, dst_img, mask_format,
216                                  src_x, src_y, dst_x, dst_y, n_traps, traps);
217
218     if (dst_format == PIXMAN_x8r8g8b8)
219     {
220         /* ignore unused part */
221         for (i = 0; i < dst_stride * dst_height / 4; i++)
222             dst_bits[i] &= 0xFFFFFF;
223     }
224
225     image_endian_swap (dst_img);
226
227     if (verbose)
228     {
229         int j;
230         
231         for (i = 0; i < dst_height; i++)
232         {
233             for (j = 0; j < dst_stride; j++)
234                 printf ("%02X ", *((uint8_t *)dst_bits + i * dst_stride + j));
235
236             printf ("\n");
237         }
238     }
239
240     crc32 = compute_crc32 (0, dst_bits, dst_stride * dst_height);
241
242     fence_free (dst_bits);
243     
244     pixman_image_unref (src_img);
245     pixman_image_unref (dst_img);
246     fence_free (traps);
247
248     FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
249     return crc32;
250 }
251
252 int
253 main (int argc, const char *argv[])
254 {
255     return fuzzer_test_main("composite traps", 40000, 0xE3112106,
256                             test_composite, argc, argv);
257 }