test: Move palette initialization to utils.[ch]
[profile/ivi/pixman.git] / test / utils.c
1 #define _GNU_SOURCE
2
3 #include "utils.h"
4 #include <signal.h>
5
6 #ifdef HAVE_GETTIMEOFDAY
7 #include <sys/time.h>
8 #else
9 #include <time.h>
10 #endif
11
12 #ifdef HAVE_UNISTD_H
13 #include <unistd.h>
14 #endif
15
16 #ifdef HAVE_SYS_MMAN_H
17 #include <sys/mman.h>
18 #endif
19
20 #ifdef HAVE_FENV_H
21 #include <fenv.h>
22 #endif
23
24 /* Random number seed
25  */
26
27 uint32_t lcg_seed;
28
29 /*----------------------------------------------------------------------------*\
30  *  CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
31  *
32  *  This program generates the CRC-32 values for the files named in the
33  *  command-line arguments.  These are the same CRC-32 values used by GZIP,
34  *  PKZIP, and ZMODEM.  The Crc32_ComputeBuf () can also be detached and
35  *  used independently.
36  *
37  *  THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
38  *
39  *  Based on the byte-oriented implementation "File Verification Using CRC"
40  *  by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
41  *
42  *  v1.0.0: original release.
43  *  v1.0.1: fixed printf formats.
44  *  v1.0.2: fixed something else.
45  *  v1.0.3: replaced CRC constant table by generator function.
46  *  v1.0.4: reformatted code, made ANSI C.  1994-12-05.
47  *  v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
48 \*----------------------------------------------------------------------------*/
49
50 /*----------------------------------------------------------------------------*\
51  *  NAME:
52  *     Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer
53  *  DESCRIPTION:
54  *     Computes or accumulates the CRC-32 value for a memory buffer.
55  *     The 'inCrc32' gives a previously accumulated CRC-32 value to allow
56  *     a CRC to be generated for multiple sequential buffer-fuls of data.
57  *     The 'inCrc32' for the first buffer must be zero.
58  *  ARGUMENTS:
59  *     inCrc32 - accumulated CRC-32 value, must be 0 on first call
60  *     buf     - buffer to compute CRC-32 value for
61  *     bufLen  - number of bytes in buffer
62  *  RETURNS:
63  *     crc32 - computed CRC-32 value
64  *  ERRORS:
65  *     (no errors are possible)
66 \*----------------------------------------------------------------------------*/
67
68 uint32_t
69 compute_crc32 (uint32_t    in_crc32,
70                const void *buf,
71                size_t      buf_len)
72 {
73     static const uint32_t crc_table[256] = {
74         0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
75         0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
76         0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
77         0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
78         0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
79         0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
80         0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
81         0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
82         0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
83         0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
84         0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
85         0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
86         0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
87         0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
88         0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
89         0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
90         0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
91         0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
92         0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
93         0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
94         0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
95         0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
96         0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
97         0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
98         0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
99         0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
100         0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
101         0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
102         0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
103         0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
104         0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
105         0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
106         0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
107         0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
108         0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
109         0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
110         0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
111         0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
112         0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
113         0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
114         0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
115         0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
116         0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
117     };
118
119     uint32_t              crc32;
120     unsigned char *       byte_buf;
121     size_t                i;
122
123     /* accumulate crc32 for buffer */
124     crc32 = in_crc32 ^ 0xFFFFFFFF;
125     byte_buf = (unsigned char*) buf;
126
127     for (i = 0; i < buf_len; i++)
128         crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF];
129
130     return (crc32 ^ 0xFFFFFFFF);
131 }
132
133 /* perform endian conversion of pixel data
134  */
135 void
136 image_endian_swap (pixman_image_t *img, int bpp)
137 {
138     int stride = pixman_image_get_stride (img);
139     uint32_t *data = pixman_image_get_data (img);
140     int height = pixman_image_get_height (img);
141     int i, j;
142
143     /* swap bytes only on big endian systems */
144     volatile uint16_t endian_check_var = 0x1234;
145     if (*(volatile uint8_t *)&endian_check_var != 0x12)
146         return;
147
148     for (i = 0; i < height; i++)
149     {
150         uint8_t *line_data = (uint8_t *)data + stride * i;
151         /* swap bytes only for 16, 24 and 32 bpp for now */
152         switch (bpp)
153         {
154         case 1:
155             for (j = 0; j < stride; j++)
156             {
157                 line_data[j] =
158                     ((line_data[j] & 0x80) >> 7) |
159                     ((line_data[j] & 0x40) >> 5) |
160                     ((line_data[j] & 0x20) >> 3) |
161                     ((line_data[j] & 0x10) >> 1) |
162                     ((line_data[j] & 0x08) << 1) |
163                     ((line_data[j] & 0x04) << 3) |
164                     ((line_data[j] & 0x02) << 5) |
165                     ((line_data[j] & 0x01) << 7);
166             }
167             break;
168         case 4:
169             for (j = 0; j < stride; j++)
170             {
171                 line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4);
172             }
173             break;
174         case 16:
175             for (j = 0; j + 2 <= stride; j += 2)
176             {
177                 char t1 = line_data[j + 0];
178                 char t2 = line_data[j + 1];
179
180                 line_data[j + 1] = t1;
181                 line_data[j + 0] = t2;
182             }
183             break;
184         case 24:
185             for (j = 0; j + 3 <= stride; j += 3)
186             {
187                 char t1 = line_data[j + 0];
188                 char t2 = line_data[j + 1];
189                 char t3 = line_data[j + 2];
190
191                 line_data[j + 2] = t1;
192                 line_data[j + 1] = t2;
193                 line_data[j + 0] = t3;
194             }
195             break;
196         case 32:
197             for (j = 0; j + 4 <= stride; j += 4)
198             {
199                 char t1 = line_data[j + 0];
200                 char t2 = line_data[j + 1];
201                 char t3 = line_data[j + 2];
202                 char t4 = line_data[j + 3];
203
204                 line_data[j + 3] = t1;
205                 line_data[j + 2] = t2;
206                 line_data[j + 1] = t3;
207                 line_data[j + 0] = t4;
208             }
209             break;
210         default:
211             break;
212         }
213     }
214 }
215
216 #define N_LEADING_PROTECTED     10
217 #define N_TRAILING_PROTECTED    10
218
219 typedef struct
220 {
221     void *addr;
222     uint32_t len;
223     uint8_t *trailing;
224     int n_bytes;
225 } info_t;
226
227 #if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE) && defined(HAVE_SYS_MMAN_H)
228
229 /* This is apparently necessary on at least OS X */
230 #ifndef MAP_ANONYMOUS
231 #define MAP_ANONYMOUS MAP_ANON
232 #endif
233
234 void *
235 fence_malloc (uint32_t len)
236 {
237     unsigned long page_size = getpagesize();
238     unsigned long page_mask = page_size - 1;
239     uint32_t n_payload_bytes = (len + page_mask) & ~page_mask;
240     uint32_t n_bytes =
241         (page_size * (N_LEADING_PROTECTED + N_TRAILING_PROTECTED + 2) +
242          n_payload_bytes) & ~page_mask;
243     uint8_t *initial_page;
244     uint8_t *leading_protected;
245     uint8_t *trailing_protected;
246     uint8_t *payload;
247     uint8_t *addr;
248
249     addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
250                  -1, 0);
251
252     if (addr == MAP_FAILED)
253     {
254         printf ("mmap failed on %u %u\n", len, n_bytes);
255         return NULL;
256     }
257
258     initial_page = (uint8_t *)(((unsigned long)addr + page_mask) & ~page_mask);
259     leading_protected = initial_page + page_size;
260     payload = leading_protected + N_LEADING_PROTECTED * page_size;
261     trailing_protected = payload + n_payload_bytes;
262
263     ((info_t *)initial_page)->addr = addr;
264     ((info_t *)initial_page)->len = len;
265     ((info_t *)initial_page)->trailing = trailing_protected;
266     ((info_t *)initial_page)->n_bytes = n_bytes;
267
268     if ((mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
269                   PROT_NONE) == -1) ||
270         (mprotect (trailing_protected, N_TRAILING_PROTECTED * page_size,
271                   PROT_NONE) == -1))
272     {
273         munmap (addr, n_bytes);
274         return NULL;
275     }
276
277     return payload;
278 }
279
280 void
281 fence_free (void *data)
282 {
283     uint32_t page_size = getpagesize();
284     uint8_t *payload = data;
285     uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size;
286     uint8_t *initial_page = leading_protected - page_size;
287     info_t *info = (info_t *)initial_page;
288
289     munmap (info->addr, info->n_bytes);
290 }
291
292 #else
293
294 void *
295 fence_malloc (uint32_t len)
296 {
297     return malloc (len);
298 }
299
300 void
301 fence_free (void *data)
302 {
303     free (data);
304 }
305
306 #endif
307
308 uint8_t *
309 make_random_bytes (int n_bytes)
310 {
311     uint8_t *bytes = fence_malloc (n_bytes);
312     int i;
313
314     if (!bytes)
315         return NULL;
316
317     for (i = 0; i < n_bytes; ++i)
318         bytes[i] = lcg_rand () & 0xff;
319
320     return bytes;
321 }
322
323 /*
324  * A function, which can be used as a core part of the test programs,
325  * intended to detect various problems with the help of fuzzing input
326  * to pixman API (according to some templates, aka "smart" fuzzing).
327  * Some general information about such testing can be found here:
328  * http://en.wikipedia.org/wiki/Fuzz_testing
329  *
330  * It may help detecting:
331  *  - crashes on bad handling of valid or reasonably invalid input to
332  *    pixman API.
333  *  - deviations from the behavior of older pixman releases.
334  *  - deviations from the behavior of the same pixman release, but
335  *    configured in a different way (for example with SIMD optimizations
336  *    disabled), or running on a different OS or hardware.
337  *
338  * The test is performed by calling a callback function a huge number
339  * of times. The callback function is expected to run some snippet of
340  * pixman code with pseudorandom variations to the data feeded to
341  * pixman API. A result of running each callback function should be
342  * some deterministic value which depends on test number (test number
343  * can be used as a seed for PRNG). When 'verbose' argument is nonzero,
344  * callback function is expected to print to stdout some information
345  * about what it does.
346  *
347  * Return values from many small tests are accumulated together and
348  * used as final checksum, which can be compared to some expected
349  * value. Running the tests not individually, but in a batch helps
350  * to reduce process start overhead and also allows to parallelize
351  * testing and utilize multiple CPU cores.
352  *
353  * The resulting executable can be run without any arguments. In
354  * this case it runs a batch of tests starting from 1 and up to
355  * 'default_number_of_iterations'. The resulting checksum is
356  * compared with 'expected_checksum' and FAIL or PASS verdict
357  * depends on the result of this comparison.
358  *
359  * If the executable is run with 2 numbers provided as command line
360  * arguments, they specify the starting and ending numbers for a test
361  * batch.
362  *
363  * If the executable is run with only one number provided as a command
364  * line argument, then this number is used to call the callback function
365  * once, and also with verbose flag set.
366  */
367 int
368 fuzzer_test_main (const char *test_name,
369                   int         default_number_of_iterations,
370                   uint32_t    expected_checksum,
371                   uint32_t    (*test_function)(int testnum, int verbose),
372                   int         argc,
373                   const char *argv[])
374 {
375     int i, n1 = 1, n2 = 0;
376     uint32_t checksum = 0;
377     int verbose = getenv ("VERBOSE") != NULL;
378
379     if (argc >= 3)
380     {
381         n1 = atoi (argv[1]);
382         n2 = atoi (argv[2]);
383         if (n2 < n1)
384         {
385             printf ("invalid test range\n");
386             return 1;
387         }
388     }
389     else if (argc >= 2)
390     {
391         n2 = atoi (argv[1]);
392         checksum = test_function (n2, 1);
393         printf ("%d: checksum=%08X\n", n2, checksum);
394         return 0;
395     }
396     else
397     {
398         n1 = 1;
399         n2 = default_number_of_iterations;
400     }
401
402 #ifdef USE_OPENMP
403     #pragma omp parallel for reduction(+:checksum) default(none) \
404                                         shared(n1, n2, test_function, verbose)
405 #endif
406     for (i = n1; i <= n2; i++)
407     {
408         uint32_t crc = test_function (i, 0);
409         if (verbose)
410             printf ("%d: %08X\n", i, crc);
411         checksum += crc;
412     }
413
414     if (n1 == 1 && n2 == default_number_of_iterations)
415     {
416         if (checksum == expected_checksum)
417         {
418             printf ("%s test passed (checksum=%08X)\n",
419                     test_name, checksum);
420         }
421         else
422         {
423             printf ("%s test failed! (checksum=%08X, expected %08X)\n",
424                     test_name, checksum, expected_checksum);
425             return 1;
426         }
427     }
428     else
429     {
430         printf ("%d-%d: checksum=%08X\n", n1, n2, checksum);
431     }
432
433     return 0;
434 }
435
436 /* Try to obtain current time in seconds */
437 double
438 gettime (void)
439 {
440 #ifdef HAVE_GETTIMEOFDAY
441     struct timeval tv;
442
443     gettimeofday (&tv, NULL);
444     return (double)((int64_t)tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.;
445 #else
446     return (double)clock() / (double)CLOCKS_PER_SEC;
447 #endif
448 }
449
450 static const char *global_msg;
451
452 static void
453 on_alarm (int signo)
454 {
455     printf ("%s\n", global_msg);
456     exit (1);
457 }
458
459 void
460 fail_after (int seconds, const char *msg)
461 {
462 #ifdef HAVE_SIGACTION
463 #ifdef HAVE_ALARM
464     struct sigaction action;
465
466     global_msg = msg;
467
468     memset (&action, 0, sizeof (action));
469     action.sa_handler = on_alarm;
470
471     alarm (seconds);
472
473     sigaction (SIGALRM, &action, NULL);
474 #endif
475 #endif
476 }
477
478 void
479 enable_fp_exceptions (void)
480 {
481 #ifdef HAVE_FENV_H
482 #ifdef HAVE_FEENABLEEXCEPT
483     /* Note: we don't enable the FE_INEXACT trap because
484      * that happens quite commonly. It is possible that
485      * over- and underflow should similarly be considered
486      * okay, but for now the test suite passes with them
487      * enabled, and it's useful to know if they start
488      * occuring.
489      */
490     feenableexcept (FE_DIVBYZERO        |
491                     FE_INVALID          |
492                     FE_OVERFLOW         |
493                     FE_UNDERFLOW);
494 #endif
495 #endif
496 }
497
498 void *
499 aligned_malloc (size_t align, size_t size)
500 {
501     void *result;
502
503 #ifdef HAVE_POSIX_MEMALIGN
504     if (posix_memalign (&result, align, size) != 0)
505       result = NULL;
506 #else
507     result = malloc (size);
508 #endif
509
510     return result;
511 }
512
513 #define CONVERT_15(c, is_rgb)                                           \
514     (is_rgb?                                                            \
515      ((((c) >> 3) & 0x001f) |                                           \
516       (((c) >> 6) & 0x03e0) |                                           \
517       (((c) >> 9) & 0x7c00)) :                                          \
518      (((((c) >> 16) & 0xff) * 153 +                                     \
519        (((c) >>  8) & 0xff) * 301 +                                     \
520        (((c)      ) & 0xff) * 58) >> 2))
521
522 void
523 initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
524 {
525     int i;
526     uint32_t mask = (1 << depth) - 1;
527
528     for (i = 0; i < 32768; ++i)
529         palette->ent[i] = lcg_rand() & mask;
530
531     for (i = 0; i < mask + 1; ++i)
532     {
533         uint32_t rgba24;
534         pixman_bool_t retry;
535         uint32_t i15;
536
537         /* We filled the rgb->index map with random numbers, but we
538          * do need the ability to round trip, that is if some indexed
539          * color expands to an argb24, then the 15 bit version of that
540          * color must map back to the index. Anything else, we don't
541          * care about too much.
542          */
543         do
544         {
545             uint32_t old_idx;
546
547             rgba24 = lcg_rand();
548             i15 = CONVERT_15 (rgba24, is_rgb);
549
550             old_idx = palette->ent[i15];
551             if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
552                 retry = 1;
553             else
554                 retry = 0;
555         } while (retry);
556
557         palette->rgba[i] = rgba24;
558         palette->ent[i15] = i;
559     }
560
561     for (i = 0; i < mask + 1; ++i)
562     {
563         assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
564     }
565 }