diff options
Diffstat (limited to 'test/cairo-test.c')
-rw-r--r-- | test/cairo-test.c | 162 |
1 files changed, 100 insertions, 62 deletions
diff --git a/test/cairo-test.c b/test/cairo-test.c index 2364570a2..06f7672fd 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -32,10 +32,12 @@ #include "cairo_test.h" +#include "buffer_diff.h" #include "read_png.h" #include "write_png.h" #include "xmalloc.h" +#define CAIRO_TEST_LOG_SUFFIX ".log" #define CAIRO_TEST_PNG_SUFFIX "-out.png" #define CAIRO_TEST_REF_SUFFIX "-ref.png" #define CAIRO_TEST_DIFF_SUFFIX "-diff.png" @@ -43,9 +45,10 @@ static void xasprintf (char **strp, const char *fmt, ...) { +#ifdef HAVE_VASPRINTF va_list va; int ret; - + va_start (va, fmt); ret = vasprintf (strp, fmt, va); va_end (va); @@ -54,53 +57,42 @@ xasprintf (char **strp, const char *fmt, ...) fprintf (stderr, "Out of memory\n"); exit (1); } +#else /* !HAVE_VASNPRINTF */ +#define BUF_SIZE 1024 + va_list va; + char buffer[BUF_SIZE]; + int ret; + + va_start (va, fmt); + ret = vsnprintf (buffer, sizeof(buffer), fmt, va); + va_end (va); + + if (ret < 0) { + fprintf (stderr, "Failure in vsnprintf\n"); + exit (1); + } + + if (strlen (buffer) == sizeof(buffer) - 1) { + fprintf (stderr, "Overflowed fixed buffer\n"); + exit (1); + } + + *strp = strdup (buffer); + if (!*strp) { + fprintf (stderr, "Out of memory\n"); + exit (1); + } +#endif /* !HAVE_VASNPRINTF */ } -/* Image comparison code courttesy of Richard Worth. - * Returns number of pixels changed. - * Also fills out a "diff" image intended to visually show where the - * images differ. - */ -static int -image_diff (char *buf_a, char *buf_b, char *buf_diff, - int width, int height, int stride) +static void +xunlink (const char *pathname) { - int x, y; - int total_pixels_changed = 0; - unsigned char *row_a, *row_b, *row; - - for (y = 0; y < height; y++) - { - row_a = buf_a + y * stride; - row_b = buf_b + y * stride; - row = buf_diff + y * stride; - for (x = 0; x < width; x++) - { - int channel; - unsigned char value_a, value_b; - int pixel_changed = 0; - for (channel = 0; channel < 4; channel++) - { - double diff; - value_a = row_a[x * 4 + channel]; - value_b = row_b[x * 4 + channel]; - if (value_a != value_b) - pixel_changed = 1; - diff = value_a - value_b; - row[x * 4 + channel] = 128 + diff / 3.0; - } - if (pixel_changed) { - total_pixels_changed++; - } else { - row[x*4+0] = 0; - row[x*4+1] = 0; - row[x*4+2] = 0; - } - row[x * 4 + 3] = 0xff; /* Set ALPHA to 100% (opaque) */ - } + if (unlink (pathname) < 0 && errno != ENOENT) { + fprintf (stderr, " Error: Cannot remove %s: %s\n", + pathname, strerror (errno)); + exit (1); } - - return total_pixels_changed; } cairo_test_status_t @@ -109,12 +101,14 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw) cairo_t *cr; int stride; unsigned char *png_buf, *ref_buf, *diff_buf; - char *png_name, *ref_name, *diff_name; + char *log_name, *png_name, *ref_name, *diff_name; char *srcdir; int pixels_changed; int ref_width, ref_height, ref_stride; read_png_status_t png_status; cairo_test_status_t ret; + FILE *png_file; + FILE *log_file; /* The cairo part of the test is the easiest part */ cr = cairo_create (); @@ -142,57 +136,68 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw) srcdir = getenv ("srcdir"); if (!srcdir) srcdir = "."; + xasprintf (&log_name, "%s%s", test->name, CAIRO_TEST_LOG_SUFFIX); xasprintf (&png_name, "%s%s", test->name, CAIRO_TEST_PNG_SUFFIX); xasprintf (&ref_name, "%s/%s%s", srcdir, test->name, CAIRO_TEST_REF_SUFFIX); xasprintf (&diff_name, "%s%s", test->name, CAIRO_TEST_DIFF_SUFFIX); - write_png_argb32 (png_buf, png_name, test->width, test->height, stride); + png_file = fopen (png_name, "w"); + write_png_argb32 (png_buf, png_file, test->width, test->height, stride); + fclose (png_file); + + xunlink (log_name); ref_buf = NULL; png_status = (read_png_argb32 (ref_name, &ref_buf, &ref_width, &ref_height, &ref_stride)); if (png_status) { + log_file = fopen (log_name, "a"); switch (png_status) { case READ_PNG_FILE_NOT_FOUND: - fprintf (stderr, " Error: No reference image found: %s\n", ref_name); + fprintf (log_file, "Error: No reference image found: %s\n", ref_name); break; case READ_PNG_FILE_NOT_PNG: - fprintf (stderr, " Error: %s is not a png image\n", ref_name); + fprintf (log_file, "Error: %s is not a png image\n", ref_name); break; default: - fprintf (stderr, " Error: Failed to read %s\n", ref_name); + fprintf (log_file, "Error: Failed to read %s\n", ref_name); } + fclose (log_file); ret = CAIRO_TEST_FAILURE; goto BAIL; + } else { } if (test->width != ref_width || test->height != ref_height) { - fprintf (stderr, - " Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n" - " for %s vs %s\n", + log_file = fopen (log_name, "a"); + fprintf (log_file, + "Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n" + " for %s vs %s\n", test->width, test->height, ref_width, ref_height, png_name, ref_name); + fclose (log_file); + ret = CAIRO_TEST_FAILURE; goto BAIL; } - pixels_changed = image_diff (png_buf, ref_buf, diff_buf, - test->width, test->height, stride); + pixels_changed = buffer_diff (png_buf, ref_buf, diff_buf, + test->width, test->height, stride); if (pixels_changed) { - fprintf (stderr, " Error: %d pixels differ from reference image %s\n", + log_file = fopen (log_name, "a"); + fprintf (log_file, "Error: %d pixels differ from reference image %s\n", pixels_changed, ref_name); - write_png_argb32 (diff_buf, diff_name, test->width, test->height, stride); + png_file = fopen (diff_name, "w"); + write_png_argb32 (diff_buf, png_file, test->width, test->height, stride); + fclose (png_file); + fclose (log_file); + ret = CAIRO_TEST_FAILURE; goto BAIL; } else { - if (unlink (diff_name) < 0 && errno != ENOENT) { - fprintf (stderr, " Error: Cannot remove %s: %s\n", - diff_name, strerror (errno)); - ret = CAIRO_TEST_FAILURE; - goto BAIL; - } + xunlink (diff_name); } ret = CAIRO_TEST_SUCCESS; @@ -201,9 +206,42 @@ BAIL: free (png_buf); free (ref_buf); free (diff_buf); + free (log_name); free (png_name); free (ref_name); free (diff_name); return ret; } + +cairo_pattern_t * +cairo_test_create_png_pattern (cairo_t *cr, const char *filename) +{ + cairo_surface_t *image; + cairo_pattern_t *pattern; + unsigned char *buffer; + int w, h, stride; + read_png_status_t status; + char *srcdir = getenv ("srcdir"); + + status = read_png_argb32 (filename, &buffer, &w,&h, &stride); + if (status != READ_PNG_SUCCESS) { + if (srcdir) { + char *srcdir_filename; + xasprintf (&srcdir_filename, "%s/%s", srcdir, filename); + status = read_png_argb32 (srcdir_filename, &buffer, &w,&h, &stride); + free (srcdir_filename); + } + } + if (status != READ_PNG_SUCCESS) + return NULL; + + image = cairo_surface_create_for_image (buffer, CAIRO_FORMAT_ARGB32, + w, h, stride); + + cairo_surface_set_repeat (image, 1); + + pattern = cairo_pattern_create_for_surface (image); + + return pattern; +} |