diff options
author | Siarhei Siamashka <siarhei.siamashka@nokia.com> | 2009-03-31 20:58:56 +0300 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-03-31 21:30:03 -0400 |
commit | a9adae3dc38764fe055b66e38175be5220fb3f9a (patch) | |
tree | c7c5812cfe1ae250e2adfe918e2d9661166e56bc | |
parent | 29e8556814ddddf269da90989e0de6d406d0afe6 (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.am | 2 | ||||
-rw-r--r-- | test/scaling-test-bisect.rb | 38 | ||||
-rw-r--r-- | test/scaling-test.c | 261 |
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; +} |