summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiarhei Siamashka <siarhei.siamashka@nokia.com>2009-03-31 20:58:56 +0300
committerSøren Sandmann Pedersen <sandmann@redhat.com>2009-03-31 21:30:03 -0400
commita9adae3dc38764fe055b66e38175be5220fb3f9a (patch)
treec7c5812cfe1ae250e2adfe918e2d9661166e56bc
parent29e8556814ddddf269da90989e0de6d406d0afe6 (diff)
Image scaling regression test script
This test script can help in finding regressions in image scaling fastpath implementations. It uses test program compiled with and without fastpath code and can compare results of execution for different pseudorandom compositing operations involving scaling. Signed-off-by: Søren Sandmann Pedersen <sandmann@redhat.com>
-rw-r--r--test/Makefile.am2
-rw-r--r--test/scaling-test-bisect.rb38
-rw-r--r--test/scaling-test.c261
3 files changed, 301 insertions, 0 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index 33e2200d..31307d46 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -4,6 +4,7 @@ TESTPROGRAMS = \
composite-test \
gradient-test \
region-test \
+ scaling-test \
fetch-test
noinst_PROGRAMS = $(TESTPROGRAMS)
@@ -14,6 +15,7 @@ composite_test_LDADD = $(top_builddir)/pixman/libpixman-1.la $(GTK_LIBS)
gradient_test_LDADD = $(top_builddir)/pixman/libpixman-1.la $(GTK_LIBS)
fetch_test_LDADD = $(top_builddir)/pixman/libpixman-1.la
region_test_LDADD = $(top_builddir)/pixman/libpixman-1.la
+scaling_test_LDADD = $(top_builddir)/pixman/libpixman-1.la
clip_test_LDADD = $(top_builddir)/pixman/libpixman-1.la $(GTK_LIBS)
endif
diff --git a/test/scaling-test-bisect.rb b/test/scaling-test-bisect.rb
new file mode 100644
index 00000000..2e4aff30
--- /dev/null
+++ b/test/scaling-test-bisect.rb
@@ -0,0 +1,38 @@
+#!/usr/bin/env ruby
+
+if not ARGV[0] or not ARGV[1] then
+ printf("Please provide two 'scaling-test' static binaries in the command line.\n\n")
+ printf("The first should be linked with the correct reference pixman library.\n")
+ printf("The second binrary should be linked with the pixman library to be tested.\n")
+ exit(0)
+end
+
+$MAX = 10000
+$MIN = 1
+$AVG = 0
+
+if `#{ARGV[0]} #{$MAX} 2>/dev/null` == `#{ARGV[1]} #{$MAX} 2>/dev/null` then
+ printf("test ok\n")
+ exit(0)
+end
+
+printf("test failed, bisecting...\n")
+
+while $MAX != $MIN + 1 do
+ $AVG = (($MIN + $MAX) / 2).to_i
+ res1 = `#{ARGV[0]} #{$AVG} 2>/dev/null`
+ res2 = `#{ARGV[1]} #{$AVG} 2>/dev/null`
+ if res1 != res2 then
+ $MAX = $AVG
+ else
+ $MIN = $AVG
+ end
+end
+
+printf("-- ref --\n")
+printf("%s\n", `#{ARGV[0]} -#{$MAX}`)
+printf("-- new --\n")
+printf("%s\n", `#{ARGV[1]} -#{$MAX}`)
+
+printf("\nFailed test number is %d, you can reproduce the problematic conditions\n", $MAX)
+printf("by running 'scaling-test -%d'\n", $MAX)
diff --git a/test/scaling-test.c b/test/scaling-test.c
new file mode 100644
index 00000000..ff24b1d4
--- /dev/null
+++ b/test/scaling-test.c
@@ -0,0 +1,261 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "pixman.h"
+
+/* A primitive pseudorandom number generator, taken from POSIX.1-2001 example */
+
+static uint32_t lcg_seed;
+
+uint32_t lcg_rand(void)
+{
+ lcg_seed = lcg_seed * 1103515245 + 12345;
+ return ((uint32_t)(lcg_seed / 65536) % 32768);
+}
+
+void lcg_srand(uint32_t seed)
+{
+ lcg_seed = seed;
+}
+
+uint32_t lcg_rand_n(int max)
+{
+ return lcg_rand() % max;
+}
+
+/*----------------------------------------------------------------------------*\
+ * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
+ *
+ * This program generates the CRC-32 values for the files named in the
+ * command-line arguments. These are the same CRC-32 values used by GZIP,
+ * PKZIP, and ZMODEM. The Crc32_ComputeBuf() can also be detached and
+ * used independently.
+ *
+ * THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
+ *
+ * Based on the byte-oriented implementation "File Verification Using CRC"
+ * by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
+ *
+ * v1.0.0: original release.
+ * v1.0.1: fixed printf formats.
+ * v1.0.2: fixed something else.
+ * v1.0.3: replaced CRC constant table by generator function.
+ * v1.0.4: reformatted code, made ANSI C. 1994-12-05.
+ * v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
+\*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*\
+ * NAME:
+ * Crc32_ComputeBuf() - computes the CRC-32 value of a memory buffer
+ * DESCRIPTION:
+ * Computes or accumulates the CRC-32 value for a memory buffer.
+ * The 'inCrc32' gives a previously accumulated CRC-32 value to allow
+ * a CRC to be generated for multiple sequential buffer-fuls of data.
+ * The 'inCrc32' for the first buffer must be zero.
+ * ARGUMENTS:
+ * inCrc32 - accumulated CRC-32 value, must be 0 on first call
+ * buf - buffer to compute CRC-32 value for
+ * bufLen - number of bytes in buffer
+ * RETURNS:
+ * crc32 - computed CRC-32 value
+ * ERRORS:
+ * (no errors are possible)
+\*----------------------------------------------------------------------------*/
+
+static uint32_t Crc32_ComputeBuf( uint32_t inCrc32, const void *buf,
+ size_t bufLen )
+{
+ static const uint32_t crcTable[256] = {
+ 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,
+ 0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,
+ 0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,
+ 0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,
+ 0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,
+ 0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,
+ 0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,0x26D930AC,
+ 0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,
+ 0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,
+ 0xB6662D3D,0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,
+ 0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,
+ 0x086D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,
+ 0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,
+ 0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,0x4DB26158,0x3AB551CE,
+ 0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,
+ 0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
+ 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,
+ 0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,
+ 0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,
+ 0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,
+ 0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,0xF00F9344,0x8708A3D2,0x1E01F268,
+ 0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,
+ 0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,
+ 0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,
+ 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,
+ 0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,
+ 0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,
+ 0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,
+ 0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,
+ 0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242,
+ 0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,
+ 0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
+ 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,
+ 0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,
+ 0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,
+ 0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,
+ 0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D };
+ uint32_t crc32;
+ unsigned char *byteBuf;
+ size_t i;
+
+ /** accumulate crc32 for buffer **/
+ crc32 = inCrc32 ^ 0xFFFFFFFF;
+ byteBuf = (unsigned char*) buf;
+ for (i=0; i < bufLen; i++) {
+ crc32 = (crc32 >> 8) ^ crcTable[ (crc32 ^ byteBuf[i]) & 0xFF ];
+ }
+ return( crc32 ^ 0xFFFFFFFF );
+}
+
+
+#define MAX_SRC_WIDTH 100
+#define MAX_SRC_HEIGHT 100
+#define MAX_DST_WIDTH 100
+#define MAX_DST_HEIGHT 100
+#define MAX_STRIDE 16
+
+/*
+ * Composite operation with pseudorandom images
+ */
+uint32_t test_composite(uint32_t initcrc, int testnum, int verbose)
+{
+ int i;
+ pixman_image_t *src_img;
+ pixman_image_t *dst_img;
+ pixman_transform_t transform;
+ pixman_region16_t clip;
+ int src_width, src_height;
+ int dst_width, dst_height;
+ int src_stride, dst_stride;
+ int src_x, src_y;
+ int dst_x, dst_y;
+ int src_bpp;
+ int dst_bpp;
+ int w, h;
+ int scale_x = 32768, scale_y = 32768;
+ int op;
+ int repeat = 0;
+ int src_fmt, dst_fmt;
+ uint32_t *srcbuf;
+ uint32_t *dstbuf;
+ uint32_t crc32;
+
+ lcg_srand(testnum);
+
+ src_bpp = /*(lcg_rand_n(2) == 0) ? 2 :*/ 4;
+ dst_bpp = /*(lcg_rand_n(2) == 0) ? 2 :*/ 4;
+ op = (lcg_rand_n(2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
+
+ src_width = lcg_rand_n(MAX_SRC_WIDTH) + 1;
+ src_height = lcg_rand_n(MAX_SRC_HEIGHT) + 1;
+ dst_width = lcg_rand_n(MAX_DST_WIDTH) + 1;
+ dst_height = lcg_rand_n(MAX_DST_HEIGHT) + 1;
+ src_stride = src_width * src_bpp + lcg_rand_n(MAX_STRIDE) * src_bpp;
+ dst_stride = dst_width * dst_bpp + lcg_rand_n(MAX_STRIDE) * dst_bpp;
+
+ src_x = -src_width + lcg_rand_n(src_width * 3);
+ src_y = -src_height + lcg_rand_n(src_height * 3);
+ dst_x = -dst_width + lcg_rand_n(dst_width * 2);
+ dst_y = -dst_height + lcg_rand_n(dst_height * 3);
+
+ srcbuf = (uint32_t *)malloc(src_stride * src_height);
+ dstbuf = (uint32_t *)malloc(dst_stride * dst_height);
+ for (i = 0; i < src_stride * src_height; i++)
+ *((uint8_t *)srcbuf + i) = lcg_rand_n(256);
+ for (i = 0; i < dst_stride * dst_height; i++)
+ *((uint8_t *)dstbuf + i) = lcg_rand_n(256);
+
+ src_fmt = src_bpp == 4 ? (lcg_rand_n(2) == 0 ?
+ PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
+
+ dst_fmt = dst_bpp == 4 ? (lcg_rand_n(2) == 0 ?
+ PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
+
+ src_img = pixman_image_create_bits(
+ src_fmt, src_width, src_height, srcbuf, src_stride);
+
+ dst_img = pixman_image_create_bits(
+ dst_fmt, dst_width, dst_height, dstbuf, dst_stride);
+
+ if (lcg_rand_n(2) == 0) {
+ scale_x = 32768 + lcg_rand_n(65536);
+ scale_y = 32768 + lcg_rand_n(65536);
+ pixman_transform_init_scale(&transform, scale_x, scale_y);
+ pixman_image_set_transform(src_img, &transform);
+ }
+
+ switch (lcg_rand_n(4)) {
+ case 0: repeat = PIXMAN_REPEAT_NONE; break;
+ case 1: repeat = PIXMAN_REPEAT_NORMAL; break;
+ case 2: repeat = PIXMAN_REPEAT_PAD; break;
+ case 3: repeat = PIXMAN_REPEAT_REFLECT; break;
+ }
+ pixman_image_set_repeat(src_img, repeat);
+
+ w = lcg_rand_n(MAX_DST_WIDTH * 2);
+ h = lcg_rand_n(MAX_DST_HEIGHT * 2);
+
+ if (verbose) {
+ printf("op=%d, scale_x=%d, scale_y=%d, repeat=%d\n",
+ op, scale_x, scale_y, repeat);
+ printf("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
+ src_width, src_height, dst_width, dst_height);
+ printf("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
+ src_x, src_y, dst_x, dst_y);
+ printf("w=%d, h=%d\n", w, h);
+ }
+
+ pixman_image_composite (op, src_img, NULL, dst_img,
+ src_x, src_y, 0, 0, dst_x, dst_y, w, h);
+
+ if (verbose) {
+ int j;
+ for (i = 0; i < dst_height; i++) {
+ for (j = 0; j < dst_stride; j++) {
+ printf("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
+ }
+ printf("\n");
+ }
+ }
+
+ pixman_image_unref (src_img);
+ pixman_image_unref (dst_img);
+
+ crc32 = Crc32_ComputeBuf(initcrc, dstbuf, dst_stride * dst_height);
+ free(srcbuf);
+ free(dstbuf);
+ return crc32;
+}
+
+int main(int argc, char *argv[])
+{
+ int i, n = 0;
+ uint32_t crc = 0;
+
+ if (argc >= 2)
+ n = atoi(argv[1]);
+
+ if (n == 0) n = 10000;
+
+ if (n < 0) {
+ crc = test_composite(0, -n, 1);
+ printf("crc32=%08X\n", crc);
+ }
+ else {
+ for (i = 1; i <= n; i++)
+ {
+ crc = test_composite(crc, i, 0);
+ }
+ printf("crc32=%08X\n", crc);
+ }
+ return 0;
+}