Fix compile warnings
[profile/ivi/pixman.git] / test / blitters-test.c
1 /*
2  * Test program, which stresses the use of different color formats and
3  * compositing operations.
4  *
5  * Just run it without any command line arguments, and it will report either
6  *   "blitters test passed" - everything is ok
7  *   "blitters test failed!" - there is some problem
8  *
9  * In the case of failure, finding the problem involves the following steps:
10  * 1. Get the reference 'blitters-test' binary. It makes sense to disable all
11  *    the cpu specific optimizations in pixman and also configure it with
12  *    '--disable-shared' option. Those who are paranoid can also tweak the
13  *    sources to disable all fastpath functions. The resulting binary
14  *    can be renamed to something like 'blitters-test.ref'.
15  * 2. Compile the buggy binary (also with the '--disable-shared' option).
16  * 3. Run 'ruby blitters-test-bisect.rb ./blitters-test.ref ./blitters-test'
17  * 4. Look at the information about failed case (destination buffer content
18  *    will be shown) and try to figure out what is wrong. Loading
19  *    test program in gdb, specifying failed test number in the command
20  *    line with '-' character prepended and setting breakpoint on
21  *    'pixman_image_composite' function can provide detailed information
22  *    about function arguments
23  */
24 #include <assert.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <config.h>
28 #include "pixman.h"
29
30 /* A primitive pseudorandom number generator, taken from POSIX.1-2001 example */
31
32 static uint32_t lcg_seed;
33
34 static inline uint32_t
35 lcg_rand (void)
36 {
37     lcg_seed = lcg_seed * 1103515245 + 12345;
38     return ((uint32_t)(lcg_seed / 65536) % 32768);
39 }
40
41 static inline void
42 lcg_srand (uint32_t seed)
43 {
44     lcg_seed = seed;
45 }
46
47 static inline uint32_t
48 lcg_rand_n (int max)
49 {
50     return lcg_rand () % max;
51 }
52
53 static void *
54 aligned_malloc (size_t align, size_t size)
55 {
56     void *result;
57
58 #ifdef HAVE_POSIX_MEMALIGN
59     if (posix_memalign (&result, align, size) != 0)
60       result = NULL;
61 #else
62     result = malloc (size);
63 #endif
64
65     return result;
66 }
67
68 /*----------------------------------------------------------------------------*\
69  *  CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
70  *
71  *  This program generates the CRC-32 values for the files named in the
72  *  command-line arguments.  These are the same CRC-32 values used by GZIP,
73  *  PKZIP, and ZMODEM.  The Crc32_ComputeBuf () can also be detached and
74  *  used independently.
75  *
76  *  THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
77  *
78  *  Based on the byte-oriented implementation "File Verification Using CRC"
79  *  by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
80  *
81  *  v1.0.0: original release.
82  *  v1.0.1: fixed printf formats.
83  *  v1.0.2: fixed something else.
84  *  v1.0.3: replaced CRC constant table by generator function.
85  *  v1.0.4: reformatted code, made ANSI C.  1994-12-05.
86  *  v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
87 \*----------------------------------------------------------------------------*/
88
89 /*----------------------------------------------------------------------------*\
90  *  NAME:
91  *     Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer
92  *  DESCRIPTION:
93  *     Computes or accumulates the CRC-32 value for a memory buffer.
94  *     The 'inCrc32' gives a previously accumulated CRC-32 value to allow
95  *     a CRC to be generated for multiple sequential buffer-fuls of data.
96  *     The 'inCrc32' for the first buffer must be zero.
97  *  ARGUMENTS:
98  *     inCrc32 - accumulated CRC-32 value, must be 0 on first call
99  *     buf     - buffer to compute CRC-32 value for
100  *     bufLen  - number of bytes in buffer
101  *  RETURNS:
102  *     crc32 - computed CRC-32 value
103  *  ERRORS:
104  *     (no errors are possible)
105 \*----------------------------------------------------------------------------*/
106
107 static uint32_t
108 compute_crc32 (uint32_t    in_crc32,
109                const void *buf,
110                size_t      buf_len)
111 {
112     static const uint32_t crc_table[256] = {
113         0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
114         0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
115         0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
116         0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
117         0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
118         0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
119         0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
120         0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
121         0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
122         0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
123         0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
124         0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
125         0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
126         0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
127         0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
128         0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
129         0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
130         0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
131         0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
132         0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
133         0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
134         0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
135         0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
136         0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
137         0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
138         0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
139         0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
140         0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
141         0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
142         0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
143         0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
144         0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
145         0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
146         0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
147         0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
148         0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
149         0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
150         0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
151         0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
152         0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
153         0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
154         0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
155         0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
156     };
157
158     uint32_t              crc32;
159     unsigned char *       byte_buf;
160     size_t                i;
161
162     /* accumulate crc32 for buffer */
163     crc32 = in_crc32 ^ 0xFFFFFFFF;
164     byte_buf = (unsigned char*) buf;
165
166     for (i = 0; i < buf_len; i++)
167         crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF];
168
169     return (crc32 ^ 0xFFFFFFFF);
170 }
171
172 /* perform endian conversion of pixel data */
173 static void
174 image_endian_swap (pixman_image_t *img, int bpp)
175 {
176     int stride = pixman_image_get_stride (img);
177     uint32_t *data = pixman_image_get_data (img);
178     int height = pixman_image_get_height (img);
179     int i, j;
180
181     /* swap bytes only on big endian systems */
182     volatile uint16_t endian_check_var = 0x1234;
183     if (*(volatile uint8_t *)&endian_check_var != 0x12)
184         return;
185
186     for (i = 0; i < height; i++)
187     {
188         uint8_t *line_data = (uint8_t *)data + stride * i;
189         /* swap bytes only for 16, 24 and 32 bpp for now */
190         switch (bpp)
191         {
192         case 1:
193             for (j = 0; j < stride; j++)
194             {
195                 line_data[j] =
196                     ((line_data[j] & 0x80) >> 7) |
197                     ((line_data[j] & 0x40) >> 5) |
198                     ((line_data[j] & 0x20) >> 3) |
199                     ((line_data[j] & 0x10) >> 1) |
200                     ((line_data[j] & 0x08) << 1) |
201                     ((line_data[j] & 0x04) << 3) |
202                     ((line_data[j] & 0x02) << 5) |
203                     ((line_data[j] & 0x01) << 7);
204             }
205             break;
206         case 4:
207             for (j = 0; j < stride; j++)
208             {
209                 line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4);
210             }
211             break;
212         case 16:
213             for (j = 0; j + 2 <= stride; j += 2)
214             {
215                 char t1 = line_data[j + 0];
216                 char t2 = line_data[j + 1];
217
218                 line_data[j + 1] = t1;
219                 line_data[j + 0] = t2;
220             }
221             break;
222         case 24:
223             for (j = 0; j + 3 <= stride; j += 3)
224             {
225                 char t1 = line_data[j + 0];
226                 char t2 = line_data[j + 1];
227                 char t3 = line_data[j + 2];
228
229                 line_data[j + 2] = t1;
230                 line_data[j + 1] = t2;
231                 line_data[j + 0] = t3;
232             }
233             break;
234         case 32:
235             for (j = 0; j + 4 <= stride; j += 4)
236             {
237                 char t1 = line_data[j + 0];
238                 char t2 = line_data[j + 1];
239                 char t3 = line_data[j + 2];
240                 char t4 = line_data[j + 3];
241
242                 line_data[j + 3] = t1;
243                 line_data[j + 2] = t2;
244                 line_data[j + 1] = t3;
245                 line_data[j + 0] = t4;
246             }
247             break;
248         default:
249             break;
250         }
251     }
252 }
253
254 /* Create random image for testing purposes */
255 static pixman_image_t *
256 create_random_image (pixman_format_code_t *allowed_formats,
257                      int                   max_width,
258                      int                   max_height,
259                      int                   max_extra_stride,
260                      pixman_format_code_t *used_fmt)
261 {
262     int n = 0, i, width, height, stride;
263     pixman_format_code_t fmt;
264     uint32_t *buf;
265     pixman_image_t *img;
266
267     while (allowed_formats[n] != -1)
268         n++;
269     fmt = allowed_formats[lcg_rand_n (n)];
270     width = lcg_rand_n (max_width) + 1;
271     height = lcg_rand_n (max_height) + 1;
272     stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 +
273         lcg_rand_n (max_extra_stride + 1);
274     stride = (stride + 3) & ~3;
275
276     /* do the allocation */
277     buf = aligned_malloc (64, stride * height);
278
279     /* initialize image with random data */
280     for (i = 0; i < stride * height; i++)
281     {
282         /* generation is biased to having more 0 or 255 bytes as
283          * they are more likely to be special-cased in code
284          */
285         *((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) :
286             (lcg_rand_n (2) ? 0 : 255);
287     }
288
289     img = pixman_image_create_bits (fmt, width, height, buf, stride);
290
291     image_endian_swap (img, PIXMAN_FORMAT_BPP (fmt));
292
293     if (used_fmt) *used_fmt = fmt;
294     return img;
295 }
296
297 /* Free random image, and optionally update crc32 based on its data */
298 static uint32_t
299 free_random_image (uint32_t initcrc,
300                    pixman_image_t *img,
301                    pixman_format_code_t fmt)
302 {
303     uint32_t crc32 = 0;
304     int stride = pixman_image_get_stride (img);
305     uint32_t *data = pixman_image_get_data (img);
306     int height = pixman_image_get_height (img);;
307
308     if (fmt != -1)
309     {
310         /* mask unused 'x' part */
311         if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
312             PIXMAN_FORMAT_DEPTH (fmt) != 0)
313         {
314             int i;
315             uint32_t *data = pixman_image_get_data (img);
316             uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;
317
318             if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA)
319                 mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
320
321             for (i = 0; i < 32; i++)
322                 mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
323
324             for (i = 0; i < stride * height / 4; i++)
325                 data[i] &= mask;
326         }
327
328         /* swap endiannes in order to provide identical results on both big
329          * and litte endian systems
330          */
331         image_endian_swap (img, PIXMAN_FORMAT_BPP (fmt));
332         crc32 = compute_crc32 (initcrc, data, stride * height);
333     }
334
335     pixman_image_unref (img);
336     free (data);
337
338     return crc32;
339 }
340
341 static pixman_op_t op_list[] = {
342     PIXMAN_OP_SRC,
343     PIXMAN_OP_OVER,
344     PIXMAN_OP_ADD,
345     PIXMAN_OP_CLEAR,
346     PIXMAN_OP_SRC,
347     PIXMAN_OP_DST,
348     PIXMAN_OP_OVER,
349     PIXMAN_OP_OVER_REVERSE,
350     PIXMAN_OP_IN,
351     PIXMAN_OP_IN_REVERSE,
352     PIXMAN_OP_OUT,
353     PIXMAN_OP_OUT_REVERSE,
354     PIXMAN_OP_ATOP,
355     PIXMAN_OP_ATOP_REVERSE,
356     PIXMAN_OP_XOR,
357     PIXMAN_OP_ADD,
358     PIXMAN_OP_SATURATE,
359     PIXMAN_OP_DISJOINT_CLEAR,
360     PIXMAN_OP_DISJOINT_SRC,
361     PIXMAN_OP_DISJOINT_DST,
362     PIXMAN_OP_DISJOINT_OVER,
363     PIXMAN_OP_DISJOINT_OVER_REVERSE,
364     PIXMAN_OP_DISJOINT_IN,
365     PIXMAN_OP_DISJOINT_IN_REVERSE,
366     PIXMAN_OP_DISJOINT_OUT,
367     PIXMAN_OP_DISJOINT_OUT_REVERSE,
368     PIXMAN_OP_DISJOINT_ATOP,
369     PIXMAN_OP_DISJOINT_ATOP_REVERSE,
370     PIXMAN_OP_DISJOINT_XOR,
371     PIXMAN_OP_CONJOINT_CLEAR,
372     PIXMAN_OP_CONJOINT_SRC,
373     PIXMAN_OP_CONJOINT_DST,
374     PIXMAN_OP_CONJOINT_OVER,
375     PIXMAN_OP_CONJOINT_OVER_REVERSE,
376     PIXMAN_OP_CONJOINT_IN,
377     PIXMAN_OP_CONJOINT_IN_REVERSE,
378     PIXMAN_OP_CONJOINT_OUT,
379     PIXMAN_OP_CONJOINT_OUT_REVERSE,
380     PIXMAN_OP_CONJOINT_ATOP,
381     PIXMAN_OP_CONJOINT_ATOP_REVERSE,
382     PIXMAN_OP_CONJOINT_XOR,
383     PIXMAN_OP_MULTIPLY,
384     PIXMAN_OP_SCREEN,
385     PIXMAN_OP_OVERLAY,
386     PIXMAN_OP_DARKEN,
387     PIXMAN_OP_LIGHTEN,
388     PIXMAN_OP_COLOR_DODGE,
389     PIXMAN_OP_COLOR_BURN,
390     PIXMAN_OP_HARD_LIGHT,
391     PIXMAN_OP_DIFFERENCE,
392     PIXMAN_OP_EXCLUSION,
393 #if 0 /* these use floating point math and are not always bitexact on different platforms */
394     PIXMAN_OP_SOFT_LIGHT,
395     PIXMAN_OP_HSL_HUE,
396     PIXMAN_OP_HSL_SATURATION,
397     PIXMAN_OP_HSL_COLOR,
398     PIXMAN_OP_HSL_LUMINOSITY,
399 #endif
400 };
401
402 static pixman_format_code_t img_fmt_list[] = {
403     PIXMAN_a8r8g8b8,
404     PIXMAN_x8r8g8b8,
405     PIXMAN_r5g6b5,
406     PIXMAN_r3g3b2,
407     PIXMAN_a8,
408     PIXMAN_a8b8g8r8,
409     PIXMAN_x8b8g8r8,
410     PIXMAN_b8g8r8a8,
411     PIXMAN_b8g8r8x8,
412     PIXMAN_r8g8b8,
413     PIXMAN_b8g8r8,
414     PIXMAN_r5g6b5,
415     PIXMAN_b5g6r5,
416     PIXMAN_x2r10g10b10,
417     PIXMAN_a2r10g10b10,
418     PIXMAN_x2b10g10r10,
419     PIXMAN_a2b10g10r10,
420     PIXMAN_a1r5g5b5,
421     PIXMAN_x1r5g5b5,
422     PIXMAN_a1b5g5r5,
423     PIXMAN_x1b5g5r5,
424     PIXMAN_a4r4g4b4,
425     PIXMAN_x4r4g4b4,
426     PIXMAN_a4b4g4r4,
427     PIXMAN_x4b4g4r4,
428     PIXMAN_a8,
429     PIXMAN_r3g3b2,
430     PIXMAN_b2g3r3,
431     PIXMAN_a2r2g2b2,
432     PIXMAN_a2b2g2r2,
433 #if 0 /* using these crashes the test */
434     PIXMAN_c8,
435     PIXMAN_g8,
436     PIXMAN_x4c4,
437     PIXMAN_x4g4,
438     PIXMAN_c4,
439     PIXMAN_g4,
440     PIXMAN_g1,
441 #endif
442     PIXMAN_x4a4,
443     PIXMAN_a4,
444     PIXMAN_r1g2b1,
445     PIXMAN_b1g2r1,
446     PIXMAN_a1r1g1b1,
447     PIXMAN_a1b1g1r1,
448     PIXMAN_a1,
449     -1
450 };
451
452 static pixman_format_code_t mask_fmt_list[] = {
453     PIXMAN_a8r8g8b8,
454     PIXMAN_a8,
455     PIXMAN_a4,
456     PIXMAN_a1,
457     -1
458 };
459
460
461 /*
462  * Composite operation with pseudorandom images
463  */
464 uint32_t
465 test_composite (uint32_t initcrc, int testnum, int verbose)
466 {
467     int i;
468     pixman_image_t *src_img = NULL;
469     pixman_image_t *dst_img = NULL;
470     pixman_image_t *mask_img = NULL;
471     int src_width, src_height;
472     int dst_width, dst_height;
473     int src_stride, dst_stride;
474     int src_x, src_y;
475     int dst_x, dst_y;
476     int w, h;
477     int op;
478     pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
479     uint32_t *dstbuf;
480     uint32_t crc32;
481     int max_width, max_height, max_extra_stride;
482
483     max_width = max_height = 24 + testnum / 10000;
484     max_extra_stride = 4 + testnum / 1000000;
485
486     if (max_width > 256)
487         max_width = 256;
488
489     if (max_height > 16)
490         max_height = 16;
491
492     if (max_extra_stride > 8)
493         max_extra_stride = 8;
494
495     lcg_srand (testnum);
496
497     op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))];
498
499     if (lcg_rand_n (8))
500     {
501         /* normal image */
502         src_img = create_random_image (img_fmt_list, max_width, max_height,
503                                        max_extra_stride, &src_fmt);
504     }
505     else
506     {
507         /* solid case */
508         src_img = create_random_image (img_fmt_list, 1, 1,
509                                        max_extra_stride, &src_fmt);
510
511         pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
512     }
513
514     dst_img = create_random_image (img_fmt_list, max_width, max_height,
515                                    max_extra_stride, &dst_fmt);
516
517     mask_img = NULL;
518     mask_fmt = -1;
519
520     if (lcg_rand_n (2))
521     {
522         if (lcg_rand_n (2))
523         {
524             mask_img = create_random_image (mask_fmt_list, max_width, max_height,
525                                            max_extra_stride, &mask_fmt);
526         }
527         else
528         {
529             /* solid case */
530             mask_img = create_random_image (mask_fmt_list, 1, 1,
531                                            max_extra_stride, &mask_fmt);
532             pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
533         }
534
535         if (lcg_rand_n (2))
536             pixman_image_set_component_alpha (mask_img, 1);
537     }
538
539     src_width = pixman_image_get_width (src_img);
540     src_height = pixman_image_get_height (src_img);
541     src_stride = pixman_image_get_stride (src_img);
542
543     dst_width = pixman_image_get_width (dst_img);
544     dst_height = pixman_image_get_height (dst_img);
545     dst_stride = pixman_image_get_stride (dst_img);
546
547     dstbuf = pixman_image_get_data (dst_img);
548
549     src_x = lcg_rand_n (src_width);
550     src_y = lcg_rand_n (src_height);
551     dst_x = lcg_rand_n (dst_width);
552     dst_y = lcg_rand_n (dst_height);
553
554     w = lcg_rand_n (dst_width - dst_x + 1);
555     h = lcg_rand_n (dst_height - dst_y + 1);
556
557     if (verbose)
558     {
559         printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n",
560             op, src_fmt, dst_fmt, mask_fmt);
561         printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
562             src_width, src_height, dst_width, dst_height);
563         printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
564             src_x, src_y, dst_x, dst_y);
565         printf ("src_stride=%d, dst_stride=%d\n",
566             src_stride, dst_stride);
567         printf ("w=%d, h=%d\n", w, h);
568     }
569
570     pixman_image_composite (op, src_img, mask_img, dst_img,
571                             src_x, src_y, src_x, src_y, dst_x, dst_y, w, h);
572
573     if (verbose)
574     {
575         int j;
576
577         printf ("---\n");
578         for (i = 0; i < dst_height; i++)
579         {
580             for (j = 0; j < dst_stride; j++)
581             {
582                 if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8)
583                     printf ("| ");
584
585                 printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
586             }
587             printf ("\n");
588         }
589         printf ("---\n");
590     }
591
592     free_random_image (initcrc, src_img, -1);
593     crc32 = free_random_image (initcrc, dst_img, dst_fmt);
594
595     if (mask_img)
596         free_random_image (initcrc, mask_img, -1);
597
598     return crc32;
599 }
600
601 int
602 main (int argc, char *argv[])
603 {
604     int i, n1 = 1, n2 = 0;
605     uint32_t crc = 0;
606     int verbose = getenv ("VERBOSE") != NULL;
607
608     if (argc >= 3)
609     {
610         n1 = atoi (argv[1]);
611         n2 = atoi (argv[2]);
612     }
613     else if (argc >= 2)
614     {
615         n2 = atoi (argv[1]);
616     }
617     else
618     {
619         n1 = 1;
620         n2 = 2000000;
621     }
622
623     if (n2 < 0)
624     {
625         crc = test_composite (0, abs (n2), 1);
626         printf ("crc32=%08X\n", crc);
627     }
628     else
629     {
630         for (i = n1; i <= n2; i++)
631         {
632             crc = test_composite (crc, i, 0);
633
634             if (verbose)
635                 printf ("%d: %08X\n", i, crc);
636         }
637         printf ("crc32=%08X\n", crc);
638
639         if (n2 == 2000000)
640         {
641             /* Predefined value for running with all the fastpath functions
642                disabled. It needs to be updated every time when changes are
643                introduced to this program or behavior of pixman changes! */
644             if (crc == 0x481369DE)
645             {
646                 printf ("blitters test passed\n");
647             }
648             else
649             {
650                 printf ("blitters test failed!\n");
651                 return 1;
652             }
653         }
654     }
655     return 0;
656 }