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