* We have a source image filled with solid color, set NORMAL or PAD repeat,
* and some transform which results in nearest neighbour scaling.
*
- * The expected result is the destination image filled with this solid
- * color.
+ * The expected result is either that the destination image filled with this solid
+ * color or, if the transformation is such that we can't composite anything at
+ * all, that nothing has changed in the destination.
+ *
+ * The surrounding memory of the source image is a different solid color so that
+ * we are sure to get failures if we access it.
*/
static int
-do_test (int32_t dst_size,
- int32_t src_size,
- int32_t src_offs,
- int32_t scale_factor,
- pixman_repeat_t repeat)
+run_test (int32_t dst_width,
+ int32_t dst_height,
+ int32_t src_width,
+ int32_t src_height,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t scale_x,
+ int32_t scale_y,
+ pixman_filter_t filter,
+ pixman_repeat_t repeat)
{
- int i;
pixman_image_t * src_img;
pixman_image_t * dst_img;
pixman_transform_t transform;
uint32_t * srcbuf;
uint32_t * dstbuf;
+ pixman_box32_t box = { 0, 0, src_width, src_height };
+ pixman_color_t color_cc = { 0xcccc, 0xcccc, 0xcccc, 0xcccc };
+ int result;
+ int i;
- srcbuf = (uint32_t *)malloc (src_size * 4);
- dstbuf = (uint32_t *)malloc (dst_size * 4);
+ static const pixman_fixed_t kernel[] =
+ {
+#define D(f) (pixman_double_to_fixed (f) + 0x0001)
+
+ pixman_int_to_fixed (5),
+ pixman_int_to_fixed (5),
+ D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0),
+ D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0),
+ D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0),
+ D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0),
+ D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0)
+ };
+
+ result = 0;
- /* horizontal test */
- memset (srcbuf, 0xCC, src_size * 4);
- memset (dstbuf, 0x33, dst_size * 4);
+ srcbuf = (uint32_t *)malloc ((src_width + 10) * (src_height + 10) * 4);
+ dstbuf = (uint32_t *)malloc (dst_width * dst_height * 4);
+
+ memset (srcbuf, 0x88, src_width * src_height * 4);
+ memset (dstbuf, 0x33, dst_width * dst_height * 4);
src_img = pixman_image_create_bits (
- PIXMAN_a8r8g8b8, src_size, 1, srcbuf, src_size * 4);
+ PIXMAN_a8r8g8b8, src_width, src_height,
+ srcbuf + (src_width + 10) * 5 + 5, (src_width + 10) * 4);
+
+ pixman_image_fill_boxes (PIXMAN_OP_SRC, src_img, &color_cc, 1, &box);
+
dst_img = pixman_image_create_bits (
- PIXMAN_a8r8g8b8, dst_size, 1, dstbuf, dst_size * 4);
+ PIXMAN_a8r8g8b8, dst_width, dst_height, dstbuf, dst_width * 4);
- pixman_transform_init_scale (&transform, scale_factor, 65536);
+ pixman_transform_init_scale (&transform, scale_x, scale_y);
pixman_image_set_transform (src_img, &transform);
pixman_image_set_repeat (src_img, repeat);
- pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
+ if (filter == PIXMAN_FILTER_CONVOLUTION)
+ pixman_image_set_filter (src_img, filter, kernel, 27);
+ else
+ pixman_image_set_filter (src_img, filter, NULL, 0);
pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img,
- src_offs, 0, 0, 0, 0, 0, dst_size, 1);
+ src_x, src_y, 0, 0, 0, 0, dst_width, dst_height);
pixman_image_unref (src_img);
pixman_image_unref (dst_img);
- for (i = 0; i < dst_size; i++)
+ for (i = 0; i < dst_width * dst_height; i++)
{
- if (dstbuf[i] != 0xCCCCCCCC)
+ if (dstbuf[i] != 0xCCCCCCCC && dstbuf[i] != 0x33333333)
{
- free (srcbuf);
- free (dstbuf);
- return 1;
+ result = 1;
+ break;
}
}
- /* vertical test */
- memset (srcbuf, 0xCC, src_size * 4);
- memset (dstbuf, 0x33, dst_size * 4);
+ free (srcbuf);
+ free (dstbuf);
+ return result;
+}
- src_img = pixman_image_create_bits (
- PIXMAN_a8r8g8b8, 1, src_size, srcbuf, 4);
- dst_img = pixman_image_create_bits (
- PIXMAN_a8r8g8b8, 1, dst_size, dstbuf, 4);
+typedef struct info_t info_t;
+struct info_t
+{
+ int value;
+ char name[28];
+};
- pixman_transform_init_scale (&transform, 65536, scale_factor);
- pixman_image_set_transform (src_img, &transform);
- pixman_image_set_repeat (src_img, repeat);
- pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
+static const info_t filters[] =
+{
+ { PIXMAN_FILTER_NEAREST, "NEAREST" },
+ { PIXMAN_FILTER_BILINEAR, "BILINEAR" },
+ { PIXMAN_FILTER_CONVOLUTION, "CONVOLUTION" },
+};
- pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img,
- 0, src_offs, 0, 0, 0, 0, 1, dst_size);
+static const info_t repeats[] =
+{
+ { PIXMAN_REPEAT_PAD, "PAD" },
+ { PIXMAN_REPEAT_REFLECT, "REFLECT" },
+ { PIXMAN_REPEAT_NORMAL, "NORMAL" }
+};
- pixman_image_unref (src_img);
- pixman_image_unref (dst_img);
+static int
+do_test (int32_t dst_size,
+ int32_t src_size,
+ int32_t src_offs,
+ int32_t scale_factor)
+{
+#define N_ELEMENTS(a) (sizeof (a) / sizeof ((a)[0]))
+ int i, j;
- for (i = 0; i < dst_size; i++)
+ for (i = 0; i < N_ELEMENTS(filters); ++i)
{
- if (dstbuf[i] != 0xCCCCCCCC)
+ for (j = 0; j < N_ELEMENTS (repeats); ++j)
{
- free (srcbuf);
- free (dstbuf);
- return 1;
+ /* horizontal test */
+ if (run_test (dst_size, 1,
+ src_size, 1,
+ src_offs, 0,
+ scale_factor, 65536,
+ filters[i].value,
+ repeats[j].value) != 0)
+ {
+ printf ("Vertical test failed with %s filter and repeat mode %s\n",
+ filters[i].name, repeats[j].name);
+
+ return 1;
+ }
+
+ /* vertical test */
+ if (run_test (1, dst_size,
+ 1, src_size,
+ 0, src_offs,
+ 65536, scale_factor,
+ filters[i].value,
+ repeats[j].value) != 0)
+ {
+ printf ("Vertical test failed with %s filter and repeat mode %s\n",
+ filters[i].name, repeats[j].name);
+
+ return 1;
+ }
}
}
- free (srcbuf);
- free (dstbuf);
return 0;
}
int
main (int argc, char *argv[])
{
+ int i;
+
pixman_disable_out_of_bounds_workaround ();
/* can potentially crash */
assert (do_test (
- 48000, 32767, 1, 65536 * 128, PIXMAN_REPEAT_NORMAL) == 0);
+ 48000, 32767, 1, 65536 * 128) == 0);
/* can potentially get into a deadloop */
assert (do_test (
- 16384, 65536, 32, 32768, PIXMAN_REPEAT_NORMAL) == 0);
+ 16384, 65536, 32, 32768) == 0);
-#if 0
/* can potentially access memory outside source image buffer */
assert (do_test (
- 10, 10, 0, 1, PIXMAN_REPEAT_PAD) == 0);
+ 10, 10, 0, 1) == 0);
assert (do_test (
- 10, 10, 0, 0, PIXMAN_REPEAT_PAD) == 0);
-#endif
+ 10, 10, 0, 0) == 0);
+
+ for (i = 0; i < 100; ++i)
+ {
+ pixman_fixed_t one_seventh =
+ (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (7 << 16);
+
+ assert (do_test (
+ 1, 7, 3, one_seventh + i - 50) == 0);
+ }
+
+ for (i = 0; i < 100; ++i)
+ {
+ pixman_fixed_t scale =
+ (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (32767 << 16);
+
+ assert (do_test (
+ 1, 32767, 16383, scale + i - 50) == 0);
+ }
-#if 0
/* can potentially provide invalid results (out of range matrix stuff) */
assert (do_test (
- 48000, 32767, 16384, 65536 * 128, PIXMAN_REPEAT_NORMAL) == 0);
-#endif
+ 48000, 32767, 16384, 65536 * 128) == 0);
return 0;
}