aboutsummaryrefslogtreecommitdiff
path: root/pixman
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2010-12-19 17:53:16 +0000
committermarha <marha@users.sourceforge.net>2010-12-19 17:53:16 +0000
commit6e799c58fa0e2cf7d9b722e9f1a737ce798ffa94 (patch)
tree1b8a0f3f96e34f83306b2b5248f8ca7b09528c01 /pixman
parente9cda97b38a5987aad2260f5153992d43bec16ce (diff)
parentb24af6c6af003368ebb5c3e042db0ab7a295d89e (diff)
downloadvcxsrv-6e799c58fa0e2cf7d9b722e9f1a737ce798ffa94.tar.gz
vcxsrv-6e799c58fa0e2cf7d9b722e9f1a737ce798ffa94.tar.bz2
vcxsrv-6e799c58fa0e2cf7d9b722e9f1a737ce798ffa94.zip
svn merge ^/branches/released .
Diffstat (limited to 'pixman')
-rw-r--r--pixman/COPYING1
-rw-r--r--pixman/configure.ac8
-rw-r--r--pixman/test/Makefile.am10
-rw-r--r--pixman/test/blitters-test.c57
-rw-r--r--pixman/test/composite.c56
-rw-r--r--pixman/test/gradient-crash-test.c123
-rw-r--r--pixman/test/stress-test.c855
-rw-r--r--pixman/test/utils.c89
-rw-r--r--pixman/test/utils.h19
9 files changed, 1087 insertions, 131 deletions
diff --git a/pixman/COPYING b/pixman/COPYING
index 47c22c370..11b022bc2 100644
--- a/pixman/COPYING
+++ b/pixman/COPYING
@@ -19,6 +19,7 @@ possible. They may also add themselves to the list below.
* Copyright 2008 Mozilla Corporation
* Copyright 2008 Frederic Plourde
* Copyright 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009, 2010 Nokia Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/pixman/configure.ac b/pixman/configure.ac
index 683e6aabe..ac0d16158 100644
--- a/pixman/configure.ac
+++ b/pixman/configure.ac
@@ -639,6 +639,14 @@ if test x$have_getpagesize = xyes; then
AC_DEFINE(HAVE_GETPAGESIZE, 1, [Whether we have getpagesize()])
fi
+AC_CHECK_HEADER([fenv.h],
+ [AC_DEFINE(HAVE_FENV_H, [1], [Define to 1 if we have <fenv.h>])])
+
+AC_CHECK_LIB(m, feenableexcept, have_feenableexcept=yes, have_feenableexcept=no)
+if test x$have_feenableexcept = xyes; then
+ AC_DEFINE(HAVE_FEENABLEEXCEPT, 1, [Whether we have feenableexcept()])
+fi
+
AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no)
AC_CHECK_HEADER(sys/time.h, have_sys_time_h=yes, have_sys_time_h=no)
if test x$have_gettimeofday = xyes && test x$have_sys_time_h = xyes; then
diff --git a/pixman/test/Makefile.am b/pixman/test/Makefile.am
index 98bf94ef0..f2fbf4ce2 100644
--- a/pixman/test/Makefile.am
+++ b/pixman/test/Makefile.am
@@ -10,11 +10,12 @@ TESTPROGRAMS = \
region-translate-test \
fetch-test \
oob-test \
- gradient-crash-test \
trap-crasher \
alpha-loop \
scaling-crash-test \
+ gradient-crash-test \
alphamap \
+ stress-test \
blitters-test \
scaling-test \
affine-test \
@@ -22,7 +23,6 @@ TESTPROGRAMS = \
a1_trap_test_LDADD = $(TEST_LDADD)
fetch_test_LDADD = $(TEST_LDADD)
-gradient_crash_test_LDADD = $(TEST_LDADD)
trap_crasher_LDADD = $(TEST_LDADD)
oob_test_LDADD = $(TEST_LDADD)
scaling_crash_test_LDADD = $(TEST_LDADD)
@@ -49,6 +49,12 @@ alpha_loop_SOURCES = alpha-loop.c utils.c utils.h
composite_LDADD = $(TEST_LDADD)
composite_SOURCES = composite.c utils.c utils.h
+gradient_crash_test_LDADD = $(TEST_LDADD)
+gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h
+
+stress_test_LDADD = $(TEST_LDADD)
+stress_test_SOURCES = stress-test.c utils.c utils.h
+
# GTK using test programs
if HAVE_GTK
diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c
index 9e2a7f42f..0ff9a1d48 100644
--- a/pixman/test/blitters-test.c
+++ b/pixman/test/blitters-test.c
@@ -400,59 +400,6 @@ test_composite (int testnum, int verbose)
return crc32;
}
-#define CONVERT_15(c, is_rgb) \
- (is_rgb? \
- ((((c) >> 3) & 0x001f) | \
- (((c) >> 6) & 0x03e0) | \
- (((c) >> 9) & 0x7c00)) : \
- (((((c) >> 16) & 0xff) * 153 + \
- (((c) >> 8) & 0xff) * 301 + \
- (((c) ) & 0xff) * 58) >> 2))
-
-static void
-initialize_palette (pixman_indexed_t *palette, uint32_t mask, int is_rgb)
-{
- int i;
-
- for (i = 0; i < 32768; ++i)
- palette->ent[i] = lcg_rand() & mask;
-
- for (i = 0; i < mask + 1; ++i)
- {
- uint32_t rgba24;
- pixman_bool_t retry;
- uint32_t i15;
-
- /* We filled the rgb->index map with random numbers, but we
- * do need the ability to round trip, that is if some indexed
- * color expands to an argb24, then the 15 bit version of that
- * color must map back to the index. Anything else, we don't
- * care about too much.
- */
- do
- {
- uint32_t old_idx;
-
- rgba24 = lcg_rand();
- i15 = CONVERT_15 (rgba24, is_rgb);
-
- old_idx = palette->ent[i15];
- if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
- retry = 1;
- else
- retry = 0;
- } while (retry);
-
- palette->rgba[i] = rgba24;
- palette->ent[i15] = i;
- }
-
- for (i = 0; i < mask + 1; ++i)
- {
- assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
- }
-}
-
int
main (int argc, const char *argv[])
{
@@ -460,8 +407,8 @@ main (int argc, const char *argv[])
for (i = 1; i <= 8; i++)
{
- initialize_palette (&(rgb_palette[i]), (1 << i) - 1, TRUE);
- initialize_palette (&(y_palette[i]), (1 << i) - 1, FALSE);
+ initialize_palette (&(rgb_palette[i]), i, TRUE);
+ initialize_palette (&(y_palette[i]), i, FALSE);
}
return fuzzer_test_main("blitters", 2000000,
diff --git a/pixman/test/composite.c b/pixman/test/composite.c
index e8a7e94dc..8b8a8f540 100644
--- a/pixman/test/composite.c
+++ b/pixman/test/composite.c
@@ -31,10 +31,6 @@
#include <time.h>
#include "utils.h"
-#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
-#define min(a,b) ((a) <= (b) ? (a) : (b))
-#define max(a,b) ((a) >= (b) ? (a) : (b))
-
typedef struct color_t color_t;
typedef struct format_t format_t;
typedef struct image_t image_t;
@@ -211,7 +207,7 @@ static const operator_t operators[] =
static double
calc_op (pixman_op_t op, double src, double dst, double srca, double dsta)
{
-#define mult_chan(src, dst, Fa, Fb) min ((src) * (Fa) + (dst) * (Fb), 1.0)
+#define mult_chan(src, dst, Fa, Fb) MIN ((src) * (Fa) + (dst) * (Fb), 1.0)
double Fa, Fb;
@@ -267,150 +263,150 @@ calc_op (pixman_op_t op, double src, double dst, double srca, double dsta)
if (srca == 0.0)
Fa = 1.0;
else
- Fa = min (1.0, (1.0 - dsta) / srca);
+ Fa = MIN (1.0, (1.0 - dsta) / srca);
return mult_chan (src, dst, Fa, 1.0);
case PIXMAN_OP_DISJOINT_OVER:
if (dsta == 0.0)
Fb = 1.0;
else
- Fb = min (1.0, (1.0 - srca) / dsta);
+ Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, 1.0, Fb);
case PIXMAN_OP_DISJOINT_IN:
if (srca == 0.0)
Fa = 0.0;
else
- Fa = max (0.0, 1.0 - (1.0 - dsta) / srca);
+ Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
return mult_chan (src, dst, Fa, 0.0);
case PIXMAN_OP_DISJOINT_IN_REVERSE:
if (dsta == 0.0)
Fb = 0.0;
else
- Fb = max (0.0, 1.0 - (1.0 - srca) / dsta);
+ Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
return mult_chan (src, dst, 0.0, Fb);
case PIXMAN_OP_DISJOINT_OUT:
if (srca == 0.0)
Fa = 1.0;
else
- Fa = min (1.0, (1.0 - dsta) / srca);
+ Fa = MIN (1.0, (1.0 - dsta) / srca);
return mult_chan (src, dst, Fa, 0.0);
case PIXMAN_OP_DISJOINT_OUT_REVERSE:
if (dsta == 0.0)
Fb = 1.0;
else
- Fb = min (1.0, (1.0 - srca) / dsta);
+ Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, 0.0, Fb);
case PIXMAN_OP_DISJOINT_ATOP:
if (srca == 0.0)
Fa = 0.0;
else
- Fa = max (0.0, 1.0 - (1.0 - dsta) / srca);
+ Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
if (dsta == 0.0)
Fb = 1.0;
else
- Fb = min (1.0, (1.0 - srca) / dsta);
+ Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, Fa, Fb);
case PIXMAN_OP_DISJOINT_ATOP_REVERSE:
if (srca == 0.0)
Fa = 1.0;
else
- Fa = min (1.0, (1.0 - dsta) / srca);
+ Fa = MIN (1.0, (1.0 - dsta) / srca);
if (dsta == 0.0)
Fb = 0.0;
else
- Fb = max (0.0, 1.0 - (1.0 - srca) / dsta);
+ Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
return mult_chan (src, dst, Fa, Fb);
case PIXMAN_OP_DISJOINT_XOR:
if (srca == 0.0)
Fa = 1.0;
else
- Fa = min (1.0, (1.0 - dsta) / srca);
+ Fa = MIN (1.0, (1.0 - dsta) / srca);
if (dsta == 0.0)
Fb = 1.0;
else
- Fb = min (1.0, (1.0 - srca) / dsta);
+ Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, Fa, Fb);
case PIXMAN_OP_CONJOINT_OVER:
if (dsta == 0.0)
Fb = 0.0;
else
- Fb = max (0.0, 1.0 - srca / dsta);
+ Fb = MAX (0.0, 1.0 - srca / dsta);
return mult_chan (src, dst, 1.0, Fb);
case PIXMAN_OP_CONJOINT_OVER_REVERSE:
if (srca == 0.0)
Fa = 0.0;
else
- Fa = max (0.0, 1.0 - dsta / srca);
+ Fa = MAX (0.0, 1.0 - dsta / srca);
return mult_chan (src, dst, Fa, 1.0);
case PIXMAN_OP_CONJOINT_IN:
if (srca == 0.0)
Fa = 1.0;
else
- Fa = min (1.0, dsta / srca);
+ Fa = MIN (1.0, dsta / srca);
return mult_chan (src, dst, Fa, 0.0);
case PIXMAN_OP_CONJOINT_IN_REVERSE:
if (dsta == 0.0)
Fb = 1.0;
else
- Fb = min (1.0, srca / dsta);
+ Fb = MIN (1.0, srca / dsta);
return mult_chan (src, dst, 0.0, Fb);
case PIXMAN_OP_CONJOINT_OUT:
if (srca == 0.0)
Fa = 0.0;
else
- Fa = max (0.0, 1.0 - dsta / srca);
+ Fa = MAX (0.0, 1.0 - dsta / srca);
return mult_chan (src, dst, Fa, 0.0);
case PIXMAN_OP_CONJOINT_OUT_REVERSE:
if (dsta == 0.0)
Fb = 0.0;
else
- Fb = max (0.0, 1.0 - srca / dsta);
+ Fb = MAX (0.0, 1.0 - srca / dsta);
return mult_chan (src, dst, 0.0, Fb);
case PIXMAN_OP_CONJOINT_ATOP:
if (srca == 0.0)
Fa = 1.0;
else
- Fa = min (1.0, dsta / srca);
+ Fa = MIN (1.0, dsta / srca);
if (dsta == 0.0)
Fb = 0.0;
else
- Fb = max (0.0, 1.0 - srca / dsta);
+ Fb = MAX (0.0, 1.0 - srca / dsta);
return mult_chan (src, dst, Fa, Fb);
case PIXMAN_OP_CONJOINT_ATOP_REVERSE:
if (srca == 0.0)
Fa = 0.0;
else
- Fa = max (0.0, 1.0 - dsta / srca);
+ Fa = MAX (0.0, 1.0 - dsta / srca);
if (dsta == 0.0)
Fb = 1.0;
else
- Fb = min (1.0, srca / dsta);
+ Fb = MIN (1.0, srca / dsta);
return mult_chan (src, dst, Fa, Fb);
case PIXMAN_OP_CONJOINT_XOR:
if (srca == 0.0)
Fa = 0.0;
else
- Fa = max (0.0, 1.0 - dsta / srca);
+ Fa = MAX (0.0, 1.0 - dsta / srca);
if (dsta == 0.0)
Fb = 0.0;
else
- Fb = max (0.0, 1.0 - srca / dsta);
+ Fb = MAX (0.0, 1.0 - srca / dsta);
return mult_chan (src, dst, Fa, Fb);
case PIXMAN_OP_MULTIPLY:
@@ -617,7 +613,7 @@ eval_diff (color_t *expected, color_t *test, pixman_format_code_t format)
gdiff = fabs (test->b - expected->b) * bscale;
adiff = fabs (test->a - expected->a) * ascale;
- return max (max (max (rdiff, gdiff), bdiff), adiff);
+ return MAX (MAX (MAX (rdiff, gdiff), bdiff), adiff);
}
static char *
diff --git a/pixman/test/gradient-crash-test.c b/pixman/test/gradient-crash-test.c
index 88424dee9..35b25b2cb 100644
--- a/pixman/test/gradient-crash-test.c
+++ b/pixman/test/gradient-crash-test.c
@@ -1,6 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include "pixman.h"
+#include "utils.h"
int
main (int argc, char **argv)
@@ -11,8 +11,14 @@ main (int argc, char **argv)
uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
pixman_image_t *src_img;
pixman_image_t *dest_img;
- int i, j;
+ int i, j, k, p;
+ typedef struct
+ {
+ pixman_point_fixed_t p0;
+ pixman_point_fixed_t p1;
+ } point_pair_t;
+
pixman_gradient_stop_t onestop[1] =
{
{ pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } },
@@ -30,29 +36,56 @@ main (int argc, char **argv)
{ pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0x1111 } }
};
- pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 };
- pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH / 8.),
- pixman_int_to_fixed (0) };
-
-#if 0
- pixman_transform_t trans = {
- { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), },
- { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), },
- { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) }
- }
- };
-#else
- pixman_transform_t trans = {
- { { pixman_fixed_1, 0, 0 },
- { 0, pixman_fixed_1, 0 },
- { 0, 0, pixman_fixed_1 } }
+ point_pair_t point_pairs [] =
+ { { { pixman_double_to_fixed (0), 0 },
+ { pixman_double_to_fixed (WIDTH / 8.), pixman_int_to_fixed (0) } },
+ { { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) },
+ { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) } }
+ };
+
+ pixman_transform_t transformations[] = {
+ {
+ { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) }
+ }
+ },
+ {
+ { { pixman_double_to_fixed (1), pixman_double_to_fixed (0), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) }
+ }
+ },
+ {
+ { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (2), pixman_double_to_fixed (1.000), pixman_double_to_fixed (1.0) }
+ }
+ },
+ {
+ { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (0) }
+ }
+ },
+ {
+ { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) }
+ }
+ },
+ {
+ { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (3), },
+ { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) }
+ }
+ },
};
-#endif
-
- pixman_point_fixed_t c_inner;
- pixman_point_fixed_t c_outer;
+
pixman_fixed_t r_inner;
pixman_fixed_t r_outer;
+
+ enable_fp_exceptions();
for (i = 0; i < WIDTH * HEIGHT; ++i)
dest[i] = 0x4f00004f; /* pale blue */
@@ -62,10 +95,6 @@ main (int argc, char **argv)
dest,
WIDTH * 4);
- c_inner.x = pixman_double_to_fixed (50.0);
- c_inner.y = pixman_double_to_fixed (50.0);
- c_outer.x = pixman_double_to_fixed (50.0);
- c_outer.y = pixman_double_to_fixed (50.0);
r_inner = 0;
r_outer = pixman_double_to_fixed (50.0);
@@ -73,6 +102,7 @@ main (int argc, char **argv)
{
pixman_gradient_stop_t *stops;
int num_stops;
+
if (i == 0)
{
stops = onestop;
@@ -91,23 +121,34 @@ main (int argc, char **argv)
for (j = 0; j < 3; ++j)
{
- if (j == 0)
- src_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
- stops, num_stops);
- else if (j == 1)
- src_img = pixman_image_create_radial_gradient (&c_inner, &c_outer,
- r_inner, r_outer,
- stops, num_stops);
- else
- src_img = pixman_image_create_linear_gradient (&p1, &p2,
- stops, num_stops);
- pixman_image_set_transform (src_img, &trans);
- pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NONE);
- pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img,
- 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);
+ for (p = 0; p < ARRAY_LENGTH (point_pairs); ++p)
+ {
+ point_pair_t *pair = &(point_pairs[p]);
+
+ if (j == 0)
+ src_img = pixman_image_create_conical_gradient (&(pair->p0), r_inner,
+ stops, num_stops);
+ else if (j == 1)
+ src_img = pixman_image_create_radial_gradient (&(pair->p0), &(pair->p1),
+ r_inner, r_outer,
+ stops, num_stops);
+ else
+ src_img = pixman_image_create_linear_gradient (&(pair->p0), &(pair->p1),
+ stops, num_stops);
+
+ for (k = 0; k < ARRAY_LENGTH (transformations); ++k)
+ {
+ pixman_image_set_transform (src_img, &transformations[k]);
+
+ pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NONE);
+ pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img,
+ 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);
+ }
+
+ pixman_image_unref (src_img);
+ }
}
- pixman_image_unref (src_img);
}
pixman_image_unref (dest_img);
diff --git a/pixman/test/stress-test.c b/pixman/test/stress-test.c
new file mode 100644
index 000000000..0a89a52e9
--- /dev/null
+++ b/pixman/test/stress-test.c
@@ -0,0 +1,855 @@
+#include "utils.h"
+
+#if 0
+#define fence_malloc malloc
+#define fence_free free
+#define make_random_bytes malloc
+#endif
+
+static const pixman_format_code_t image_formats[] =
+{
+ PIXMAN_a8r8g8b8,
+ PIXMAN_x8r8g8b8,
+ PIXMAN_r5g6b5,
+ PIXMAN_r3g3b2,
+ PIXMAN_a8,
+ PIXMAN_a8b8g8r8,
+ PIXMAN_x8b8g8r8,
+ PIXMAN_b8g8r8a8,
+ PIXMAN_b8g8r8x8,
+ PIXMAN_x14r6g6b6,
+ PIXMAN_r8g8b8,
+ PIXMAN_b8g8r8,
+ PIXMAN_r5g6b5,
+ PIXMAN_b5g6r5,
+ PIXMAN_x2r10g10b10,
+ PIXMAN_a2r10g10b10,
+ PIXMAN_x2b10g10r10,
+ PIXMAN_a2b10g10r10,
+ PIXMAN_a1r5g5b5,
+ PIXMAN_x1r5g5b5,
+ PIXMAN_a1b5g5r5,
+ PIXMAN_x1b5g5r5,
+ PIXMAN_a4r4g4b4,
+ PIXMAN_x4r4g4b4,
+ PIXMAN_a4b4g4r4,
+ PIXMAN_x4b4g4r4,
+ PIXMAN_a8,
+ PIXMAN_r3g3b2,
+ PIXMAN_b2g3r3,
+ PIXMAN_a2r2g2b2,
+ PIXMAN_a2b2g2r2,
+ PIXMAN_c8,
+ PIXMAN_g8,
+ PIXMAN_x4c4,
+ PIXMAN_x4g4,
+ PIXMAN_c4,
+ PIXMAN_g4,
+ PIXMAN_g1,
+ PIXMAN_x4a4,
+ PIXMAN_a4,
+ PIXMAN_r1g2b1,
+ PIXMAN_b1g2r1,
+ PIXMAN_a1r1g1b1,
+ PIXMAN_a1b1g1r1,
+ PIXMAN_a1
+};
+
+static pixman_filter_t filters[] =
+{
+ PIXMAN_FILTER_NEAREST,
+ PIXMAN_FILTER_BILINEAR,
+ PIXMAN_FILTER_FAST,
+ PIXMAN_FILTER_GOOD,
+ PIXMAN_FILTER_BEST,
+ PIXMAN_FILTER_CONVOLUTION
+};
+
+static int
+get_size (void)
+{
+ switch (lcg_rand_n (28))
+ {
+ case 0:
+ return 1;
+
+ case 1:
+ return 2;
+
+ default:
+ case 2:
+ return lcg_rand_n (200);
+
+ case 4:
+ return lcg_rand_n (2000) + 1000;
+
+ case 5:
+ return 65535;
+
+ case 6:
+ return 65536;
+
+ case 7:
+ return lcg_rand_N (64000) + 63000;
+ }
+}
+
+static void
+destroy (pixman_image_t *image, void *data)
+{
+ if (image->type == BITS && image->bits.free_me != image->bits.bits)
+ {
+ uint32_t *bits;
+
+ if (image->bits.bits != (void *)0x01)
+ {
+ bits = image->bits.bits;
+
+ if (image->bits.rowstride < 0)
+ bits -= (- image->bits.rowstride * (image->bits.height - 1));
+
+ fence_free (bits);
+ }
+ }
+
+ free (data);
+}
+
+static uint32_t
+real_reader (const void *src, int size)
+{
+ switch (size)
+ {
+ case 1:
+ return *(uint8_t *)src;
+ case 2:
+ return *(uint16_t *)src;
+ case 4:
+ return *(uint32_t *)src;
+ default:
+ assert (0);
+ break;
+ }
+}
+
+static void
+real_writer (void *src, uint32_t value, int size)
+{
+ switch (size)
+ {
+ case 1:
+ *(uint8_t *)src = value;
+ break;
+
+ case 2:
+ *(uint16_t *)src = value;
+ break;
+
+ case 4:
+ *(uint32_t *)src = value;
+ break;
+
+ default:
+ assert (0);
+ break;
+ }
+}
+
+static uint32_t
+fake_reader (const void *src, int size)
+{
+ uint32_t r = lcg_rand_u32 ();
+
+ assert (size == 1 || size == 2 || size == 4);
+ return r & ((1 << (size * 8)) - 1);
+}
+
+static void
+fake_writer (void *src, uint32_t value, int size)
+{
+ assert (size == 1 || size == 2 || size == 4);
+}
+
+static int32_t
+log_rand (void)
+{
+ uint32_t mask;
+
+ mask = (1 << lcg_rand_n (31)) - 1;
+
+ return (lcg_rand () & mask) - (mask >> 1);
+}
+
+static pixman_image_t *
+create_random_bits_image (void)
+{
+ pixman_format_code_t format;
+ pixman_indexed_t *indexed;
+ pixman_image_t *image;
+ int width, height, stride;
+ uint32_t *bits;
+ pixman_read_memory_func_t read_func = NULL;
+ pixman_write_memory_func_t write_func = NULL;
+ pixman_filter_t filter;
+ pixman_fixed_t *coefficients = NULL;
+ int n_coefficients = 0;
+
+ /* format */
+ format = image_formats[lcg_rand_n (ARRAY_LENGTH (image_formats))];
+
+ indexed = NULL;
+ if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
+ {
+ indexed = malloc (sizeof (pixman_indexed_t));
+
+ initialize_palette (indexed, PIXMAN_FORMAT_BPP (format), TRUE);
+ }
+ else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
+ {
+ indexed = malloc (sizeof (pixman_indexed_t));
+
+ initialize_palette (indexed, PIXMAN_FORMAT_BPP (format), FALSE);
+ }
+ else
+ {
+ indexed = NULL;
+ }
+
+ /* size */
+ width = get_size ();
+ height = get_size ();
+
+ if ((uint64_t)width * height > 200000)
+ {
+ if (lcg_rand_n(2) == 0)
+ height = 200000 / width;
+ else
+ width = 200000 / height;
+ }
+
+ if (height == 0)
+ height = 1;
+ if (width == 0)
+ width = 1;
+
+ /* bits */
+ switch (lcg_rand_n (7))
+ {
+ default:
+ case 0:
+ stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+ stride = (stride + 3) & (~3);
+ bits = (uint32_t *)make_random_bytes (height * stride);
+ break;
+
+ case 1:
+ stride = 0;
+ bits = NULL;
+ break;
+
+ case 2: /* Zero-filled */
+ stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+ stride = (stride + 3) & (~3);
+ bits = fence_malloc (height * stride);
+ if (!bits)
+ return NULL;
+ memset (bits, 0, height * stride);
+ break;
+
+ case 3: /* Filled with 0xFF */
+ stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+ stride = (stride + 3) & (~3);
+ bits = fence_malloc (height * stride);
+ if (!bits)
+ return NULL;
+ memset (bits, 0xff, height * stride);
+ break;
+
+ case 4: /* bits is a bad pointer, has read/write functions */
+ stride = 232;
+ bits = (void *)0x01;
+ read_func = fake_reader;
+ write_func = fake_writer;
+ break;
+
+ case 5: /* bits is a real pointer, has read/write functions */
+ stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+ stride = (stride + 3) & (~3);
+ bits = fence_malloc (height * stride);
+ if (!bits)
+ return NULL;
+ memset (bits, 0xff, height * stride);
+ read_func = real_reader;
+ write_func = real_writer;
+ break;
+
+ case 6: /* bits is a real pointer, stride is negative */
+ stride = (width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17));
+ stride = (stride + 3) & (~3);
+ bits = (uint32_t *)make_random_bytes (height * stride);
+ if (!bits)
+ return NULL;
+ bits += ((height - 1) * stride) / 4;
+ stride = - stride;
+ break;
+ }
+
+ /* Filter */
+ filter = filters[lcg_rand_n (ARRAY_LENGTH (filters))];
+ if (filter == PIXMAN_FILTER_CONVOLUTION)
+ {
+ int width = lcg_rand_n (17);
+ int height = lcg_rand_n (19);
+
+ n_coefficients = width * height + 2;
+ coefficients = malloc (n_coefficients * sizeof (pixman_fixed_t));
+
+ if (coefficients)
+ {
+ int i;
+
+ for (i = 0; i < width * height; ++i)
+ coefficients[i + 2] = lcg_rand_u32();
+
+ coefficients[0] = width << 16;
+ coefficients[1] = height << 16;
+ }
+ else
+ {
+ filter = PIXMAN_FILTER_BEST;
+ }
+ }
+
+ /* Finally create the image */
+ image = pixman_image_create_bits (format, width, height, bits, stride);
+ if (!image)
+ return NULL;
+
+ pixman_image_set_indexed (image, indexed);
+ pixman_image_set_destroy_function (image, destroy, indexed);
+ pixman_image_set_accessors (image, read_func, write_func);
+ pixman_image_set_filter (image, filter, coefficients, n_coefficients);
+
+ return image;
+}
+
+static pixman_repeat_t repeats[] =
+{
+ PIXMAN_REPEAT_NONE,
+ PIXMAN_REPEAT_NORMAL,
+ PIXMAN_REPEAT_REFLECT,
+ PIXMAN_REPEAT_PAD
+};
+
+static uint32_t
+absolute (int32_t i)
+{
+ return i < 0? -i : i;
+}
+
+static void
+set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
+{
+ pixman_repeat_t repeat;
+
+ /* Set properties that are generic to all images */
+
+ /* Repeat */
+ repeat = repeats[lcg_rand_n (ARRAY_LENGTH (repeats))];
+ pixman_image_set_repeat (image, repeat);
+
+ /* Alpha map */
+ if (allow_alpha_map && lcg_rand_n (3) == 0)
+ {
+ pixman_image_t *alpha_map;
+ int16_t x, y;
+
+ alpha_map = create_random_bits_image ();
+
+ if (alpha_map)
+ {
+ set_general_properties (alpha_map, FALSE);
+
+ x = lcg_rand_N (100000) - 65536;
+ y = lcg_rand_N (100000) - 65536;
+
+ pixman_image_set_alpha_map (image, alpha_map, x, y);
+
+ pixman_image_unref (alpha_map);
+ }
+ }
+
+ /* Component alpha */
+ pixman_image_set_component_alpha (image, lcg_rand_n (3) == 0);
+
+ /* Clip region */
+ if (lcg_rand_n (8) != 0)
+ {
+ pixman_region32_t region;
+ int i, n_rects;
+
+ pixman_region32_init (&region);
+
+ switch (lcg_rand_n (10))
+ {
+ case 0:
+ n_rects = 0;
+ break;
+
+ case 1: case 2: case 3:
+ n_rects = 1;
+ break;
+
+ case 4: case 5:
+ n_rects = 2;
+ break;
+
+ case 6: case 7:
+ n_rects = 3;
+
+ default:
+ n_rects = lcg_rand_n (100);
+ break;
+ }
+
+ for (i = 0; i < n_rects; ++i)
+ {
+ uint32_t width, height;
+ int x, y;
+
+ x = log_rand();
+ y = log_rand();
+ width = absolute (log_rand ()) + 1;
+ height = absolute (log_rand ()) + 1;
+
+ pixman_region32_union_rect (
+ &region, &region, x, y, width, height);
+ }
+
+ pixman_image_set_clip_region32 (image, &region);
+
+ pixman_region32_fini (&region);
+ }
+
+ /* Whether source clipping is enabled */
+ pixman_image_set_source_clipping (image, !!lcg_rand_n (2));
+
+ /* Client clip */
+ pixman_image_set_has_client_clip (image, !!lcg_rand_n (2));
+
+ /* Transform */
+ if (lcg_rand_n (5) < 2)
+ {
+ pixman_transform_t xform;
+ int i, j, k;
+ uint32_t tx, ty, sx, sy;
+ uint32_t c, s;
+
+ memset (&xform, 0, sizeof xform);
+ xform.matrix[0][0] = pixman_fixed_1;
+ xform.matrix[1][1] = pixman_fixed_1;
+ xform.matrix[2][2] = pixman_fixed_1;
+
+ for (k = 0; k < 3; ++k)
+ {
+ switch (lcg_rand_n (4))
+ {
+ case 0:
+ /* rotation */
+ c = lcg_rand_N (2 * 65536) - 65536;
+ s = lcg_rand_N (2 * 65536) - 65536;
+ pixman_transform_rotate (&xform, NULL, c, s);
+ break;
+
+ case 1:
+ /* translation */
+ tx = lcg_rand_u32();
+ ty = lcg_rand_u32();
+ pixman_transform_translate (&xform, NULL, tx, ty);
+ break;
+
+ case 2:
+ /* scale */
+ sx = lcg_rand_u32();
+ sy = lcg_rand_u32();
+ pixman_transform_scale (&xform, NULL, sx, sy);
+ break;
+
+ case 3:
+ if (lcg_rand_n (16) == 0)
+ {
+ /* random */
+ for (i = 0; i < 3; ++i)
+ for (j = 0; j < 3; ++j)
+ xform.matrix[i][j] = lcg_rand_u32();
+ break;
+ }
+ else if (lcg_rand_n (16) == 0)
+ {
+ /* zero */
+ memset (&xform, 0, sizeof xform);
+ }
+ break;
+ }
+ }
+
+ pixman_image_set_transform (image, &xform);
+ }
+}
+
+static pixman_color_t
+random_color (void)
+{
+ pixman_color_t color =
+ {
+ lcg_rand() & 0xffff,
+ lcg_rand() & 0xffff,
+ lcg_rand() & 0xffff,
+ lcg_rand() & 0xffff,
+ };
+
+ return color;
+}
+
+
+static pixman_image_t *
+create_random_solid_image (void)
+{
+ pixman_color_t color = random_color();
+ pixman_image_t *image = pixman_image_create_solid_fill (&color);
+
+ return image;
+}
+
+static pixman_gradient_stop_t *
+create_random_stops (int *n_stops)
+{
+ pixman_fixed_t step;
+ pixman_fixed_t s;
+ int i;
+ pixman_gradient_stop_t *stops;
+
+ *n_stops = lcg_rand_n (50) + 1;
+
+ step = pixman_fixed_1 / *n_stops;
+
+ stops = malloc (*n_stops * sizeof (pixman_gradient_stop_t));
+
+ s = 0;
+ for (i = 0; i < (*n_stops) - 1; ++i)
+ {
+ stops[i].x = s;
+ stops[i].color = random_color();
+
+ s += step;
+ }
+
+ stops[*n_stops - 1].x = pixman_fixed_1;
+ stops[*n_stops - 1].color = random_color();
+
+ return stops;
+}
+
+static pixman_point_fixed_t
+create_random_point (void)
+{
+ pixman_point_fixed_t p;
+
+ p.x = log_rand ();
+ p.y = log_rand ();
+
+ return p;
+}
+
+static pixman_image_t *
+create_random_linear_image (void)
+{
+ int n_stops;
+ pixman_gradient_stop_t *stops;
+ pixman_point_fixed_t p1, p2;
+ pixman_image_t *result;
+
+ stops = create_random_stops (&n_stops);
+ if (!stops)
+ return NULL;
+
+ p1 = create_random_point ();
+ p2 = create_random_point ();
+
+ result = pixman_image_create_linear_gradient (&p1, &p2, stops, n_stops);
+
+ free (stops);
+
+ return result;
+}
+
+static pixman_image_t *
+create_random_radial_image (void)
+{
+ int n_stops;
+ pixman_gradient_stop_t *stops;
+ pixman_point_fixed_t inner_c, outer_c;
+ pixman_fixed_t inner_r, outer_r;
+ pixman_image_t *result;
+
+ inner_c = create_random_point();
+ outer_c = create_random_point();
+ inner_r = lcg_rand();
+ outer_r = lcg_rand();
+
+ stops = create_random_stops (&n_stops);
+
+ if (!stops)
+ return NULL;
+
+ result = pixman_image_create_radial_gradient (
+ &inner_c, &outer_c, inner_r, outer_r, stops, n_stops);
+
+ free (stops);
+
+ return result;
+}
+
+static pixman_image_t *
+create_random_conical_image (void)
+{
+ pixman_gradient_stop_t *stops;
+ int n_stops;
+ pixman_point_fixed_t c;
+ pixman_fixed_t angle;
+ pixman_image_t *result;
+
+ c = create_random_point();
+ angle = lcg_rand();
+
+ stops = create_random_stops (&n_stops);
+
+ if (!stops)
+ return NULL;
+
+ result = pixman_image_create_conical_gradient (&c, angle, stops, n_stops);
+
+ free (stops);
+
+ return result;
+}
+
+static pixman_image_t *
+create_random_image (void)
+{
+ pixman_image_t *result;
+
+ switch (lcg_rand_n (5))
+ {
+ default:
+ case 0:
+ result = create_random_bits_image ();
+ break;
+
+ case 1:
+ result = create_random_solid_image ();
+ break;
+
+ case 2:
+ result = create_random_linear_image ();
+ break;
+
+ case 3:
+ result = create_random_radial_image ();
+ break;
+
+ case 4:
+ result = create_random_conical_image ();
+ break;
+ }
+
+ if (result)
+ set_general_properties (result, TRUE);
+
+ return result;
+}
+
+static const pixman_op_t op_list[] =
+{
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_ADD,
+ PIXMAN_OP_CLEAR,
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_DST,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_OVER_REVERSE,
+ PIXMAN_OP_IN,
+ PIXMAN_OP_IN_REVERSE,
+ PIXMAN_OP_OUT,
+ PIXMAN_OP_OUT_REVERSE,
+ PIXMAN_OP_ATOP,
+ PIXMAN_OP_ATOP_REVERSE,
+ PIXMAN_OP_XOR,
+ PIXMAN_OP_ADD,
+ PIXMAN_OP_SATURATE,
+ PIXMAN_OP_DISJOINT_CLEAR,
+ PIXMAN_OP_DISJOINT_SRC,
+ PIXMAN_OP_DISJOINT_DST,
+ PIXMAN_OP_DISJOINT_OVER,
+ PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_OP_DISJOINT_IN_REVERSE,
+ PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_OP_DISJOINT_OUT_REVERSE,
+ PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_OP_CONJOINT_CLEAR,
+ PIXMAN_OP_CONJOINT_SRC,
+ PIXMAN_OP_CONJOINT_DST,
+ PIXMAN_OP_CONJOINT_OVER,
+ PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_OP_CONJOINT_IN_REVERSE,
+ PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_OP_CONJOINT_OUT_REVERSE,
+ PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_OP_MULTIPLY,
+ PIXMAN_OP_SCREEN,
+ PIXMAN_OP_OVERLAY,
+ PIXMAN_OP_DARKEN,
+ PIXMAN_OP_LIGHTEN,
+ PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_OP_COLOR_BURN,
+ PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_OP_DIFFERENCE,
+ PIXMAN_OP_EXCLUSION,
+ PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_OP_HSL_HUE,
+ PIXMAN_OP_HSL_SATURATION,
+ PIXMAN_OP_HSL_COLOR,
+ PIXMAN_OP_HSL_LUMINOSITY,
+};
+
+static void
+run_test (uint32_t seed)
+{
+ pixman_image_t *source, *mask, *dest;
+ pixman_op_t op;
+
+ lcg_srand (seed);
+
+ source = create_random_image ();
+ mask = create_random_image ();
+ dest = create_random_bits_image ();
+
+ if (source && mask && dest)
+ {
+ set_general_properties (dest, TRUE);
+
+ op = op_list [lcg_rand_n (ARRAY_LENGTH (op_list))];
+
+ pixman_image_composite32 (op,
+ source, mask, dest,
+ log_rand(), log_rand(),
+ log_rand(), log_rand(),
+ log_rand(), log_rand(),
+ absolute (log_rand()),
+ absolute (log_rand()));
+ }
+ if (source)
+ pixman_image_unref (source);
+ if (mask)
+ pixman_image_unref (mask);
+ if (dest)
+ pixman_image_unref (dest);
+}
+
+static pixman_bool_t
+get_int (char *s, uint32_t *i)
+{
+ char *end;
+ int p;
+
+ p = strtol (s, &end, 0);
+
+ if (end != s && *end == 0)
+ {
+ *i = p;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+ int verbose = FALSE;
+ uint32_t seed = 1;
+ uint32_t n_tests = 0xffffffff;
+ uint32_t mod = 0;
+ uint32_t i;
+
+ pixman_disable_out_of_bounds_workaround ();
+
+ enable_fp_exceptions();
+
+ if (getenv ("VERBOSE") != NULL)
+ verbose = TRUE;
+
+ for (i = 1; i < argc; ++i)
+ {
+ if (strcmp (argv[i], "-v") == 0)
+ {
+ verbose = TRUE;
+
+ if (i + 1 < argc)
+ {
+ get_int (argv[i + 1], &mod);
+ i++;
+ }
+ }
+ else if (strcmp (argv[i], "-s") == 0 && i + 1 < argc)
+ {
+ get_int (argv[i + 1], &seed);
+ i++;
+ }
+ else if (strcmp (argv[i], "-n") == 0 && i + 1 < argc)
+ {
+ get_int (argv[i + 1], &n_tests);
+ i++;
+ }
+ else
+ {
+ if (strcmp (argv[i], "-h") != 0)
+ printf ("Unknown option '%s'\n\n", argv[i]);
+
+ printf ("Options:\n\n"
+ "-n <number> Number of tests to run\n"
+ "-s <seed> Seed of first test\n"
+ "-v Print out seeds\n"
+ "-v <n> Print out every n'th seed\n\n");
+
+ exit (-1);
+ }
+ }
+
+ if (n_tests == 0xffffffff)
+ n_tests = 8000;
+
+ /* FIXME: seed 2005763 fails in set_lum() with divide by zero */
+#ifdef USE_OPENMP
+# pragma omp parallel for default(none) shared(verbose, n_tests, mod, seed)
+#endif
+ for (i = seed; i < seed + n_tests; ++i)
+ {
+ if (verbose)
+ {
+ if (mod == 0 || (i % mod) == 0)
+ printf ("Seed %d\n", i);
+ }
+
+ run_test (i);
+ }
+
+ return 0;
+}
diff --git a/pixman/test/utils.c b/pixman/test/utils.c
index acf494938..883095250 100644
--- a/pixman/test/utils.c
+++ b/pixman/test/utils.c
@@ -1,3 +1,5 @@
+#define _GNU_SOURCE
+
#include "utils.h"
#include <signal.h>
@@ -15,6 +17,10 @@
#include <sys/mman.h>
#endif
+#ifdef HAVE_FENV_H
+#include <fenv.h>
+#endif
+
/* Random number seed
*/
@@ -226,7 +232,7 @@ typedef struct
#endif
void *
-fence_malloc (uint32_t len)
+fence_malloc (int64_t len)
{
unsigned long page_size = getpagesize();
unsigned long page_mask = page_size - 1;
@@ -240,12 +246,15 @@ fence_malloc (uint32_t len)
uint8_t *payload;
uint8_t *addr;
+ if (len < 0)
+ abort();
+
addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
if (addr == MAP_FAILED)
{
- printf ("mmap failed on %u %u\n", len, n_bytes);
+ printf ("mmap failed on %lld %u\n", (long long int)len, n_bytes);
return NULL;
}
@@ -469,6 +478,26 @@ fail_after (int seconds, const char *msg)
#endif
}
+void
+enable_fp_exceptions (void)
+{
+#ifdef HAVE_FENV_H
+#ifdef HAVE_FEENABLEEXCEPT
+ /* Note: we don't enable the FE_INEXACT trap because
+ * that happens quite commonly. It is possible that
+ * over- and underflow should similarly be considered
+ * okay, but for now the test suite passes with them
+ * enabled, and it's useful to know if they start
+ * occuring.
+ */
+ feenableexcept (FE_DIVBYZERO |
+ FE_INVALID |
+ FE_OVERFLOW |
+ FE_UNDERFLOW);
+#endif
+#endif
+}
+
void *
aligned_malloc (size_t align, size_t size)
{
@@ -483,3 +512,59 @@ aligned_malloc (size_t align, size_t size)
return result;
}
+
+#define CONVERT_15(c, is_rgb) \
+ (is_rgb? \
+ ((((c) >> 3) & 0x001f) | \
+ (((c) >> 6) & 0x03e0) | \
+ (((c) >> 9) & 0x7c00)) : \
+ (((((c) >> 16) & 0xff) * 153 + \
+ (((c) >> 8) & 0xff) * 301 + \
+ (((c) ) & 0xff) * 58) >> 2))
+
+void
+initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
+{
+ int i;
+ uint32_t mask = (1 << depth) - 1;
+
+ for (i = 0; i < 32768; ++i)
+ palette->ent[i] = lcg_rand() & mask;
+
+ memset (palette->rgba, 0, sizeof (palette->rgba));
+
+ for (i = 0; i < mask + 1; ++i)
+ {
+ uint32_t rgba24;
+ pixman_bool_t retry;
+ uint32_t i15;
+
+ /* We filled the rgb->index map with random numbers, but we
+ * do need the ability to round trip, that is if some indexed
+ * color expands to an argb24, then the 15 bit version of that
+ * color must map back to the index. Anything else, we don't
+ * care about too much.
+ */
+ do
+ {
+ uint32_t old_idx;
+
+ rgba24 = lcg_rand();
+ i15 = CONVERT_15 (rgba24, is_rgb);
+
+ old_idx = palette->ent[i15];
+ if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
+ retry = 1;
+ else
+ retry = 0;
+ } while (retry);
+
+ palette->rgba[i] = rgba24;
+ palette->ent[i15] = i;
+ }
+
+ for (i = 0; i < mask + 1; ++i)
+ {
+ assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
+ }
+}
diff --git a/pixman/test/utils.h b/pixman/test/utils.h
index e6122119a..90a84cd0e 100644
--- a/pixman/test/utils.h
+++ b/pixman/test/utils.h
@@ -3,6 +3,8 @@
#include <assert.h>
#include "pixman-private.h" /* For 'inline' definition */
+#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
+
/* A primitive pseudorandom number generator,
* taken from POSIX.1-2001 example
*/
@@ -39,6 +41,15 @@ lcg_rand_N (int max)
return (lo | hi) % max;
}
+static inline uint32_t
+lcg_rand_u32 (void)
+{
+ uint32_t lo = lcg_rand();
+ uint32_t hi = lcg_rand();
+
+ return (hi << 16) | lo;
+}
+
/* CRC 32 computation
*/
uint32_t
@@ -55,7 +66,7 @@ image_endian_swap (pixman_image_t *img, int bpp);
* so that out-of-bounds access will cause segfaults
*/
void *
-fence_malloc (uint32_t len);
+fence_malloc (int64_t len);
void
fence_free (void *data);
@@ -80,6 +91,9 @@ fuzzer_test_main (const char *test_name,
void
fail_after (int seconds, const char *msg);
+/* If possible, enable traps for floating point exceptions */
+void enable_fp_exceptions(void);
+
/* A pair of macros which can help to detect corruption of
* floating point registers after a function call. This may
* happen if _mm_empty() call is forgotten in MMX/SSE2 fast
@@ -118,3 +132,6 @@ fail_after (int seconds, const char *msg);
/* Try to get an aligned memory chunk */
void *
aligned_malloc (size_t align, size_t size);
+
+void
+initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb);