summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUGS11
-rw-r--r--ChangeLog27
-rw-r--r--Makefile.am2
-rw-r--r--cairo.pc.in2
-rw-r--r--configure.in41
-rw-r--r--src/Makefile.am4
-rw-r--r--test/.cvsignore10
-rw-r--r--test/Makefile.am29
-rw-r--r--test/README55
-rw-r--r--test/cairo-test.c191
-rw-r--r--test/cairo-test.h50
-rw-r--r--test/cairo_test.c191
-rw-r--r--test/cairo_test.h50
-rw-r--r--test/line-width-ref.pngbin0 -> 167 bytes
-rw-r--r--test/line-width.c63
-rw-r--r--test/line_width-ref.pngbin0 -> 167 bytes
-rw-r--r--test/line_width.c63
-rw-r--r--test/move-to-show-surface-ref.pngbin0 -> 100 bytes
-rw-r--r--test/move-to-show-surface.c69
-rw-r--r--test/move_to_show_surface-ref.pngbin0 -> 100 bytes
-rw-r--r--test/move_to_show_surface.c69
-rw-r--r--test/read-png.c166
-rw-r--r--test/read-png.h45
-rw-r--r--test/read_png.c166
-rw-r--r--test/read_png.h45
-rw-r--r--test/write-png.c102
-rw-r--r--test/write-png.h35
-rw-r--r--test/write_png.c102
-rw-r--r--test/write_png.h35
-rw-r--r--test/xmalloc.c58
-rw-r--r--test/xmalloc.h35
31 files changed, 1698 insertions, 18 deletions
diff --git a/BUGS b/BUGS
index 8d24b3d7..31690e6c 100644
--- a/BUGS
+++ b/BUGS
@@ -81,3 +81,14 @@ libpixman, (nor in glitz?).
--
font-size="0" in an SVG file does very bad things.
+
+--
+
+move_to_show_surface (see cairo/test):
+
+ * 2004-10-25 Carl Worth <cworth@cworth.org>
+ *
+ * It looks like cairo_show_surface has no effect if it follows a
+ * call to cairo_move_to to any coordinate other than 0,0. A little
+ * bit of poking around suggests this isn't a regression, (at least
+ * not since the last pixman snapshot).
diff --git a/ChangeLog b/ChangeLog
index a22b8f3f..0e15f010 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2004-10-26 Carl Worth <cworth@cworth.org>
+
+ * test/.cvsignore:
+ * test/Makefile.am:
+ * test/README:
+ * test/cairo_test.c:
+ * test/cairo_test.h:
+ * test/line_width-ref.png:
+ * test/line_width.c:
+ * test/move_to_show_surface-ref.png:
+ * test/move_to_show_surface.c:
+ * test/read_png.c:
+ * test/read_png.h:
+ * test/write_png.c:
+ * test/write_png.h:
+ * test/xmalloc.c:
+ * test/xmalloc.h: Add initial regression test suite.
+
+ * configure.in: Don't AC_SUBST a dozen different FOO_CFLAGS and
+ FOO_LIBS. Instead, incrementally build up just CAIRO_CFLAGS and
+ CAIRO_LIBS.
+
+ * cairo.pc.in (Libs): Don't list flags that should get picked up
+ via dependency information through Requires.
+
+ * BUGS (font-size): Add description of move_to_show_surface.
+
2004-10-21 Carl Worth <cworth@cworth.org>
* src/cairo_png_surface.c:
diff --git a/Makefile.am b/Makefile.am
index aed2d88a..624ec133 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = src
+SUBDIRS = src test
EXTRA_DIST = \
COPYING \
diff --git a/cairo.pc.in b/cairo.pc.in
index b2859b24..339d576b 100644
--- a/cairo.pc.in
+++ b/cairo.pc.in
@@ -8,6 +8,6 @@ Description: Multi-platform 2D graphics library
Version: @VERSION@
Requires: fontconfig libpixman @XRENDER_REQUIRES@ @PNG_REQUIRES@ @GLITZ_REQUIRES@
-Libs: -L${libdir} -lcairo -lm @XRENDER_LIBS@ @PS_LIBS@ @FREETYPE_LIBS@
+Libs: -L${libdir} -lcairo -lm
Cflags: -I${includedir} @FREETYPE_CFLAGS@
diff --git a/configure.in b/configure.in
index 3415b12f..ebe259a1 100644
--- a/configure.in
+++ b/configure.in
@@ -60,9 +60,10 @@ else
AM_CONDITIONAL(CAIRO_HAS_XLIB_SURFACE, true)
fi
+CAIRO_CFLAGS="$CAIRO_CFLAGS $XRENDER_CFLAGS"
+CAIRO_LIBS="$CAIRO_LIBS $XRENDER_LIBS"
+
AC_SUBST(XLIB_SURFACE_FEATURE)
-AC_SUBST(XRENDER_CFLAGS)
-AC_SUBST(XRENDER_LIBS)
AC_SUBST(XRENDER_REQUIRES)
dnl ===========================================================================
@@ -84,9 +85,10 @@ else
AM_CONDITIONAL(CAIRO_HAS_XCB_SURFACE, true)
fi
+CAIRO_CFLAGS="$CAIRO_CFLAGS $XCB_CFLAGS"
+CAIRO_LIBS="$CAIRO_LIBS $XCB_LIBS"
+
AC_SUBST(XCB_SURFACE_FEATURE)
-AC_SUBST(XCB_CFLAGS)
-AC_SUBST(XCB_LIBS)
dnl ===========================================================================
@@ -103,6 +105,8 @@ else
AM_CONDITIONAL(CAIRO_HAS_PS_SURFACE, true)
fi
+CAIRO_LIBS="$CAIRO_LIBS $PS_LIBS"
+
AC_SUBST(PS_SURFACE_FEATURE)
AC_SUBST(PS_LIBS)
@@ -129,9 +133,10 @@ else
AM_CONDITIONAL(CAIRO_HAS_PNG_SURFACE, true)
fi
+CAIRO_CFLAGS="$CAIRO_CFLAGS $PNG_CFLAGS"
+CAIRO_LIBS="$CAIRO_LIBS $PNG_LIBS"
+
AC_SUBST(PNG_SURFACE_FEATURE)
-AC_SUBST(PNG_CFLAGS)
-AC_SUBST(PNG_LIBS)
AC_SUBST(PNG_REQUIRES)
dnl ===========================================================================
@@ -154,8 +159,9 @@ else
AM_CONDITIONAL(CAIRO_HAS_GLITZ_SURFACE, true)
fi
-AC_SUBST(GLITZ_LIBS)
-AC_SUBST(GLITZ_CFLAGS)
+CAIRO_CFLAGS="$CAIRO_CFLAGS $GLITZ_CFLAGS"
+CAIRO_LIBS="$CAIRO_LIBS $GLITZ_LIBS"
+
AC_SUBST(GLITZ_SURFACE_FEATURE)
AC_SUBST(GLITZ_REQUIRES)
@@ -176,7 +182,12 @@ AC_SUBST(SANITY_CHECKING_FEATURE)
dnl ===========================================================================
PKG_CHECK_MODULES(FONTCONFIG, fontconfig)
-PKG_CHECK_MODULES(CAIRO, libpixman >= 0.1.1)
+CAIRO_CFLAGS="$CAIRO_CFLAGS $FONTCONFIG_CFLAGS"
+CAIRO_LIBS="$CAIRO_LIBS $FONTCONFIG_LIBS"
+
+PKG_CHECK_MODULES(PIXMAN, libpixman >= 0.1.1)
+CAIRO_CFLAGS="$CAIRO_CFLAGS $PIXMAN_CFLAGS"
+CAIRO_LIBS="$CAIRO_LIBS $PIXMAN_LIBS"
# Test for freetype2 separate from pkg-config since at least up to
# 2003-06-07, there was no freetype2.pc in the release.
@@ -218,13 +229,9 @@ FREETYPE_LIBS=`$FREETYPE_CONFIG --libs`
AC_SUBST(FREETYPE_CFLAGS)
AC_SUBST(FREETYPE_LIBS)
-
CAIRO_CFLAGS="$CAIRO_CFLAGS $FREETYPE_CFLAGS"
CAIRO_LIBS="$CAIRO_LIBS $FREETYPE_LIBS"
-AC_SUBST(CAIRO_CFLAGS)
-AC_SUBST(CAIRO_LIBS)
-
dnl ===========================================================================
dnl Checks for precise integer types
@@ -239,7 +246,12 @@ if test "x$GCC" = "xyes"; then
-Wmissing-prototypes -Wmissing-declarations \
-Wnested-externs -fno-strict-aliasing"
fi
-AC_SUBST(WARN_CFLAGS)
+
+CAIRO_CFLAGS="$CAIRO_CFLAGS $WARN_CFLAGS"
+CAIRO_LIBS = "$CAIRO_LIBS -lm"
+
+AC_SUBST(CAIRO_CFLAGS)
+AC_SUBST(CAIRO_LIBS)
dnl ===========================================================================
@@ -248,6 +260,7 @@ cairo.pc
Makefile
src/Makefile
src/cairo-features.h
+test/Makefile
])
dnl ===========================================================================
diff --git a/src/Makefile.am b/src/Makefile.am
index 8f5f639a..8343cb1c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -62,6 +62,6 @@ libcairo_la_SOURCES = \
libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined
-INCLUDES = -I$(srcdir) $(WARN_CFLAGS) $(CAIRO_CFLAGS) $(FONTCONFIG_CFLAGS) $(XRENDER_CFLAGS) $(XCB_CFLAGS) $(PNG_CFLAGS) $(GLITZ_CFLAGS)
+INCLUDES = -I$(srcdir) $(CAIRO_CFLAGS)
-libcairo_la_LIBADD = $(CAIRO_LIBS) $(FONTCONFIG_LIBS) $(XRENDER_LIBS) $(XCB_LIBS) $(PS_LIBS) $(PNG_LIBS) $(GLITZ_LIBS) -lm
+libcairo_la_LIBADD = $(CAIRO_LIBS) -lm
diff --git a/test/.cvsignore b/test/.cvsignore
new file mode 100644
index 00000000..1937368c
--- /dev/null
+++ b/test/.cvsignore
@@ -0,0 +1,10 @@
+.deps
+.libs
+Makefile
+Makefile.in
+line_width
+move_to_show_surface
+*-out.png
+*-diff.png
+
+
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 00000000..132d4037
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,29 @@
+TESTS = \
+line_width \
+move_to_show_surface
+
+# Known bugs (not regressions). We do need to fix these before the
+# next release, but they are expected to fail for now, so they don't
+# need to hold up any new code commit.
+#
+# When new bugs are found in committed code they can be listed
+# here. New failures due to local, uncommitted code changes are
+# regression bugs that should not be listed here. Instead they should
+# be fixed before the code is committed.
+XFAIL_TESTS = \
+move_to_show_surface
+
+check_PROGRAMS = $(TESTS)
+
+INCLUDES = -I$(srcdir) $(CAIRO_CFLAGS) -I$(srcdir)/../src
+
+AM_LDFLAGS = $(CAIRO_LIBS) -L../src -lcairo
+
+cairo_test_lib = cairo_test.c read_png.c write_png.c xmalloc.c
+
+line_width_SOURCES = line_width.c $(cairo_test_lib)
+move_to_show_surface_SOURCES = move_to_show_surface.c $(cairo_test_lib)
+
+
+
+
diff --git a/test/README b/test/README
new file mode 100644
index 00000000..3e7acf5c
--- /dev/null
+++ b/test/README
@@ -0,0 +1,55 @@
+Regression test suite for cairo.
+
+Using this test should be as simple as running:
+
+ make check
+
+assuming that the cairo distribution in the directory above has been
+configured and built. The test suite here goes through some effort to
+run against the locally compiled library rather than any installed
+version.
+
+The test suite needs to be run before any code is committed and before
+any release. Here are the rules governing the use of the suite:
+
+Before committing
+-----------------
+
+All tests should return a result of PASS or XFAIL. The XFAIL results
+indicate known bugs. The final message should be one of the following:
+
+ All XX tests behaved as expected (YY expected failures)
+ All XX tests passed
+
+If any tests have a status of FAIL, then the new code has caused a
+regression error which should be fixed before the code is committed.
+
+When a new bug is found
+-----------------------
+A new test case should be added by imitating the style of an existing
+test. This means adding the following files:
+
+ new_bug.c
+ new_bug-ref.png
+
+Where new_bug.c is a minimal program to demonstrate the bug, following
+the style of existing tests. The new_bug-ref.png image should contain
+the desired result of new_bug.c if the bug were fixed.
+
+Makefile.am should be edited, adding new_bug.c to both the TESTS and
+XFAIL_TESTS lists.
+
+When a bug is fixed
+-------------------
+The fix shold be verified by running the test suite which should
+result in an "unexpected pass" for the test of interest. Rejoice as
+appropriate, then remove the relevant file name from the XFAIL_TESTS
+variable in Makefile.am.
+
+Before releasing
+----------------
+All tests should return a result of PASS meaning all known bugs are
+fixed, resulting in the happy message:
+
+ All XX tests passed
+
diff --git a/test/cairo-test.c b/test/cairo-test.c
new file mode 100644
index 00000000..0c2d09f3
--- /dev/null
+++ b/test/cairo-test.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+#include "cairo_test.h"
+
+#include "read_png.h"
+#include "write_png.h"
+#include "xmalloc.h"
+
+#define CAIRO_TEST_PNG_SUFFIX "-out.png"
+#define CAIRO_TEST_REF_SUFFIX "-ref.png"
+#define CAIRO_TEST_DIFF_SUFFIX "-diff.png"
+
+static char *
+xstrcat_alloc (const char *s1, const char *s2)
+{
+ char *ret;
+
+ ret = xmalloc (strlen (s1) + strlen (s2) + 1);
+ strcpy (ret, s1);
+ strcat (ret, s2);
+
+ return ret;
+}
+
+/* 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)
+{
+ 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) */
+ }
+ }
+
+ return total_pixels_changed;
+}
+
+cairo_test_status_t
+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;
+ int pixels_changed;
+ int ref_width, ref_height, ref_stride;
+ read_png_status_t png_status;
+ cairo_test_status_t ret;
+
+ /* The cairo part of the test is the easiest part */
+ cr = cairo_create ();
+
+ stride = 4 * test->width;
+
+ png_buf = xcalloc (stride * test->height, 1);
+ diff_buf = xcalloc (stride * test->height, 1);
+
+ cairo_set_target_image (cr, png_buf, CAIRO_FORMAT_ARGB32,
+ test->width, test->height, stride);
+
+ (draw) (cr, test->width, test->height);
+
+ cairo_destroy (cr);
+
+ /* Then we've got a bunch of string manipulation and file I/O for the check */
+
+ png_name = xstrcat_alloc (test->name, CAIRO_TEST_PNG_SUFFIX);
+ ref_name = xstrcat_alloc (test->name, CAIRO_TEST_REF_SUFFIX);
+ diff_name = xstrcat_alloc (test->name, CAIRO_TEST_DIFF_SUFFIX);
+
+ write_png_argb32 (png_buf, png_name, test->width, test->height, stride);
+
+ ref_buf = NULL;
+ png_status = (read_png_argb32 (ref_name, &ref_buf, &ref_width, &ref_height, &ref_stride));
+ if (png_status) {
+ switch (png_status)
+ {
+ case READ_PNG_FILE_NOT_FOUND:
+ fprintf (stderr, " 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);
+ break;
+ default:
+ fprintf (stderr, " Error: Failed to read %s\n", ref_name);
+ }
+
+ ret = CAIRO_TEST_FAILURE;
+ goto BAIL;
+ }
+
+ 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",
+ test->width, test->height,
+ ref_width, ref_height,
+ png_name, ref_name);
+ ret = CAIRO_TEST_FAILURE;
+ goto BAIL;
+ }
+
+ pixels_changed = image_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",
+ pixels_changed, ref_name);
+ write_png_argb32 (diff_buf, diff_name, test->width, test->height, stride);
+ 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;
+ }
+ }
+
+ ret = CAIRO_TEST_SUCCESS;
+
+BAIL:
+ free (png_buf);
+ free (ref_buf);
+ free (diff_buf);
+ free (png_name);
+ free (ref_name);
+ free (diff_name);
+
+ return ret;
+}
diff --git a/test/cairo-test.h b/test/cairo-test.h
new file mode 100644
index 00000000..7062f029
--- /dev/null
+++ b/test/cairo-test.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+#ifndef _CAIRO_TEST_H_
+#define _CAIRO_TEST_H_
+
+#include <cairo.h>
+
+typedef enum cairo_test_status {
+ CAIRO_TEST_SUCCESS = 0,
+ CAIRO_TEST_FAILURE
+} cairo_test_status_t;
+
+typedef struct cairo_test {
+ char *name;
+ char *description;
+ int width;
+ int height;
+} cairo_test_t;
+
+typedef void (*cairo_test_draw_function_t) (cairo_t *cr, int width, int height);
+
+/* cairo_test.c */
+cairo_test_status_t
+cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw);
+
+#endif
+
diff --git a/test/cairo_test.c b/test/cairo_test.c
new file mode 100644
index 00000000..0c2d09f3
--- /dev/null
+++ b/test/cairo_test.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+#include "cairo_test.h"
+
+#include "read_png.h"
+#include "write_png.h"
+#include "xmalloc.h"
+
+#define CAIRO_TEST_PNG_SUFFIX "-out.png"
+#define CAIRO_TEST_REF_SUFFIX "-ref.png"
+#define CAIRO_TEST_DIFF_SUFFIX "-diff.png"
+
+static char *
+xstrcat_alloc (const char *s1, const char *s2)
+{
+ char *ret;
+
+ ret = xmalloc (strlen (s1) + strlen (s2) + 1);
+ strcpy (ret, s1);
+ strcat (ret, s2);
+
+ return ret;
+}
+
+/* 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)
+{
+ 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) */
+ }
+ }
+
+ return total_pixels_changed;
+}
+
+cairo_test_status_t
+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;
+ int pixels_changed;
+ int ref_width, ref_height, ref_stride;
+ read_png_status_t png_status;
+ cairo_test_status_t ret;
+
+ /* The cairo part of the test is the easiest part */
+ cr = cairo_create ();
+
+ stride = 4 * test->width;
+
+ png_buf = xcalloc (stride * test->height, 1);
+ diff_buf = xcalloc (stride * test->height, 1);
+
+ cairo_set_target_image (cr, png_buf, CAIRO_FORMAT_ARGB32,
+ test->width, test->height, stride);
+
+ (draw) (cr, test->width, test->height);
+
+ cairo_destroy (cr);
+
+ /* Then we've got a bunch of string manipulation and file I/O for the check */
+
+ png_name = xstrcat_alloc (test->name, CAIRO_TEST_PNG_SUFFIX);
+ ref_name = xstrcat_alloc (test->name, CAIRO_TEST_REF_SUFFIX);
+ diff_name = xstrcat_alloc (test->name, CAIRO_TEST_DIFF_SUFFIX);
+
+ write_png_argb32 (png_buf, png_name, test->width, test->height, stride);
+
+ ref_buf = NULL;
+ png_status = (read_png_argb32 (ref_name, &ref_buf, &ref_width, &ref_height, &ref_stride));
+ if (png_status) {
+ switch (png_status)
+ {
+ case READ_PNG_FILE_NOT_FOUND:
+ fprintf (stderr, " 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);
+ break;
+ default:
+ fprintf (stderr, " Error: Failed to read %s\n", ref_name);
+ }
+
+ ret = CAIRO_TEST_FAILURE;
+ goto BAIL;
+ }
+
+ 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",
+ test->width, test->height,
+ ref_width, ref_height,
+ png_name, ref_name);
+ ret = CAIRO_TEST_FAILURE;
+ goto BAIL;
+ }
+
+ pixels_changed = image_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",
+ pixels_changed, ref_name);
+ write_png_argb32 (diff_buf, diff_name, test->width, test->height, stride);
+ 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;
+ }
+ }
+
+ ret = CAIRO_TEST_SUCCESS;
+
+BAIL:
+ free (png_buf);
+ free (ref_buf);
+ free (diff_buf);
+ free (png_name);
+ free (ref_name);
+ free (diff_name);
+
+ return ret;
+}
diff --git a/test/cairo_test.h b/test/cairo_test.h
new file mode 100644
index 00000000..7062f029
--- /dev/null
+++ b/test/cairo_test.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+#ifndef _CAIRO_TEST_H_
+#define _CAIRO_TEST_H_
+
+#include <cairo.h>
+
+typedef enum cairo_test_status {
+ CAIRO_TEST_SUCCESS = 0,
+ CAIRO_TEST_FAILURE
+} cairo_test_status_t;
+
+typedef struct cairo_test {
+ char *name;
+ char *description;
+ int width;
+ int height;
+} cairo_test_t;
+
+typedef void (*cairo_test_draw_function_t) (cairo_t *cr, int width, int height);
+
+/* cairo_test.c */
+cairo_test_status_t
+cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw);
+
+#endif
+
diff --git a/test/line-width-ref.png b/test/line-width-ref.png
new file mode 100644
index 00000000..1490b1b4
--- /dev/null
+++ b/test/line-width-ref.png
Binary files differ
diff --git a/test/line-width.c b/test/line-width.c
new file mode 100644
index 00000000..9c3ed89b
--- /dev/null
+++ b/test/line-width.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+#include "cairo_test.h"
+
+#define LINES 5
+#define LINE_LENGTH 10
+#define IMAGE_WIDTH 2 * LINE_LENGTH + 6
+#define IMAGE_HEIGHT ((LINES+4)*LINES)/2 + 2
+
+cairo_test_t test = {
+ "line_width",
+ "Tests cairo_set_line_width",
+ IMAGE_WIDTH, IMAGE_HEIGHT
+};
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_rgb_color (cr, 0, 0, 0);
+ cairo_translate (cr, 2, 2);
+
+ for (i=0; i < LINES; i++) {
+ cairo_set_line_width (cr, i+1);
+ cairo_move_to (cr, 0, 0);
+ cairo_rel_line_to (cr, LINE_LENGTH, 0);
+ cairo_stroke (cr);
+ cairo_move_to (cr, LINE_LENGTH + 2, 0.5);
+ cairo_rel_line_to (cr, LINE_LENGTH, 0);
+ cairo_stroke (cr);
+ cairo_translate (cr, 0, i+3);
+ }
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/line_width-ref.png b/test/line_width-ref.png
new file mode 100644
index 00000000..1490b1b4
--- /dev/null
+++ b/test/line_width-ref.png
Binary files differ
diff --git a/test/line_width.c b/test/line_width.c
new file mode 100644
index 00000000..9c3ed89b
--- /dev/null
+++ b/test/line_width.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+#include "cairo_test.h"
+
+#define LINES 5
+#define LINE_LENGTH 10
+#define IMAGE_WIDTH 2 * LINE_LENGTH + 6
+#define IMAGE_HEIGHT ((LINES+4)*LINES)/2 + 2
+
+cairo_test_t test = {
+ "line_width",
+ "Tests cairo_set_line_width",
+ IMAGE_WIDTH, IMAGE_HEIGHT
+};
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_rgb_color (cr, 0, 0, 0);
+ cairo_translate (cr, 2, 2);
+
+ for (i=0; i < LINES; i++) {
+ cairo_set_line_width (cr, i+1);
+ cairo_move_to (cr, 0, 0);
+ cairo_rel_line_to (cr, LINE_LENGTH, 0);
+ cairo_stroke (cr);
+ cairo_move_to (cr, LINE_LENGTH + 2, 0.5);
+ cairo_rel_line_to (cr, LINE_LENGTH, 0);
+ cairo_stroke (cr);
+ cairo_translate (cr, 0, i+3);
+ }
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/move-to-show-surface-ref.png b/test/move-to-show-surface-ref.png
new file mode 100644
index 00000000..765adc4a
--- /dev/null
+++ b/test/move-to-show-surface-ref.png
Binary files differ
diff --git a/test/move-to-show-surface.c b/test/move-to-show-surface.c
new file mode 100644
index 00000000..6dcda210
--- /dev/null
+++ b/test/move-to-show-surface.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2004-10-25 Carl Worth <cworth@cworth.org>
+ *
+ * It looks like cairo_show_surface has no effect if it follows a
+ * call to cairo_move_to to any coordinate other than 0,0. A little
+ * bit of poking around suggests this isn't a regression, (at least
+ * not since the last pixman snapshot).
+ *
+ */
+
+
+#include "cairo_test.h"
+
+cairo_test_t test = {
+ "move_to_show_surface",
+ "Tests calls to cairo_show_surface after cairo_move_to",
+ 2, 2
+};
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t colors[4] = {
+ 0xffffffff, 0xffff0000,
+ 0xff00ff00, 0xff0000ff
+ };
+ int i;
+
+ for (i=0; i < 4; i++) {
+ surface = cairo_surface_create_for_image ((char *) &colors[i],
+ CAIRO_FORMAT_ARGB32, 1, 1, 4);
+ cairo_move_to (cr, i % 2, i / 2);
+ cairo_show_surface (cr, surface, 1, 1);
+ cairo_surface_destroy (surface);
+ }
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/move_to_show_surface-ref.png b/test/move_to_show_surface-ref.png
new file mode 100644
index 00000000..765adc4a
--- /dev/null
+++ b/test/move_to_show_surface-ref.png
Binary files differ
diff --git a/test/move_to_show_surface.c b/test/move_to_show_surface.c
new file mode 100644
index 00000000..6dcda210
--- /dev/null
+++ b/test/move_to_show_surface.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2004-10-25 Carl Worth <cworth@cworth.org>
+ *
+ * It looks like cairo_show_surface has no effect if it follows a
+ * call to cairo_move_to to any coordinate other than 0,0. A little
+ * bit of poking around suggests this isn't a regression, (at least
+ * not since the last pixman snapshot).
+ *
+ */
+
+
+#include "cairo_test.h"
+
+cairo_test_t test = {
+ "move_to_show_surface",
+ "Tests calls to cairo_show_surface after cairo_move_to",
+ 2, 2
+};
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t colors[4] = {
+ 0xffffffff, 0xffff0000,
+ 0xff00ff00, 0xff0000ff
+ };
+ int i;
+
+ for (i=0; i < 4; i++) {
+ surface = cairo_surface_create_for_image ((char *) &colors[i],
+ CAIRO_FORMAT_ARGB32, 1, 1, 4);
+ cairo_move_to (cr, i % 2, i / 2);
+ cairo_show_surface (cr, surface, 1, 1);
+ cairo_surface_destroy (surface);
+ }
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/read-png.c b/test/read-png.c
new file mode 100644
index 00000000..23f91e83
--- /dev/null
+++ b/test/read-png.c
@@ -0,0 +1,166 @@
+/*
+ * 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@isi.edu>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <png.h>
+
+#include "read_png.h"
+#include "xmalloc.h"
+
+static void
+premultiply_data (png_structp png,
+ png_row_infop row_info,
+ png_bytep data)
+{
+ int i;
+
+ for (i = 0; i < row_info->rowbytes; i += 4) {
+ unsigned char *base = &data[i];
+ unsigned char blue = base[0];
+ unsigned char green = base[1];
+ unsigned char red = base[2];
+ unsigned char alpha = base[3];
+ unsigned long p;
+
+ red = (unsigned) red * (unsigned) alpha / 255;
+ green = (unsigned) green * (unsigned) alpha / 255;
+ blue = (unsigned) blue * (unsigned) alpha / 255;
+ p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
+ memcpy (base, &p, sizeof (unsigned long));
+ }
+}
+
+read_png_status_t
+read_png_argb32 (const char *filename,
+ unsigned char **data,
+ unsigned int *width,
+ unsigned int *height,
+ unsigned int *stride)
+{
+ int i;
+ FILE *file;
+ static const int 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) {
+ 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);
+ 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);
+ return READ_PNG_NO_MEMORY;
+ }
+
+ info = png_create_info_struct (png);
+ if (info == NULL) {
+ fclose (file);
+ png_destroy_read_struct (&png, NULL, NULL);
+ 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
new file mode 100644
index 00000000..9c9ba433
--- /dev/null
+++ b/test/read-png.h
@@ -0,0 +1,45 @@
+/*
+ * 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@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/read_png.c b/test/read_png.c
new file mode 100644
index 00000000..23f91e83
--- /dev/null
+++ b/test/read_png.c
@@ -0,0 +1,166 @@
+/*
+ * 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@isi.edu>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <png.h>
+
+#include "read_png.h"
+#include "xmalloc.h"
+
+static void
+premultiply_data (png_structp png,
+ png_row_infop row_info,
+ png_bytep data)
+{
+ int i;
+
+ for (i = 0; i < row_info->rowbytes; i += 4) {
+ unsigned char *base = &data[i];
+ unsigned char blue = base[0];
+ unsigned char green = base[1];
+ unsigned char red = base[2];
+ unsigned char alpha = base[3];
+ unsigned long p;
+
+ red = (unsigned) red * (unsigned) alpha / 255;
+ green = (unsigned) green * (unsigned) alpha / 255;
+ blue = (unsigned) blue * (unsigned) alpha / 255;
+ p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
+ memcpy (base, &p, sizeof (unsigned long));
+ }
+}
+
+read_png_status_t
+read_png_argb32 (const char *filename,
+ unsigned char **data,
+ unsigned int *width,
+ unsigned int *height,
+ unsigned int *stride)
+{
+ int i;
+ FILE *file;
+ static const int 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) {
+ 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);
+ 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);
+ return READ_PNG_NO_MEMORY;
+ }
+
+ info = png_create_info_struct (png);
+ if (info == NULL) {
+ fclose (file);
+ png_destroy_read_struct (&png, NULL, NULL);
+ 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
new file mode 100644
index 00000000..9c9ba433
--- /dev/null
+++ b/test/read_png.h
@@ -0,0 +1,45 @@
+/*
+ * 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@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
new file mode 100644
index 00000000..2ea29d06
--- /dev/null
+++ b/test/write-png.c
@@ -0,0 +1,102 @@
+/*
+ * 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@isi.edu>
+ */
+
+#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)
+{
+ int 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;
+ b[1] = (((pixel & 0x00ff00) >> 8) * 255) / alpha;
+ b[2] = (((pixel & 0xff0000) >> 16) * 255) / alpha;
+ b[3] = alpha;
+ }
+ }
+}
+
+void
+write_png_argb32 (char *buffer, char *filename,
+ int width, int height, int stride)
+{
+ FILE *f;
+ int i;
+ png_struct *png;
+ png_info *info;
+ png_byte **rows;
+ png_color_16 white;
+
+ f = fopen (filename, "w");
+ 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, f);
+ 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);
+ fclose (f);
+}
diff --git a/test/write-png.h b/test/write-png.h
new file mode 100644
index 00000000..a71ca6a3
--- /dev/null
+++ b/test/write-png.h
@@ -0,0 +1,35 @@
+/*
+ * 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@isi.edu>
+ */
+
+#ifndef WRITE_PNG_H
+#define WRITE_PNG_H
+
+void
+write_png_argb32 (char *buffer, char *filename,
+ int width, int height, int stride);
+
+#endif
diff --git a/test/write_png.c b/test/write_png.c
new file mode 100644
index 00000000..2ea29d06
--- /dev/null
+++ b/test/write_png.c
@@ -0,0 +1,102 @@
+/*
+ * 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@isi.edu>
+ */
+
+#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)
+{
+ int 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;
+ b[1] = (((pixel & 0x00ff00) >> 8) * 255) / alpha;
+ b[2] = (((pixel & 0xff0000) >> 16) * 255) / alpha;
+ b[3] = alpha;
+ }
+ }
+}
+
+void
+write_png_argb32 (char *buffer, char *filename,
+ int width, int height, int stride)
+{
+ FILE *f;
+ int i;
+ png_struct *png;
+ png_info *info;
+ png_byte **rows;
+ png_color_16 white;
+
+ f = fopen (filename, "w");
+ 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, f);
+ 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);
+ fclose (f);
+}
diff --git a/test/write_png.h b/test/write_png.h
new file mode 100644
index 00000000..a71ca6a3
--- /dev/null
+++ b/test/write_png.h
@@ -0,0 +1,35 @@
+/*
+ * 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@isi.edu>
+ */
+
+#ifndef WRITE_PNG_H
+#define WRITE_PNG_H
+
+void
+write_png_argb32 (char *buffer, char *filename,
+ int width, int height, int stride);
+
+#endif
diff --git a/test/xmalloc.c b/test/xmalloc.c
new file mode 100644
index 00000000..04ed38af
--- /dev/null
+++ b/test/xmalloc.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "xmalloc.h"
+
+void *
+xmalloc (size_t size)
+{
+ void *buf;
+
+ buf = malloc (size);
+ if (!buf) {
+ fprintf (stderr, "Error: Out of memory. Exiting.\n");
+ exit (1);
+ }
+
+ return buf;
+}
+
+void *
+xcalloc (size_t nmemb, size_t size)
+{
+ void *buf;
+
+ buf = calloc (nmemb, size);
+ if (!buf) {
+ fprintf (stderr, "Error: Out of memory. Exiting\n");
+ exit (1);
+ }
+
+ return buf;
+}
+
diff --git a/test/xmalloc.h b/test/xmalloc.h
new file mode 100644
index 00000000..a4ba24b6
--- /dev/null
+++ b/test/xmalloc.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2004 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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@cworth.org>
+ */
+
+#ifndef _XMALLOC_H_
+#define _XMALLOC_H_
+
+void *
+xmalloc (size_t size);
+
+void *
+xcalloc (size_t nmemb, size_t size);
+
+#endif