11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <assert.h> 21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdlib.h> 31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdio.h> 41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <string.h> 51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "utils.h" 61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* 81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * We have a source image filled with solid color, set NORMAL or PAD repeat, 91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * and some transform which results in nearest neighbour scaling. 101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * The expected result is either that the destination image filled with this solid 121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * color or, if the transformation is such that we can't composite anything at 131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * all, that nothing has changed in the destination. 141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * The surrounding memory of the source image is a different solid color so that 161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * we are sure to get failures if we access it. 171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 181176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic int 191176bdada62cabc6ec4b0308a930e83b679d5d36John Reckrun_test (int32_t dst_width, 201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t dst_height, 211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t src_width, 221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t src_height, 231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t src_x, 241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t src_y, 251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t scale_x, 261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t scale_y, 271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_filter_t filter, 281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_repeat_t repeat) 291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t * src_img; 311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t * dst_img; 321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_transform_t transform; 331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * srcbuf; 341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * dstbuf; 351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_color_t color_cc = { 0xcccc, 0xcccc, 0xcccc, 0xcccc }; 361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t * solid; 371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int result; 381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i; 391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static const pixman_fixed_t kernel[] = 411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define D(f) (pixman_double_to_fixed (f) + 0x0001) 431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_int_to_fixed (5), 451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_int_to_fixed (5), 461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), 471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), 481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), 491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), 501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0) 511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck }; 521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck result = 0; 541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srcbuf = (uint32_t *)malloc ((src_width + 10) * (src_height + 10) * 4); 561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck dstbuf = (uint32_t *)malloc (dst_width * dst_height * 4); 571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck memset (srcbuf, 0x88, src_width * src_height * 4); 591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck memset (dstbuf, 0x33, dst_width * dst_height * 4); 601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck src_img = pixman_image_create_bits ( 621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck PIXMAN_a8r8g8b8, src_width, src_height, 631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srcbuf + (src_width + 10) * 5 + 5, (src_width + 10) * 4); 641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck solid = pixman_image_create_solid_fill (&color_cc); 661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_composite32 (PIXMAN_OP_SRC, solid, NULL, src_img, 671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 0, 0, 0, 0, 0, 0, src_width, src_height); 681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_unref (solid); 691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck dst_img = pixman_image_create_bits ( 711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck PIXMAN_a8r8g8b8, dst_width, dst_height, dstbuf, dst_width * 4); 721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_transform_init_scale (&transform, scale_x, scale_y); 741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_set_transform (src_img, &transform); 751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_set_repeat (src_img, repeat); 761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (filter == PIXMAN_FILTER_CONVOLUTION) 771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_set_filter (src_img, filter, kernel, 27); 781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_set_filter (src_img, filter, NULL, 0); 801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img, 821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck src_x, src_y, 0, 0, 0, 0, dst_width, dst_height); 831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_unref (src_img); 851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_unref (dst_img); 861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < dst_width * dst_height; i++) 881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (dstbuf[i] != 0xCCCCCCCC && dstbuf[i] != 0x33333333) 901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck result = 1; 921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck break; 931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck free (srcbuf); 971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck free (dstbuf); 981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return result; 991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1011176bdada62cabc6ec4b0308a930e83b679d5d36John Recktypedef struct filter_info_t filter_info_t; 1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstruct filter_info_t 1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_filter_t value; 1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck char name[28]; 1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}; 1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic const filter_info_t filters[] = 1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_FILTER_NEAREST, "NEAREST" }, 1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_FILTER_BILINEAR, "BILINEAR" }, 1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_FILTER_CONVOLUTION, "CONVOLUTION" }, 1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}; 1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1151176bdada62cabc6ec4b0308a930e83b679d5d36John Recktypedef struct repeat_info_t repeat_info_t; 1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstruct repeat_info_t 1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_repeat_t value; 1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck char name[28]; 1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}; 1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic const repeat_info_t repeats[] = 1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_REPEAT_PAD, "PAD" }, 1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_REPEAT_REFLECT, "REFLECT" }, 1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_REPEAT_NORMAL, "NORMAL" } 1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}; 1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic int 1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reckdo_test (int32_t dst_size, 1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t src_size, 1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t src_offs, 1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t scale_factor) 1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i, j; 1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < ARRAY_LENGTH (filters); ++i) 1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (j = 0; j < ARRAY_LENGTH (repeats); ++j) 1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* horizontal test */ 1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (run_test (dst_size, 1, 1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck src_size, 1, 1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck src_offs, 0, 1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck scale_factor, 65536, 1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck filters[i].value, 1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeats[j].value) != 0) 1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck printf ("Vertical test failed with %s filter and repeat mode %s\n", 1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck filters[i].name, repeats[j].name); 1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return 1; 1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* vertical test */ 1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (run_test (1, dst_size, 1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1, src_size, 1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 0, src_offs, 1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 65536, scale_factor, 1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck filters[i].value, 1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeats[j].value) != 0) 1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck printf ("Vertical test failed with %s filter and repeat mode %s\n", 1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck filters[i].name, repeats[j].name); 1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return 1; 1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return 0; 1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reckint 1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reckmain (int argc, char *argv[]) 1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i; 1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_disable_out_of_bounds_workaround (); 1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* can potentially crash */ 1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck assert (do_test ( 1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 48000, 32767, 1, 65536 * 128) == 0); 1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* can potentially get into a deadloop */ 1871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck assert (do_test ( 1881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16384, 65536, 32, 32768) == 0); 1891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* can potentially access memory outside source image buffer */ 1911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck assert (do_test ( 1921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10, 10, 0, 1) == 0); 1931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck assert (do_test ( 1941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10, 10, 0, 0) == 0); 1951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < 100; ++i) 1971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t one_seventh = 1991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (7 << 16); 2001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck assert (do_test ( 2021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1, 7, 3, one_seventh + i - 50) == 0); 2031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < 100; ++i) 2061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t scale = 2081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (32767 << 16); 2091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck assert (do_test ( 2111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1, 32767, 16383, scale + i - 50) == 0); 2121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* can potentially provide invalid results (out of range matrix stuff) */ 2151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck assert (do_test ( 2161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 48000, 32767, 16384, 65536 * 128) == 0); 2171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return 0; 2191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 220