utils.h revision 14b11b2b
114b11b2bSmrg#ifdef HAVE_CONFIG_H
214b11b2bSmrg#include <pixman-config.h>
314b11b2bSmrg#endif
414b11b2bSmrg
514b11b2bSmrg#include <assert.h>
614b11b2bSmrg#include "pixman-private.h" /* For 'inline' definition */
714b11b2bSmrg#include "utils-prng.h"
814b11b2bSmrg
914b11b2bSmrg#if defined(_MSC_VER)
1014b11b2bSmrg#define snprintf _snprintf
1114b11b2bSmrg#define strcasecmp _stricmp
1214b11b2bSmrg#endif
1314b11b2bSmrg
1414b11b2bSmrg#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
1514b11b2bSmrg
1614b11b2bSmrg/* A primitive pseudorandom number generator,
1714b11b2bSmrg * taken from POSIX.1-2001 example
1814b11b2bSmrg */
1914b11b2bSmrg
2014b11b2bSmrgextern prng_t prng_state_data;
2114b11b2bSmrgextern prng_t *prng_state;
2214b11b2bSmrg#ifdef USE_OPENMP
2314b11b2bSmrg#pragma omp threadprivate(prng_state_data)
2414b11b2bSmrg#pragma omp threadprivate(prng_state)
2514b11b2bSmrg#endif
2614b11b2bSmrg
2714b11b2bSmrgstatic inline uint32_t
2814b11b2bSmrgprng_rand (void)
2914b11b2bSmrg{
3014b11b2bSmrg    return prng_rand_r (prng_state);
3114b11b2bSmrg}
3214b11b2bSmrg
3314b11b2bSmrgstatic inline void
3414b11b2bSmrgprng_srand (uint32_t seed)
3514b11b2bSmrg{
3614b11b2bSmrg    if (!prng_state)
3714b11b2bSmrg    {
3814b11b2bSmrg        /* Without setting a seed, PRNG does not work properly (is just
3914b11b2bSmrg         * returning zeros). So we only initialize the pointer here to
4014b11b2bSmrg         * make sure that 'prng_srand' is always called before any
4114b11b2bSmrg         * other 'prng_*' function. The wrongdoers violating this order
4214b11b2bSmrg         * will get a segfault. */
4314b11b2bSmrg        prng_state = &prng_state_data;
4414b11b2bSmrg    }
4514b11b2bSmrg    prng_srand_r (prng_state, seed);
4614b11b2bSmrg}
4714b11b2bSmrg
4814b11b2bSmrgstatic inline uint32_t
4914b11b2bSmrgprng_rand_n (int max)
5014b11b2bSmrg{
5114b11b2bSmrg    return prng_rand () % max;
5214b11b2bSmrg}
5314b11b2bSmrg
5414b11b2bSmrgstatic inline void
5514b11b2bSmrgprng_randmemset (void *buffer, size_t size, prng_randmemset_flags_t flags)
5614b11b2bSmrg{
5714b11b2bSmrg    prng_randmemset_r (prng_state, buffer, size, flags);
5814b11b2bSmrg}
5914b11b2bSmrg
6014b11b2bSmrg/* CRC 32 computation
6114b11b2bSmrg */
6214b11b2bSmrguint32_t
6314b11b2bSmrgcompute_crc32 (uint32_t    in_crc32,
6414b11b2bSmrg	       const void *buf,
6514b11b2bSmrg	       size_t      buf_len);
6614b11b2bSmrg
6714b11b2bSmrguint32_t
6814b11b2bSmrgcompute_crc32_for_image (uint32_t        in_crc32,
6914b11b2bSmrg			 pixman_image_t *image);
7014b11b2bSmrg
7114b11b2bSmrg/* Print the image in hexadecimal */
7214b11b2bSmrgvoid
7314b11b2bSmrgprint_image (pixman_image_t *image);
7414b11b2bSmrg
7514b11b2bSmrg/* Returns TRUE if running on a little endian system
7614b11b2bSmrg */
7714b11b2bSmrgstatic force_inline pixman_bool_t
7814b11b2bSmrgis_little_endian (void)
7914b11b2bSmrg{
8014b11b2bSmrg    unsigned long endian_check_var = 1;
8114b11b2bSmrg    return *(unsigned char *)&endian_check_var == 1;
8214b11b2bSmrg}
8314b11b2bSmrg
8414b11b2bSmrg/* perform endian conversion of pixel data
8514b11b2bSmrg */
8614b11b2bSmrgvoid
8714b11b2bSmrgimage_endian_swap (pixman_image_t *img);
8814b11b2bSmrg
8914b11b2bSmrg#if defined (HAVE_MPROTECT) && defined (HAVE_GETPAGESIZE) && \
9014b11b2bSmrg    defined (HAVE_SYS_MMAN_H) && defined (HAVE_MMAP)
9114b11b2bSmrg/* fence_malloc and friends have working fence implementation.
9214b11b2bSmrg * Without this, fence_malloc still allocs but does not catch
9314b11b2bSmrg * out-of-bounds accesses.
9414b11b2bSmrg */
9514b11b2bSmrg#define FENCE_MALLOC_ACTIVE 1
9614b11b2bSmrg#else
9714b11b2bSmrg#define FENCE_MALLOC_ACTIVE 0
9814b11b2bSmrg#endif
9914b11b2bSmrg
10014b11b2bSmrg/* Allocate memory that is bounded by protected pages,
10114b11b2bSmrg * so that out-of-bounds access will cause segfaults
10214b11b2bSmrg */
10314b11b2bSmrgvoid *
10414b11b2bSmrgfence_malloc (int64_t len);
10514b11b2bSmrg
10614b11b2bSmrgvoid
10714b11b2bSmrgfence_free (void *data);
10814b11b2bSmrg
10914b11b2bSmrgpixman_image_t *
11014b11b2bSmrgfence_image_create_bits (pixman_format_code_t format,
11114b11b2bSmrg                         int min_width,
11214b11b2bSmrg                         int height,
11314b11b2bSmrg                         pixman_bool_t stride_fence);
11414b11b2bSmrg
11514b11b2bSmrg/* Return the page size if FENCE_MALLOC_ACTIVE, or zero otherwise */
11614b11b2bSmrgunsigned long
11714b11b2bSmrgfence_get_page_size ();
11814b11b2bSmrg
11914b11b2bSmrg/* Generate n_bytes random bytes in fence_malloced memory */
12014b11b2bSmrguint8_t *
12114b11b2bSmrgmake_random_bytes (int n_bytes);
12214b11b2bSmrgfloat *
12314b11b2bSmrgmake_random_floats (int n_bytes);
12414b11b2bSmrg
12514b11b2bSmrg/* Return current time in seconds */
12614b11b2bSmrgdouble
12714b11b2bSmrggettime (void);
12814b11b2bSmrg
12914b11b2bSmrguint32_t
13014b11b2bSmrgget_random_seed (void);
13114b11b2bSmrg
13214b11b2bSmrg/* main body of the fuzzer test */
13314b11b2bSmrgint
13414b11b2bSmrgfuzzer_test_main (const char *test_name,
13514b11b2bSmrg		  int         default_number_of_iterations,
13614b11b2bSmrg		  uint32_t    expected_checksum,
13714b11b2bSmrg		  uint32_t    (*test_function)(int testnum, int verbose),
13814b11b2bSmrg		  int         argc,
13914b11b2bSmrg		  const char *argv[]);
14014b11b2bSmrg
14114b11b2bSmrgvoid
14214b11b2bSmrgfail_after (int seconds, const char *msg);
14314b11b2bSmrg
14414b11b2bSmrg/* If possible, enable traps for floating point exceptions */
14514b11b2bSmrgvoid enable_divbyzero_exceptions(void);
14614b11b2bSmrgvoid enable_invalid_exceptions(void);
14714b11b2bSmrg
14814b11b2bSmrg/* Converts a8r8g8b8 pixels to pixels that
14914b11b2bSmrg *  - are not premultiplied,
15014b11b2bSmrg *  - are stored in this order in memory: R, G, B, A, regardless of
15114b11b2bSmrg *    the endianness of the computer.
15214b11b2bSmrg * It is allowed for @src and @dst to point to the same memory buffer.
15314b11b2bSmrg */
15414b11b2bSmrgvoid
15514b11b2bSmrga8r8g8b8_to_rgba_np (uint32_t *dst, uint32_t *src, int n_pixels);
15614b11b2bSmrg
15714b11b2bSmrgpixman_bool_t
15814b11b2bSmrgwrite_png (pixman_image_t *image, const char *filename);
15914b11b2bSmrg
16014b11b2bSmrgvoid
16114b11b2bSmrgdraw_checkerboard (pixman_image_t *image,
16214b11b2bSmrg		   int check_size,
16314b11b2bSmrg		   uint32_t color1, uint32_t color2);
16414b11b2bSmrg
16514b11b2bSmrg/* A pair of macros which can help to detect corruption of
16614b11b2bSmrg * floating point registers after a function call. This may
16714b11b2bSmrg * happen if _mm_empty() call is forgotten in MMX/SSE2 fast
16814b11b2bSmrg * path code, or ARM NEON assembly optimized function forgets
16914b11b2bSmrg * to save/restore d8-d15 registers before use.
17014b11b2bSmrg */
17114b11b2bSmrg
17214b11b2bSmrg#define FLOAT_REGS_CORRUPTION_DETECTOR_START()                 \
17314b11b2bSmrg    static volatile double frcd_volatile_constant1 = 123451;   \
17414b11b2bSmrg    static volatile double frcd_volatile_constant2 = 123452;   \
17514b11b2bSmrg    static volatile double frcd_volatile_constant3 = 123453;   \
17614b11b2bSmrg    static volatile double frcd_volatile_constant4 = 123454;   \
17714b11b2bSmrg    static volatile double frcd_volatile_constant5 = 123455;   \
17814b11b2bSmrg    static volatile double frcd_volatile_constant6 = 123456;   \
17914b11b2bSmrg    static volatile double frcd_volatile_constant7 = 123457;   \
18014b11b2bSmrg    static volatile double frcd_volatile_constant8 = 123458;   \
18114b11b2bSmrg    double frcd_canary_variable1 = frcd_volatile_constant1;    \
18214b11b2bSmrg    double frcd_canary_variable2 = frcd_volatile_constant2;    \
18314b11b2bSmrg    double frcd_canary_variable3 = frcd_volatile_constant3;    \
18414b11b2bSmrg    double frcd_canary_variable4 = frcd_volatile_constant4;    \
18514b11b2bSmrg    double frcd_canary_variable5 = frcd_volatile_constant5;    \
18614b11b2bSmrg    double frcd_canary_variable6 = frcd_volatile_constant6;    \
18714b11b2bSmrg    double frcd_canary_variable7 = frcd_volatile_constant7;    \
18814b11b2bSmrg    double frcd_canary_variable8 = frcd_volatile_constant8;
18914b11b2bSmrg
19014b11b2bSmrg#define FLOAT_REGS_CORRUPTION_DETECTOR_FINISH()                \
19114b11b2bSmrg    assert (frcd_canary_variable1 == frcd_volatile_constant1); \
19214b11b2bSmrg    assert (frcd_canary_variable2 == frcd_volatile_constant2); \
19314b11b2bSmrg    assert (frcd_canary_variable3 == frcd_volatile_constant3); \
19414b11b2bSmrg    assert (frcd_canary_variable4 == frcd_volatile_constant4); \
19514b11b2bSmrg    assert (frcd_canary_variable5 == frcd_volatile_constant5); \
19614b11b2bSmrg    assert (frcd_canary_variable6 == frcd_volatile_constant6); \
19714b11b2bSmrg    assert (frcd_canary_variable7 == frcd_volatile_constant7); \
19814b11b2bSmrg    assert (frcd_canary_variable8 == frcd_volatile_constant8);
19914b11b2bSmrg
20014b11b2bSmrg/* Try to get an aligned memory chunk */
20114b11b2bSmrgvoid *
20214b11b2bSmrgaligned_malloc (size_t align, size_t size);
20314b11b2bSmrg
20414b11b2bSmrgdouble
20514b11b2bSmrgconvert_srgb_to_linear (double component);
20614b11b2bSmrg
20714b11b2bSmrgdouble
20814b11b2bSmrgconvert_linear_to_srgb (double component);
20914b11b2bSmrg
21014b11b2bSmrgvoid
21114b11b2bSmrginitialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb);
21214b11b2bSmrg
21314b11b2bSmrgpixman_format_code_t
21414b11b2bSmrgformat_from_string (const char *s);
21514b11b2bSmrg
21614b11b2bSmrgvoid
21714b11b2bSmrglist_formats (void);
21814b11b2bSmrg
21914b11b2bSmrgvoid
22014b11b2bSmrglist_operators (void);
22114b11b2bSmrg
22214b11b2bSmrgvoid list_dithers (void);
22314b11b2bSmrg
22414b11b2bSmrgpixman_op_t
22514b11b2bSmrgoperator_from_string (const char *s);
22614b11b2bSmrg
22714b11b2bSmrgpixman_dither_t
22814b11b2bSmrgdither_from_string (const char *s);
22914b11b2bSmrg
23014b11b2bSmrgconst char *
23114b11b2bSmrgoperator_name (pixman_op_t op);
23214b11b2bSmrg
23314b11b2bSmrgconst char *
23414b11b2bSmrgformat_name (pixman_format_code_t format);
23514b11b2bSmrg
23614b11b2bSmrgconst char *
23714b11b2bSmrgdither_name (pixman_dither_t dither);
23814b11b2bSmrg
23914b11b2bSmrgtypedef struct
24014b11b2bSmrg{
24114b11b2bSmrg    double r, g, b, a;
24214b11b2bSmrg} color_t;
24314b11b2bSmrg
24414b11b2bSmrgvoid
24514b11b2bSmrgdo_composite (pixman_op_t op,
24614b11b2bSmrg	      const color_t *src,
24714b11b2bSmrg	      const color_t *mask,
24814b11b2bSmrg	      const color_t *dst,
24914b11b2bSmrg	      color_t *result,
25014b11b2bSmrg	      pixman_bool_t component_alpha);
25114b11b2bSmrg
25214b11b2bSmrgvoid
25314b11b2bSmrground_color (pixman_format_code_t format, color_t *color);
25414b11b2bSmrg
25514b11b2bSmrgtypedef struct
25614b11b2bSmrg{
25714b11b2bSmrg    pixman_format_code_t format;
25814b11b2bSmrg    uint32_t am, rm, gm, bm;
25914b11b2bSmrg    uint32_t as, rs, gs, bs;
26014b11b2bSmrg    uint32_t aw, rw, gw, bw;
26114b11b2bSmrg    float ad, rd, gd, bd;
26214b11b2bSmrg} pixel_checker_t;
26314b11b2bSmrg
26414b11b2bSmrgvoid
26514b11b2bSmrgpixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format);
26614b11b2bSmrg
26714b11b2bSmrgvoid
26814b11b2bSmrgpixel_checker_allow_dither (pixel_checker_t *checker);
26914b11b2bSmrg
27014b11b2bSmrgvoid
27114b11b2bSmrgpixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel,
27214b11b2bSmrg			   int *a, int *r, int *g, int *b);
27314b11b2bSmrg
27414b11b2bSmrgvoid
27514b11b2bSmrgpixel_checker_get_max (const pixel_checker_t *checker, color_t *color,
27614b11b2bSmrg		       int *a, int *r, int *g, int *b);
27714b11b2bSmrg
27814b11b2bSmrgvoid
27914b11b2bSmrgpixel_checker_get_min (const pixel_checker_t *checker, color_t *color,
28014b11b2bSmrg		       int *a, int *r, int *g, int *b);
28114b11b2bSmrg
28214b11b2bSmrgpixman_bool_t
28314b11b2bSmrgpixel_checker_check (const pixel_checker_t *checker,
28414b11b2bSmrg		     uint32_t pixel, color_t *color);
28514b11b2bSmrg
28614b11b2bSmrgvoid
28714b11b2bSmrgpixel_checker_convert_pixel_to_color (const pixel_checker_t *checker,
28814b11b2bSmrg                                      uint32_t pixel, color_t *color);
28914b11b2bSmrg
29014b11b2bSmrgvoid
29114b11b2bSmrgpixel_checker_get_masks (const pixel_checker_t *checker,
29214b11b2bSmrg                         uint32_t              *am,
29314b11b2bSmrg                         uint32_t              *rm,
29414b11b2bSmrg                         uint32_t              *gm,
29514b11b2bSmrg                         uint32_t              *bm);
296