utils.c revision 14b11b2b
1#define _GNU_SOURCE
2
3#include "utils.h"
4#include <math.h>
5#include <signal.h>
6#include <stdlib.h>
7#include <float.h>
8#include <ctype.h>
9#include <limits.h>
10
11#ifdef HAVE_GETTIMEOFDAY
12#include <sys/time.h>
13#else
14#include <time.h>
15#endif
16
17#ifdef HAVE_UNISTD_H
18#include <unistd.h>
19#endif
20
21#ifdef HAVE_SYS_MMAN_H
22#include <sys/mman.h>
23#endif
24
25#ifdef HAVE_FENV_H
26#include <fenv.h>
27#endif
28
29#ifdef HAVE_LIBPNG
30#include <png.h>
31#endif
32
33#define ROUND_UP(x, mult) (((x) + (mult) - 1) / (mult) * (mult))
34
35/* Random number generator state
36 */
37
38prng_t prng_state_data = {0};
39prng_t *prng_state = NULL;
40
41/*----------------------------------------------------------------------------*\
42 *  CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
43 *
44 *  This program generates the CRC-32 values for the files named in the
45 *  command-line arguments.  These are the same CRC-32 values used by GZIP,
46 *  PKZIP, and ZMODEM.  The Crc32_ComputeBuf () can also be detached and
47 *  used independently.
48 *
49 *  THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
50 *
51 *  Based on the byte-oriented implementation "File Verification Using CRC"
52 *  by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
53 *
54 *  v1.0.0: original release.
55 *  v1.0.1: fixed printf formats.
56 *  v1.0.2: fixed something else.
57 *  v1.0.3: replaced CRC constant table by generator function.
58 *  v1.0.4: reformatted code, made ANSI C.  1994-12-05.
59 *  v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
60\*----------------------------------------------------------------------------*/
61
62/*----------------------------------------------------------------------------*\
63 *  NAME:
64 *     Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer
65 *  DESCRIPTION:
66 *     Computes or accumulates the CRC-32 value for a memory buffer.
67 *     The 'inCrc32' gives a previously accumulated CRC-32 value to allow
68 *     a CRC to be generated for multiple sequential buffer-fuls of data.
69 *     The 'inCrc32' for the first buffer must be zero.
70 *  ARGUMENTS:
71 *     inCrc32 - accumulated CRC-32 value, must be 0 on first call
72 *     buf     - buffer to compute CRC-32 value for
73 *     bufLen  - number of bytes in buffer
74 *  RETURNS:
75 *     crc32 - computed CRC-32 value
76 *  ERRORS:
77 *     (no errors are possible)
78\*----------------------------------------------------------------------------*/
79
80uint32_t
81compute_crc32 (uint32_t    in_crc32,
82	       const void *buf,
83	       size_t      buf_len)
84{
85    static const uint32_t crc_table[256] = {
86	0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
87	0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
88	0x09B64C2B, 0x7EB17CBD,	0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
89	0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
90	0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,	0x14015C4F, 0x63066CD9,
91	0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
92	0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
93	0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
94	0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
95	0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
96	0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
97	0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
98	0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
99	0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
100	0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
101	0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
102	0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
103	0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
104	0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
105	0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
106	0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
107	0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
108	0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
109	0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
110	0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
111	0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
112	0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
113	0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
114	0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
115	0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
116	0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
117	0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
118	0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
119	0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
120	0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
121	0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
122	0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
123	0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
124	0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
125	0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
126	0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
127	0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
128	0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
129    };
130
131    uint32_t              crc32;
132    unsigned char *       byte_buf;
133    size_t                i;
134
135    /* accumulate crc32 for buffer */
136    crc32 = in_crc32 ^ 0xFFFFFFFF;
137    byte_buf = (unsigned char*) buf;
138
139    for (i = 0; i < buf_len; i++)
140	crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF];
141
142    return (crc32 ^ 0xFFFFFFFF);
143}
144
145static uint32_t
146compute_crc32_for_image_internal (uint32_t        crc32,
147				  pixman_image_t *img,
148				  pixman_bool_t	  remove_alpha,
149				  pixman_bool_t	  remove_rgb)
150{
151    pixman_format_code_t fmt = pixman_image_get_format (img);
152    uint32_t *data = pixman_image_get_data (img);
153    int stride = pixman_image_get_stride (img);
154    int height = pixman_image_get_height (img);
155    uint32_t mask = 0xffffffff;
156    int i;
157
158    if (stride < 0)
159    {
160	data += (stride / 4) * (height - 1);
161	stride = - stride;
162    }
163
164    /* mask unused 'x' part */
165    if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
166	PIXMAN_FORMAT_DEPTH (fmt) != 0)
167    {
168	uint32_t m = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;
169
170	if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
171	    PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
172	{
173	    m <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
174	}
175
176	mask &= m;
177    }
178
179    /* mask alpha channel */
180    if (remove_alpha && PIXMAN_FORMAT_A (fmt))
181    {
182	uint32_t m;
183
184	if (PIXMAN_FORMAT_BPP (fmt) == 32)
185	    m = 0xffffffff;
186	else
187	    m = (1 << PIXMAN_FORMAT_BPP (fmt)) - 1;
188
189	m >>= PIXMAN_FORMAT_A (fmt);
190
191	if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
192	    PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA ||
193	    PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_A)
194	{
195	    /* Alpha is at the bottom of the pixel */
196	    m <<= PIXMAN_FORMAT_A (fmt);
197	}
198
199	mask &= m;
200    }
201
202    /* mask rgb channels */
203    if (remove_rgb && PIXMAN_FORMAT_RGB (fmt))
204    {
205	uint32_t m = ((uint32_t)~0) >> (32 - PIXMAN_FORMAT_BPP (fmt));
206	uint32_t size = PIXMAN_FORMAT_R (fmt) + PIXMAN_FORMAT_G (fmt) + PIXMAN_FORMAT_B (fmt);
207
208	m &= ~((1 << size) - 1);
209
210	if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
211	    PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
212	{
213	    /* RGB channels are at the top of the pixel */
214	    m >>= size;
215	}
216
217	mask &= m;
218    }
219
220    for (i = 0; i * PIXMAN_FORMAT_BPP (fmt) < 32; i++)
221	mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
222
223    for (i = 0; i < stride * height / 4; i++)
224	data[i] &= mask;
225
226    /* swap endiannes in order to provide identical results on both big
227     * and litte endian systems
228     */
229    image_endian_swap (img);
230
231    return compute_crc32 (crc32, data, stride * height);
232}
233
234uint32_t
235compute_crc32_for_image (uint32_t        crc32,
236			 pixman_image_t *img)
237{
238    if (img->common.alpha_map)
239    {
240	crc32 = compute_crc32_for_image_internal (crc32, img, TRUE, FALSE);
241	crc32 = compute_crc32_for_image_internal (
242	    crc32, (pixman_image_t *)img->common.alpha_map, FALSE, TRUE);
243    }
244    else
245    {
246	crc32 = compute_crc32_for_image_internal (crc32, img, FALSE, FALSE);
247    }
248
249    return crc32;
250}
251
252void
253print_image (pixman_image_t *image)
254{
255    int i, j;
256    int width, height, stride;
257    pixman_format_code_t format;
258    uint8_t *buffer;
259    int s;
260
261    width = pixman_image_get_width (image);
262    height = pixman_image_get_height (image);
263    stride = pixman_image_get_stride (image);
264    format = pixman_image_get_format (image);
265    buffer = (uint8_t *)pixman_image_get_data (image);
266
267    s = (stride >= 0)? stride : - stride;
268
269    printf ("---\n");
270    for (i = 0; i < height; i++)
271    {
272	for (j = 0; j < s; j++)
273	{
274	    if (j == (width * PIXMAN_FORMAT_BPP (format) + 7) / 8)
275		printf ("| ");
276
277	    printf ("%02X ", *((uint8_t *)buffer + i * stride + j));
278	}
279	printf ("\n");
280    }
281    printf ("---\n");
282}
283
284/* perform endian conversion of pixel data
285 */
286void
287image_endian_swap (pixman_image_t *img)
288{
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    int bpp = PIXMAN_FORMAT_BPP (pixman_image_get_format (img));
293    int i, j;
294
295    /* swap bytes only on big endian systems */
296    if (is_little_endian())
297	return;
298
299    if (bpp == 8)
300	return;
301
302    for (i = 0; i < height; i++)
303    {
304	uint8_t *line_data = (uint8_t *)data + stride * i;
305	int s = (stride >= 0)? stride : - stride;
306
307	switch (bpp)
308	{
309	case 1:
310	    for (j = 0; j < s; j++)
311	    {
312		line_data[j] =
313		    ((line_data[j] & 0x80) >> 7) |
314		    ((line_data[j] & 0x40) >> 5) |
315		    ((line_data[j] & 0x20) >> 3) |
316		    ((line_data[j] & 0x10) >> 1) |
317		    ((line_data[j] & 0x08) << 1) |
318		    ((line_data[j] & 0x04) << 3) |
319		    ((line_data[j] & 0x02) << 5) |
320		    ((line_data[j] & 0x01) << 7);
321	    }
322	    break;
323	case 4:
324	    for (j = 0; j < s; j++)
325	    {
326		line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4);
327	    }
328	    break;
329	case 16:
330	    for (j = 0; j + 2 <= s; j += 2)
331	    {
332		char t1 = line_data[j + 0];
333		char t2 = line_data[j + 1];
334
335		line_data[j + 1] = t1;
336		line_data[j + 0] = t2;
337	    }
338	    break;
339	case 24:
340	    for (j = 0; j + 3 <= s; j += 3)
341	    {
342		char t1 = line_data[j + 0];
343		char t2 = line_data[j + 1];
344		char t3 = line_data[j + 2];
345
346		line_data[j + 2] = t1;
347		line_data[j + 1] = t2;
348		line_data[j + 0] = t3;
349	    }
350	    break;
351	case 32:
352	    for (j = 0; j + 4 <= s; j += 4)
353	    {
354		char t1 = line_data[j + 0];
355		char t2 = line_data[j + 1];
356		char t3 = line_data[j + 2];
357		char t4 = line_data[j + 3];
358
359		line_data[j + 3] = t1;
360		line_data[j + 2] = t2;
361		line_data[j + 1] = t3;
362		line_data[j + 0] = t4;
363	    }
364	    break;
365	default:
366	    assert (FALSE);
367	    break;
368	}
369    }
370}
371
372#define N_LEADING_PROTECTED	10
373#define N_TRAILING_PROTECTED	10
374
375typedef struct
376{
377    void *addr;
378    uint32_t len;
379    uint8_t *trailing;
380    int n_bytes;
381} info_t;
382
383#if FENCE_MALLOC_ACTIVE
384
385unsigned long
386fence_get_page_size ()
387{
388    /* You can fake a page size here, if you want to test e.g. 64 kB
389     * pages on a 4 kB page system. Just put a multiplier below.
390     */
391    return getpagesize ();
392}
393
394/* This is apparently necessary on at least OS X */
395#ifndef MAP_ANONYMOUS
396#define MAP_ANONYMOUS MAP_ANON
397#endif
398
399void *
400fence_malloc (int64_t len)
401{
402    unsigned long page_size = fence_get_page_size ();
403    unsigned long page_mask = page_size - 1;
404    uint32_t n_payload_bytes = (len + page_mask) & ~page_mask;
405    uint32_t n_bytes =
406	(page_size * (N_LEADING_PROTECTED + N_TRAILING_PROTECTED + 2) +
407	 n_payload_bytes) & ~page_mask;
408    uint8_t *initial_page;
409    uint8_t *leading_protected;
410    uint8_t *trailing_protected;
411    uint8_t *payload;
412    uint8_t *addr;
413
414    if (len < 0)
415	abort();
416
417    addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
418		 -1, 0);
419
420    if (addr == MAP_FAILED)
421    {
422	printf ("mmap failed on %lld %u\n", (long long int)len, n_bytes);
423	return NULL;
424    }
425
426    initial_page = (uint8_t *)(((uintptr_t)addr + page_mask) & ~page_mask);
427    leading_protected = initial_page + page_size;
428    payload = leading_protected + N_LEADING_PROTECTED * page_size;
429    trailing_protected = payload + n_payload_bytes;
430
431    ((info_t *)initial_page)->addr = addr;
432    ((info_t *)initial_page)->len = len;
433    ((info_t *)initial_page)->trailing = trailing_protected;
434    ((info_t *)initial_page)->n_bytes = n_bytes;
435
436    if ((mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
437		  PROT_NONE) == -1) ||
438	(mprotect (trailing_protected, N_TRAILING_PROTECTED * page_size,
439		  PROT_NONE) == -1))
440    {
441	munmap (addr, n_bytes);
442	return NULL;
443    }
444
445    return payload;
446}
447
448void
449fence_free (void *data)
450{
451    uint32_t page_size = fence_get_page_size ();
452    uint8_t *payload = data;
453    uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size;
454    uint8_t *initial_page = leading_protected - page_size;
455    info_t *info = (info_t *)initial_page;
456
457    munmap (info->addr, info->n_bytes);
458}
459
460static void
461fence_image_destroy (pixman_image_t *image, void *data)
462{
463    fence_free (data);
464}
465
466/* Create an image with fence pages.
467 *
468 * Creates an image, where the data area is allocated with fence_malloc ().
469 * Each row has an additional page in the stride.
470 *
471 * min_width is only a minimum width for the image. The width is aligned up
472 * for the row size to be divisible by both page size and pixel size.
473 *
474 * If stride_fence is true, the additional page on each row will be
475 * armed to cause SIGSEGV or SIGBUS on all accesses. This should catch
476 * all accesses outside the valid row pixels.
477 */
478pixman_image_t *
479fence_image_create_bits (pixman_format_code_t format,
480                         int min_width,
481                         int height,
482                         pixman_bool_t stride_fence)
483{
484    unsigned page_size = fence_get_page_size ();
485    unsigned page_mask = page_size - 1;
486    unsigned bitspp = PIXMAN_FORMAT_BPP (format);
487    unsigned bits_boundary;
488    unsigned row_bits;
489    int width;       /* pixels */
490    unsigned stride; /* bytes */
491    void *pixels;
492    pixman_image_t *image;
493    int i;
494
495    /* must be power of two */
496    assert (page_size && (page_size & page_mask) == 0);
497
498    if (bitspp < 1 || min_width < 1 || height < 1)
499        abort ();
500
501    /* least common multiple between page size * 8 and bitspp */
502    bits_boundary = bitspp;
503    while (! (bits_boundary & 1))
504        bits_boundary >>= 1;
505    bits_boundary *= page_size * 8;
506
507    /* round up to bits_boundary */
508    row_bits = ROUND_UP ( (unsigned)min_width * bitspp, bits_boundary);
509    width = row_bits / bitspp;
510
511    stride = row_bits / 8;
512    if (stride_fence)
513        stride += page_size; /* add fence page */
514
515    if (UINT_MAX / stride < (unsigned)height)
516        abort ();
517
518    pixels = fence_malloc (stride * (unsigned)height);
519    if (!pixels)
520        return NULL;
521
522    if (stride_fence)
523    {
524        uint8_t *guard = (uint8_t *)pixels + stride - page_size;
525
526        /* arm row end fence pages */
527        for (i = 0; i < height; i++)
528        {
529            if (mprotect (guard + i * stride, page_size, PROT_NONE) == -1)
530                goto out_fail;
531        }
532    }
533
534    assert (width >= min_width);
535
536    image = pixman_image_create_bits_no_clear (format, width, height,
537                                               pixels, stride);
538    if (!image)
539        goto out_fail;
540
541    pixman_image_set_destroy_function (image, fence_image_destroy, pixels);
542
543    return image;
544
545out_fail:
546    fence_free (pixels);
547
548    return NULL;
549}
550
551#else /* FENCE_MALLOC_ACTIVE */
552
553void *
554fence_malloc (int64_t len)
555{
556    return malloc (len);
557}
558
559void
560fence_free (void *data)
561{
562    free (data);
563}
564
565pixman_image_t *
566fence_image_create_bits (pixman_format_code_t format,
567                         int min_width,
568                         int height,
569                         pixman_bool_t stride_fence)
570{
571    return pixman_image_create_bits (format, min_width, height, NULL, 0);
572    /* Implicitly allocated storage does not need a destroy function
573     * to get freed on refcount hitting zero.
574     */
575}
576
577unsigned long
578fence_get_page_size ()
579{
580    return 0;
581}
582
583#endif /* FENCE_MALLOC_ACTIVE */
584
585uint8_t *
586make_random_bytes (int n_bytes)
587{
588    uint8_t *bytes = fence_malloc (n_bytes);
589
590    if (!bytes)
591	return NULL;
592
593    prng_randmemset (bytes, n_bytes, 0);
594
595    return bytes;
596}
597
598float *
599make_random_floats (int n_bytes)
600{
601    uint8_t *bytes = fence_malloc (n_bytes);
602    float *vals = (float *)bytes;
603
604    if (!bytes)
605	return 0;
606
607    for (n_bytes /= 4; n_bytes; vals++, n_bytes--)
608	*vals = (float)rand() / (float)RAND_MAX;
609
610    return (float *)bytes;
611}
612
613void
614a8r8g8b8_to_rgba_np (uint32_t *dst, uint32_t *src, int n_pixels)
615{
616    uint8_t *dst8 = (uint8_t *)dst;
617    int i;
618
619    for (i = 0; i < n_pixels; ++i)
620    {
621	uint32_t p = src[i];
622	uint8_t a, r, g, b;
623
624	a = (p & 0xff000000) >> 24;
625	r = (p & 0x00ff0000) >> 16;
626	g = (p & 0x0000ff00) >> 8;
627	b = (p & 0x000000ff) >> 0;
628
629	if (a != 0)
630	{
631#define DIVIDE(c, a)							\
632	    do								\
633	    {								\
634		int t = ((c) * 255) / a;				\
635		(c) = t < 0? 0 : t > 255? 255 : t;			\
636	    } while (0)
637
638	    DIVIDE (r, a);
639	    DIVIDE (g, a);
640	    DIVIDE (b, a);
641	}
642
643	*dst8++ = r;
644	*dst8++ = g;
645	*dst8++ = b;
646	*dst8++ = a;
647    }
648}
649
650#ifdef HAVE_LIBPNG
651
652pixman_bool_t
653write_png (pixman_image_t *image, const char *filename)
654{
655    int width = pixman_image_get_width (image);
656    int height = pixman_image_get_height (image);
657    int stride = width * 4;
658    uint32_t *data = malloc (height * stride);
659    pixman_image_t *copy;
660    png_struct *write_struct;
661    png_info *info_struct;
662    pixman_bool_t result = FALSE;
663    FILE *f = fopen (filename, "wb");
664    png_bytep *row_pointers;
665    int i;
666
667    if (!f)
668	return FALSE;
669
670    row_pointers = malloc (height * sizeof (png_bytep));
671
672    copy = pixman_image_create_bits (
673	PIXMAN_a8r8g8b8, width, height, data, stride);
674
675    pixman_image_composite32 (
676	PIXMAN_OP_SRC, image, NULL, copy, 0, 0, 0, 0, 0, 0, width, height);
677
678    a8r8g8b8_to_rgba_np (data, data, height * width);
679
680    for (i = 0; i < height; ++i)
681	row_pointers[i] = (png_bytep)(data + i * width);
682
683    if (!(write_struct = png_create_write_struct (
684	      PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
685	goto out1;
686
687    if (!(info_struct = png_create_info_struct (write_struct)))
688	goto out2;
689
690    png_init_io (write_struct, f);
691
692    png_set_IHDR (write_struct, info_struct, width, height,
693		  8, PNG_COLOR_TYPE_RGB_ALPHA,
694		  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
695		  PNG_FILTER_TYPE_BASE);
696
697    png_write_info (write_struct, info_struct);
698
699    png_write_image (write_struct, row_pointers);
700
701    png_write_end (write_struct, NULL);
702
703    result = TRUE;
704
705out2:
706    png_destroy_write_struct (&write_struct, &info_struct);
707
708out1:
709    if (fclose (f) != 0)
710	result = FALSE;
711
712    pixman_image_unref (copy);
713    free (row_pointers);
714    free (data);
715    return result;
716}
717
718#else /* no libpng */
719
720pixman_bool_t
721write_png (pixman_image_t *image, const char *filename)
722{
723    return FALSE;
724}
725
726#endif
727
728static void
729color8_to_color16 (uint32_t color8, pixman_color_t *color16)
730{
731    color16->alpha = ((color8 & 0xff000000) >> 24);
732    color16->red =   ((color8 & 0x00ff0000) >> 16);
733    color16->green = ((color8 & 0x0000ff00) >> 8);
734    color16->blue =  ((color8 & 0x000000ff) >> 0);
735
736    color16->alpha |= color16->alpha << 8;
737    color16->red   |= color16->red << 8;
738    color16->blue  |= color16->blue << 8;
739    color16->green |= color16->green << 8;
740}
741
742void
743draw_checkerboard (pixman_image_t *image,
744		   int check_size,
745		   uint32_t color1, uint32_t color2)
746{
747    pixman_color_t check1, check2;
748    pixman_image_t *c1, *c2;
749    int n_checks_x, n_checks_y;
750    int i, j;
751
752    color8_to_color16 (color1, &check1);
753    color8_to_color16 (color2, &check2);
754
755    c1 = pixman_image_create_solid_fill (&check1);
756    c2 = pixman_image_create_solid_fill (&check2);
757
758    n_checks_x = (
759	pixman_image_get_width (image) + check_size - 1) / check_size;
760    n_checks_y = (
761	pixman_image_get_height (image) + check_size - 1) / check_size;
762
763    for (j = 0; j < n_checks_y; j++)
764    {
765	for (i = 0; i < n_checks_x; i++)
766	{
767	    pixman_image_t *src;
768
769	    if (((i ^ j) & 1))
770		src = c1;
771	    else
772		src = c2;
773
774	    pixman_image_composite32 (PIXMAN_OP_SRC, src, NULL, image,
775				      0, 0, 0, 0,
776				      i * check_size, j * check_size,
777				      check_size, check_size);
778	}
779    }
780}
781
782static uint32_t
783call_test_function (uint32_t    (*test_function)(int testnum, int verbose),
784		    int		testnum,
785		    int		verbose)
786{
787    uint32_t retval;
788
789#if defined (__GNUC__) && defined (_WIN32) && (defined (__i386) || defined (__i386__))
790    __asm__ (
791	/* Deliberately avoid aligning the stack to 16 bytes */
792	"pushl	%1\n\t"
793	"pushl	%2\n\t"
794	"call	*%3\n\t"
795	"addl	$8, %%esp\n\t"
796	: "=a" (retval)
797	: "r" (verbose),
798	  "r" (testnum),
799	  "r" (test_function)
800	: "edx", "ecx"); /* caller save registers */
801#else
802    retval = test_function (testnum, verbose);
803#endif
804
805    return retval;
806}
807
808/*
809 * A function, which can be used as a core part of the test programs,
810 * intended to detect various problems with the help of fuzzing input
811 * to pixman API (according to some templates, aka "smart" fuzzing).
812 * Some general information about such testing can be found here:
813 * http://en.wikipedia.org/wiki/Fuzz_testing
814 *
815 * It may help detecting:
816 *  - crashes on bad handling of valid or reasonably invalid input to
817 *    pixman API.
818 *  - deviations from the behavior of older pixman releases.
819 *  - deviations from the behavior of the same pixman release, but
820 *    configured in a different way (for example with SIMD optimizations
821 *    disabled), or running on a different OS or hardware.
822 *
823 * The test is performed by calling a callback function a huge number
824 * of times. The callback function is expected to run some snippet of
825 * pixman code with pseudorandom variations to the data feeded to
826 * pixman API. A result of running each callback function should be
827 * some deterministic value which depends on test number (test number
828 * can be used as a seed for PRNG). When 'verbose' argument is nonzero,
829 * callback function is expected to print to stdout some information
830 * about what it does.
831 *
832 * Return values from many small tests are accumulated together and
833 * used as final checksum, which can be compared to some expected
834 * value. Running the tests not individually, but in a batch helps
835 * to reduce process start overhead and also allows to parallelize
836 * testing and utilize multiple CPU cores.
837 *
838 * The resulting executable can be run without any arguments. In
839 * this case it runs a batch of tests starting from 1 and up to
840 * 'default_number_of_iterations'. The resulting checksum is
841 * compared with 'expected_checksum' and FAIL or PASS verdict
842 * depends on the result of this comparison.
843 *
844 * If the executable is run with 2 numbers provided as command line
845 * arguments, they specify the starting and ending numbers for a test
846 * batch.
847 *
848 * If the executable is run with only one number provided as a command
849 * line argument, then this number is used to call the callback function
850 * once, and also with verbose flag set.
851 */
852int
853fuzzer_test_main (const char *test_name,
854		  int         default_number_of_iterations,
855		  uint32_t    expected_checksum,
856		  uint32_t    (*test_function)(int testnum, int verbose),
857		  int         argc,
858		  const char *argv[])
859{
860    int i, n1 = 1, n2 = 0;
861    uint32_t checksum = 0;
862    int verbose = getenv ("VERBOSE") != NULL;
863
864    if (argc >= 3)
865    {
866	n1 = atoi (argv[1]);
867	n2 = atoi (argv[2]);
868	if (n2 < n1)
869	{
870	    printf ("invalid test range\n");
871	    return 1;
872	}
873    }
874    else if (argc >= 2)
875    {
876	n2 = atoi (argv[1]);
877
878	checksum = call_test_function (test_function, n2, 1);
879
880	printf ("%d: checksum=%08X\n", n2, checksum);
881	return 0;
882    }
883    else
884    {
885	n1 = 1;
886	n2 = default_number_of_iterations;
887    }
888
889#ifdef USE_OPENMP
890    #pragma omp parallel for reduction(+:checksum) default(none) \
891					shared(n1, n2, test_function, verbose)
892#endif
893    for (i = n1; i <= n2; i++)
894    {
895	uint32_t crc = call_test_function (test_function, i, 0);
896	if (verbose)
897	    printf ("%d: %08X\n", i, crc);
898	checksum += crc;
899    }
900
901    if (n1 == 1 && n2 == default_number_of_iterations)
902    {
903	if (checksum == expected_checksum)
904	{
905	    printf ("%s test passed (checksum=%08X)\n",
906		    test_name, checksum);
907	}
908	else
909	{
910	    printf ("%s test failed! (checksum=%08X, expected %08X)\n",
911		    test_name, checksum, expected_checksum);
912	    return 1;
913	}
914    }
915    else
916    {
917	printf ("%d-%d: checksum=%08X\n", n1, n2, checksum);
918    }
919
920    return 0;
921}
922
923/* Try to obtain current time in seconds */
924double
925gettime (void)
926{
927#ifdef HAVE_GETTIMEOFDAY
928    struct timeval tv;
929
930    gettimeofday (&tv, NULL);
931    return (double)((int64_t)tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.;
932#else
933    return (double)clock() / (double)CLOCKS_PER_SEC;
934#endif
935}
936
937uint32_t
938get_random_seed (void)
939{
940    union { double d; uint32_t u32; } t;
941    t.d = gettime();
942    prng_srand (t.u32);
943
944    return prng_rand ();
945}
946
947#ifdef HAVE_SIGACTION
948#ifdef HAVE_ALARM
949static const char *global_msg;
950
951static void
952on_alarm (int signo)
953{
954    printf ("%s\n", global_msg);
955    exit (1);
956}
957#endif
958#endif
959
960void
961fail_after (int seconds, const char *msg)
962{
963#ifdef HAVE_SIGACTION
964#ifdef HAVE_ALARM
965    struct sigaction action;
966
967    global_msg = msg;
968
969    memset (&action, 0, sizeof (action));
970    action.sa_handler = on_alarm;
971
972    alarm (seconds);
973
974    sigaction (SIGALRM, &action, NULL);
975#endif
976#endif
977}
978
979void
980enable_divbyzero_exceptions (void)
981{
982#ifdef HAVE_FENV_H
983#ifdef HAVE_FEENABLEEXCEPT
984#ifdef HAVE_FEDIVBYZERO
985    feenableexcept (FE_DIVBYZERO);
986#endif
987#endif
988#endif
989}
990
991void
992enable_invalid_exceptions (void)
993{
994#ifdef HAVE_FENV_H
995#ifdef HAVE_FEENABLEEXCEPT
996#ifdef FE_INVALID
997    feenableexcept (FE_INVALID);
998#endif
999#endif
1000#endif
1001}
1002
1003void *
1004aligned_malloc (size_t align, size_t size)
1005{
1006    void *result;
1007
1008#ifdef HAVE_POSIX_MEMALIGN
1009    if (posix_memalign (&result, align, size) != 0)
1010      result = NULL;
1011#else
1012    result = malloc (size);
1013#endif
1014
1015    return result;
1016}
1017
1018#define CONVERT_15(c, is_rgb)						\
1019    (is_rgb?								\
1020     ((((c) >> 3) & 0x001f) |						\
1021      (((c) >> 6) & 0x03e0) |						\
1022      (((c) >> 9) & 0x7c00)) :						\
1023     (((((c) >> 16) & 0xff) * 153 +					\
1024       (((c) >>  8) & 0xff) * 301 +					\
1025       (((c)      ) & 0xff) * 58) >> 2))
1026
1027double
1028convert_srgb_to_linear (double c)
1029{
1030    if (c <= 0.04045)
1031        return c / 12.92;
1032    else
1033        return pow ((c + 0.055) / 1.055, 2.4);
1034}
1035
1036double
1037convert_linear_to_srgb (double c)
1038{
1039    if (c <= 0.0031308)
1040        return c * 12.92;
1041    else
1042        return 1.055 * pow (c, 1.0/2.4) - 0.055;
1043}
1044
1045void
1046initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
1047{
1048    int i;
1049    uint32_t mask = (1 << depth) - 1;
1050
1051    for (i = 0; i < 32768; ++i)
1052	palette->ent[i] = prng_rand() & mask;
1053
1054    memset (palette->rgba, 0, sizeof (palette->rgba));
1055
1056    for (i = 0; i < mask + 1; ++i)
1057    {
1058	uint32_t rgba24;
1059 	pixman_bool_t retry;
1060	uint32_t i15;
1061
1062	/* We filled the rgb->index map with random numbers, but we
1063	 * do need the ability to round trip, that is if some indexed
1064	 * color expands to an argb24, then the 15 bit version of that
1065	 * color must map back to the index. Anything else, we don't
1066	 * care about too much.
1067	 */
1068	do
1069	{
1070	    uint32_t old_idx;
1071
1072	    rgba24 = prng_rand();
1073	    i15 = CONVERT_15 (rgba24, is_rgb);
1074
1075	    old_idx = palette->ent[i15];
1076	    if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
1077		retry = 1;
1078	    else
1079		retry = 0;
1080	} while (retry);
1081
1082	palette->rgba[i] = rgba24;
1083	palette->ent[i15] = i;
1084    }
1085
1086    for (i = 0; i < mask + 1; ++i)
1087    {
1088	assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
1089    }
1090}
1091
1092struct operator_entry {
1093    pixman_op_t		 op;
1094    const char		*name;
1095    pixman_bool_t	 is_alias;
1096};
1097
1098typedef struct operator_entry operator_entry_t;
1099
1100static const operator_entry_t op_list[] =
1101{
1102#define ENTRY(op)							\
1103    { PIXMAN_OP_##op, "PIXMAN_OP_" #op, FALSE }
1104#define ALIAS(op, nam)							\
1105    { PIXMAN_OP_##op, nam, TRUE }
1106
1107    /* operator_name () will return the first hit in this table,
1108     * so keep the list properly ordered between entries and aliases.
1109     * Aliases are not listed by list_operators ().
1110     */
1111
1112    ENTRY (CLEAR),
1113    ENTRY (SRC),
1114    ENTRY (DST),
1115    ENTRY (OVER),
1116    ENTRY (OVER_REVERSE),
1117    ALIAS (OVER_REVERSE,		"overrev"),
1118    ENTRY (IN),
1119    ENTRY (IN_REVERSE),
1120    ALIAS (IN_REVERSE,			"inrev"),
1121    ENTRY (OUT),
1122    ENTRY (OUT_REVERSE),
1123    ALIAS (OUT_REVERSE,			"outrev"),
1124    ENTRY (ATOP),
1125    ENTRY (ATOP_REVERSE),
1126    ALIAS (ATOP_REVERSE,		"atoprev"),
1127    ENTRY (XOR),
1128    ENTRY (ADD),
1129    ENTRY (SATURATE),
1130
1131    ENTRY (DISJOINT_CLEAR),
1132    ENTRY (DISJOINT_SRC),
1133    ENTRY (DISJOINT_DST),
1134    ENTRY (DISJOINT_OVER),
1135    ENTRY (DISJOINT_OVER_REVERSE),
1136    ENTRY (DISJOINT_IN),
1137    ENTRY (DISJOINT_IN_REVERSE),
1138    ENTRY (DISJOINT_OUT),
1139    ENTRY (DISJOINT_OUT_REVERSE),
1140    ENTRY (DISJOINT_ATOP),
1141    ENTRY (DISJOINT_ATOP_REVERSE),
1142    ENTRY (DISJOINT_XOR),
1143
1144    ENTRY (CONJOINT_CLEAR),
1145    ENTRY (CONJOINT_SRC),
1146    ENTRY (CONJOINT_DST),
1147    ENTRY (CONJOINT_OVER),
1148    ENTRY (CONJOINT_OVER_REVERSE),
1149    ENTRY (CONJOINT_IN),
1150    ENTRY (CONJOINT_IN_REVERSE),
1151    ENTRY (CONJOINT_OUT),
1152    ENTRY (CONJOINT_OUT_REVERSE),
1153    ENTRY (CONJOINT_ATOP),
1154    ENTRY (CONJOINT_ATOP_REVERSE),
1155    ENTRY (CONJOINT_XOR),
1156
1157    ENTRY (MULTIPLY),
1158    ENTRY (SCREEN),
1159    ENTRY (OVERLAY),
1160    ENTRY (DARKEN),
1161    ENTRY (LIGHTEN),
1162    ENTRY (COLOR_DODGE),
1163    ENTRY (COLOR_BURN),
1164    ENTRY (HARD_LIGHT),
1165    ENTRY (SOFT_LIGHT),
1166    ENTRY (DIFFERENCE),
1167    ENTRY (EXCLUSION),
1168    ENTRY (HSL_HUE),
1169    ENTRY (HSL_SATURATION),
1170    ENTRY (HSL_COLOR),
1171    ENTRY (HSL_LUMINOSITY),
1172
1173    ALIAS (NONE, "<invalid operator 'none'>")
1174
1175#undef ENTRY
1176#undef ALIAS
1177};
1178
1179typedef struct {
1180    pixman_dither_t	 dither;
1181    const char		*name;
1182    pixman_bool_t	 is_alias;
1183} dither_entry_t;
1184
1185static const dither_entry_t dither_list[] =
1186{
1187#define ENTRY(dither)							\
1188    { PIXMAN_DITHER_##dither, "PIXMAN_DITHER_" #dither, FALSE }
1189#define ALIAS(dither, nam)							\
1190    { PIXMAN_DITHER_##dither, nam, TRUE }
1191
1192    /* dither_name () will return the first hit in this table,
1193     * so keep the list properly ordered between entries and aliases.
1194     * Aliases are not listed by list_dithers ().
1195     */
1196
1197    ENTRY (ORDERED_BAYER_8),
1198    ENTRY (ORDERED_BLUE_NOISE_64),
1199    ENTRY (NONE),
1200
1201#undef ENTRY
1202#undef ALIAS
1203};
1204
1205struct format_entry
1206{
1207    pixman_format_code_t format;
1208    const char		*name;
1209    pixman_bool_t	 is_alias;
1210};
1211
1212typedef struct format_entry format_entry_t;
1213
1214static const format_entry_t format_list[] =
1215{
1216#define ENTRY(f)							\
1217    { PIXMAN_##f, #f, FALSE }
1218#define ALIAS(f, nam)							\
1219    { PIXMAN_##f, nam, TRUE }
1220
1221    /* format_name () will return the first hit in this table,
1222     * so keep the list properly ordered between entries and aliases.
1223     * Aliases are not listed by list_formats ().
1224     */
1225
1226/* 128bpp formats */
1227    ENTRY (rgba_float),
1228/* 96bpp formats */
1229    ENTRY (rgb_float),
1230
1231/* 64bpp formats */
1232    ENTRY (a16b16g16r16),
1233
1234/* 32bpp formats */
1235    ENTRY (a8r8g8b8),
1236    ALIAS (a8r8g8b8,		"8888"),
1237    ENTRY (x8r8g8b8),
1238    ALIAS (x8r8g8b8,		"x888"),
1239    ENTRY (a8b8g8r8),
1240    ENTRY (x8b8g8r8),
1241    ENTRY (b8g8r8a8),
1242    ENTRY (b8g8r8x8),
1243    ENTRY (r8g8b8a8),
1244    ENTRY (r8g8b8x8),
1245    ENTRY (x14r6g6b6),
1246    ENTRY (x2r10g10b10),
1247    ALIAS (x2r10g10b10,		"2x10"),
1248    ENTRY (a2r10g10b10),
1249    ALIAS (a2r10g10b10,		"2a10"),
1250    ENTRY (x2b10g10r10),
1251    ENTRY (a2b10g10r10),
1252
1253/* sRGB formats */
1254    ENTRY (a8r8g8b8_sRGB),
1255    ENTRY (r8g8b8_sRGB),
1256
1257/* 24bpp formats */
1258    ENTRY (r8g8b8),
1259    ALIAS (r8g8b8,		"0888"),
1260    ENTRY (b8g8r8),
1261
1262/* 16 bpp formats */
1263    ENTRY (r5g6b5),
1264    ALIAS (r5g6b5,		"0565"),
1265    ENTRY (b5g6r5),
1266
1267    ENTRY (a1r5g5b5),
1268    ALIAS (a1r5g5b5,		"1555"),
1269    ENTRY (x1r5g5b5),
1270    ENTRY (a1b5g5r5),
1271    ENTRY (x1b5g5r5),
1272    ENTRY (a4r4g4b4),
1273    ALIAS (a4r4g4b4,		"4444"),
1274    ENTRY (x4r4g4b4),
1275    ENTRY (a4b4g4r4),
1276    ENTRY (x4b4g4r4),
1277
1278/* 8bpp formats */
1279    ENTRY (a8),
1280    ALIAS (a8,			"8"),
1281    ENTRY (r3g3b2),
1282    ENTRY (b2g3r3),
1283    ENTRY (a2r2g2b2),
1284    ALIAS (a2r2g2b2,		"2222"),
1285    ENTRY (a2b2g2r2),
1286
1287    ALIAS (c8,			"x4c4 / c8"),
1288    /* ENTRY (c8), */
1289    ALIAS (g8,			"x4g4 / g8"),
1290    /* ENTRY (g8), */
1291
1292    ENTRY (x4a4),
1293
1294    /* These format codes are identical to c8 and g8, respectively. */
1295    /* ENTRY (x4c4), */
1296    /* ENTRY (x4g4), */
1297
1298/* 4 bpp formats */
1299    ENTRY (a4),
1300    ENTRY (r1g2b1),
1301    ENTRY (b1g2r1),
1302    ENTRY (a1r1g1b1),
1303    ENTRY (a1b1g1r1),
1304
1305    ALIAS (c4,			"c4"),
1306    /* ENTRY (c4), */
1307    ALIAS (g4,			"g4"),
1308    /* ENTRY (g4), */
1309
1310/* 1bpp formats */
1311    ENTRY (a1),
1312
1313    ALIAS (g1,			"g1"),
1314    /* ENTRY (g1), */
1315
1316/* YUV formats */
1317    ALIAS (yuy2,		"yuy2"),
1318    /* ENTRY (yuy2), */
1319    ALIAS (yv12,		"yv12"),
1320    /* ENTRY (yv12), */
1321
1322/* Fake formats, not in pixman_format_code_t enum */
1323    ALIAS (null,		"null"),
1324    ALIAS (solid,		"solid"),
1325    ALIAS (solid,		"n"),
1326    ALIAS (pixbuf,		"pixbuf"),
1327    ALIAS (rpixbuf,		"rpixbuf"),
1328    ALIAS (unknown,		"unknown"),
1329
1330#undef ENTRY
1331#undef ALIAS
1332};
1333
1334pixman_format_code_t
1335format_from_string (const char *s)
1336{
1337    int i;
1338
1339    for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
1340    {
1341        const format_entry_t *ent = &format_list[i];
1342
1343        if (strcasecmp (ent->name, s) == 0)
1344            return ent->format;
1345    }
1346
1347    return PIXMAN_null;
1348}
1349
1350static void
1351emit (const char *s, int *n_chars)
1352{
1353    *n_chars += printf ("%s,", s);
1354    if (*n_chars > 60)
1355    {
1356        printf ("\n    ");
1357        *n_chars = 0;
1358    }
1359    else
1360    {
1361        printf (" ");
1362        (*n_chars)++;
1363    }
1364}
1365
1366void
1367list_formats (void)
1368{
1369    int n_chars;
1370    int i;
1371
1372    printf ("Formats:\n    ");
1373
1374    n_chars = 0;
1375    for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
1376    {
1377        const format_entry_t *ent = &format_list[i];
1378
1379        if (ent->is_alias)
1380            continue;
1381
1382        emit (ent->name, &n_chars);
1383    }
1384
1385    printf ("\n\n");
1386}
1387
1388void
1389list_operators (void)
1390{
1391    char short_name [128] = { 0 };
1392    int i, n_chars;
1393
1394    printf ("Operators:\n    ");
1395
1396    n_chars = 0;
1397    for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
1398    {
1399        const operator_entry_t *ent = &op_list[i];
1400        int j;
1401
1402        if (ent->is_alias)
1403            continue;
1404
1405        snprintf (short_name, sizeof (short_name) - 1, "%s",
1406                  ent->name + strlen ("PIXMAN_OP_"));
1407
1408        for (j = 0; short_name[j] != '\0'; ++j)
1409            short_name[j] = tolower (short_name[j]);
1410
1411        emit (short_name, &n_chars);
1412    }
1413
1414    printf ("\n\n");
1415}
1416
1417void
1418list_dithers (void)
1419{
1420    int n_chars;
1421    int i;
1422
1423    printf ("Dithers:\n    ");
1424
1425    n_chars = 0;
1426    for (i = 0; i < ARRAY_LENGTH (dither_list); ++i)
1427    {
1428        const dither_entry_t *ent = &dither_list[i];
1429
1430        if (ent->is_alias)
1431            continue;
1432
1433        emit (ent->name, &n_chars);
1434    }
1435
1436    printf ("\n\n");
1437}
1438
1439pixman_op_t
1440operator_from_string (const char *s)
1441{
1442    int i;
1443
1444    for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
1445    {
1446        const operator_entry_t *ent = &op_list[i];
1447
1448        if (ent->is_alias)
1449        {
1450            if (strcasecmp (ent->name, s) == 0)
1451                return ent->op;
1452        }
1453        else
1454        {
1455            if (strcasecmp (ent->name + strlen ("PIXMAN_OP_"), s) == 0)
1456                return ent->op;
1457        }
1458    }
1459
1460    return PIXMAN_OP_NONE;
1461}
1462
1463pixman_dither_t
1464dither_from_string (const char *s)
1465{
1466    int i;
1467
1468    for (i = 0; i < ARRAY_LENGTH (dither_list); ++i)
1469    {
1470        const dither_entry_t *ent = &dither_list[i];
1471
1472        if (strcasecmp (ent->name, s) == 0)
1473            return ent->dither;
1474    }
1475
1476    return PIXMAN_DITHER_NONE;
1477}
1478
1479const char *
1480operator_name (pixman_op_t op)
1481{
1482    int i;
1483
1484    for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
1485    {
1486        const operator_entry_t *ent = &op_list[i];
1487
1488        if (ent->op == op)
1489            return ent->name;
1490    }
1491
1492    return "<unknown operator>";
1493}
1494
1495const char *
1496format_name (pixman_format_code_t format)
1497{
1498    int i;
1499
1500    for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
1501    {
1502        const format_entry_t *ent = &format_list[i];
1503
1504        if (ent->format == format)
1505            return ent->name;
1506    }
1507
1508    return "<unknown format>";
1509};
1510
1511const char *
1512dither_name (pixman_dither_t dither)
1513{
1514    int i;
1515
1516    for (i = 0; i < ARRAY_LENGTH (dither_list); ++i)
1517    {
1518	const dither_entry_t *ent = &dither_list[i];
1519
1520	if (ent->dither == dither)
1521	    return ent->name;
1522    }
1523
1524    return "<unknown dither>";
1525}
1526
1527#define IS_ZERO(f)     (-DBL_MIN < (f) && (f) < DBL_MIN)
1528
1529typedef double (* blend_func_t) (double as, double s, double ad, double d);
1530
1531static force_inline double
1532blend_multiply (double sa, double s, double da, double d)
1533{
1534    return d * s;
1535}
1536
1537static force_inline double
1538blend_screen (double sa, double s, double da, double d)
1539{
1540    return d * sa + s * da - s * d;
1541}
1542
1543static force_inline double
1544blend_overlay (double sa, double s, double da, double d)
1545{
1546    if (2 * d < da)
1547        return 2 * s * d;
1548    else
1549        return sa * da - 2 * (da - d) * (sa - s);
1550}
1551
1552static force_inline double
1553blend_darken (double sa, double s, double da, double d)
1554{
1555    s = s * da;
1556    d = d * sa;
1557
1558    if (s > d)
1559        return d;
1560    else
1561        return s;
1562}
1563
1564static force_inline double
1565blend_lighten (double sa, double s, double da, double d)
1566{
1567    s = s * da;
1568    d = d * sa;
1569
1570    if (s > d)
1571        return s;
1572    else
1573        return d;
1574}
1575
1576static force_inline double
1577blend_color_dodge (double sa, double s, double da, double d)
1578{
1579    if (IS_ZERO (d))
1580        return 0.0f;
1581    else if (d * sa >= sa * da - s * da)
1582        return sa * da;
1583    else if (IS_ZERO (sa - s))
1584        return sa * da;
1585    else
1586        return sa * sa * d / (sa - s);
1587}
1588
1589static force_inline double
1590blend_color_burn (double sa, double s, double da, double d)
1591{
1592    if (d >= da)
1593        return sa * da;
1594    else if (sa * (da - d) >= s * da)
1595        return 0.0f;
1596    else if (IS_ZERO (s))
1597        return 0.0f;
1598    else
1599        return sa * (da - sa * (da - d) / s);
1600}
1601
1602static force_inline double
1603blend_hard_light (double sa, double s, double da, double d)
1604{
1605    if (2 * s < sa)
1606        return 2 * s * d;
1607    else
1608        return sa * da - 2 * (da - d) * (sa - s);
1609}
1610
1611static force_inline double
1612blend_soft_light (double sa, double s, double da, double d)
1613{
1614    if (2 * s <= sa)
1615    {
1616        if (IS_ZERO (da))
1617            return d * sa;
1618        else
1619            return d * sa - d * (da - d) * (sa - 2 * s) / da;
1620    }
1621    else
1622    {
1623        if (IS_ZERO (da))
1624        {
1625	    return d * sa;
1626        }
1627        else
1628        {
1629            if (4 * d <= da)
1630                return d * sa + (2 * s - sa) * d * ((16 * d / da - 12) * d / da + 3);
1631            else
1632                return d * sa + (sqrt (d * da) - d) * (2 * s - sa);
1633        }
1634    }
1635}
1636
1637static force_inline double
1638blend_difference (double sa, double s, double da, double d)
1639{
1640    double dsa = d * sa;
1641    double sda = s * da;
1642
1643    if (sda < dsa)
1644        return dsa - sda;
1645    else
1646        return sda - dsa;
1647}
1648
1649static force_inline double
1650blend_exclusion (double sa, double s, double da, double d)
1651{
1652    return s * da + d * sa - 2 * d * s;
1653}
1654
1655static double
1656clamp (double d)
1657{
1658    if (d > 1.0)
1659	return 1.0;
1660    else if (d < 0.0)
1661	return 0.0;
1662    else
1663	return d;
1664}
1665
1666static double
1667blend_channel (double as, double s, double ad, double d,
1668                   blend_func_t blend)
1669{
1670    return clamp ((1 - ad) * s + (1 - as) * d + blend (as, s, ad, d));
1671}
1672
1673static double
1674calc_op (pixman_op_t op, double src, double dst, double srca, double dsta)
1675{
1676#define mult_chan(src, dst, Fa, Fb) MIN ((src) * (Fa) + (dst) * (Fb), 1.0)
1677
1678    double Fa, Fb;
1679
1680    switch (op)
1681    {
1682    case PIXMAN_OP_CLEAR:
1683    case PIXMAN_OP_DISJOINT_CLEAR:
1684    case PIXMAN_OP_CONJOINT_CLEAR:
1685	return mult_chan (src, dst, 0.0, 0.0);
1686
1687    case PIXMAN_OP_SRC:
1688    case PIXMAN_OP_DISJOINT_SRC:
1689    case PIXMAN_OP_CONJOINT_SRC:
1690	return mult_chan (src, dst, 1.0, 0.0);
1691
1692    case PIXMAN_OP_DST:
1693    case PIXMAN_OP_DISJOINT_DST:
1694    case PIXMAN_OP_CONJOINT_DST:
1695	return mult_chan (src, dst, 0.0, 1.0);
1696
1697    case PIXMAN_OP_OVER:
1698	return mult_chan (src, dst, 1.0, 1.0 - srca);
1699
1700    case PIXMAN_OP_OVER_REVERSE:
1701	return mult_chan (src, dst, 1.0 - dsta, 1.0);
1702
1703    case PIXMAN_OP_IN:
1704	return mult_chan (src, dst, dsta, 0.0);
1705
1706    case PIXMAN_OP_IN_REVERSE:
1707	return mult_chan (src, dst, 0.0, srca);
1708
1709    case PIXMAN_OP_OUT:
1710	return mult_chan (src, dst, 1.0 - dsta, 0.0);
1711
1712    case PIXMAN_OP_OUT_REVERSE:
1713	return mult_chan (src, dst, 0.0, 1.0 - srca);
1714
1715    case PIXMAN_OP_ATOP:
1716	return mult_chan (src, dst, dsta, 1.0 - srca);
1717
1718    case PIXMAN_OP_ATOP_REVERSE:
1719	return mult_chan (src, dst, 1.0 - dsta,  srca);
1720
1721    case PIXMAN_OP_XOR:
1722	return mult_chan (src, dst, 1.0 - dsta, 1.0 - srca);
1723
1724    case PIXMAN_OP_ADD:
1725	return mult_chan (src, dst, 1.0, 1.0);
1726
1727    case PIXMAN_OP_SATURATE:
1728    case PIXMAN_OP_DISJOINT_OVER_REVERSE:
1729	if (srca == 0.0)
1730	    Fa = 1.0;
1731	else
1732	    Fa = MIN (1.0, (1.0 - dsta) / srca);
1733	return mult_chan (src, dst, Fa, 1.0);
1734
1735    case PIXMAN_OP_DISJOINT_OVER:
1736	if (dsta == 0.0)
1737	    Fb = 1.0;
1738	else
1739	    Fb = MIN (1.0, (1.0 - srca) / dsta);
1740	return mult_chan (src, dst, 1.0, Fb);
1741
1742    case PIXMAN_OP_DISJOINT_IN:
1743	if (srca == 0.0)
1744	    Fa = 0.0;
1745	else
1746	    Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
1747	return mult_chan (src, dst, Fa, 0.0);
1748
1749    case PIXMAN_OP_DISJOINT_IN_REVERSE:
1750	if (dsta == 0.0)
1751	    Fb = 0.0;
1752	else
1753	    Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
1754	return mult_chan (src, dst, 0.0, Fb);
1755
1756    case PIXMAN_OP_DISJOINT_OUT:
1757	if (srca == 0.0)
1758	    Fa = 1.0;
1759	else
1760	    Fa = MIN (1.0, (1.0 - dsta) / srca);
1761	return mult_chan (src, dst, Fa, 0.0);
1762
1763    case PIXMAN_OP_DISJOINT_OUT_REVERSE:
1764	if (dsta == 0.0)
1765	    Fb = 1.0;
1766	else
1767	    Fb = MIN (1.0, (1.0 - srca) / dsta);
1768	return mult_chan (src, dst, 0.0, Fb);
1769
1770    case PIXMAN_OP_DISJOINT_ATOP:
1771	if (srca == 0.0)
1772	    Fa = 0.0;
1773	else
1774	    Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
1775	if (dsta == 0.0)
1776	    Fb = 1.0;
1777	else
1778	    Fb = MIN (1.0, (1.0 - srca) / dsta);
1779	return mult_chan (src, dst, Fa, Fb);
1780
1781    case PIXMAN_OP_DISJOINT_ATOP_REVERSE:
1782	if (srca == 0.0)
1783	    Fa = 1.0;
1784	else
1785	    Fa = MIN (1.0, (1.0 - dsta) / srca);
1786	if (dsta == 0.0)
1787	    Fb = 0.0;
1788	else
1789	    Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
1790	return mult_chan (src, dst, Fa, Fb);
1791
1792    case PIXMAN_OP_DISJOINT_XOR:
1793	if (srca == 0.0)
1794	    Fa = 1.0;
1795	else
1796	    Fa = MIN (1.0, (1.0 - dsta) / srca);
1797	if (dsta == 0.0)
1798	    Fb = 1.0;
1799	else
1800	    Fb = MIN (1.0, (1.0 - srca) / dsta);
1801	return mult_chan (src, dst, Fa, Fb);
1802
1803    case PIXMAN_OP_CONJOINT_OVER:
1804	if (dsta == 0.0)
1805	    Fb = 0.0;
1806	else
1807	    Fb = MAX (0.0, 1.0 - srca / dsta);
1808	return mult_chan (src, dst, 1.0, Fb);
1809
1810    case PIXMAN_OP_CONJOINT_OVER_REVERSE:
1811	if (srca == 0.0)
1812	    Fa = 0.0;
1813	else
1814	    Fa = MAX (0.0, 1.0 - dsta / srca);
1815	return mult_chan (src, dst, Fa, 1.0);
1816
1817    case PIXMAN_OP_CONJOINT_IN:
1818	if (srca == 0.0)
1819	    Fa = 1.0;
1820	else
1821	    Fa = MIN (1.0, dsta / srca);
1822	return mult_chan (src, dst, Fa, 0.0);
1823
1824    case PIXMAN_OP_CONJOINT_IN_REVERSE:
1825	if (dsta == 0.0)
1826	    Fb = 1.0;
1827	else
1828	    Fb = MIN (1.0, srca / dsta);
1829	return mult_chan (src, dst, 0.0, Fb);
1830
1831    case PIXMAN_OP_CONJOINT_OUT:
1832	if (srca == 0.0)
1833	    Fa = 0.0;
1834	else
1835	    Fa = MAX (0.0, 1.0 - dsta / srca);
1836	return mult_chan (src, dst, Fa, 0.0);
1837
1838    case PIXMAN_OP_CONJOINT_OUT_REVERSE:
1839	if (dsta == 0.0)
1840	    Fb = 0.0;
1841	else
1842	    Fb = MAX (0.0, 1.0 - srca / dsta);
1843	return mult_chan (src, dst, 0.0, Fb);
1844
1845    case PIXMAN_OP_CONJOINT_ATOP:
1846	if (srca == 0.0)
1847	    Fa = 1.0;
1848	else
1849	    Fa = MIN (1.0, dsta / srca);
1850	if (dsta == 0.0)
1851	    Fb = 0.0;
1852	else
1853	    Fb = MAX (0.0, 1.0 - srca / dsta);
1854	return mult_chan (src, dst, Fa, Fb);
1855
1856    case PIXMAN_OP_CONJOINT_ATOP_REVERSE:
1857	if (srca == 0.0)
1858	    Fa = 0.0;
1859	else
1860	    Fa = MAX (0.0, 1.0 - dsta / srca);
1861	if (dsta == 0.0)
1862	    Fb = 1.0;
1863	else
1864	    Fb = MIN (1.0, srca / dsta);
1865	return mult_chan (src, dst, Fa, Fb);
1866
1867    case PIXMAN_OP_CONJOINT_XOR:
1868	if (srca == 0.0)
1869	    Fa = 0.0;
1870	else
1871	    Fa = MAX (0.0, 1.0 - dsta / srca);
1872	if (dsta == 0.0)
1873	    Fb = 0.0;
1874	else
1875	    Fb = MAX (0.0, 1.0 - srca / dsta);
1876	return mult_chan (src, dst, Fa, Fb);
1877
1878    case PIXMAN_OP_MULTIPLY:
1879    case PIXMAN_OP_SCREEN:
1880    case PIXMAN_OP_OVERLAY:
1881    case PIXMAN_OP_DARKEN:
1882    case PIXMAN_OP_LIGHTEN:
1883    case PIXMAN_OP_COLOR_DODGE:
1884    case PIXMAN_OP_COLOR_BURN:
1885    case PIXMAN_OP_HARD_LIGHT:
1886    case PIXMAN_OP_SOFT_LIGHT:
1887    case PIXMAN_OP_DIFFERENCE:
1888    case PIXMAN_OP_EXCLUSION:
1889    case PIXMAN_OP_HSL_HUE:
1890    case PIXMAN_OP_HSL_SATURATION:
1891    case PIXMAN_OP_HSL_COLOR:
1892    case PIXMAN_OP_HSL_LUMINOSITY:
1893    default:
1894	abort();
1895	return 0; /* silence MSVC */
1896    }
1897#undef mult_chan
1898}
1899
1900void
1901do_composite (pixman_op_t op,
1902	      const color_t *src,
1903	      const color_t *mask,
1904	      const color_t *dst,
1905	      color_t *result,
1906	      pixman_bool_t component_alpha)
1907{
1908    color_t srcval, srcalpha;
1909
1910    static const blend_func_t blend_funcs[] =
1911    {
1912        blend_multiply,
1913        blend_screen,
1914        blend_overlay,
1915        blend_darken,
1916        blend_lighten,
1917        blend_color_dodge,
1918        blend_color_burn,
1919        blend_hard_light,
1920        blend_soft_light,
1921        blend_difference,
1922        blend_exclusion,
1923    };
1924
1925    if (mask == NULL)
1926    {
1927	srcval = *src;
1928
1929	srcalpha.r = src->a;
1930	srcalpha.g = src->a;
1931	srcalpha.b = src->a;
1932	srcalpha.a = src->a;
1933    }
1934    else if (component_alpha)
1935    {
1936	srcval.r = src->r * mask->r;
1937	srcval.g = src->g * mask->g;
1938	srcval.b = src->b * mask->b;
1939	srcval.a = src->a * mask->a;
1940
1941	srcalpha.r = src->a * mask->r;
1942	srcalpha.g = src->a * mask->g;
1943	srcalpha.b = src->a * mask->b;
1944	srcalpha.a = src->a * mask->a;
1945    }
1946    else
1947    {
1948	srcval.r = src->r * mask->a;
1949	srcval.g = src->g * mask->a;
1950	srcval.b = src->b * mask->a;
1951	srcval.a = src->a * mask->a;
1952
1953	srcalpha.r = src->a * mask->a;
1954	srcalpha.g = src->a * mask->a;
1955	srcalpha.b = src->a * mask->a;
1956	srcalpha.a = src->a * mask->a;
1957    }
1958
1959    if (op >= PIXMAN_OP_MULTIPLY)
1960    {
1961        blend_func_t func = blend_funcs[op - PIXMAN_OP_MULTIPLY];
1962
1963	result->a = srcalpha.a + dst->a - srcalpha.a * dst->a;
1964	result->r = blend_channel (srcalpha.r, srcval.r, dst->a, dst->r, func);
1965	result->g = blend_channel (srcalpha.g, srcval.g, dst->a, dst->g, func);
1966	result->b = blend_channel (srcalpha.b, srcval.b, dst->a, dst->b, func);
1967    }
1968    else
1969    {
1970        result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a);
1971        result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a);
1972        result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a);
1973        result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a);
1974    }
1975}
1976
1977static double
1978round_channel (double p, int m)
1979{
1980    int t;
1981    double r;
1982
1983    t = p * ((1 << m));
1984    t -= t >> m;
1985
1986    r = t / (double)((1 << m) - 1);
1987
1988    return r;
1989}
1990
1991void
1992round_color (pixman_format_code_t format, color_t *color)
1993{
1994    if (PIXMAN_FORMAT_R (format) == 0)
1995    {
1996	color->r = 0.0;
1997	color->g = 0.0;
1998	color->b = 0.0;
1999    }
2000    else
2001    {
2002	color->r = round_channel (color->r, PIXMAN_FORMAT_R (format));
2003	color->g = round_channel (color->g, PIXMAN_FORMAT_G (format));
2004	color->b = round_channel (color->b, PIXMAN_FORMAT_B (format));
2005    }
2006
2007    if (PIXMAN_FORMAT_A (format) == 0)
2008	color->a = 1;
2009    else
2010	color->a = round_channel (color->a, PIXMAN_FORMAT_A (format));
2011}
2012
2013/* The acceptable deviation in units of [0.0, 1.0]
2014 */
2015#define DEVIATION (0.0128)
2016
2017/* Check whether @pixel is a valid quantization of the a, r, g, b
2018 * parameters. Some slack is permitted.
2019 */
2020void
2021pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format)
2022{
2023    assert (PIXMAN_FORMAT_VIS (format));
2024
2025    checker->format = format;
2026
2027    if (format == PIXMAN_rgba_float ||
2028	format == PIXMAN_rgb_float)
2029	return;
2030
2031    switch (PIXMAN_FORMAT_TYPE (format))
2032    {
2033    case PIXMAN_TYPE_A:
2034	checker->bs = 0;
2035	checker->gs = 0;
2036	checker->rs = 0;
2037	checker->as = 0;
2038	break;
2039
2040    case PIXMAN_TYPE_ARGB:
2041    case PIXMAN_TYPE_ARGB_SRGB:
2042	checker->bs = 0;
2043	checker->gs = checker->bs + PIXMAN_FORMAT_B (format);
2044	checker->rs = checker->gs + PIXMAN_FORMAT_G (format);
2045	checker->as = checker->rs + PIXMAN_FORMAT_R (format);
2046	break;
2047
2048    case PIXMAN_TYPE_ABGR:
2049	checker->rs = 0;
2050	checker->gs = checker->rs + PIXMAN_FORMAT_R (format);
2051	checker->bs = checker->gs + PIXMAN_FORMAT_G (format);
2052	checker->as = checker->bs + PIXMAN_FORMAT_B (format);
2053	break;
2054
2055    case PIXMAN_TYPE_BGRA:
2056	/* With BGRA formats we start counting at the high end of the pixel */
2057	checker->bs = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format);
2058	checker->gs = checker->bs - PIXMAN_FORMAT_B (format);
2059	checker->rs = checker->gs - PIXMAN_FORMAT_G (format);
2060	checker->as = checker->rs - PIXMAN_FORMAT_R (format);
2061	break;
2062
2063    case PIXMAN_TYPE_RGBA:
2064	/* With BGRA formats we start counting at the high end of the pixel */
2065	checker->rs = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format);
2066	checker->gs = checker->rs - PIXMAN_FORMAT_R (format);
2067	checker->bs = checker->gs - PIXMAN_FORMAT_G (format);
2068	checker->as = checker->bs - PIXMAN_FORMAT_B (format);
2069	break;
2070
2071    default:
2072	assert (0);
2073	break;
2074    }
2075
2076    checker->am = ((1U << PIXMAN_FORMAT_A (format)) - 1) << checker->as;
2077    checker->rm = ((1U << PIXMAN_FORMAT_R (format)) - 1) << checker->rs;
2078    checker->gm = ((1U << PIXMAN_FORMAT_G (format)) - 1) << checker->gs;
2079    checker->bm = ((1U << PIXMAN_FORMAT_B (format)) - 1) << checker->bs;
2080
2081    checker->aw = PIXMAN_FORMAT_A (format);
2082    checker->rw = PIXMAN_FORMAT_R (format);
2083    checker->gw = PIXMAN_FORMAT_G (format);
2084    checker->bw = PIXMAN_FORMAT_B (format);
2085
2086    checker->ad = DEVIATION;
2087    checker->rd = DEVIATION;
2088    checker->gd = DEVIATION;
2089    checker->bd = DEVIATION;
2090}
2091
2092/* When dithering is enabled, we allow one extra pixel of tolerance
2093 */
2094void
2095pixel_checker_allow_dither (pixel_checker_t *checker)
2096{
2097    checker->ad += 1 / (double)((1 << checker->aw) - 1);
2098    checker->rd += 1 / (double)((1 << checker->rw) - 1);
2099    checker->gd += 1 / (double)((1 << checker->gw) - 1);
2100    checker->bd += 1 / (double)((1 << checker->bw) - 1);
2101}
2102
2103static void
2104pixel_checker_require_uint32_format (const pixel_checker_t *checker)
2105{
2106    assert (checker->format != PIXMAN_rgba_float &&
2107	    checker->format != PIXMAN_rgb_float);
2108}
2109
2110void
2111pixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel,
2112			   int *a, int *r, int *g, int *b)
2113{
2114    pixel_checker_require_uint32_format(checker);
2115
2116    *a = (pixel & checker->am) >> checker->as;
2117    *r = (pixel & checker->rm) >> checker->rs;
2118    *g = (pixel & checker->gm) >> checker->gs;
2119    *b = (pixel & checker->bm) >> checker->bs;
2120}
2121
2122void
2123pixel_checker_get_masks (const pixel_checker_t *checker,
2124                         uint32_t              *am,
2125                         uint32_t              *rm,
2126                         uint32_t              *gm,
2127                         uint32_t              *bm)
2128{
2129    pixel_checker_require_uint32_format(checker);
2130
2131    if (am)
2132        *am = checker->am;
2133    if (rm)
2134        *rm = checker->rm;
2135    if (gm)
2136        *gm = checker->gm;
2137    if (bm)
2138        *bm = checker->bm;
2139}
2140
2141void
2142pixel_checker_convert_pixel_to_color (const pixel_checker_t *checker,
2143                                      uint32_t pixel, color_t *color)
2144{
2145    int a, r, g, b;
2146
2147    pixel_checker_require_uint32_format(checker);
2148
2149    pixel_checker_split_pixel (checker, pixel, &a, &r, &g, &b);
2150
2151    if (checker->am == 0)
2152        color->a = 1.0;
2153    else
2154        color->a = a / (double)(checker->am >> checker->as);
2155
2156    if (checker->rm == 0)
2157        color->r = 0.0;
2158    else
2159        color->r = r / (double)(checker->rm >> checker->rs);
2160
2161    if (checker->gm == 0)
2162        color->g = 0.0;
2163    else
2164        color->g = g / (double)(checker->gm >> checker->gs);
2165
2166    if (checker->bm == 0)
2167        color->b = 0.0;
2168    else
2169        color->b = b / (double)(checker->bm >> checker->bs);
2170
2171    if (PIXMAN_FORMAT_TYPE (checker->format) == PIXMAN_TYPE_ARGB_SRGB)
2172    {
2173	color->r = convert_srgb_to_linear (color->r);
2174	color->g = convert_srgb_to_linear (color->g);
2175	color->b = convert_srgb_to_linear (color->b);
2176    }
2177}
2178
2179static int32_t
2180convert (double v, uint32_t width, uint32_t mask, uint32_t shift, double def)
2181{
2182    int32_t r;
2183
2184    if (!mask)
2185	v = def;
2186
2187    r = (v * ((mask >> shift) + 1));
2188    r -= r >> width;
2189
2190    return r;
2191}
2192
2193static void
2194get_limits (const pixel_checker_t *checker, double sign,
2195	    color_t *color,
2196	    int *ao, int *ro, int *go, int *bo)
2197{
2198    color_t tmp;
2199
2200    if (PIXMAN_FORMAT_TYPE (checker->format) == PIXMAN_TYPE_ARGB_SRGB)
2201    {
2202	tmp.a = color->a;
2203	tmp.r = convert_linear_to_srgb (color->r);
2204	tmp.g = convert_linear_to_srgb (color->g);
2205	tmp.b = convert_linear_to_srgb (color->b);
2206
2207	color = &tmp;
2208    }
2209
2210    *ao = convert (color->a + sign * checker->ad,
2211		   checker->aw, checker->am, checker->as, 1.0);
2212    *ro = convert (color->r + sign * checker->rd,
2213		   checker->rw, checker->rm, checker->rs, 0.0);
2214    *go = convert (color->g + sign * checker->gd,
2215		   checker->gw, checker->gm, checker->gs, 0.0);
2216    *bo = convert (color->b + sign * checker->bd,
2217		   checker->bw, checker->bm, checker->bs, 0.0);
2218}
2219
2220void
2221pixel_checker_get_max (const pixel_checker_t *checker, color_t *color,
2222		       int *am, int *rm, int *gm, int *bm)
2223{
2224    pixel_checker_require_uint32_format(checker);
2225
2226    get_limits (checker, 1, color, am, rm, gm, bm);
2227}
2228
2229void
2230pixel_checker_get_min (const pixel_checker_t *checker, color_t *color,
2231		       int *am, int *rm, int *gm, int *bm)
2232{
2233    pixel_checker_require_uint32_format(checker);
2234
2235    get_limits (checker, - 1, color, am, rm, gm, bm);
2236}
2237
2238pixman_bool_t
2239pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel,
2240		     color_t *color)
2241{
2242    int32_t a_lo, a_hi, r_lo, r_hi, g_lo, g_hi, b_lo, b_hi;
2243    int32_t ai, ri, gi, bi;
2244    pixman_bool_t result;
2245
2246    pixel_checker_require_uint32_format(checker);
2247
2248    pixel_checker_get_min (checker, color, &a_lo, &r_lo, &g_lo, &b_lo);
2249    pixel_checker_get_max (checker, color, &a_hi, &r_hi, &g_hi, &b_hi);
2250    pixel_checker_split_pixel (checker, pixel, &ai, &ri, &gi, &bi);
2251
2252    result =
2253	a_lo <= ai && ai <= a_hi	&&
2254	r_lo <= ri && ri <= r_hi	&&
2255	g_lo <= gi && gi <= g_hi	&&
2256	b_lo <= bi && bi <= b_hi;
2257
2258    return result;
2259}
2260
2261static void
2262color_limits (const pixel_checker_t *checker,
2263	      double limit, const color_t *color, color_t *out)
2264{
2265    if (PIXMAN_FORMAT_A(checker->format))
2266	out->a = color->a + limit;
2267    else
2268	out->a = 1.;
2269
2270    out->r = color->r + limit;
2271    out->g = color->g + limit;
2272    out->b = color->b + limit;
2273}
2274
2275pixman_bool_t
2276pixel_checker_check_color (const pixel_checker_t *checker,
2277			   const color_t *actual, const color_t *reference)
2278{
2279    color_t min, max;
2280    pixman_bool_t result;
2281
2282    color_limits(checker, -DEVIATION, reference, &min);
2283    color_limits(checker, DEVIATION, reference, &max);
2284
2285    result =
2286	actual->a >= min.a && actual->a <= max.a &&
2287	actual->r >= min.r && actual->r <= max.r &&
2288	actual->g >= min.g && actual->g <= max.g &&
2289	actual->b >= min.b && actual->b <= max.b;
2290
2291    return result;
2292}
2293