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