Add qemu 2.4.0
[kvmfornfv.git] / qemu / pixman / test / utils.c
1 #define _GNU_SOURCE
2
3 #include "utils.h"
4 #include <math.h>
5 #include <signal.h>
6 #include <stdlib.h>
7
8 #ifdef HAVE_GETTIMEOFDAY
9 #include <sys/time.h>
10 #else
11 #include <time.h>
12 #endif
13
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17
18 #ifdef HAVE_SYS_MMAN_H
19 #include <sys/mman.h>
20 #endif
21
22 #ifdef HAVE_FENV_H
23 #include <fenv.h>
24 #endif
25
26 #ifdef HAVE_LIBPNG
27 #include <png.h>
28 #endif
29
30 /* Random number generator state
31  */
32
33 prng_t prng_state_data;
34 prng_t *prng_state;
35
36 /*----------------------------------------------------------------------------*\
37  *  CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
38  *
39  *  This program generates the CRC-32 values for the files named in the
40  *  command-line arguments.  These are the same CRC-32 values used by GZIP,
41  *  PKZIP, and ZMODEM.  The Crc32_ComputeBuf () can also be detached and
42  *  used independently.
43  *
44  *  THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
45  *
46  *  Based on the byte-oriented implementation "File Verification Using CRC"
47  *  by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
48  *
49  *  v1.0.0: original release.
50  *  v1.0.1: fixed printf formats.
51  *  v1.0.2: fixed something else.
52  *  v1.0.3: replaced CRC constant table by generator function.
53  *  v1.0.4: reformatted code, made ANSI C.  1994-12-05.
54  *  v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
55 \*----------------------------------------------------------------------------*/
56
57 /*----------------------------------------------------------------------------*\
58  *  NAME:
59  *     Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer
60  *  DESCRIPTION:
61  *     Computes or accumulates the CRC-32 value for a memory buffer.
62  *     The 'inCrc32' gives a previously accumulated CRC-32 value to allow
63  *     a CRC to be generated for multiple sequential buffer-fuls of data.
64  *     The 'inCrc32' for the first buffer must be zero.
65  *  ARGUMENTS:
66  *     inCrc32 - accumulated CRC-32 value, must be 0 on first call
67  *     buf     - buffer to compute CRC-32 value for
68  *     bufLen  - number of bytes in buffer
69  *  RETURNS:
70  *     crc32 - computed CRC-32 value
71  *  ERRORS:
72  *     (no errors are possible)
73 \*----------------------------------------------------------------------------*/
74
75 uint32_t
76 compute_crc32 (uint32_t    in_crc32,
77                const void *buf,
78                size_t      buf_len)
79 {
80     static const uint32_t crc_table[256] = {
81         0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
82         0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
83         0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
84         0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
85         0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
86         0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
87         0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
88         0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
89         0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
90         0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
91         0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
92         0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
93         0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
94         0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
95         0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
96         0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
97         0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
98         0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
99         0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
100         0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
101         0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
102         0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
103         0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
104         0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
105         0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
106         0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
107         0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
108         0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
109         0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
110         0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
111         0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
112         0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
113         0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
114         0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
115         0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
116         0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
117         0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
118         0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
119         0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
120         0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
121         0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
122         0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
123         0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
124     };
125
126     uint32_t              crc32;
127     unsigned char *       byte_buf;
128     size_t                i;
129
130     /* accumulate crc32 for buffer */
131     crc32 = in_crc32 ^ 0xFFFFFFFF;
132     byte_buf = (unsigned char*) buf;
133
134     for (i = 0; i < buf_len; i++)
135         crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF];
136
137     return (crc32 ^ 0xFFFFFFFF);
138 }
139
140 static uint32_t
141 compute_crc32_for_image_internal (uint32_t        crc32,
142                                   pixman_image_t *img,
143                                   pixman_bool_t   remove_alpha,
144                                   pixman_bool_t   remove_rgb)
145 {
146     pixman_format_code_t fmt = pixman_image_get_format (img);
147     uint32_t *data = pixman_image_get_data (img);
148     int stride = pixman_image_get_stride (img);
149     int height = pixman_image_get_height (img);
150     uint32_t mask = 0xffffffff;
151     int i;
152
153     if (stride < 0)
154     {
155         data += (stride / 4) * (height - 1);
156         stride = - stride;
157     }
158
159     /* mask unused 'x' part */
160     if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
161         PIXMAN_FORMAT_DEPTH (fmt) != 0)
162     {
163         uint32_t m = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;
164
165         if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
166             PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
167         {
168             m <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
169         }
170
171         mask &= m;
172     }
173
174     /* mask alpha channel */
175     if (remove_alpha && PIXMAN_FORMAT_A (fmt))
176     {
177         uint32_t m;
178
179         if (PIXMAN_FORMAT_BPP (fmt) == 32)
180             m = 0xffffffff;
181         else
182             m = (1 << PIXMAN_FORMAT_BPP (fmt)) - 1;
183
184         m >>= PIXMAN_FORMAT_A (fmt);
185
186         if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
187             PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA ||
188             PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_A)
189         {
190             /* Alpha is at the bottom of the pixel */
191             m <<= PIXMAN_FORMAT_A (fmt);
192         }
193
194         mask &= m;
195     }
196
197     /* mask rgb channels */
198     if (remove_rgb && PIXMAN_FORMAT_RGB (fmt))
199     {
200         uint32_t m = ((uint32_t)~0) >> (32 - PIXMAN_FORMAT_BPP (fmt));
201         uint32_t size = PIXMAN_FORMAT_R (fmt) + PIXMAN_FORMAT_G (fmt) + PIXMAN_FORMAT_B (fmt);
202
203         m &= ~((1 << size) - 1);
204
205         if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
206             PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
207         {
208             /* RGB channels are at the top of the pixel */
209             m >>= size;
210         }
211
212         mask &= m;
213     }
214
215     for (i = 0; i * PIXMAN_FORMAT_BPP (fmt) < 32; i++)
216         mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
217
218     for (i = 0; i < stride * height / 4; i++)
219         data[i] &= mask;
220
221     /* swap endiannes in order to provide identical results on both big
222      * and litte endian systems
223      */
224     image_endian_swap (img);
225
226     return compute_crc32 (crc32, data, stride * height);
227 }
228
229 uint32_t
230 compute_crc32_for_image (uint32_t        crc32,
231                          pixman_image_t *img)
232 {
233     if (img->common.alpha_map)
234     {
235         crc32 = compute_crc32_for_image_internal (crc32, img, TRUE, FALSE);
236         crc32 = compute_crc32_for_image_internal (
237             crc32, (pixman_image_t *)img->common.alpha_map, FALSE, TRUE);
238     }
239     else
240     {
241         crc32 = compute_crc32_for_image_internal (crc32, img, FALSE, FALSE);
242     }
243
244     return crc32;
245 }
246
247 void
248 print_image (pixman_image_t *image)
249 {
250     int i, j;
251     int width, height, stride;
252     pixman_format_code_t format;
253     uint8_t *buffer;
254     int s;
255
256     width = pixman_image_get_width (image);
257     height = pixman_image_get_height (image);
258     stride = pixman_image_get_stride (image);
259     format = pixman_image_get_format (image);
260     buffer = (uint8_t *)pixman_image_get_data (image);
261
262     s = (stride >= 0)? stride : - stride;
263     
264     printf ("---\n");
265     for (i = 0; i < height; i++)
266     {
267         for (j = 0; j < s; j++)
268         {
269             if (j == (width * PIXMAN_FORMAT_BPP (format) + 7) / 8)
270                 printf ("| ");
271
272             printf ("%02X ", *((uint8_t *)buffer + i * stride + j));
273         }
274         printf ("\n");
275     }
276     printf ("---\n");
277 }
278
279 /* perform endian conversion of pixel data
280  */
281 void
282 image_endian_swap (pixman_image_t *img)
283 {
284     int stride = pixman_image_get_stride (img);
285     uint32_t *data = pixman_image_get_data (img);
286     int height = pixman_image_get_height (img);
287     int bpp = PIXMAN_FORMAT_BPP (pixman_image_get_format (img));
288     int i, j;
289
290     /* swap bytes only on big endian systems */
291     if (is_little_endian())
292         return;
293
294     if (bpp == 8)
295         return;
296
297     for (i = 0; i < height; i++)
298     {
299         uint8_t *line_data = (uint8_t *)data + stride * i;
300         int s = (stride >= 0)? stride : - stride;
301         
302         switch (bpp)
303         {
304         case 1:
305             for (j = 0; j < s; j++)
306             {
307                 line_data[j] =
308                     ((line_data[j] & 0x80) >> 7) |
309                     ((line_data[j] & 0x40) >> 5) |
310                     ((line_data[j] & 0x20) >> 3) |
311                     ((line_data[j] & 0x10) >> 1) |
312                     ((line_data[j] & 0x08) << 1) |
313                     ((line_data[j] & 0x04) << 3) |
314                     ((line_data[j] & 0x02) << 5) |
315                     ((line_data[j] & 0x01) << 7);
316             }
317             break;
318         case 4:
319             for (j = 0; j < s; j++)
320             {
321                 line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4);
322             }
323             break;
324         case 16:
325             for (j = 0; j + 2 <= s; j += 2)
326             {
327                 char t1 = line_data[j + 0];
328                 char t2 = line_data[j + 1];
329
330                 line_data[j + 1] = t1;
331                 line_data[j + 0] = t2;
332             }
333             break;
334         case 24:
335             for (j = 0; j + 3 <= s; j += 3)
336             {
337                 char t1 = line_data[j + 0];
338                 char t2 = line_data[j + 1];
339                 char t3 = line_data[j + 2];
340
341                 line_data[j + 2] = t1;
342                 line_data[j + 1] = t2;
343                 line_data[j + 0] = t3;
344             }
345             break;
346         case 32:
347             for (j = 0; j + 4 <= s; j += 4)
348             {
349                 char t1 = line_data[j + 0];
350                 char t2 = line_data[j + 1];
351                 char t3 = line_data[j + 2];
352                 char t4 = line_data[j + 3];
353
354                 line_data[j + 3] = t1;
355                 line_data[j + 2] = t2;
356                 line_data[j + 1] = t3;
357                 line_data[j + 0] = t4;
358             }
359             break;
360         default:
361             assert (FALSE);
362             break;
363         }
364     }
365 }
366
367 #define N_LEADING_PROTECTED     10
368 #define N_TRAILING_PROTECTED    10
369
370 typedef struct
371 {
372     void *addr;
373     uint32_t len;
374     uint8_t *trailing;
375     int n_bytes;
376 } info_t;
377
378 #if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE) && defined(HAVE_SYS_MMAN_H) && defined(HAVE_MMAP)
379
380 /* This is apparently necessary on at least OS X */
381 #ifndef MAP_ANONYMOUS
382 #define MAP_ANONYMOUS MAP_ANON
383 #endif
384
385 void *
386 fence_malloc (int64_t len)
387 {
388     unsigned long page_size = getpagesize();
389     unsigned long page_mask = page_size - 1;
390     uint32_t n_payload_bytes = (len + page_mask) & ~page_mask;
391     uint32_t n_bytes =
392         (page_size * (N_LEADING_PROTECTED + N_TRAILING_PROTECTED + 2) +
393          n_payload_bytes) & ~page_mask;
394     uint8_t *initial_page;
395     uint8_t *leading_protected;
396     uint8_t *trailing_protected;
397     uint8_t *payload;
398     uint8_t *addr;
399
400     if (len < 0)
401         abort();
402     
403     addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
404                  -1, 0);
405
406     if (addr == MAP_FAILED)
407     {
408         printf ("mmap failed on %lld %u\n", (long long int)len, n_bytes);
409         return NULL;
410     }
411
412     initial_page = (uint8_t *)(((uintptr_t)addr + page_mask) & ~page_mask);
413     leading_protected = initial_page + page_size;
414     payload = leading_protected + N_LEADING_PROTECTED * page_size;
415     trailing_protected = payload + n_payload_bytes;
416
417     ((info_t *)initial_page)->addr = addr;
418     ((info_t *)initial_page)->len = len;
419     ((info_t *)initial_page)->trailing = trailing_protected;
420     ((info_t *)initial_page)->n_bytes = n_bytes;
421
422     if ((mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
423                   PROT_NONE) == -1) ||
424         (mprotect (trailing_protected, N_TRAILING_PROTECTED * page_size,
425                   PROT_NONE) == -1))
426     {
427         munmap (addr, n_bytes);
428         return NULL;
429     }
430
431     return payload;
432 }
433
434 void
435 fence_free (void *data)
436 {
437     uint32_t page_size = getpagesize();
438     uint8_t *payload = data;
439     uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size;
440     uint8_t *initial_page = leading_protected - page_size;
441     info_t *info = (info_t *)initial_page;
442
443     munmap (info->addr, info->n_bytes);
444 }
445
446 #else
447
448 void *
449 fence_malloc (int64_t len)
450 {
451     return malloc (len);
452 }
453
454 void
455 fence_free (void *data)
456 {
457     free (data);
458 }
459
460 #endif
461
462 uint8_t *
463 make_random_bytes (int n_bytes)
464 {
465     uint8_t *bytes = fence_malloc (n_bytes);
466
467     if (!bytes)
468         return NULL;
469
470     prng_randmemset (bytes, n_bytes, 0);
471
472     return bytes;
473 }
474
475 void
476 a8r8g8b8_to_rgba_np (uint32_t *dst, uint32_t *src, int n_pixels)
477 {
478     uint8_t *dst8 = (uint8_t *)dst;
479     int i;
480
481     for (i = 0; i < n_pixels; ++i)
482     {
483         uint32_t p = src[i];
484         uint8_t a, r, g, b;
485
486         a = (p & 0xff000000) >> 24;
487         r = (p & 0x00ff0000) >> 16;
488         g = (p & 0x0000ff00) >> 8;
489         b = (p & 0x000000ff) >> 0;
490
491         if (a != 0)
492         {
493 #define DIVIDE(c, a)                                                    \
494             do                                                          \
495             {                                                           \
496                 int t = ((c) * 255) / a;                                \
497                 (c) = t < 0? 0 : t > 255? 255 : t;                      \
498             } while (0)
499
500             DIVIDE (r, a);
501             DIVIDE (g, a);
502             DIVIDE (b, a);
503         }
504
505         *dst8++ = r;
506         *dst8++ = g;
507         *dst8++ = b;
508         *dst8++ = a;
509     }
510 }
511
512 #ifdef HAVE_LIBPNG
513
514 pixman_bool_t
515 write_png (pixman_image_t *image, const char *filename)
516 {
517     int width = pixman_image_get_width (image);
518     int height = pixman_image_get_height (image);
519     int stride = width * 4;
520     uint32_t *data = malloc (height * stride);
521     pixman_image_t *copy;
522     png_struct *write_struct;
523     png_info *info_struct;
524     pixman_bool_t result = FALSE;
525     FILE *f = fopen (filename, "wb");
526     png_bytep *row_pointers;
527     int i;
528
529     if (!f)
530         return FALSE;
531
532     row_pointers = malloc (height * sizeof (png_bytep));
533
534     copy = pixman_image_create_bits (
535         PIXMAN_a8r8g8b8, width, height, data, stride);
536
537     pixman_image_composite32 (
538         PIXMAN_OP_SRC, image, NULL, copy, 0, 0, 0, 0, 0, 0, width, height);
539
540     a8r8g8b8_to_rgba_np (data, data, height * width);
541
542     for (i = 0; i < height; ++i)
543         row_pointers[i] = (png_bytep)(data + i * width);
544
545     if (!(write_struct = png_create_write_struct (
546               PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
547         goto out1;
548
549     if (!(info_struct = png_create_info_struct (write_struct)))
550         goto out2;
551
552     png_init_io (write_struct, f);
553
554     png_set_IHDR (write_struct, info_struct, width, height,
555                   8, PNG_COLOR_TYPE_RGB_ALPHA,
556                   PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
557                   PNG_FILTER_TYPE_BASE);
558
559     png_write_info (write_struct, info_struct);
560
561     png_write_image (write_struct, row_pointers);
562
563     png_write_end (write_struct, NULL);
564
565     result = TRUE;
566
567 out2:
568     png_destroy_write_struct (&write_struct, &info_struct);
569
570 out1:
571     if (fclose (f) != 0)
572         result = FALSE;
573
574     pixman_image_unref (copy);
575     free (row_pointers);
576     free (data);
577     return result;
578 }
579
580 #else /* no libpng */
581
582 pixman_bool_t
583 write_png (pixman_image_t *image, const char *filename)
584 {
585     return FALSE;
586 }
587
588 #endif
589
590 static void
591 color8_to_color16 (uint32_t color8, pixman_color_t *color16)
592 {
593     color16->alpha = ((color8 & 0xff000000) >> 24);
594     color16->red =   ((color8 & 0x00ff0000) >> 16);
595     color16->green = ((color8 & 0x0000ff00) >> 8);
596     color16->blue =  ((color8 & 0x000000ff) >> 0);
597
598     color16->alpha |= color16->alpha << 8;
599     color16->red   |= color16->red << 8;
600     color16->blue  |= color16->blue << 8;
601     color16->green |= color16->green << 8;
602 }
603
604 void
605 draw_checkerboard (pixman_image_t *image,
606                    int check_size,
607                    uint32_t color1, uint32_t color2)
608 {
609     pixman_color_t check1, check2;
610     pixman_image_t *c1, *c2;
611     int n_checks_x, n_checks_y;
612     int i, j;
613
614     color8_to_color16 (color1, &check1);
615     color8_to_color16 (color2, &check2);
616     
617     c1 = pixman_image_create_solid_fill (&check1);
618     c2 = pixman_image_create_solid_fill (&check2);
619
620     n_checks_x = (
621         pixman_image_get_width (image) + check_size - 1) / check_size;
622     n_checks_y = (
623         pixman_image_get_height (image) + check_size - 1) / check_size;
624
625     for (j = 0; j < n_checks_y; j++)
626     {
627         for (i = 0; i < n_checks_x; i++)
628         {
629             pixman_image_t *src;
630
631             if (((i ^ j) & 1))
632                 src = c1;
633             else
634                 src = c2;
635
636             pixman_image_composite32 (PIXMAN_OP_SRC, src, NULL, image,
637                                       0, 0, 0, 0,
638                                       i * check_size, j * check_size,
639                                       check_size, check_size);
640         }
641     }
642 }
643
644 static uint32_t
645 call_test_function (uint32_t    (*test_function)(int testnum, int verbose),
646                     int         testnum,
647                     int         verbose)
648 {
649     uint32_t retval;
650
651 #if defined (__GNUC__) && defined (_WIN32) && (defined (__i386) || defined (__i386__))
652     __asm__ (
653         /* Deliberately avoid aligning the stack to 16 bytes */
654         "pushl  %1\n\t"
655         "pushl  %2\n\t"
656         "call   *%3\n\t"
657         "addl   $8, %%esp\n\t"
658         : "=a" (retval)
659         : "r" (verbose),
660           "r" (testnum),
661           "r" (test_function)
662         : "edx", "ecx"); /* caller save registers */
663 #else
664     retval = test_function (testnum, verbose);
665 #endif
666
667     return retval;
668 }
669
670 /*
671  * A function, which can be used as a core part of the test programs,
672  * intended to detect various problems with the help of fuzzing input
673  * to pixman API (according to some templates, aka "smart" fuzzing).
674  * Some general information about such testing can be found here:
675  * http://en.wikipedia.org/wiki/Fuzz_testing
676  *
677  * It may help detecting:
678  *  - crashes on bad handling of valid or reasonably invalid input to
679  *    pixman API.
680  *  - deviations from the behavior of older pixman releases.
681  *  - deviations from the behavior of the same pixman release, but
682  *    configured in a different way (for example with SIMD optimizations
683  *    disabled), or running on a different OS or hardware.
684  *
685  * The test is performed by calling a callback function a huge number
686  * of times. The callback function is expected to run some snippet of
687  * pixman code with pseudorandom variations to the data feeded to
688  * pixman API. A result of running each callback function should be
689  * some deterministic value which depends on test number (test number
690  * can be used as a seed for PRNG). When 'verbose' argument is nonzero,
691  * callback function is expected to print to stdout some information
692  * about what it does.
693  *
694  * Return values from many small tests are accumulated together and
695  * used as final checksum, which can be compared to some expected
696  * value. Running the tests not individually, but in a batch helps
697  * to reduce process start overhead and also allows to parallelize
698  * testing and utilize multiple CPU cores.
699  *
700  * The resulting executable can be run without any arguments. In
701  * this case it runs a batch of tests starting from 1 and up to
702  * 'default_number_of_iterations'. The resulting checksum is
703  * compared with 'expected_checksum' and FAIL or PASS verdict
704  * depends on the result of this comparison.
705  *
706  * If the executable is run with 2 numbers provided as command line
707  * arguments, they specify the starting and ending numbers for a test
708  * batch.
709  *
710  * If the executable is run with only one number provided as a command
711  * line argument, then this number is used to call the callback function
712  * once, and also with verbose flag set.
713  */
714 int
715 fuzzer_test_main (const char *test_name,
716                   int         default_number_of_iterations,
717                   uint32_t    expected_checksum,
718                   uint32_t    (*test_function)(int testnum, int verbose),
719                   int         argc,
720                   const char *argv[])
721 {
722     int i, n1 = 1, n2 = 0;
723     uint32_t checksum = 0;
724     int verbose = getenv ("VERBOSE") != NULL;
725
726     if (argc >= 3)
727     {
728         n1 = atoi (argv[1]);
729         n2 = atoi (argv[2]);
730         if (n2 < n1)
731         {
732             printf ("invalid test range\n");
733             return 1;
734         }
735     }
736     else if (argc >= 2)
737     {
738         n2 = atoi (argv[1]);
739
740         checksum = call_test_function (test_function, n2, 1);
741
742         printf ("%d: checksum=%08X\n", n2, checksum);
743         return 0;
744     }
745     else
746     {
747         n1 = 1;
748         n2 = default_number_of_iterations;
749     }
750
751 #ifdef USE_OPENMP
752     #pragma omp parallel for reduction(+:checksum) default(none) \
753                                         shared(n1, n2, test_function, verbose)
754 #endif
755     for (i = n1; i <= n2; i++)
756     {
757         uint32_t crc = call_test_function (test_function, i, 0);
758         if (verbose)
759             printf ("%d: %08X\n", i, crc);
760         checksum += crc;
761     }
762
763     if (n1 == 1 && n2 == default_number_of_iterations)
764     {
765         if (checksum == expected_checksum)
766         {
767             printf ("%s test passed (checksum=%08X)\n",
768                     test_name, checksum);
769         }
770         else
771         {
772             printf ("%s test failed! (checksum=%08X, expected %08X)\n",
773                     test_name, checksum, expected_checksum);
774             return 1;
775         }
776     }
777     else
778     {
779         printf ("%d-%d: checksum=%08X\n", n1, n2, checksum);
780     }
781
782     return 0;
783 }
784
785 /* Try to obtain current time in seconds */
786 double
787 gettime (void)
788 {
789 #ifdef HAVE_GETTIMEOFDAY
790     struct timeval tv;
791
792     gettimeofday (&tv, NULL);
793     return (double)((int64_t)tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.;
794 #else
795     return (double)clock() / (double)CLOCKS_PER_SEC;
796 #endif
797 }
798
799 uint32_t
800 get_random_seed (void)
801 {
802     union { double d; uint32_t u32; } t;
803     t.d = gettime();
804     prng_srand (t.u32);
805
806     return prng_rand ();
807 }
808
809 #ifdef HAVE_SIGACTION
810 #ifdef HAVE_ALARM
811 static const char *global_msg;
812
813 static void
814 on_alarm (int signo)
815 {
816     printf ("%s\n", global_msg);
817     exit (1);
818 }
819 #endif
820 #endif
821
822 void
823 fail_after (int seconds, const char *msg)
824 {
825 #ifdef HAVE_SIGACTION
826 #ifdef HAVE_ALARM
827     struct sigaction action;
828
829     global_msg = msg;
830
831     memset (&action, 0, sizeof (action));
832     action.sa_handler = on_alarm;
833
834     alarm (seconds);
835
836     sigaction (SIGALRM, &action, NULL);
837 #endif
838 #endif
839 }
840
841 void
842 enable_divbyzero_exceptions (void)
843 {
844 #ifdef HAVE_FENV_H
845 #ifdef HAVE_FEENABLEEXCEPT
846     feenableexcept (FE_DIVBYZERO);
847 #endif
848 #endif
849 }
850
851 void *
852 aligned_malloc (size_t align, size_t size)
853 {
854     void *result;
855
856 #ifdef HAVE_POSIX_MEMALIGN
857     if (posix_memalign (&result, align, size) != 0)
858       result = NULL;
859 #else
860     result = malloc (size);
861 #endif
862
863     return result;
864 }
865
866 #define CONVERT_15(c, is_rgb)                                           \
867     (is_rgb?                                                            \
868      ((((c) >> 3) & 0x001f) |                                           \
869       (((c) >> 6) & 0x03e0) |                                           \
870       (((c) >> 9) & 0x7c00)) :                                          \
871      (((((c) >> 16) & 0xff) * 153 +                                     \
872        (((c) >>  8) & 0xff) * 301 +                                     \
873        (((c)      ) & 0xff) * 58) >> 2))
874
875 double
876 convert_srgb_to_linear (double c)
877 {
878     if (c <= 0.04045)
879         return c / 12.92;
880     else
881         return pow ((c + 0.055) / 1.055, 2.4);
882 }
883
884 double
885 convert_linear_to_srgb (double c)
886 {
887     if (c <= 0.0031308)
888         return c * 12.92;
889     else
890         return 1.055 * pow (c, 1.0/2.4) - 0.055;
891 }
892
893 void
894 initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
895 {
896     int i;
897     uint32_t mask = (1 << depth) - 1;
898
899     for (i = 0; i < 32768; ++i)
900         palette->ent[i] = prng_rand() & mask;
901
902     memset (palette->rgba, 0, sizeof (palette->rgba));
903
904     for (i = 0; i < mask + 1; ++i)
905     {
906         uint32_t rgba24;
907         pixman_bool_t retry;
908         uint32_t i15;
909
910         /* We filled the rgb->index map with random numbers, but we
911          * do need the ability to round trip, that is if some indexed
912          * color expands to an argb24, then the 15 bit version of that
913          * color must map back to the index. Anything else, we don't
914          * care about too much.
915          */
916         do
917         {
918             uint32_t old_idx;
919
920             rgba24 = prng_rand();
921             i15 = CONVERT_15 (rgba24, is_rgb);
922
923             old_idx = palette->ent[i15];
924             if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
925                 retry = 1;
926             else
927                 retry = 0;
928         } while (retry);
929
930         palette->rgba[i] = rgba24;
931         palette->ent[i15] = i;
932     }
933
934     for (i = 0; i < mask + 1; ++i)
935     {
936         assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
937     }
938 }
939
940 const char *
941 operator_name (pixman_op_t op)
942 {
943     switch (op)
944     {
945     case PIXMAN_OP_CLEAR: return "PIXMAN_OP_CLEAR";
946     case PIXMAN_OP_SRC: return "PIXMAN_OP_SRC";
947     case PIXMAN_OP_DST: return "PIXMAN_OP_DST";
948     case PIXMAN_OP_OVER: return "PIXMAN_OP_OVER";
949     case PIXMAN_OP_OVER_REVERSE: return "PIXMAN_OP_OVER_REVERSE";
950     case PIXMAN_OP_IN: return "PIXMAN_OP_IN";
951     case PIXMAN_OP_IN_REVERSE: return "PIXMAN_OP_IN_REVERSE";
952     case PIXMAN_OP_OUT: return "PIXMAN_OP_OUT";
953     case PIXMAN_OP_OUT_REVERSE: return "PIXMAN_OP_OUT_REVERSE";
954     case PIXMAN_OP_ATOP: return "PIXMAN_OP_ATOP";
955     case PIXMAN_OP_ATOP_REVERSE: return "PIXMAN_OP_ATOP_REVERSE";
956     case PIXMAN_OP_XOR: return "PIXMAN_OP_XOR";
957     case PIXMAN_OP_ADD: return "PIXMAN_OP_ADD";
958     case PIXMAN_OP_SATURATE: return "PIXMAN_OP_SATURATE";
959
960     case PIXMAN_OP_DISJOINT_CLEAR: return "PIXMAN_OP_DISJOINT_CLEAR";
961     case PIXMAN_OP_DISJOINT_SRC: return "PIXMAN_OP_DISJOINT_SRC";
962     case PIXMAN_OP_DISJOINT_DST: return "PIXMAN_OP_DISJOINT_DST";
963     case PIXMAN_OP_DISJOINT_OVER: return "PIXMAN_OP_DISJOINT_OVER";
964     case PIXMAN_OP_DISJOINT_OVER_REVERSE: return "PIXMAN_OP_DISJOINT_OVER_REVERSE";
965     case PIXMAN_OP_DISJOINT_IN: return "PIXMAN_OP_DISJOINT_IN";
966     case PIXMAN_OP_DISJOINT_IN_REVERSE: return "PIXMAN_OP_DISJOINT_IN_REVERSE";
967     case PIXMAN_OP_DISJOINT_OUT: return "PIXMAN_OP_DISJOINT_OUT";
968     case PIXMAN_OP_DISJOINT_OUT_REVERSE: return "PIXMAN_OP_DISJOINT_OUT_REVERSE";
969     case PIXMAN_OP_DISJOINT_ATOP: return "PIXMAN_OP_DISJOINT_ATOP";
970     case PIXMAN_OP_DISJOINT_ATOP_REVERSE: return "PIXMAN_OP_DISJOINT_ATOP_REVERSE";
971     case PIXMAN_OP_DISJOINT_XOR: return "PIXMAN_OP_DISJOINT_XOR";
972
973     case PIXMAN_OP_CONJOINT_CLEAR: return "PIXMAN_OP_CONJOINT_CLEAR";
974     case PIXMAN_OP_CONJOINT_SRC: return "PIXMAN_OP_CONJOINT_SRC";
975     case PIXMAN_OP_CONJOINT_DST: return "PIXMAN_OP_CONJOINT_DST";
976     case PIXMAN_OP_CONJOINT_OVER: return "PIXMAN_OP_CONJOINT_OVER";
977     case PIXMAN_OP_CONJOINT_OVER_REVERSE: return "PIXMAN_OP_CONJOINT_OVER_REVERSE";
978     case PIXMAN_OP_CONJOINT_IN: return "PIXMAN_OP_CONJOINT_IN";
979     case PIXMAN_OP_CONJOINT_IN_REVERSE: return "PIXMAN_OP_CONJOINT_IN_REVERSE";
980     case PIXMAN_OP_CONJOINT_OUT: return "PIXMAN_OP_CONJOINT_OUT";
981     case PIXMAN_OP_CONJOINT_OUT_REVERSE: return "PIXMAN_OP_CONJOINT_OUT_REVERSE";
982     case PIXMAN_OP_CONJOINT_ATOP: return "PIXMAN_OP_CONJOINT_ATOP";
983     case PIXMAN_OP_CONJOINT_ATOP_REVERSE: return "PIXMAN_OP_CONJOINT_ATOP_REVERSE";
984     case PIXMAN_OP_CONJOINT_XOR: return "PIXMAN_OP_CONJOINT_XOR";
985
986     case PIXMAN_OP_MULTIPLY: return "PIXMAN_OP_MULTIPLY";
987     case PIXMAN_OP_SCREEN: return "PIXMAN_OP_SCREEN";
988     case PIXMAN_OP_OVERLAY: return "PIXMAN_OP_OVERLAY";
989     case PIXMAN_OP_DARKEN: return "PIXMAN_OP_DARKEN";
990     case PIXMAN_OP_LIGHTEN: return "PIXMAN_OP_LIGHTEN";
991     case PIXMAN_OP_COLOR_DODGE: return "PIXMAN_OP_COLOR_DODGE";
992     case PIXMAN_OP_COLOR_BURN: return "PIXMAN_OP_COLOR_BURN";
993     case PIXMAN_OP_HARD_LIGHT: return "PIXMAN_OP_HARD_LIGHT";
994     case PIXMAN_OP_SOFT_LIGHT: return "PIXMAN_OP_SOFT_LIGHT";
995     case PIXMAN_OP_DIFFERENCE: return "PIXMAN_OP_DIFFERENCE";
996     case PIXMAN_OP_EXCLUSION: return "PIXMAN_OP_EXCLUSION";
997     case PIXMAN_OP_HSL_HUE: return "PIXMAN_OP_HSL_HUE";
998     case PIXMAN_OP_HSL_SATURATION: return "PIXMAN_OP_HSL_SATURATION";
999     case PIXMAN_OP_HSL_COLOR: return "PIXMAN_OP_HSL_COLOR";
1000     case PIXMAN_OP_HSL_LUMINOSITY: return "PIXMAN_OP_HSL_LUMINOSITY";
1001
1002     case PIXMAN_OP_NONE:
1003         return "<invalid operator 'none'>";
1004     };
1005
1006     return "<unknown operator>";
1007 }
1008
1009 const char *
1010 format_name (pixman_format_code_t format)
1011 {
1012     switch (format)
1013     {
1014 /* 32bpp formats */
1015     case PIXMAN_a8r8g8b8: return "a8r8g8b8";
1016     case PIXMAN_x8r8g8b8: return "x8r8g8b8";
1017     case PIXMAN_a8b8g8r8: return "a8b8g8r8";
1018     case PIXMAN_x8b8g8r8: return "x8b8g8r8";
1019     case PIXMAN_b8g8r8a8: return "b8g8r8a8";
1020     case PIXMAN_b8g8r8x8: return "b8g8r8x8";
1021     case PIXMAN_r8g8b8a8: return "r8g8b8a8";
1022     case PIXMAN_r8g8b8x8: return "r8g8b8x8";
1023     case PIXMAN_x14r6g6b6: return "x14r6g6b6";
1024     case PIXMAN_x2r10g10b10: return "x2r10g10b10";
1025     case PIXMAN_a2r10g10b10: return "a2r10g10b10";
1026     case PIXMAN_x2b10g10r10: return "x2b10g10r10";
1027     case PIXMAN_a2b10g10r10: return "a2b10g10r10";
1028
1029 /* sRGB formats */
1030     case PIXMAN_a8r8g8b8_sRGB: return "a8r8g8b8_sRGB";
1031
1032 /* 24bpp formats */
1033     case PIXMAN_r8g8b8: return "r8g8b8";
1034     case PIXMAN_b8g8r8: return "b8g8r8";
1035
1036 /* 16bpp formats */
1037     case PIXMAN_r5g6b5: return "r5g6b5";
1038     case PIXMAN_b5g6r5: return "b5g6r5";
1039
1040     case PIXMAN_a1r5g5b5: return "a1r5g5b5";
1041     case PIXMAN_x1r5g5b5: return "x1r5g5b5";
1042     case PIXMAN_a1b5g5r5: return "a1b5g5r5";
1043     case PIXMAN_x1b5g5r5: return "x1b5g5r5";
1044     case PIXMAN_a4r4g4b4: return "a4r4g4b4";
1045     case PIXMAN_x4r4g4b4: return "x4r4g4b4";
1046     case PIXMAN_a4b4g4r4: return "a4b4g4r4";
1047     case PIXMAN_x4b4g4r4: return "x4b4g4r4";
1048
1049 /* 8bpp formats */
1050     case PIXMAN_a8: return "a8";
1051     case PIXMAN_r3g3b2: return "r3g3b2";
1052     case PIXMAN_b2g3r3: return "b2g3r3";
1053     case PIXMAN_a2r2g2b2: return "a2r2g2b2";
1054     case PIXMAN_a2b2g2r2: return "a2b2g2r2";
1055
1056 #if 0
1057     case PIXMAN_x4c4: return "x4c4";
1058     case PIXMAN_g8: return "g8";
1059 #endif
1060     case PIXMAN_c8: return "x4c4 / c8";
1061     case PIXMAN_x4g4: return "x4g4 / g8";
1062
1063     case PIXMAN_x4a4: return "x4a4";
1064
1065 /* 4bpp formats */
1066     case PIXMAN_a4: return "a4";
1067     case PIXMAN_r1g2b1: return "r1g2b1";
1068     case PIXMAN_b1g2r1: return "b1g2r1";
1069     case PIXMAN_a1r1g1b1: return "a1r1g1b1";
1070     case PIXMAN_a1b1g1r1: return "a1b1g1r1";
1071
1072     case PIXMAN_c4: return "c4";
1073     case PIXMAN_g4: return "g4";
1074
1075 /* 1bpp formats */
1076     case PIXMAN_a1: return "a1";
1077
1078     case PIXMAN_g1: return "g1";
1079
1080 /* YUV formats */
1081     case PIXMAN_yuy2: return "yuy2";
1082     case PIXMAN_yv12: return "yv12";
1083     };
1084
1085     /* Fake formats.
1086      *
1087      * This is separate switch to prevent GCC from complaining
1088      * that the values are not in the pixman_format_code_t enum.
1089      */
1090     switch ((uint32_t)format)
1091     {
1092     case PIXMAN_null: return "null"; 
1093     case PIXMAN_solid: return "solid"; 
1094     case PIXMAN_pixbuf: return "pixbuf"; 
1095     case PIXMAN_rpixbuf: return "rpixbuf"; 
1096     case PIXMAN_unknown: return "unknown"; 
1097     };
1098
1099     return "<unknown format>";
1100 };
1101
1102 static double
1103 calc_op (pixman_op_t op, double src, double dst, double srca, double dsta)
1104 {
1105 #define mult_chan(src, dst, Fa, Fb) MIN ((src) * (Fa) + (dst) * (Fb), 1.0)
1106
1107     double Fa, Fb;
1108
1109     switch (op)
1110     {
1111     case PIXMAN_OP_CLEAR:
1112     case PIXMAN_OP_DISJOINT_CLEAR:
1113     case PIXMAN_OP_CONJOINT_CLEAR:
1114         return mult_chan (src, dst, 0.0, 0.0);
1115
1116     case PIXMAN_OP_SRC:
1117     case PIXMAN_OP_DISJOINT_SRC:
1118     case PIXMAN_OP_CONJOINT_SRC:
1119         return mult_chan (src, dst, 1.0, 0.0);
1120
1121     case PIXMAN_OP_DST:
1122     case PIXMAN_OP_DISJOINT_DST:
1123     case PIXMAN_OP_CONJOINT_DST:
1124         return mult_chan (src, dst, 0.0, 1.0);
1125
1126     case PIXMAN_OP_OVER:
1127         return mult_chan (src, dst, 1.0, 1.0 - srca);
1128
1129     case PIXMAN_OP_OVER_REVERSE:
1130         return mult_chan (src, dst, 1.0 - dsta, 1.0);
1131
1132     case PIXMAN_OP_IN:
1133         return mult_chan (src, dst, dsta, 0.0);
1134
1135     case PIXMAN_OP_IN_REVERSE:
1136         return mult_chan (src, dst, 0.0, srca);
1137
1138     case PIXMAN_OP_OUT:
1139         return mult_chan (src, dst, 1.0 - dsta, 0.0);
1140
1141     case PIXMAN_OP_OUT_REVERSE:
1142         return mult_chan (src, dst, 0.0, 1.0 - srca);
1143
1144     case PIXMAN_OP_ATOP:
1145         return mult_chan (src, dst, dsta, 1.0 - srca);
1146
1147     case PIXMAN_OP_ATOP_REVERSE:
1148         return mult_chan (src, dst, 1.0 - dsta,  srca);
1149
1150     case PIXMAN_OP_XOR:
1151         return mult_chan (src, dst, 1.0 - dsta, 1.0 - srca);
1152
1153     case PIXMAN_OP_ADD:
1154         return mult_chan (src, dst, 1.0, 1.0);
1155
1156     case PIXMAN_OP_SATURATE:
1157     case PIXMAN_OP_DISJOINT_OVER_REVERSE:
1158         if (srca == 0.0)
1159             Fa = 1.0;
1160         else
1161             Fa = MIN (1.0, (1.0 - dsta) / srca);
1162         return mult_chan (src, dst, Fa, 1.0);
1163
1164     case PIXMAN_OP_DISJOINT_OVER:
1165         if (dsta == 0.0)
1166             Fb = 1.0;
1167         else
1168             Fb = MIN (1.0, (1.0 - srca) / dsta);
1169         return mult_chan (src, dst, 1.0, Fb);
1170
1171     case PIXMAN_OP_DISJOINT_IN:
1172         if (srca == 0.0)
1173             Fa = 0.0;
1174         else
1175             Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
1176         return mult_chan (src, dst, Fa, 0.0);
1177
1178     case PIXMAN_OP_DISJOINT_IN_REVERSE:
1179         if (dsta == 0.0)
1180             Fb = 0.0;
1181         else
1182             Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
1183         return mult_chan (src, dst, 0.0, Fb);
1184
1185     case PIXMAN_OP_DISJOINT_OUT:
1186         if (srca == 0.0)
1187             Fa = 1.0;
1188         else
1189             Fa = MIN (1.0, (1.0 - dsta) / srca);
1190         return mult_chan (src, dst, Fa, 0.0);
1191
1192     case PIXMAN_OP_DISJOINT_OUT_REVERSE:
1193         if (dsta == 0.0)
1194             Fb = 1.0;
1195         else
1196             Fb = MIN (1.0, (1.0 - srca) / dsta);
1197         return mult_chan (src, dst, 0.0, Fb);
1198
1199     case PIXMAN_OP_DISJOINT_ATOP:
1200         if (srca == 0.0)
1201             Fa = 0.0;
1202         else
1203             Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
1204         if (dsta == 0.0)
1205             Fb = 1.0;
1206         else
1207             Fb = MIN (1.0, (1.0 - srca) / dsta);
1208         return mult_chan (src, dst, Fa, Fb);
1209
1210     case PIXMAN_OP_DISJOINT_ATOP_REVERSE:
1211         if (srca == 0.0)
1212             Fa = 1.0;
1213         else
1214             Fa = MIN (1.0, (1.0 - dsta) / srca);
1215         if (dsta == 0.0)
1216             Fb = 0.0;
1217         else
1218             Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
1219         return mult_chan (src, dst, Fa, Fb);
1220
1221     case PIXMAN_OP_DISJOINT_XOR:
1222         if (srca == 0.0)
1223             Fa = 1.0;
1224         else
1225             Fa = MIN (1.0, (1.0 - dsta) / srca);
1226         if (dsta == 0.0)
1227             Fb = 1.0;
1228         else
1229             Fb = MIN (1.0, (1.0 - srca) / dsta);
1230         return mult_chan (src, dst, Fa, Fb);
1231
1232     case PIXMAN_OP_CONJOINT_OVER:
1233         if (dsta == 0.0)
1234             Fb = 0.0;
1235         else
1236             Fb = MAX (0.0, 1.0 - srca / dsta);
1237         return mult_chan (src, dst, 1.0, Fb);
1238
1239     case PIXMAN_OP_CONJOINT_OVER_REVERSE:
1240         if (srca == 0.0)
1241             Fa = 0.0;
1242         else
1243             Fa = MAX (0.0, 1.0 - dsta / srca);
1244         return mult_chan (src, dst, Fa, 1.0);
1245
1246     case PIXMAN_OP_CONJOINT_IN:
1247         if (srca == 0.0)
1248             Fa = 1.0;
1249         else
1250             Fa = MIN (1.0, dsta / srca);
1251         return mult_chan (src, dst, Fa, 0.0);
1252
1253     case PIXMAN_OP_CONJOINT_IN_REVERSE:
1254         if (dsta == 0.0)
1255             Fb = 1.0;
1256         else
1257             Fb = MIN (1.0, srca / dsta);
1258         return mult_chan (src, dst, 0.0, Fb);
1259
1260     case PIXMAN_OP_CONJOINT_OUT:
1261         if (srca == 0.0)
1262             Fa = 0.0;
1263         else
1264             Fa = MAX (0.0, 1.0 - dsta / srca);
1265         return mult_chan (src, dst, Fa, 0.0);
1266
1267     case PIXMAN_OP_CONJOINT_OUT_REVERSE:
1268         if (dsta == 0.0)
1269             Fb = 0.0;
1270         else
1271             Fb = MAX (0.0, 1.0 - srca / dsta);
1272         return mult_chan (src, dst, 0.0, Fb);
1273
1274     case PIXMAN_OP_CONJOINT_ATOP:
1275         if (srca == 0.0)
1276             Fa = 1.0;
1277         else
1278             Fa = MIN (1.0, dsta / srca);
1279         if (dsta == 0.0)
1280             Fb = 0.0;
1281         else
1282             Fb = MAX (0.0, 1.0 - srca / dsta);
1283         return mult_chan (src, dst, Fa, Fb);
1284
1285     case PIXMAN_OP_CONJOINT_ATOP_REVERSE:
1286         if (srca == 0.0)
1287             Fa = 0.0;
1288         else
1289             Fa = MAX (0.0, 1.0 - dsta / srca);
1290         if (dsta == 0.0)
1291             Fb = 1.0;
1292         else
1293             Fb = MIN (1.0, srca / dsta);
1294         return mult_chan (src, dst, Fa, Fb);
1295
1296     case PIXMAN_OP_CONJOINT_XOR:
1297         if (srca == 0.0)
1298             Fa = 0.0;
1299         else
1300             Fa = MAX (0.0, 1.0 - dsta / srca);
1301         if (dsta == 0.0)
1302             Fb = 0.0;
1303         else
1304             Fb = MAX (0.0, 1.0 - srca / dsta);
1305         return mult_chan (src, dst, Fa, Fb);
1306
1307     case PIXMAN_OP_MULTIPLY:
1308     case PIXMAN_OP_SCREEN:
1309     case PIXMAN_OP_OVERLAY:
1310     case PIXMAN_OP_DARKEN:
1311     case PIXMAN_OP_LIGHTEN:
1312     case PIXMAN_OP_COLOR_DODGE:
1313     case PIXMAN_OP_COLOR_BURN:
1314     case PIXMAN_OP_HARD_LIGHT:
1315     case PIXMAN_OP_SOFT_LIGHT:
1316     case PIXMAN_OP_DIFFERENCE:
1317     case PIXMAN_OP_EXCLUSION:
1318     case PIXMAN_OP_HSL_HUE:
1319     case PIXMAN_OP_HSL_SATURATION:
1320     case PIXMAN_OP_HSL_COLOR:
1321     case PIXMAN_OP_HSL_LUMINOSITY:
1322     default:
1323         abort();
1324         return 0; /* silence MSVC */
1325     }
1326 #undef mult_chan
1327 }
1328
1329 void
1330 do_composite (pixman_op_t op,
1331               const color_t *src,
1332               const color_t *mask,
1333               const color_t *dst,
1334               color_t *result,
1335               pixman_bool_t component_alpha)
1336 {
1337     color_t srcval, srcalpha;
1338
1339     if (mask == NULL)
1340     {
1341         srcval = *src;
1342
1343         srcalpha.r = src->a;
1344         srcalpha.g = src->a;
1345         srcalpha.b = src->a;
1346         srcalpha.a = src->a;
1347     }
1348     else if (component_alpha)
1349     {
1350         srcval.r = src->r * mask->r;
1351         srcval.g = src->g * mask->g;
1352         srcval.b = src->b * mask->b;
1353         srcval.a = src->a * mask->a;
1354
1355         srcalpha.r = src->a * mask->r;
1356         srcalpha.g = src->a * mask->g;
1357         srcalpha.b = src->a * mask->b;
1358         srcalpha.a = src->a * mask->a;
1359     }
1360     else
1361     {
1362         srcval.r = src->r * mask->a;
1363         srcval.g = src->g * mask->a;
1364         srcval.b = src->b * mask->a;
1365         srcval.a = src->a * mask->a;
1366
1367         srcalpha.r = src->a * mask->a;
1368         srcalpha.g = src->a * mask->a;
1369         srcalpha.b = src->a * mask->a;
1370         srcalpha.a = src->a * mask->a;
1371     }
1372
1373     result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a);
1374     result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a);
1375     result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a);
1376     result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a);
1377 }
1378
1379 static double
1380 round_channel (double p, int m)
1381 {
1382     int t;
1383     double r;
1384
1385     t = p * ((1 << m));
1386     t -= t >> m;
1387
1388     r = t / (double)((1 << m) - 1);
1389
1390     return r;
1391 }
1392
1393 void
1394 round_color (pixman_format_code_t format, color_t *color)
1395 {
1396     if (PIXMAN_FORMAT_R (format) == 0)
1397     {
1398         color->r = 0.0;
1399         color->g = 0.0;
1400         color->b = 0.0;
1401     }
1402     else
1403     {
1404         color->r = round_channel (color->r, PIXMAN_FORMAT_R (format));
1405         color->g = round_channel (color->g, PIXMAN_FORMAT_G (format));
1406         color->b = round_channel (color->b, PIXMAN_FORMAT_B (format));
1407     }
1408
1409     if (PIXMAN_FORMAT_A (format) == 0)
1410         color->a = 1;
1411     else
1412         color->a = round_channel (color->a, PIXMAN_FORMAT_A (format));
1413 }
1414
1415 /* Check whether @pixel is a valid quantization of the a, r, g, b
1416  * parameters. Some slack is permitted.
1417  */
1418 void
1419 pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format)
1420 {
1421     assert (PIXMAN_FORMAT_VIS (format));
1422
1423     checker->format = format;
1424
1425     switch (PIXMAN_FORMAT_TYPE (format))
1426     {
1427     case PIXMAN_TYPE_A:
1428         checker->bs = 0;
1429         checker->gs = 0;
1430         checker->rs = 0;
1431         checker->as = 0;
1432         break;
1433
1434     case PIXMAN_TYPE_ARGB:
1435     case PIXMAN_TYPE_ARGB_SRGB:
1436         checker->bs = 0;
1437         checker->gs = checker->bs + PIXMAN_FORMAT_B (format);
1438         checker->rs = checker->gs + PIXMAN_FORMAT_G (format);
1439         checker->as = checker->rs + PIXMAN_FORMAT_R (format);
1440         break;
1441
1442     case PIXMAN_TYPE_ABGR:
1443         checker->rs = 0;
1444         checker->gs = checker->rs + PIXMAN_FORMAT_R (format);
1445         checker->bs = checker->gs + PIXMAN_FORMAT_G (format);
1446         checker->as = checker->bs + PIXMAN_FORMAT_B (format);
1447         break;
1448
1449     case PIXMAN_TYPE_BGRA:
1450         /* With BGRA formats we start counting at the high end of the pixel */
1451         checker->bs = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format);
1452         checker->gs = checker->bs - PIXMAN_FORMAT_B (format);
1453         checker->rs = checker->gs - PIXMAN_FORMAT_G (format);
1454         checker->as = checker->rs - PIXMAN_FORMAT_R (format);
1455         break;
1456
1457     case PIXMAN_TYPE_RGBA:
1458         /* With BGRA formats we start counting at the high end of the pixel */
1459         checker->rs = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format);
1460         checker->gs = checker->rs - PIXMAN_FORMAT_R (format);
1461         checker->bs = checker->gs - PIXMAN_FORMAT_G (format);
1462         checker->as = checker->bs - PIXMAN_FORMAT_B (format);
1463         break;
1464
1465     default:
1466         assert (0);
1467         break;
1468     }
1469
1470     checker->am = ((1 << PIXMAN_FORMAT_A (format)) - 1) << checker->as;
1471     checker->rm = ((1 << PIXMAN_FORMAT_R (format)) - 1) << checker->rs;
1472     checker->gm = ((1 << PIXMAN_FORMAT_G (format)) - 1) << checker->gs;
1473     checker->bm = ((1 << PIXMAN_FORMAT_B (format)) - 1) << checker->bs;
1474
1475     checker->aw = PIXMAN_FORMAT_A (format);
1476     checker->rw = PIXMAN_FORMAT_R (format);
1477     checker->gw = PIXMAN_FORMAT_G (format);
1478     checker->bw = PIXMAN_FORMAT_B (format);
1479 }
1480
1481 void
1482 pixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel,
1483                            int *a, int *r, int *g, int *b)
1484 {
1485     *a = (pixel & checker->am) >> checker->as;
1486     *r = (pixel & checker->rm) >> checker->rs;
1487     *g = (pixel & checker->gm) >> checker->gs;
1488     *b = (pixel & checker->bm) >> checker->bs;
1489 }
1490
1491 void
1492 pixel_checker_get_masks (const pixel_checker_t *checker,
1493                          uint32_t              *am,
1494                          uint32_t              *rm,
1495                          uint32_t              *gm,
1496                          uint32_t              *bm)
1497 {
1498     if (am)
1499         *am = checker->am;
1500     if (rm)
1501         *rm = checker->rm;
1502     if (gm)
1503         *gm = checker->gm;
1504     if (bm)
1505         *bm = checker->bm;
1506 }
1507
1508 void
1509 pixel_checker_convert_pixel_to_color (const pixel_checker_t *checker,
1510                                       uint32_t pixel, color_t *color)
1511 {
1512     int a, r, g, b;
1513
1514     pixel_checker_split_pixel (checker, pixel, &a, &r, &g, &b);
1515
1516     if (checker->am == 0)
1517         color->a = 1.0;
1518     else
1519         color->a = a / (double)(checker->am >> checker->as);
1520
1521     if (checker->rm == 0)
1522         color->r = 0.0;
1523     else
1524         color->r = r / (double)(checker->rm >> checker->rs);
1525
1526     if (checker->gm == 0)
1527         color->g = 0.0;
1528     else
1529         color->g = g / (double)(checker->gm >> checker->gs);
1530
1531     if (checker->bm == 0)
1532         color->b = 0.0;
1533     else
1534         color->b = b / (double)(checker->bm >> checker->bs);
1535
1536     if (PIXMAN_FORMAT_TYPE (checker->format) == PIXMAN_TYPE_ARGB_SRGB)
1537     {
1538         color->r = convert_srgb_to_linear (color->r);
1539         color->g = convert_srgb_to_linear (color->g);
1540         color->b = convert_srgb_to_linear (color->b);
1541     }
1542 }
1543
1544 static int32_t
1545 convert (double v, uint32_t width, uint32_t mask, uint32_t shift, double def)
1546 {
1547     int32_t r;
1548
1549     if (!mask)
1550         v = def;
1551
1552     r = (v * ((mask >> shift) + 1));
1553     r -= r >> width;
1554
1555     return r;
1556 }
1557
1558 static void
1559 get_limits (const pixel_checker_t *checker, double limit,
1560             color_t *color,
1561             int *ao, int *ro, int *go, int *bo)
1562 {
1563     color_t tmp;
1564
1565     if (PIXMAN_FORMAT_TYPE (checker->format) == PIXMAN_TYPE_ARGB_SRGB)
1566     {
1567         tmp.a = color->a;
1568         tmp.r = convert_linear_to_srgb (color->r);
1569         tmp.g = convert_linear_to_srgb (color->g);
1570         tmp.b = convert_linear_to_srgb (color->b);
1571
1572         color = &tmp;
1573     }
1574     
1575     *ao = convert (color->a + limit, checker->aw, checker->am, checker->as, 1.0);
1576     *ro = convert (color->r + limit, checker->rw, checker->rm, checker->rs, 0.0);
1577     *go = convert (color->g + limit, checker->gw, checker->gm, checker->gs, 0.0);
1578     *bo = convert (color->b + limit, checker->bw, checker->bm, checker->bs, 0.0);
1579 }
1580
1581 /* The acceptable deviation in units of [0.0, 1.0]
1582  */
1583 #define DEVIATION (0.0064)
1584
1585 void
1586 pixel_checker_get_max (const pixel_checker_t *checker, color_t *color,
1587                        int *am, int *rm, int *gm, int *bm)
1588 {
1589     get_limits (checker, DEVIATION, color, am, rm, gm, bm);
1590 }
1591
1592 void
1593 pixel_checker_get_min (const pixel_checker_t *checker, color_t *color,
1594                        int *am, int *rm, int *gm, int *bm)
1595 {
1596     get_limits (checker, - DEVIATION, color, am, rm, gm, bm);
1597 }
1598
1599 pixman_bool_t
1600 pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel,
1601                      color_t *color)
1602 {
1603     int32_t a_lo, a_hi, r_lo, r_hi, g_lo, g_hi, b_lo, b_hi;
1604     int32_t ai, ri, gi, bi;
1605     pixman_bool_t result;
1606
1607     pixel_checker_get_min (checker, color, &a_lo, &r_lo, &g_lo, &b_lo);
1608     pixel_checker_get_max (checker, color, &a_hi, &r_hi, &g_hi, &b_hi);
1609     pixel_checker_split_pixel (checker, pixel, &ai, &ri, &gi, &bi);
1610
1611     result =
1612         a_lo <= ai && ai <= a_hi        &&
1613         r_lo <= ri && ri <= r_hi        &&
1614         g_lo <= gi && gi <= g_hi        &&
1615         b_lo <= bi && bi <= b_hi;
1616
1617     return result;
1618 }