[cairo-commit] Branch '1.2' - 4 commits - Makefile.am test/buffer-diff.c test/buffer-diff.h test/cairo-test.c test/cairo-test.h test/imagediff.c test/Makefile.am test/read-png.c test/read-png.h test/write-png.c test/write-png.h test/xlib-surface.c

Carl Worth cworth at kemper.freedesktop.org
Thu Nov 2 15:12:39 PST 2006


 Makefile.am         |    2 
 test/Makefile.am    |    4 
 test/buffer-diff.c  |  334 ++++++++++++++++++++++++----------------------------
 test/buffer-diff.h  |   63 +++++++--
 test/cairo-test.c   |  150 +++++++++++++----------
 test/cairo-test.h   |    7 +
 test/imagediff.c    |   21 ++-
 test/read-png.c     |  196 ------------------------------
 test/read-png.h     |   45 -------
 test/write-png.c    |   99 ---------------
 test/write-png.h    |   35 -----
 test/xlib-surface.c |   75 ++++++-----
 12 files changed, 355 insertions(+), 676 deletions(-)

New commits:
diff-tree 76cc6af100ca5588a36a42eaddeacbdfc288bb82 (from ad4f0ba2d59cb417498408606ec1466dae723715)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Oct 26 15:52:21 2006 -0700

    Make xlib and xcb backends tolerant of single-bit errors in the test suite output.
    
    Manually "cherry picked" from 61bf9b009b47312c20d54198790542cd20fc5576
    (the cherry-pick command cannot handle the file renames and
    indentation changes involved here).

diff --git a/test/cairo-test.c b/test/cairo-test.c
index 22b150e..eab373d 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -1801,13 +1801,17 @@ cairo_test_expecting (cairo_test_t *test
 		create_win32_surface, cairo_surface_write_to_png, cleanup_win32 },
 #endif
 #if CAIRO_HAS_XCB_SURFACE
-	    { "xcb", CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 0,
+	    /* Acceleration architectures may make the results differ by a
+	     * bit, so we set the error tolerance to 1. */
+	    { "xcb", CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
 		create_xcb_surface, cairo_surface_write_to_png, cleanup_xcb},
 #endif
 #if CAIRO_HAS_XLIB_SURFACE
-	    { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 0,
+	    /* Acceleration architectures may make the results differ by a
+	     * bit, so we set the error tolerance to 1. */
+	    { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1,
 		create_xlib_surface, cairo_surface_write_to_png, cleanup_xlib},
-	    { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 0,
+	    { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
 		create_xlib_surface, cairo_surface_write_to_png, cleanup_xlib},
 #endif
 #if CAIRO_HAS_PS_SURFACE
@@ -1847,7 +1851,7 @@ cairo_test_expecting (cairo_test_t *test
 	     * through librsvg and cairo, but for some mysterious reason, some
 	     * systems get an error of 1 for some pixels on some of the text
 	     * tests. XXX: I'd still like to chase these down at some point.
-	     * For now just set teh svg error tolerance to 1. */
+	     * For now just set the svg error tolerance to 1. */
 	    { "svg", CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
 		    create_svg_surface, svg_surface_write_to_png, cleanup_svg },
 	    { "svg", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 1,
diff-tree ad4f0ba2d59cb417498408606ec1466dae723715 (from 02497b39c86e451cd12cf21f860fbdacc59afe38)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Sep 5 22:25:21 2006 -0700

    Move target tolerance to cairo_test_target structure (should let single-pixel SVG errors pass)
    
    Previously we were setting the target tolerance based on the surface
    type. But that doesn't work as multiple backends will provide a surface
    of type meta. So instead we put the tolerance as a value in the
    cairo_test_target data structure.
    
    With this change, some single-pixel errors of 1 in the SVG backend
    should now be ignored.
    
    Manually "cherry picked" from bcb7863f00b4cfdf0985993067fc32d07b81540b
    (the regular cherry-pick command cannot handle the file renames and
     indentation changes involved here).

diff --git a/test/cairo-test.c b/test/cairo-test.c
index 82d5d6a..22b150e 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -133,50 +133,13 @@ typedef struct _cairo_test_target
     const char		       	       *name;
     cairo_surface_type_t		expected_type;
     cairo_content_t			content;
+    int					error_tolerance;
     cairo_test_create_target_surface_t	create_target_surface;
     cairo_test_write_to_png_t		write_to_png;
     cairo_test_cleanup_target_t		cleanup_target;
     void			       *closure;
 } cairo_test_target_t;
 
-/* What's the maximum single-channel difference we will tolerate and
- * still allow a test to pass? */
-static unsigned int
-target_tolerance (cairo_test_target_t *target)
-{
-    switch (target->expected_type) {
-    /* I'm uncompromising about leaving the image backend as no
-     * tolerance. There's shouldn't ever be anything that is out of
-     * our control here. */
-    case CAIRO_SURFACE_TYPE_IMAGE:
-	return 0;
-
-    /* It seems we should be able to round-trip SVG content perfrectly
-     * through librsvg and cairo, but for some mysterious reason, some
-     * systems get an error of 1 for some pixels on some of the text
-     * tests. XXX: I'd still like to chase these down at some point. */
-    case CAIRO_SURFACE_TYPE_SVG:
-	return 1;
-
-    /* Everything else gets the no-tolerance policy. It would actually
-     * be nice to go through some of the backends and see * if it
-     * wouldn't make sense to increase this. For example, * could we
-     * use a small value here for the PS backend and * eliminate some
-     * of the ps-specific reference images? */
-    case CAIRO_SURFACE_TYPE_PDF:
-    case CAIRO_SURFACE_TYPE_PS:
-    case CAIRO_SURFACE_TYPE_XLIB:
-    case CAIRO_SURFACE_TYPE_XCB:
-    case CAIRO_SURFACE_TYPE_GLITZ:
-    case CAIRO_SURFACE_TYPE_QUARTZ:
-    case CAIRO_SURFACE_TYPE_WIN32:
-    case CAIRO_SURFACE_TYPE_BEOS:
-    case CAIRO_SURFACE_TYPE_DIRECTFB:
-    default:
-	return 0;
-    }
-}
-
 void
 cairo_test_init (const char *test_name)
 {
@@ -1715,7 +1678,7 @@ cairo_test_for_target (cairo_test_t		 *t
 	if (result.pixels_changed) {
 	    cairo_test_log ("%d pixels differ (with maximum difference of %d) from reference image %s\n",
 			    result.pixels_changed, result.max_diff, ref_name);
-	    if (result.max_diff > target_tolerance (target)) {
+	    if (result.max_diff > target->error_tolerance) {
 		ret = CAIRO_TEST_FAILURE;
 		goto UNWIND_CAIRO;
 	    }
@@ -1771,82 +1734,85 @@ cairo_test_expecting (cairo_test_t *test
     cairo_test_target_t ** volatile targets_to_test;
     cairo_test_target_t targets[] =
 	{
-	    { "image", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA,
+	    /* I'm uncompromising about leaving the image backend as 0
+	     * for tolerance. There shouldn't ever be anything that is out of
+	     * our control here. */
+	    { "image", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA, 0,
 	      create_image_surface, cairo_surface_write_to_png, NULL},
-	    { "image", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR,
+	    { "image", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
 	      create_image_surface, cairo_surface_write_to_png, NULL},
 #ifdef CAIRO_HAS_TEST_SURFACES
 	    { "test-fallback", CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
-	      CAIRO_CONTENT_COLOR_ALPHA,
+	      CAIRO_CONTENT_COLOR_ALPHA, 0,
 	      create_test_fallback_surface, cairo_surface_write_to_png, NULL },
 	    { "test-fallback", CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
-	      CAIRO_CONTENT_COLOR,
+	      CAIRO_CONTENT_COLOR, 0,
 	      create_test_fallback_surface, cairo_surface_write_to_png, NULL },
 	    { "test-meta", CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
-	      CAIRO_CONTENT_COLOR_ALPHA,
+	      CAIRO_CONTENT_COLOR_ALPHA, 0,
 	      create_test_meta_surface, cairo_surface_write_to_png, NULL },
 	    { "test-meta", CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
-	      CAIRO_CONTENT_COLOR,
+	      CAIRO_CONTENT_COLOR, 0,
 	      create_test_meta_surface, cairo_surface_write_to_png, NULL },
 	    { "test-paginated", CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
-	      CAIRO_CONTENT_COLOR_ALPHA,
+	      CAIRO_CONTENT_COLOR_ALPHA, 0,
 	      create_test_paginated_surface,
 	      test_paginated_write_to_png,
 	      cleanup_test_paginated },
 	    { "test-paginated", CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
-	      CAIRO_CONTENT_COLOR,
+	      CAIRO_CONTENT_COLOR, 0,
 	      create_test_paginated_surface,
 	      test_paginated_write_to_png,
 	      cleanup_test_paginated },
 #endif
 #ifdef CAIRO_HAS_GLITZ_SURFACE
 #if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE
-	    { "glitz-glx", CAIRO_SURFACE_TYPE_GLITZ,CAIRO_CONTENT_COLOR_ALPHA,
+	    { "glitz-glx", CAIRO_SURFACE_TYPE_GLITZ,CAIRO_CONTENT_COLOR_ALPHA, 0,
 		create_cairo_glitz_glx_surface, cairo_surface_write_to_png,
 		cleanup_cairo_glitz_glx },
-	    { "glitz-glx", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR,
+	    { "glitz-glx", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
 		create_cairo_glitz_glx_surface, cairo_surface_write_to_png,
 		cleanup_cairo_glitz_glx },
 #endif
 #if CAIRO_CAN_TEST_GLITZ_AGL_SURFACE
-	    { "glitz-agl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA,
+	    { "glitz-agl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
 		create_cairo_glitz_agl_surface, cairo_surface_write_to_png,
 		cleanup_cairo_glitz_agl },
-	    { "glitz-agl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR,
+	    { "glitz-agl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
 		create_cairo_glitz_agl_surface, cairo_surface_write_to_png,
 		cleanup_cairo_glitz_agl },
 #endif
 #if CAIRO_CAN_TEST_GLITZ_WGL_SURFACE
-	    { "glitz-wgl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA,
+	    { "glitz-wgl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
 		create_cairo_glitz_wgl_surface, cairo_surface_write_to_png,
 		cleanup_cairo_glitz_wgl },
-	    { "glitz-wgl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR,
+	    { "glitz-wgl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
 		create_cairo_glitz_wgl_surface, cairo_surface_write_to_png,
 		cleanup_cairo_glitz_wgl },
 #endif
 #endif /* CAIRO_HAS_GLITZ_SURFACE */
 #if 0 && CAIRO_HAS_QUARTZ_SURFACE
-	    { "quartz", CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR,
+	    { "quartz", CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR, 0,
 		create_quartz_surface, cairo_surface_write_to_png,
 		cleanup_quartz },
 #endif
 #if CAIRO_HAS_WIN32_SURFACE
-	    { "win32", CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR,
+	    { "win32", CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR, 0,
 		create_win32_surface, cairo_surface_write_to_png, cleanup_win32 },
 #endif
 #if CAIRO_HAS_XCB_SURFACE
-	    { "xcb", CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA,
+	    { "xcb", CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 0,
 		create_xcb_surface, cairo_surface_write_to_png, cleanup_xcb},
 #endif
 #if CAIRO_HAS_XLIB_SURFACE
-	    { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA,
+	    { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 0,
 		create_xlib_surface, cairo_surface_write_to_png, cleanup_xlib},
-	    { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR,
+	    { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 0,
 		create_xlib_surface, cairo_surface_write_to_png, cleanup_xlib},
 #endif
 #if CAIRO_HAS_PS_SURFACE
 	    { "ps", CAIRO_SURFACE_TYPE_PS,
-	        CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED,
+	        CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
 		create_ps_surface, ps_surface_write_to_png, cleanup_ps },
 
 	    /* XXX: We expect type image here only due to a limitation in
@@ -1857,12 +1823,12 @@ cairo_test_expecting (cairo_test_t *test
 	     * have source support for PS/meta-surfaces, so the
 	     * create_similar path for all paginated surfaces currently
 	     * returns an image surface.*/
-	    { "ps", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR,
+	    { "ps", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
 		create_ps_surface, ps_surface_write_to_png, cleanup_ps },
 #endif
 #if CAIRO_HAS_PDF_SURFACE && CAIRO_CAN_TEST_PDF_SURFACE
 	    { "pdf", CAIRO_SURFACE_TYPE_PDF,
-	        CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED,
+	        CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
 		create_pdf_surface, pdf_surface_write_to_png, cleanup_pdf },
 
 	    /* XXX: We expect type image here only due to a limitation in
@@ -1873,28 +1839,33 @@ cairo_test_expecting (cairo_test_t *test
 	     * have source support for PDF/meta-surfaces, so the
 	     * create_similar path for all paginated surfaces currently
 	     * returns an image surface.*/
-	    { "pdf", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR,
+	    { "pdf", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
 		create_pdf_surface, pdf_surface_write_to_png, cleanup_pdf },
 #endif
 #if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE
-	    { "svg", CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA,
+	    /* It seems we should be able to round-trip SVG content perfrectly
+	     * through librsvg and cairo, but for some mysterious reason, some
+	     * systems get an error of 1 for some pixels on some of the text
+	     * tests. XXX: I'd still like to chase these down at some point.
+	     * For now just set teh svg error tolerance to 1. */
+	    { "svg", CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
 		    create_svg_surface, svg_surface_write_to_png, cleanup_svg },
-	    { "svg", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR,
+	    { "svg", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 1,
 		    create_svg_surface, svg_surface_write_to_png, cleanup_svg },
 #endif
 #if CAIRO_HAS_BEOS_SURFACE
-	    { "beos", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR,
+	    { "beos", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 0,
 		create_beos_surface, cairo_surface_write_to_png, cleanup_beos},
-	    { "beos-bitmap", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR,
+	    { "beos-bitmap", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 0,
 		create_beos_bitmap_surface, cairo_surface_write_to_png, cleanup_beos_bitmap},
-	    { "beos-bitmap", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR_ALPHA,
+	    { "beos-bitmap", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR_ALPHA, 0,
 		create_beos_bitmap_surface, cairo_surface_write_to_png, cleanup_beos_bitmap},
 #endif
 
 #if CAIRO_HAS_DIRECTFB_SURFACE
-	    { "directfb", CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR,
+	    { "directfb", CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR, 0,
 		create_directfb_surface, cairo_surface_write_to_png, cleanup_directfb},
-	    { "directfb-bitmap", CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR_ALPHA,
+	    { "directfb-bitmap", CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR_ALPHA, 0,
 		create_directfb_bitmap_surface, cairo_surface_write_to_png,cleanup_directfb},
 #endif
 	};
diff-tree 02497b39c86e451cd12cf21f860fbdacc59afe38 (from 11127fc21009cfa55312fcab8aed43470f7e4cc0)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Aug 31 04:01:10 2006 -0700

    test: Ignore single-bit errors for SVG backend.
    
    The interface of the various buffer/image_diff functions is improved to
    provide the maximum pixel difference in addition to the number of pixels
    that differ. This value can then be used to compare against a per-backend
    tolerance.
    
    Currently I've set the SVG backend's tolerance to 1 to handle some issues
    we're currently seeing of single-bit differences on different systems, (but
    we're not exactly sure why yet).
    
    Also I improved the image_diff routines to properly report a status value
    on failure rather than the bogus value of -1 for pixels_changed.
    
    Cherry-picked from d1834cca192fe6f8e429be0461fab6914e04024d
    (and fixed ever so slightly to actually compile).

diff --git a/Makefile.am b/Makefile.am
index cf8e95e..57798d0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-DIST_SUBDIRS = pixman src test doc
+DIST_SUBDIRS = pixman src boilerplate test doc
 SUBDIRS = pixman src doc
 
 .PHONY: doc test retest recheck check-valgrind
diff --git a/test/buffer-diff.c b/test/buffer-diff.c
index b59b5e8..8009333 100644
--- a/test/buffer-diff.c
+++ b/test/buffer-diff.c
@@ -51,10 +51,14 @@ xunlink (const char *pathname)
     }
 }
 
-/* This function should be rewritten to compare all formats supported by
+/* Compare two buffers, returning the number of pixels that are
+ * different and the maximum difference of any single color channel in
+ * result_ret.
+ *
+ * This function should be rewritten to compare all formats supported by
  * cairo_format_t instead of taking a mask as a parameter.
  */
-static int
+static void
 buffer_diff_core (unsigned char *_buf_a,
 		  unsigned char *_buf_b,
 		  unsigned char *_buf_diff,
@@ -63,11 +67,12 @@ buffer_diff_core (unsigned char *_buf_a,
 		  int		stride_a,
 		  int		stride_b,
 		  int		stride_diff,
-		  pixman_bits_t mask)
+		  pixman_bits_t mask,
+		  buffer_diff_result_t *result_ret)
 {
     int x, y;
     pixman_bits_t *row_a, *row_b, *row;
-    int pixels_changed = 0;
+    buffer_diff_result_t result = {0, 0};
     pixman_bits_t *buf_a = (pixman_bits_t*)_buf_a;
     pixman_bits_t *buf_b = (pixman_bits_t*)_buf_b;
     pixman_bits_t *buf_diff = (pixman_bits_t*)_buf_diff;
@@ -93,6 +98,8 @@ buffer_diff_core (unsigned char *_buf_a,
 		    int value_b = (row_b[x] >> (channel*8)) & 0xff;
 		    unsigned int diff;
 		    diff = abs (value_a - value_b);
+		    if (diff > result.max_diff)
+			result.max_diff = diff;
 		    diff *= 4;  /* emphasize */
 		    if (diff)
 		        diff += 128; /* make sure it's visible */
@@ -101,7 +108,7 @@ buffer_diff_core (unsigned char *_buf_a,
 		    diff_pixel |= diff << (channel*8);
 		}
 
-		pixels_changed++;
+		result.pixels_changed++;
 		row[x] = diff_pixel;
 	    } else {
 		row[x] = 0;
@@ -110,10 +117,10 @@ buffer_diff_core (unsigned char *_buf_a,
 	}
     }
 
-    return pixels_changed;
+    *result_ret = result;
 }
 
-int
+void
 buffer_diff (unsigned char *buf_a,
 	     unsigned char *buf_b,
 	     unsigned char *buf_diff,
@@ -121,13 +128,15 @@ buffer_diff (unsigned char *buf_a,
 	     int	   height,
 	     int	   stride_a,
 	     int	   stride_b,
-	     int	   stride_diff)
+	     int	   stride_diff,
+	     buffer_diff_result_t *result)
 {
-    return buffer_diff_core(buf_a, buf_b, buf_diff,
-			    width, height, stride_a, stride_b, stride_diff, 0xffffffff);
+    buffer_diff_core(buf_a, buf_b, buf_diff,
+		     width, height, stride_a, stride_b, stride_diff, 0xffffffff,
+		     result);
 }
 
-int
+void
 buffer_diff_noalpha (unsigned char *buf_a,
 		     unsigned char *buf_b,
 		     unsigned char *buf_diff,
@@ -135,10 +144,12 @@ buffer_diff_noalpha (unsigned char *buf_
 		     int	   height,
 		     int	   stride_a,
 		     int	   stride_b,
-		     int	   stride_diff)
+		     int	   stride_diff,
+		     buffer_diff_result_t *result)
 {
-    return buffer_diff_core(buf_a, buf_b, buf_diff,
-			    width, height, stride_a, stride_b, stride_diff, 0x00ffffff);
+    buffer_diff_core(buf_a, buf_b, buf_diff,
+		     width, height, stride_a, stride_b, stride_diff, 0x00ffffff,
+		     result);
 }
 
 static cairo_status_t
@@ -188,8 +199,18 @@ flatten_surface (cairo_surface_t **surfa
  * Returns number of pixels changed, (or -1 on error).
  * Also saves a "diff" image intended to visually show where the
  * images differ.
+ *
+ * The return value simply indicates whether a check was successfully
+ * made, (as opposed to a file-not-found condition or similar). It
+ * does not indicate anything about how much the images differ. For
+ * that, see result.
+ *
+ * One failure mode is if the two images provided do not have the same
+ * dimensions. In this case, this function will return
+ * CAIRO_STATUS_SURFACE_TYPE_MISMATCH (which is a bit of an abuse, but
+ * oh well).
  */
-static int
+static cairo_status_t
 image_diff_core (const char *filename_a,
 		 const char *filename_b,
 		 const char *filename_diff,
@@ -197,21 +218,21 @@ image_diff_core (const char *filename_a,
 		 int		ay,
 		 int		bx,
 		 int		by,
+		 buffer_diff_result_t *result,
 		 cairo_bool_t	flatten)
 {
-    int pixels_changed;
     unsigned int width_a, height_a, stride_a;
     unsigned int width_b, height_b, stride_b;
     cairo_surface_t *surface_a, *surface_b, *surface_diff;
 
     surface_a = cairo_image_surface_create_from_png (filename_a);
     if (cairo_surface_status (surface_a))
-	return -1;
+	return cairo_surface_status (surface_a);
 
     surface_b = cairo_image_surface_create_from_png (filename_b);
     if (cairo_surface_status (surface_b)) {
 	cairo_surface_destroy (surface_a);
-	return -1;
+	return cairo_surface_status (surface_b);
     }
 
     width_a = cairo_image_surface_get_width (surface_a) - ax;
@@ -229,7 +250,7 @@ image_diff_core (const char *filename_a,
 			filename_a, filename_b);
 	cairo_surface_destroy (surface_a);
 	cairo_surface_destroy (surface_b);
-	return -1;
+	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
     }
 
     if (flatten) {
@@ -244,16 +265,17 @@ image_diff_core (const char *filename_a,
     stride_a = cairo_image_surface_get_stride (surface_a);
     stride_b = cairo_image_surface_get_stride (surface_b);
 
-    pixels_changed = buffer_diff (cairo_image_surface_get_data (surface_a)
-				  + (ay * stride_a) + ax * 4,
-                                  cairo_image_surface_get_data (surface_b)
-				  + (by * stride_b) + by * 4,
-                                  cairo_image_surface_get_data (surface_diff),
-                                  width_a, height_a,
-				  stride_a, stride_b,
-				  cairo_image_surface_get_stride (surface_diff));
+    buffer_diff (cairo_image_surface_get_data (surface_a)
+		 + (ay * stride_a) + ax * 4,
+		 cairo_image_surface_get_data (surface_b)
+		 + (by * stride_b) + by * 4,
+		 cairo_image_surface_get_data (surface_diff),
+		 width_a, height_a,
+		 stride_a, stride_b,
+		 cairo_image_surface_get_stride (surface_diff),
+		 result);
 
-    if (pixels_changed) {
+    if (result->pixels_changed) {
 	FILE *png_file;
 
 	if (filename_diff)
@@ -274,33 +296,35 @@ image_diff_core (const char *filename_a,
     cairo_surface_destroy (surface_b);
     cairo_surface_destroy (surface_diff);
 
-    return pixels_changed;
+    return CAIRO_STATUS_SUCCESS;
 }
 
-int
+cairo_status_t
 image_diff (const char *filename_a,
 	    const char *filename_b,
 	    const char *filename_diff,
 	    int		ax,
 	    int		ay,
 	    int		bx,
-	    int		by)
+	    int		by,
+	    buffer_diff_result_t *result)
 {
     return image_diff_core (filename_a, filename_b, filename_diff,
 			    ax, ay, bx, by,
-			    FALSE);
+			    result, FALSE);
 }
 
-int
+cairo_status_t
 image_diff_flattened (const char *filename_a,
 		      const char *filename_b,
 		      const char *filename_diff,
 		      int	  ax,
 		      int	  ay,
 		      int	  bx,
-		      int	  by)
+		      int	  by,
+		      buffer_diff_result_t *result)
 {
     return image_diff_core (filename_a, filename_b, filename_diff,
 			    ax, ay, bx, by,
-			    TRUE);
+			    result, TRUE);
 }
diff --git a/test/buffer-diff.h b/test/buffer-diff.h
index 2be2b39..bef42cf 100644
--- a/test/buffer-diff.h
+++ b/test/buffer-diff.h
@@ -1,36 +1,50 @@
 /* imagediff - Compare two images
  *
  * Copyright © 2004 Richard D. Worth
+ * Copyright © 2006 Red Hat, Inc.
  *
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of Richard Worth
+ * appear in supporting documentation, and that the name of the authors
  * not be used in advertising or publicity pertaining to distribution
  * of the software without specific, written prior permission.
- * Richard Worth makes no representations about the suitability of this
+ * The authors make no representations about the suitability of this
  * software for any purpose.  It is provided "as is" without express
  * or implied warranty.
  *
- * RICHARD WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
- * NO EVENT SHALL RICHARD WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: Richard D. Worth <richard at theworths.org> */
+ * Authors: Richard D. Worth <richard at theworths.org>
+ *	    Carl Worth <cworth at cworth.org>
+ */
 
 #ifndef BUFFER_DIFF_H
 #define BUFFER_DIFF_H
 
-/* Returns number of pixels changed.
+#include "cairo-test.h"
+
+typedef struct _buffer_diff_result {
+    unsigned int pixels_changed;
+    unsigned int max_diff;
+} buffer_diff_result_t;
+
+/* Compares two image buffers.
+ *
+ * Provides number of pixels changed and maximum single-channel
+ * difference in result.
+ *
  * Also fills in a "diff" buffer intended to visually show where the
  * images differ.
  */
-int
+void
 buffer_diff (unsigned char *buf_a,
 	     unsigned char *buf_b,
 	     unsigned char *buf_diff,
@@ -38,13 +52,18 @@ buffer_diff (unsigned char *buf_a,
 	     int	    height,
 	     int	    stride_a,
 	     int	    stride_b,
-	     int	    stride_diff);
+	     int	    stride_diff,
+	     buffer_diff_result_t *result);
 
-/* Returns number of pixels changed ignoring the alpha channel.
+/* Compares two image buffers ignoring the alpha channel.
+ *
+ * Provides number of pixels changed and maximum single-channel
+ * difference in result.
+ *
  * Also fills in a "diff" buffer intended to visually show where the
  * images differ.
  */
-int
+void
 buffer_diff_noalpha (unsigned char *buf_a,
 		     unsigned char *buf_b,
 		     unsigned char *buf_diff,
@@ -52,29 +71,41 @@ buffer_diff_noalpha (unsigned char *buf_
 		     int	    height,
 		     int	    stride_a,
 		     int	    stride_b,
-		     int	    stride_diff);
+		     int	    stride_diff,
+		     buffer_diff_result_t *result);
 
-/* Returns number of pixels changed, (or -1 on error).
+/* Compares two image buffers ignoring the alpha channel. A return
+ * value of CAIRO_STATUS_SUCCESS indicates that a comparison was made,
+ * (but the images may or may not differ). Failure modes include
+ * CAIRO_STATUS_FILE_NOT_FOUND, CAIRO_STATUS_READ_ERROR,
+ * CAIRO_STATUS_NO_MEMORY, and CAIRO_STATUS_SURFACE_TYPE_MISMATCH
+ * (which is used if the image sizes differ).
+ *
+ * Provides number of pixels changed and maximum single-channel
+ * difference in result.
+ *
  * Also saves a "diff" image intended to visually show where the
  * images differ.
  */
-int
+cairo_status_t
 image_diff (const char *filename_a,
 	    const char *filename_b,
 	    const char *filename_diff,
 	    int		ax,
 	    int		ay,
 	    int		bx,
-	    int		by);
+	    int		by,
+	    buffer_diff_result_t *result);
 
 /* Like image_diff, but blending the contents of b over white first. */
-int
+cairo_status_t
 image_diff_flattened (const char *filename_a,
 		      const char *filename_b,
 		      const char *filename_diff,
                       int         ax,
                       int         ay,
                       int         bx,
-                      int         by);
+                      int         by,
+		      buffer_diff_result_t *result);
 
 #endif
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 3eb5545..82d5d6a 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -117,6 +117,66 @@ const char *srcdir;
  * an nonrecoverable fashion. */
 jmp_buf jmpbuf;
 
+typedef cairo_surface_t *
+(*cairo_test_create_target_surface_t) (cairo_test_t	 *test,
+				       cairo_content_t	  content,
+				       void		**closure);
+
+typedef cairo_status_t
+(*cairo_test_write_to_png_t) (cairo_surface_t *surface, const char *filename);
+
+typedef void
+(*cairo_test_cleanup_target_t) (void *closure);
+
+typedef struct _cairo_test_target
+{
+    const char		       	       *name;
+    cairo_surface_type_t		expected_type;
+    cairo_content_t			content;
+    cairo_test_create_target_surface_t	create_target_surface;
+    cairo_test_write_to_png_t		write_to_png;
+    cairo_test_cleanup_target_t		cleanup_target;
+    void			       *closure;
+} cairo_test_target_t;
+
+/* What's the maximum single-channel difference we will tolerate and
+ * still allow a test to pass? */
+static unsigned int
+target_tolerance (cairo_test_target_t *target)
+{
+    switch (target->expected_type) {
+    /* I'm uncompromising about leaving the image backend as no
+     * tolerance. There's shouldn't ever be anything that is out of
+     * our control here. */
+    case CAIRO_SURFACE_TYPE_IMAGE:
+	return 0;
+
+    /* It seems we should be able to round-trip SVG content perfrectly
+     * through librsvg and cairo, but for some mysterious reason, some
+     * systems get an error of 1 for some pixels on some of the text
+     * tests. XXX: I'd still like to chase these down at some point. */
+    case CAIRO_SURFACE_TYPE_SVG:
+	return 1;
+
+    /* Everything else gets the no-tolerance policy. It would actually
+     * be nice to go through some of the backends and see * if it
+     * wouldn't make sense to increase this. For example, * could we
+     * use a small value here for the PS backend and * eliminate some
+     * of the ps-specific reference images? */
+    case CAIRO_SURFACE_TYPE_PDF:
+    case CAIRO_SURFACE_TYPE_PS:
+    case CAIRO_SURFACE_TYPE_XLIB:
+    case CAIRO_SURFACE_TYPE_XCB:
+    case CAIRO_SURFACE_TYPE_GLITZ:
+    case CAIRO_SURFACE_TYPE_QUARTZ:
+    case CAIRO_SURFACE_TYPE_WIN32:
+    case CAIRO_SURFACE_TYPE_BEOS:
+    case CAIRO_SURFACE_TYPE_DIRECTFB:
+    default:
+	return 0;
+    }
+}
+
 void
 cairo_test_init (const char *test_name)
 {
@@ -199,28 +259,6 @@ xunlink (const char *pathname)
     }
 }
 
-typedef cairo_surface_t *
-(*cairo_test_create_target_surface_t) (cairo_test_t	 *test,
-				       cairo_content_t	  content,
-				       void		**closure);
-
-typedef cairo_status_t
-(*cairo_test_write_to_png_t) (cairo_surface_t *surface, const char *filename);
-
-typedef void
-(*cairo_test_cleanup_target_t) (void *closure);
-
-typedef struct _cairo_test_target
-{
-    const char		       	       *name;
-    cairo_surface_type_t		expected_type;
-    cairo_content_t			content;
-    cairo_test_create_target_surface_t	create_target_surface;
-    cairo_test_write_to_png_t		write_to_png;
-    cairo_test_cleanup_target_t		cleanup_target;
-    void			       *closure;
-} cairo_test_target_t;
-
 static const char *
 _cairo_test_content_name (cairo_content_t content)
 {
@@ -1646,7 +1684,8 @@ cairo_test_for_target (cairo_test_t		 *t
 
     /* Skip image check for tests with no image (width,height == 0,0) */
     if (test->width != 0 && test->height != 0) {
-	int pixels_changed;
+	buffer_diff_result_t result;
+	cairo_status_t diff_status;
 	xunlink (png_name);
 	(target->write_to_png) (surface, png_name);
 
@@ -1660,17 +1699,27 @@ cairo_test_for_target (cairo_test_t		 *t
 	    goto UNWIND_CAIRO;
 	}
 
-	if (target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
-	    pixels_changed = image_diff_flattened (png_name, ref_name, diff_name, dev_offset, dev_offset, 0, 0);
-	else
-	    pixels_changed = image_diff (png_name, ref_name, diff_name, dev_offset, dev_offset, 0, 0);
-	if (pixels_changed) {
-	    if (pixels_changed > 0)
-		cairo_test_log ("Error: %d pixels differ from reference image %s\n",
-				pixels_changed, ref_name);
+	if (target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) {
+	    diff_status= image_diff_flattened (png_name, ref_name, diff_name,
+					       dev_offset, dev_offset, 0, 0, &result);
+	} else {
+	    diff_status = image_diff (png_name, ref_name, diff_name,
+				      dev_offset, dev_offset, 0, 0, &result);
+	}
+	if (diff_status) {
+	    cairo_test_log ("Error: Failed to compare images: %s\n",
+			    cairo_status_to_string (diff_status));
 	    ret = CAIRO_TEST_FAILURE;
 	    goto UNWIND_CAIRO;
 	}
+	if (result.pixels_changed) {
+	    cairo_test_log ("%d pixels differ (with maximum difference of %d) from reference image %s\n",
+			    result.pixels_changed, result.max_diff, ref_name);
+	    if (result.max_diff > target_tolerance (target)) {
+		ret = CAIRO_TEST_FAILURE;
+		goto UNWIND_CAIRO;
+	    }
+	}
     }
 
     ret = CAIRO_TEST_SUCCESS;
diff --git a/test/imagediff.c b/test/imagediff.c
index 9030877..188c1a9 100644
--- a/test/imagediff.c
+++ b/test/imagediff.c
@@ -32,7 +32,8 @@
 int
 main (int argc, char *argv[])
 {
-    int total_pixels_changed;
+    buffer_diff_result_t result;
+    cairo_status_t status;
 
     unsigned int ax, ay, bx, by;
 
@@ -53,10 +54,18 @@ main (int argc, char *argv[])
 	ax = ay = bx = by = 0;
     }
 
-    total_pixels_changed = image_diff (argv[1], argv[2], NULL, ax, ay, bx, by);
+    status = image_diff (argv[1], argv[2], NULL, ax, ay, bx, by, &result);
 
-    if (total_pixels_changed)
-	fprintf (stderr, "Total pixels changed: %d\n", total_pixels_changed);
+    if (status) {
+	fprintf (stderr, "Error comparing images: %s\n",
+		 cairo_status_to_string (status));
+	return 1;
+    }
+
+    if (result.pixels_changed)
+	fprintf (stderr, "Total pixels changed: %d with a maximum channel difference of %d.\n",
+		 result.pixels_changed,
+		 result.max_diff);
 
-    return (total_pixels_changed != 0);
+    return (result.pixels_changed != 0);
 }
diff --git a/test/xlib-surface.c b/test/xlib-surface.c
index e20b6eb..ccde14c 100644
--- a/test/xlib-surface.c
+++ b/test/xlib-surface.c
@@ -74,7 +74,7 @@ erase_pattern (cairo_surface_t *surface)
     cairo_destroy (cr);
 }
 
-static cairo_bool_t
+static cairo_test_status_t
 do_test (Display        *dpy,
 	 unsigned char  *reference_data,
 	 unsigned char  *test_data,
@@ -87,12 +87,12 @@ do_test (Display        *dpy,
     cairo_surface_t *surface;
     cairo_surface_t *test_surface;
     cairo_t *test_cr;
-    cairo_bool_t result;
+    buffer_diff_result_t result;
     Drawable drawable;
     int screen = DefaultScreen (dpy);
 
     if (use_pixmap && offscreen)
-	return 1;
+	return CAIRO_TEST_SUCCESS;
 
     if (use_pixmap) {
 	drawable = XCreatePixmap (dpy, DefaultRootWindow (dpy),
@@ -129,7 +129,7 @@ do_test (Display        *dpy,
 
 	if (cairo_xlib_surface_get_width (surface) != SIZE ||
 	    cairo_xlib_surface_get_height (surface) != SIZE)
-	    return 0;
+	    return CAIRO_TEST_FAILURE;
     }
 
     draw_pattern (surface);
@@ -160,23 +160,25 @@ do_test (Display        *dpy,
     if (offscreen) {
 	size_t offset = 4 * (SIZE * OFFSCREEN_OFFSET + OFFSCREEN_OFFSET);
 
-	result = !buffer_diff_noalpha (reference_data + offset,
-				       test_data + offset,
-				       diff_data + offset,
-				       SIZE - OFFSCREEN_OFFSET,
-				       SIZE - OFFSCREEN_OFFSET,
-				       4 * SIZE,
-				       4 * SIZE,
-				       4 * SIZE);
+	buffer_diff_noalpha (reference_data + offset,
+			     test_data + offset,
+			     diff_data + offset,
+			     SIZE - OFFSCREEN_OFFSET,
+			     SIZE - OFFSCREEN_OFFSET,
+			     4 * SIZE,
+			     4 * SIZE,
+			     4 * SIZE,
+			     &result);
     } else {
-	result = !buffer_diff_noalpha (reference_data,
-				       test_data,
-				       diff_data,
-				       SIZE,
-				       SIZE,
-				       4 * SIZE,
-				       4 * SIZE,
-				       4 * SIZE);
+	buffer_diff_noalpha (reference_data,
+			     test_data,
+			     diff_data,
+			     SIZE,
+			     SIZE,
+			     4 * SIZE,
+			     4 * SIZE,
+			     4 * SIZE,
+			     &result);
     }
 
     fprintf (log_file, "xlib-surface: %s, %s, %s%s: %s\n",
@@ -186,9 +188,12 @@ do_test (Display        *dpy,
 	     use_pixmap ?
 	     "           " :
 	     (offscreen ? ", offscreen" : ",  onscreen"),
-	     result ? "PASS" : "FAIL");
+	     result.pixels_changed ? "FAIL" : "PASS");
 
-    return result;
+    if (result.pixels_changed)
+	return CAIRO_TEST_FAILURE;
+    else
+	return CAIRO_TEST_SUCCESS;
 }
 
 static cairo_bool_t
@@ -218,7 +223,7 @@ main (void)
     cairo_bool_t use_pixmap;
     cairo_bool_t set_size;
     cairo_bool_t offscreen;
-    result = 0;
+    cairo_test_status_t status, result = CAIRO_TEST_SUCCESS;
 
     cairo_test_init ("xlib-surface");
     log_file = fopen ("xlib-surface.log", "w");
@@ -254,21 +259,25 @@ main (void)
 
     for (set_size = 0; set_size <= 1; set_size++)
 	for (use_pixmap = 0; use_pixmap <= 1; use_pixmap++)
-	    for (offscreen = 0; offscreen <= 1; offscreen++)
-		if (!do_test (dpy,
-			      reference_data, test_data, diff_data,
-			      1, use_pixmap, set_size, offscreen))
-		    result = 1;
+	    for (offscreen = 0; offscreen <= 1; offscreen++) {
+		status = do_test (dpy,
+				  reference_data, test_data, diff_data,
+				  1, use_pixmap, set_size, offscreen);
+		if (status)
+		    result = status;
+	    }
 
     _cairo_xlib_test_disable_render ();
 
     for (set_size = 0; set_size <= 1; set_size++)
 	for (use_pixmap = 0; use_pixmap <= 1; use_pixmap++)
-	    for (offscreen = 0; offscreen <= 1; offscreen++)
-		if (!do_test (dpy,
-			      reference_data, test_data, diff_data,
-			      0, use_pixmap, set_size, offscreen))
-		    result = 1;
+	    for (offscreen = 0; offscreen <= 1; offscreen++) {
+		status = do_test (dpy,
+				  reference_data, test_data, diff_data,
+				  0, use_pixmap, set_size, offscreen);
+		if (status)
+		    result = status;
+	    }
 
     free (reference_data);
     free (test_data);
diff-tree 11127fc21009cfa55312fcab8aed43470f7e4cc0 (from 37dcbe61cf8881aa4b3101d96235ad9abe7ef1bb)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Aug 30 23:41:48 2006 -0700

    test: Remove custom read/write-png code in favor of using cairo surfaces
    
    Also combine image_diff and image_diff_flattened into a single function
    
    This was manually taken from 95475218858792ccb20ac6ad28db22e233c783d7
    (It would have been a cherry-pick, but that doesn't yet handle file
    renames.)

diff --git a/test/Makefile.am b/test/Makefile.am
index 32c4329..9d4ea8b 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -389,10 +389,6 @@ buffer-diff.c		\
 buffer-diff.h		\
 cairo-test.c		\
 cairo-test.h		\
-read-png.c		\
-read-png.h		\
-write-png.c		\
-write-png.h		\
 xmalloc.c		\
 xmalloc.h
 
diff --git a/test/buffer-diff.c b/test/buffer-diff.c
index ade0cc8..b59b5e8 100644
--- a/test/buffer-diff.c
+++ b/test/buffer-diff.c
@@ -39,8 +39,6 @@
 #include "cairo-test.h"
 
 #include "buffer-diff.h"
-#include "read-png.h"
-#include "write-png.h"
 #include "xmalloc.h"
 
 static void
@@ -143,71 +141,128 @@ buffer_diff_noalpha (unsigned char *buf_
 			    width, height, stride_a, stride_b, stride_diff, 0x00ffffff);
 }
 
+static cairo_status_t
+stdio_write_func (void *closure, const unsigned char *data, unsigned int length)
+{
+    FILE *file = closure;
+
+    if (fwrite (data, 1, length, file) != length)
+	return CAIRO_STATUS_WRITE_ERROR;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+/* Flatten an ARGB surface by blending it over white. The resulting
+ * surface, (still in ARGB32 format, but with only alpha==1.0
+ * everywhere) is returned in the same surface pointer.
+ *
+ * The original surface will be destroyed.
+ *
+ * The (x,y) value specify an origin of interest for the original
+ * image. The flattened image will be generated only from the box
+ * extending from (x,y) to (width,height).
+ */
+static void
+flatten_surface (cairo_surface_t **surface, int x, int y)
+{
+    cairo_surface_t *flat;
+    cairo_t *cr;
+
+    flat = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+				       cairo_image_surface_get_width (*surface) - x,
+				       cairo_image_surface_get_height (*surface) - y);
+    cairo_surface_set_device_offset (flat, -x, -y);
+
+    cr = cairo_create (flat);
+    cairo_set_source_rgb (cr, 1, 1, 1);
+    cairo_paint (cr);
+    cairo_set_source_surface (cr, *surface, 0, 0);
+    cairo_paint (cr);
+    cairo_destroy (cr);
+
+    cairo_surface_destroy (*surface);
+    *surface = flat;
+}
+
 /* Image comparison code courtesy of Richard Worth <richard at theworths.org>
  * Returns number of pixels changed, (or -1 on error).
  * Also saves a "diff" image intended to visually show where the
  * images differ.
  */
-int
-image_diff (const char *filename_a,
-	    const char *filename_b,
-	    const char *filename_diff,
-	    int		ax,
-	    int		ay,
-	    int		bx,
-	    int		by)
+static int
+image_diff_core (const char *filename_a,
+		 const char *filename_b,
+		 const char *filename_diff,
+		 int		ax,
+		 int		ay,
+		 int		bx,
+		 int		by,
+		 cairo_bool_t	flatten)
 {
     int pixels_changed;
     unsigned int width_a, height_a, stride_a;
     unsigned int width_b, height_b, stride_b;
-    unsigned int stride_diff;
-    unsigned char *buf_a, *buf_b, *buf_diff;
-    read_png_status_t status;
+    cairo_surface_t *surface_a, *surface_b, *surface_diff;
 
-    status = read_png_argb32 (filename_a, &buf_a, &width_a, &height_a, &stride_a);
-    if (status)
+    surface_a = cairo_image_surface_create_from_png (filename_a);
+    if (cairo_surface_status (surface_a))
 	return -1;
 
-    status = read_png_argb32 (filename_b, &buf_b, &width_b, &height_b, &stride_b);
-    if (status) {
-	free (buf_a);
+    surface_b = cairo_image_surface_create_from_png (filename_b);
+    if (cairo_surface_status (surface_b)) {
+	cairo_surface_destroy (surface_a);
 	return -1;
     }
 
-    width_a -= ax;
-    height_a -= ay;
-    width_b -= bx;
-    height_b -= by;
+    width_a = cairo_image_surface_get_width (surface_a) - ax;
+    height_a = cairo_image_surface_get_height (surface_a) - ay;
+    width_b = cairo_image_surface_get_width (surface_b) - bx;
+    height_b = cairo_image_surface_get_height (surface_b) - by;
 
     if (width_a  != width_b  ||
 	height_a != height_b)
     {
-	cairo_test_log ("Error: Image size mismatch: (%dx%d@%d) vs. (%dx%d@%d)\n"
+	cairo_test_log ("Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n"
 			"       for %s vs. %s\n",
-			width_a, height_a, stride_a,
-			width_b, height_b, stride_b,
+			width_a, height_a,
+			width_b, height_b,
 			filename_a, filename_b);
-	free (buf_a);
-	free (buf_b);
+	cairo_surface_destroy (surface_a);
+	cairo_surface_destroy (surface_b);
 	return -1;
     }
 
-    stride_diff = 4 * width_a;
-    buf_diff = xcalloc (stride_diff * height_a, 1);
+    if (flatten) {
+	flatten_surface (&surface_a, ax, ay);
+	flatten_surface (&surface_b, bx, by);
+	ax = ay = bx = by = 0;
+    }
+
+    surface_diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+					       width_a, height_a);
 
-    pixels_changed = buffer_diff (buf_a + (ay * stride_a) + ax * 4,
-                                  buf_b + (by * stride_b) + by * 4,
-                                  buf_diff,
+    stride_a = cairo_image_surface_get_stride (surface_a);
+    stride_b = cairo_image_surface_get_stride (surface_b);
+
+    pixels_changed = buffer_diff (cairo_image_surface_get_data (surface_a)
+				  + (ay * stride_a) + ax * 4,
+                                  cairo_image_surface_get_data (surface_b)
+				  + (by * stride_b) + by * 4,
+                                  cairo_image_surface_get_data (surface_diff),
                                   width_a, height_a,
-				  stride_a, stride_b, stride_diff);
+				  stride_a, stride_b,
+				  cairo_image_surface_get_stride (surface_diff));
 
     if (pixels_changed) {
 	FILE *png_file;
+
 	if (filename_diff)
 	    png_file = fopen (filename_diff, "wb");
 	else
 	    png_file = stdout;
-	write_png_argb32 (buf_diff, png_file, width_a, height_a, stride_diff);
+
+	cairo_surface_write_to_png_stream (surface_diff, stdio_write_func, png_file);
+
 	if (png_file != stdout)
 	    fclose (png_file);
     } else {
@@ -215,25 +270,27 @@ image_diff (const char *filename_a,
 	    xunlink (filename_diff);
     }
 
-    free (buf_a);
-    free (buf_b);
-    free (buf_diff);
+    cairo_surface_destroy (surface_a);
+    cairo_surface_destroy (surface_b);
+    cairo_surface_destroy (surface_diff);
 
     return pixels_changed;
 }
 
-/* Like image_diff, but first "flatten" the contents of filename_b by
- * blending over white.
- *
- * Yes, this is an ugly copy-and-paste of another function. I'm doing
- * this for two reasons:
- *
- * 1) I want to rewrite all of the image_diff interfaces anyway
- *    (should use cairo_image_surface_create_from_png, should save
- *    loaded buffers for re-use).
- *
- * 2) There is a second reason no more.
- */
+int
+image_diff (const char *filename_a,
+	    const char *filename_b,
+	    const char *filename_diff,
+	    int		ax,
+	    int		ay,
+	    int		bx,
+	    int		by)
+{
+    return image_diff_core (filename_a, filename_b, filename_diff,
+			    ax, ay, bx, by,
+			    FALSE);
+}
+
 int
 image_diff_flattened (const char *filename_a,
 		      const char *filename_b,
@@ -243,106 +300,7 @@ image_diff_flattened (const char *filena
 		      int	  bx,
 		      int	  by)
 {
-    int pixels_changed;
-    unsigned int width_a, height_a, stride_a;
-    unsigned int width_b, height_b, stride_b;
-    unsigned char *buf_a, *buf_b, *buf_diff;
-    unsigned char *a_flat, *b_flat;
-    cairo_surface_t *buf_a_surface, *a_flat_surface;
-    cairo_surface_t *buf_b_surface, *b_flat_surface;
-    cairo_t *cr;
-    read_png_status_t status;
-
-    status = read_png_argb32 (filename_a, &buf_a, &width_a, &height_a, &stride_a);
-    if (status)
-	return -1;
-
-    status = read_png_argb32 (filename_b, &buf_b, &width_b, &height_b, &stride_b);
-    if (status) {
-	free (buf_a);
-	return -1;
-    }
-
-    width_a -= ax;
-    height_a -= ay;
-    width_b -= bx;
-    height_b -= by;
-
-    if (width_a  != width_b  ||
-	height_a != height_b)
-    {
-	cairo_test_log ("Error: Image size mismatch: (%dx%d@%d) vs. (%dx%d@%d)\n"
-			"       for %s vs. %s\n",
-			width_a, height_a, stride_a,
-			width_b, height_b, stride_b,
-			filename_a, filename_b);
-	free (buf_a);
-	free (buf_b);
-	return -1;
-    }
-
-    buf_a_surface =  cairo_image_surface_create_for_data (buf_a,
-							  CAIRO_FORMAT_ARGB32,
-							  width_a + ax, height_a + ay,
-							  stride_a);
-    buf_b_surface =  cairo_image_surface_create_for_data (buf_b,
-							  CAIRO_FORMAT_ARGB32,
-							  width_b + bx, height_b + by,
-							  stride_b);
-
-    buf_diff = xcalloc (stride_a * height_a, 1);
-
-    a_flat = xcalloc (stride_a * height_a, 1);
-    b_flat = xcalloc (stride_b * height_b, 1);
-
-    a_flat_surface = cairo_image_surface_create_for_data (a_flat,
-							  CAIRO_FORMAT_ARGB32,
-							  width_a, height_a,
-							  stride_a);
-    cairo_surface_set_device_offset (a_flat_surface, -ax, -ay);
-    b_flat_surface = cairo_image_surface_create_for_data (b_flat,
-							  CAIRO_FORMAT_ARGB32,
-							  width_b, height_b,
-							  stride_b);
-    cairo_surface_set_device_offset (b_flat_surface, -bx, -by);
-
-    cr = cairo_create (a_flat_surface);
-    cairo_set_source_rgb (cr, 1, 1, 1);
-    cairo_paint (cr);
-    cairo_set_source_surface (cr, buf_a_surface, 0, 0);
-    cairo_paint (cr);
-    cairo_destroy (cr);
-    cairo_surface_destroy (a_flat_surface);
-    cairo_surface_destroy (buf_a_surface);
-
-    cr = cairo_create (b_flat_surface);
-    cairo_set_source_rgb (cr, 1, 1, 1);
-    cairo_paint (cr);
-    cairo_set_source_surface (cr, buf_b_surface, 0, 0);
-    cairo_paint (cr);
-    cairo_destroy (cr);
-    cairo_surface_destroy (b_flat_surface);
-    cairo_surface_destroy (buf_b_surface);
-
-    pixels_changed = buffer_diff (a_flat,
-                                  b_flat,
-                                  buf_diff,
-				  width_a, height_a,
-                                  stride_a, stride_b, stride_a);
-
-    if (pixels_changed) {
-	FILE *png_file = fopen (filename_diff, "wb");
-	write_png_argb32 (buf_diff, png_file, width_a, height_a, stride_a);
-	fclose (png_file);
-    } else {
-	xunlink (filename_diff);
-    }
-
-    free (buf_a);
-    free (buf_b);
-    free (a_flat);
-    free (b_flat);
-    free (buf_diff);
-
-    return pixels_changed;
+    return image_diff_core (filename_a, filename_b, filename_diff,
+			    ax, ay, bx, by,
+			    TRUE);
 }
diff --git a/test/cairo-test.c b/test/cairo-test.c
index bf52f8a..3eb5545 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2004 Red Hat, Inc.
+ * Copyright © 2004,2006 Red Hat, Inc.
  *
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
@@ -48,8 +48,6 @@
 #include "cairo-test.h"
 
 #include "buffer-diff.h"
-#include "read-png.h"
-#include "write-png.h"
 #include "xmalloc.h"
 
 /* This is copied from cairoint.h. That makes it painful to keep in
diff --git a/test/cairo-test.h b/test/cairo-test.h
index 4f430ac..83b43d0 100644
--- a/test/cairo-test.h
+++ b/test/cairo-test.h
@@ -143,6 +143,13 @@ cairo_test_paint_checkered (cairo_t *cr)
 void
 xasprintf (char **strp, const char *fmt, ...) CAIRO_PRINTF_FORMAT(2, 3);
 
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
+
 CAIRO_END_DECLS
 
 #endif
diff --git a/test/imagediff.c b/test/imagediff.c
index d030e76..9030877 100644
--- a/test/imagediff.c
+++ b/test/imagediff.c
@@ -27,8 +27,6 @@
 #include <stdlib.h>
 
 #include "buffer-diff.h"
-#include "read-png.h"
-#include "write-png.h"
 #include "xmalloc.h"
 
 int
diff --git a/test/read-png.c b/test/read-png.c
deleted file mode 100644
index bb02e50..0000000
--- a/test/read-png.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright © 2003 USC, Information Sciences Institute
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of the
- * University of Southern California not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. The University of Southern
- * California makes no representations about the suitability of this
- * software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
- * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Carl D. Worth <cworth at isi.edu>
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if   HAVE_STDINT_H
-# include <stdint.h>
-#elif HAVE_INTTYPES_H
-# include <inttypes.h>
-#elif HAVE_SYS_INT_TYPES_H
-# include <sys/int_types.h>
-#elif defined(_MSC_VER)
-  typedef __int8 int8_t;
-  typedef unsigned __int8 uint8_t;
-  typedef __int16 int16_t;
-  typedef unsigned __int16 uint16_t;
-  typedef __int32 int32_t;
-  typedef unsigned __int32 uint32_t;
-  typedef __int64 int64_t;
-  typedef unsigned __int64 uint64_t;
-# ifndef HAVE_UINT64_T
-#  define HAVE_UINT64_T 1
-# endif
-#else
-#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <png.h>
-
-#include "cairo-test.h"
-#include "read-png.h"
-#include "xmalloc.h"
-
-static void
-premultiply_data (png_structp   png,
-                  png_row_infop row_info,
-                  png_bytep     data)
-{
-    size_t i;
-
-    for (i = 0; i < row_info->rowbytes; i += 4) {
-	uint8_t *base = &data[i];
-	uint8_t  blue = base[0];
-	uint8_t  green = base[1];
-	uint8_t  red = base[2];
-	uint8_t  alpha = base[3];
-	uint32_t p;
-
-	red = ((unsigned) red * (unsigned) alpha + 127) / 255;
-	green = ((unsigned) green * (unsigned) alpha + 127) / 255;
-	blue = ((unsigned) blue * (unsigned) alpha + 127) / 255;
-	p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
-	memcpy (base, &p, sizeof (uint32_t));
-    }
-}
-
-read_png_status_t
-read_png_argb32 (const char         *filename,
-		 unsigned char      **data,
-		 unsigned int       *width,
-		 unsigned int       *height,
-		 unsigned int	    *stride)
-{
-    size_t i;
-    FILE *file;
-#define PNG_SIG_SIZE 8
-    unsigned char png_sig[PNG_SIG_SIZE];
-    int sig_bytes;
-    png_struct *png;
-    png_info *info;
-    png_uint_32 png_width, png_height;
-    int depth, color_type, interlace;
-    unsigned int pixel_size;
-    png_byte **row_pointers;
-
-    file = fopen (filename, "rb");
-    if (file == NULL) {
-	cairo_test_log ("Error: File not found: %s\n", filename);
-	return READ_PNG_FILE_NOT_FOUND;
-    }
-
-    sig_bytes = fread (png_sig, 1, PNG_SIG_SIZE, file);
-    if (png_check_sig (png_sig, sig_bytes) == 0) {
-        fclose (file);
-	cairo_test_log ("Error: File is not a PNG image: %s\n", filename);
-	return READ_PNG_FILE_NOT_PNG;
-    }
-
-    /* XXX: Perhaps we'll want some other error handlers? */
-    png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
-                                  NULL,
-                                  NULL,
-                                  NULL);
-    if (png == NULL) {
-        fclose (file);
-	cairo_test_log ("Error: Out of memory while reading %s\n", filename);
-	return READ_PNG_NO_MEMORY;
-    }
-
-    info = png_create_info_struct (png);
-    if (info == NULL) {
-        fclose (file);
-        png_destroy_read_struct (&png, NULL, NULL);
-	cairo_test_log ("Error: Out of memory while reading %s\n", filename);
-	return READ_PNG_NO_MEMORY;
-    }
-
-    png_init_io (png, file);
-    png_set_sig_bytes (png, sig_bytes);
-
-    png_read_info (png, info);
-
-    png_get_IHDR (png, info,
-                  &png_width, &png_height, &depth,
-                  &color_type, &interlace, NULL, NULL);
-    *width = png_width;
-    *height = png_height;
-    *stride = 4 * png_width;
-
-    /* convert palette/gray image to rgb */
-    if (color_type == PNG_COLOR_TYPE_PALETTE)
-        png_set_palette_to_rgb (png);
-
-    /* expand gray bit depth if needed */
-    if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8)
-        png_set_gray_1_2_4_to_8 (png);
-    /* transform transparency to alpha */
-    if (png_get_valid(png, info, PNG_INFO_tRNS))
-        png_set_tRNS_to_alpha (png);
-
-    if (depth == 16)
-        png_set_strip_16 (png);
-
-    if (depth < 8)
-        png_set_packing (png);
-
-    /* convert grayscale to RGB */
-    if (color_type == PNG_COLOR_TYPE_GRAY
-        || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-        png_set_gray_to_rgb (png);
-
-    if (interlace != PNG_INTERLACE_NONE)
-        png_set_interlace_handling (png);
-
-    png_set_bgr (png);
-    png_set_filler (png, 0xff, PNG_FILLER_AFTER);
-
-    png_set_read_user_transform_fn (png, premultiply_data);
-
-    png_read_update_info (png, info);
-
-    pixel_size = 4;
-    *data = xmalloc (png_width * png_height * pixel_size);
-
-    row_pointers = malloc (png_height * sizeof(char *));
-    for (i=0; i < png_height; i++)
-        row_pointers[i] = (png_byte *) (*data + i * png_width * pixel_size);
-
-    png_read_image (png, row_pointers);
-    png_read_end (png, info);
-
-    free (row_pointers);
-    fclose (file);
-
-    png_destroy_read_struct (&png, &info, NULL);
-
-    return READ_PNG_SUCCESS;
-}
diff --git a/test/read-png.h b/test/read-png.h
deleted file mode 100644
index 9c9ba43..0000000
--- a/test/read-png.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright © 2003 USC, Information Sciences Institute
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of the
- * University of Southern California not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. The University of Southern
- * California makes no representations about the suitability of this
- * software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
- * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Carl D. Worth <cworth at isi.edu>
- */
-
-#ifndef READ_PNG_H
-#define READ_PNG_H
-
-typedef enum {
-    READ_PNG_SUCCESS = 0,
-    READ_PNG_FILE_NOT_FOUND,
-    READ_PNG_FILE_NOT_PNG,
-    READ_PNG_NO_MEMORY
-} read_png_status_t;
-
-read_png_status_t
-read_png_argb32 (const char         *filename,
-		 unsigned char      **data,
-		 unsigned int       *width,
-		 unsigned int       *height,
-		 unsigned int	    *stride);
-
-#endif
diff --git a/test/write-png.c b/test/write-png.c
deleted file mode 100644
index c906df5..0000000
--- a/test/write-png.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright © 2003 USC, Information Sciences Institute
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of the
- * University of Southern California not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. The University of Southern
- * California makes no representations about the suitability of this
- * software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
- * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Carl D. Worth <cworth at cworth.org>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <png.h>
-
-#include "write-png.h"
-
-static void
-unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
-{
-    size_t i;
-
-    for (i = 0; i < row_info->rowbytes; i += 4) {
-        unsigned char *b = &data[i];
-        unsigned int pixel;
-        unsigned char alpha;
-
-	memcpy (&pixel, b, sizeof (unsigned int));
-	alpha = (pixel & 0xff000000) >> 24;
-        if (alpha == 0) {
-	    b[0] = b[1] = b[2] = b[3] = 0;
-	} else {
-            b[0] = (((pixel & 0x0000ff) >>  0) * 255 + alpha / 2) / alpha;
-            b[1] = (((pixel & 0x00ff00) >>  8) * 255 + alpha / 2) / alpha;
-            b[2] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
-	    b[3] = alpha;
-	}
-    }
-}
-
-void
-write_png_argb32 (unsigned char *buffer, FILE *file,
-		  int width, int height, int stride)
-{
-    int i;
-    png_struct *png;
-    png_info *info;
-    png_byte **rows;
-    png_color_16 white;
-
-    rows = malloc (height * sizeof(png_byte*));
-
-    for (i = 0; i < height; i++) {
-	rows[i] = buffer + i * stride;
-    }
-
-    png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-    info = png_create_info_struct (png);
-
-    png_init_io (png, file);
-    png_set_IHDR (png, info,
-		  width, height, 8,
-		  PNG_COLOR_TYPE_RGB_ALPHA,
-		  PNG_INTERLACE_NONE,
-		  PNG_COMPRESSION_TYPE_DEFAULT,
-		  PNG_FILTER_TYPE_DEFAULT);
-
-    white.red = 0xff;
-    white.blue = 0xff;
-    white.green = 0xff;
-    png_set_bKGD (png, info, &white);
-
-    png_set_write_user_transform_fn (png, unpremultiply_data);
-    png_set_bgr (png);
-
-    png_write_info (png, info);
-    png_write_image (png, rows);
-    png_write_end (png, info);
-
-    png_destroy_write_struct (&png, &info);
-
-    free (rows);
-}
diff --git a/test/write-png.h b/test/write-png.h
deleted file mode 100644
index 8074666..0000000
--- a/test/write-png.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright © 2003 USC, Information Sciences Institute
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of the
- * University of Southern California not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. The University of Southern
- * California makes no representations about the suitability of this
- * software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- *
- * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
- * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Carl D. Worth <cworth at isi.edu>
- */
-
-#ifndef WRITE_PNG_H
-#define WRITE_PNG_H
-
-void
-write_png_argb32 (unsigned char *buffer, FILE * file,
-		  int width, int height, int stride);
-
-#endif


More information about the cairo-commit mailing list