diff options
-rw-r--r-- | BUGS | 11 | ||||
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | cairo.pc.in | 2 | ||||
-rw-r--r-- | configure.in | 41 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | test/.cvsignore | 10 | ||||
-rw-r--r-- | test/Makefile.am | 29 | ||||
-rw-r--r-- | test/README | 55 | ||||
-rw-r--r-- | test/cairo-test.c | 191 | ||||
-rw-r--r-- | test/cairo-test.h | 50 | ||||
-rw-r--r-- | test/cairo_test.c | 191 | ||||
-rw-r--r-- | test/cairo_test.h | 50 | ||||
-rw-r--r-- | test/line-width-ref.png | bin | 0 -> 167 bytes | |||
-rw-r--r-- | test/line-width.c | 63 | ||||
-rw-r--r-- | test/line_width-ref.png | bin | 0 -> 167 bytes | |||
-rw-r--r-- | test/line_width.c | 63 | ||||
-rw-r--r-- | test/move-to-show-surface-ref.png | bin | 0 -> 100 bytes | |||
-rw-r--r-- | test/move-to-show-surface.c | 69 | ||||
-rw-r--r-- | test/move_to_show_surface-ref.png | bin | 0 -> 100 bytes | |||
-rw-r--r-- | test/move_to_show_surface.c | 69 | ||||
-rw-r--r-- | test/read-png.c | 166 | ||||
-rw-r--r-- | test/read-png.h | 45 | ||||
-rw-r--r-- | test/read_png.c | 166 | ||||
-rw-r--r-- | test/read_png.h | 45 | ||||
-rw-r--r-- | test/write-png.c | 102 | ||||
-rw-r--r-- | test/write-png.h | 35 | ||||
-rw-r--r-- | test/write_png.c | 102 | ||||
-rw-r--r-- | test/write_png.h | 35 | ||||
-rw-r--r-- | test/xmalloc.c | 58 | ||||
-rw-r--r-- | test/xmalloc.h | 35 |
31 files changed, 1698 insertions, 18 deletions
@@ -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). @@ -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 Binary files differnew file mode 100644 index 00000000..1490b1b4 --- /dev/null +++ b/test/line-width-ref.png 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 Binary files differnew file mode 100644 index 00000000..1490b1b4 --- /dev/null +++ b/test/line_width-ref.png 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 Binary files differnew file mode 100644 index 00000000..765adc4a --- /dev/null +++ b/test/move-to-show-surface-ref.png 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 Binary files differnew file mode 100644 index 00000000..765adc4a --- /dev/null +++ b/test/move_to_show_surface-ref.png 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 |