summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/.cvsignore4
-rw-r--r--test/Makefile.am35
-rw-r--r--test/buffer-diff.c73
-rw-r--r--test/buffer-diff.h38
-rw-r--r--test/buffer_diff.c73
-rw-r--r--test/buffer_diff.h38
-rw-r--r--test/cairo-test.c162
-rw-r--r--test/cairo-test.h4
-rw-r--r--test/cairo_test.c162
-rw-r--r--test/cairo_test.h4
-rw-r--r--test/clip-twice-ref.pngbin0 -> 751 bytes
-rw-r--r--test/clip-twice.c72
-rw-r--r--test/clip_twice-ref.pngbin0 -> 751 bytes
-rw-r--r--test/clip_twice.c72
-rw-r--r--test/coverage-ref.pngbin0 -> 44324 bytes
-rw-r--r--test/coverage.c182
-rw-r--r--test/imagediff.c84
-rw-r--r--test/linear-gradient-ref.pngbin0 -> 12724 bytes
-rw-r--r--test/linear-gradient.c141
-rw-r--r--test/linear_gradient-ref.pngbin0 -> 12724 bytes
-rw-r--r--test/linear_gradient.c141
-rw-r--r--test/pixman-rotate-ref.pngbin0 -> 260 bytes
-rw-r--r--test/pixman-rotate.c78
-rw-r--r--test/pixman_rotate-ref.pngbin0 -> 260 bytes
-rw-r--r--test/pixman_rotate.c78
-rw-r--r--test/read-png.c6
-rw-r--r--test/read_png.c6
-rw-r--r--test/romedalen.pngbin0 -> 80944 bytes
-rwxr-xr-xtest/testsvg51
-rw-r--r--test/write-png.c17
-rw-r--r--test/write-png.h4
-rw-r--r--test/write_png.c17
-rw-r--r--test/write_png.h4
33 files changed, 1384 insertions, 162 deletions
diff --git a/test/.cvsignore b/test/.cvsignore
index 27e57c1d..6194e267 100644
--- a/test/.cvsignore
+++ b/test/.cvsignore
@@ -2,12 +2,16 @@
.libs
Makefile
Makefile.in
+coverage
fill_rule
+imagediff
leaky_polygon
line_width
move_to_show_surface
+pixman_rotate
text_cache_crash
text_rotate
+clip_twice
*-out.png
*-diff.png
diff --git a/test/Makefile.am b/test/Makefile.am
index e7fd3fd6..04d42e2d 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -3,18 +3,27 @@ TESTS = \
fill_rule \
leaky_polygon \
line_width \
+linear_gradient \
move_to_show_surface \
text_cache_crash \
-text_rotate
+text_rotate \
+coverage \
+clip_twice \
+pixman_rotate
-# And all new test go here too. I really don't like having to repeat
+# And all new tests go here too. I really don't like having to repeat
# this list. Anyone know a good way to avoid it? Can I use a wildcard
# here?
-EXTRA_DIST = \
-fill_rule-ref.png \
-leaky_polygon-ref.png \
-line_width-ref.png \
-move_to_show_surface-ref.png
+EXTRA_DIST = \
+fill_rule-ref.png \
+leaky_polygon-ref.png \
+line_width-ref.png \
+linear_gradient-ref.png \
+move_to_show_surface-ref.png \
+coverage-ref.png \
+clip_twice-ref.png \
+pixman_rotate-ref.png \
+romedalen.png
# Once we can draw the text_rotate.c test case correctly, we should
# create and add text_rotate-ref.png to the list of reference PNGs.
@@ -29,6 +38,7 @@ move_to_show_surface-ref.png
# be fixed before the code is committed.
XFAIL_TESTS = \
move_to_show_surface \
+pixman_rotate \
text_rotate
check_PROGRAMS = $(TESTS)
@@ -42,6 +52,8 @@ INCLUDES = -D_GNU_SOURCE -I$(srcdir) $(CAIRO_CFLAGS) -I$(srcdir)/../src
AM_LDFLAGS = $(CAIRO_LIBS) ../src/libcairo.la
cairo_test_lib =\
+buffer_diff.c \
+buffer_diff.h \
cairo_test.c \
cairo_test.h \
read_png.c \
@@ -57,8 +69,15 @@ xmalloc.h
fill_rule_SOURCES = fill_rule.c $(cairo_test_lib)
leaky_polygon_SOURCES = leaky_polygon.c $(cairo_test_lib)
line_width_SOURCES = line_width.c $(cairo_test_lib)
+linear_gradient_SOURCES = linear_gradient.c $(cairo_test_lib)
move_to_show_surface_SOURCES = move_to_show_surface.c $(cairo_test_lib)
text_cache_crash_SOURCES = text_cache_crash.c $(cairo_test_lib)
text_rotate_SOURCES = text_rotate.c $(cairo_test_lib)
+coverage_SOURCES = coverage.c $(cairo_test_lib)
+clip_twice_SOURCES = clip_twice.c $(cairo_test_lib)
+pixman_rotate_SOURCES = pixman_rotate.c $(cairo_test_lib)
+
+noinst_PROGRAMS = imagediff
+imagediff_SOURCES = imagediff.c $(cairo_test_lib)
-CLEANFILES = *-out.png *-diff.png
+CLEANFILES = *-out.png *-diff.png *.log
diff --git a/test/buffer-diff.c b/test/buffer-diff.c
new file mode 100644
index 00000000..07abd62a
--- /dev/null
+++ b/test/buffer-diff.c
@@ -0,0 +1,73 @@
+/* imagediff - Compare two images
+ *
+ * Copyright © 2004 Richard D. Worth
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Richard Worth
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Richard Worth makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * RICHARD WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RICHARD WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard D. Worth <richard@theworths.org> */
+
+#include "buffer_diff.h"
+
+/* 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.
+ */
+int
+buffer_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;
+}
diff --git a/test/buffer-diff.h b/test/buffer-diff.h
new file mode 100644
index 00000000..9ee51c3c
--- /dev/null
+++ b/test/buffer-diff.h
@@ -0,0 +1,38 @@
+/* imagediff - Compare two images
+ *
+ * Copyright © 2004 Richard D. Worth
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Richard Worth
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Richard Worth makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * RICHARD WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RICHARD WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard D. Worth <richard@theworths.org> */
+
+#ifndef BUFFER_DIFF_H
+#define BUFFER_DIFF_H
+
+/* 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.
+ */
+int
+buffer_diff (char *buf_a, char *buf_b, char *buf_diff,
+ int width, int height, int stride);
+
+#endif
diff --git a/test/buffer_diff.c b/test/buffer_diff.c
new file mode 100644
index 00000000..07abd62a
--- /dev/null
+++ b/test/buffer_diff.c
@@ -0,0 +1,73 @@
+/* imagediff - Compare two images
+ *
+ * Copyright © 2004 Richard D. Worth
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Richard Worth
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Richard Worth makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * RICHARD WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RICHARD WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard D. Worth <richard@theworths.org> */
+
+#include "buffer_diff.h"
+
+/* 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.
+ */
+int
+buffer_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;
+}
diff --git a/test/buffer_diff.h b/test/buffer_diff.h
new file mode 100644
index 00000000..9ee51c3c
--- /dev/null
+++ b/test/buffer_diff.h
@@ -0,0 +1,38 @@
+/* imagediff - Compare two images
+ *
+ * Copyright © 2004 Richard D. Worth
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Richard Worth
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Richard Worth makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * RICHARD WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RICHARD WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard D. Worth <richard@theworths.org> */
+
+#ifndef BUFFER_DIFF_H
+#define BUFFER_DIFF_H
+
+/* 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.
+ */
+int
+buffer_diff (char *buf_a, char *buf_b, char *buf_diff,
+ int width, int height, int stride);
+
+#endif
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 2364570a..06f7672f 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -32,10 +32,12 @@
#include "cairo_test.h"
+#include "buffer_diff.h"
#include "read_png.h"
#include "write_png.h"
#include "xmalloc.h"
+#define CAIRO_TEST_LOG_SUFFIX ".log"
#define CAIRO_TEST_PNG_SUFFIX "-out.png"
#define CAIRO_TEST_REF_SUFFIX "-ref.png"
#define CAIRO_TEST_DIFF_SUFFIX "-diff.png"
@@ -43,9 +45,10 @@
static void
xasprintf (char **strp, const char *fmt, ...)
{
+#ifdef HAVE_VASPRINTF
va_list va;
int ret;
-
+
va_start (va, fmt);
ret = vasprintf (strp, fmt, va);
va_end (va);
@@ -54,53 +57,42 @@ xasprintf (char **strp, const char *fmt, ...)
fprintf (stderr, "Out of memory\n");
exit (1);
}
+#else /* !HAVE_VASNPRINTF */
+#define BUF_SIZE 1024
+ va_list va;
+ char buffer[BUF_SIZE];
+ int ret;
+
+ va_start (va, fmt);
+ ret = vsnprintf (buffer, sizeof(buffer), fmt, va);
+ va_end (va);
+
+ if (ret < 0) {
+ fprintf (stderr, "Failure in vsnprintf\n");
+ exit (1);
+ }
+
+ if (strlen (buffer) == sizeof(buffer) - 1) {
+ fprintf (stderr, "Overflowed fixed buffer\n");
+ exit (1);
+ }
+
+ *strp = strdup (buffer);
+ if (!*strp) {
+ fprintf (stderr, "Out of memory\n");
+ exit (1);
+ }
+#endif /* !HAVE_VASNPRINTF */
}
-/* Image comparison code courttesy of Richard Worth.
- * Returns number of pixels changed.
- * Also fills out a "diff" image intended to visually show where the
- * images differ.
- */
-static int
-image_diff (char *buf_a, char *buf_b, char *buf_diff,
- int width, int height, int stride)
+static void
+xunlink (const char *pathname)
{
- int x, y;
- int total_pixels_changed = 0;
- unsigned char *row_a, *row_b, *row;
-
- for (y = 0; y < height; y++)
- {
- row_a = buf_a + y * stride;
- row_b = buf_b + y * stride;
- row = buf_diff + y * stride;
- for (x = 0; x < width; x++)
- {
- int channel;
- unsigned char value_a, value_b;
- int pixel_changed = 0;
- for (channel = 0; channel < 4; channel++)
- {
- double diff;
- value_a = row_a[x * 4 + channel];
- value_b = row_b[x * 4 + channel];
- if (value_a != value_b)
- pixel_changed = 1;
- diff = value_a - value_b;
- row[x * 4 + channel] = 128 + diff / 3.0;
- }
- if (pixel_changed) {
- total_pixels_changed++;
- } else {
- row[x*4+0] = 0;
- row[x*4+1] = 0;
- row[x*4+2] = 0;
- }
- row[x * 4 + 3] = 0xff; /* Set ALPHA to 100% (opaque) */
- }
+ if (unlink (pathname) < 0 && errno != ENOENT) {
+ fprintf (stderr, " Error: Cannot remove %s: %s\n",
+ pathname, strerror (errno));
+ exit (1);
}
-
- return total_pixels_changed;
}
cairo_test_status_t
@@ -109,12 +101,14 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw)
cairo_t *cr;
int stride;
unsigned char *png_buf, *ref_buf, *diff_buf;
- char *png_name, *ref_name, *diff_name;
+ char *log_name, *png_name, *ref_name, *diff_name;
char *srcdir;
int pixels_changed;
int ref_width, ref_height, ref_stride;
read_png_status_t png_status;
cairo_test_status_t ret;
+ FILE *png_file;
+ FILE *log_file;
/* The cairo part of the test is the easiest part */
cr = cairo_create ();
@@ -142,57 +136,68 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw)
srcdir = getenv ("srcdir");
if (!srcdir)
srcdir = ".";
+ xasprintf (&log_name, "%s%s", test->name, CAIRO_TEST_LOG_SUFFIX);
xasprintf (&png_name, "%s%s", test->name, CAIRO_TEST_PNG_SUFFIX);
xasprintf (&ref_name, "%s/%s%s", srcdir, test->name, CAIRO_TEST_REF_SUFFIX);
xasprintf (&diff_name, "%s%s", test->name, CAIRO_TEST_DIFF_SUFFIX);
- write_png_argb32 (png_buf, png_name, test->width, test->height, stride);
+ png_file = fopen (png_name, "w");
+ write_png_argb32 (png_buf, png_file, test->width, test->height, stride);
+ fclose (png_file);
+
+ xunlink (log_name);
ref_buf = NULL;
png_status = (read_png_argb32 (ref_name, &ref_buf, &ref_width, &ref_height, &ref_stride));
if (png_status) {
+ log_file = fopen (log_name, "a");
switch (png_status)
{
case READ_PNG_FILE_NOT_FOUND:
- fprintf (stderr, " Error: No reference image found: %s\n", ref_name);
+ fprintf (log_file, "Error: No reference image found: %s\n", ref_name);
break;
case READ_PNG_FILE_NOT_PNG:
- fprintf (stderr, " Error: %s is not a png image\n", ref_name);
+ fprintf (log_file, "Error: %s is not a png image\n", ref_name);
break;
default:
- fprintf (stderr, " Error: Failed to read %s\n", ref_name);
+ fprintf (log_file, "Error: Failed to read %s\n", ref_name);
}
+ fclose (log_file);
ret = CAIRO_TEST_FAILURE;
goto BAIL;
+ } else {
}
if (test->width != ref_width || test->height != ref_height) {
- fprintf (stderr,
- " Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n"
- " for %s vs %s\n",
+ log_file = fopen (log_name, "a");
+ fprintf (log_file,
+ "Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n"
+ " for %s vs %s\n",
test->width, test->height,
ref_width, ref_height,
png_name, ref_name);
+ fclose (log_file);
+
ret = CAIRO_TEST_FAILURE;
goto BAIL;
}
- pixels_changed = image_diff (png_buf, ref_buf, diff_buf,
- test->width, test->height, stride);
+ pixels_changed = buffer_diff (png_buf, ref_buf, diff_buf,
+ test->width, test->height, stride);
if (pixels_changed) {
- fprintf (stderr, " Error: %d pixels differ from reference image %s\n",
+ log_file = fopen (log_name, "a");
+ fprintf (log_file, "Error: %d pixels differ from reference image %s\n",
pixels_changed, ref_name);
- write_png_argb32 (diff_buf, diff_name, test->width, test->height, stride);
+ png_file = fopen (diff_name, "w");
+ write_png_argb32 (diff_buf, png_file, test->width, test->height, stride);
+ fclose (png_file);
+ fclose (log_file);
+
ret = CAIRO_TEST_FAILURE;
goto BAIL;
} else {
- if (unlink (diff_name) < 0 && errno != ENOENT) {
- fprintf (stderr, " Error: Cannot remove %s: %s\n",
- diff_name, strerror (errno));
- ret = CAIRO_TEST_FAILURE;
- goto BAIL;
- }
+ xunlink (diff_name);
}
ret = CAIRO_TEST_SUCCESS;
@@ -201,9 +206,42 @@ BAIL:
free (png_buf);
free (ref_buf);
free (diff_buf);
+ free (log_name);
free (png_name);
free (ref_name);
free (diff_name);
return ret;
}
+
+cairo_pattern_t *
+cairo_test_create_png_pattern (cairo_t *cr, const char *filename)
+{
+ cairo_surface_t *image;
+ cairo_pattern_t *pattern;
+ unsigned char *buffer;
+ int w, h, stride;
+ read_png_status_t status;
+ char *srcdir = getenv ("srcdir");
+
+ status = read_png_argb32 (filename, &buffer, &w,&h, &stride);
+ if (status != READ_PNG_SUCCESS) {
+ if (srcdir) {
+ char *srcdir_filename;
+ xasprintf (&srcdir_filename, "%s/%s", srcdir, filename);
+ status = read_png_argb32 (srcdir_filename, &buffer, &w,&h, &stride);
+ free (srcdir_filename);
+ }
+ }
+ if (status != READ_PNG_SUCCESS)
+ return NULL;
+
+ image = cairo_surface_create_for_image (buffer, CAIRO_FORMAT_ARGB32,
+ w, h, stride);
+
+ cairo_surface_set_repeat (image, 1);
+
+ pattern = cairo_pattern_create_for_surface (image);
+
+ return pattern;
+}
diff --git a/test/cairo-test.h b/test/cairo-test.h
index 58936d56..912ce891 100644
--- a/test/cairo-test.h
+++ b/test/cairo-test.h
@@ -47,5 +47,9 @@ typedef void (*cairo_test_draw_function_t) (cairo_t *cr, int width, int height)
cairo_test_status_t
cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw);
+cairo_pattern_t *
+cairo_test_create_png_pattern (cairo_t *cr, const char *filename);
+
+
#endif
diff --git a/test/cairo_test.c b/test/cairo_test.c
index 2364570a..06f7672f 100644
--- a/test/cairo_test.c
+++ b/test/cairo_test.c
@@ -32,10 +32,12 @@
#include "cairo_test.h"
+#include "buffer_diff.h"
#include "read_png.h"
#include "write_png.h"
#include "xmalloc.h"
+#define CAIRO_TEST_LOG_SUFFIX ".log"
#define CAIRO_TEST_PNG_SUFFIX "-out.png"
#define CAIRO_TEST_REF_SUFFIX "-ref.png"
#define CAIRO_TEST_DIFF_SUFFIX "-diff.png"
@@ -43,9 +45,10 @@
static void
xasprintf (char **strp, const char *fmt, ...)
{
+#ifdef HAVE_VASPRINTF
va_list va;
int ret;
-
+
va_start (va, fmt);
ret = vasprintf (strp, fmt, va);
va_end (va);
@@ -54,53 +57,42 @@ xasprintf (char **strp, const char *fmt, ...)
fprintf (stderr, "Out of memory\n");
exit (1);
}
+#else /* !HAVE_VASNPRINTF */
+#define BUF_SIZE 1024
+ va_list va;
+ char buffer[BUF_SIZE];
+ int ret;
+
+ va_start (va, fmt);
+ ret = vsnprintf (buffer, sizeof(buffer), fmt, va);
+ va_end (va);
+
+ if (ret < 0) {
+ fprintf (stderr, "Failure in vsnprintf\n");
+ exit (1);
+ }
+
+ if (strlen (buffer) == sizeof(buffer) - 1) {
+ fprintf (stderr, "Overflowed fixed buffer\n");
+ exit (1);
+ }
+
+ *strp = strdup (buffer);
+ if (!*strp) {
+ fprintf (stderr, "Out of memory\n");
+ exit (1);
+ }
+#endif /* !HAVE_VASNPRINTF */
}
-/* Image comparison code courttesy of Richard Worth.
- * Returns number of pixels changed.
- * Also fills out a "diff" image intended to visually show where the
- * images differ.
- */
-static int
-image_diff (char *buf_a, char *buf_b, char *buf_diff,
- int width, int height, int stride)
+static void
+xunlink (const char *pathname)
{
- int x, y;
- int total_pixels_changed = 0;
- unsigned char *row_a, *row_b, *row;
-
- for (y = 0; y < height; y++)
- {
- row_a = buf_a + y * stride;
- row_b = buf_b + y * stride;
- row = buf_diff + y * stride;
- for (x = 0; x < width; x++)
- {
- int channel;
- unsigned char value_a, value_b;
- int pixel_changed = 0;
- for (channel = 0; channel < 4; channel++)
- {
- double diff;
- value_a = row_a[x * 4 + channel];
- value_b = row_b[x * 4 + channel];
- if (value_a != value_b)
- pixel_changed = 1;
- diff = value_a - value_b;
- row[x * 4 + channel] = 128 + diff / 3.0;
- }
- if (pixel_changed) {
- total_pixels_changed++;
- } else {
- row[x*4+0] = 0;
- row[x*4+1] = 0;
- row[x*4+2] = 0;
- }
- row[x * 4 + 3] = 0xff; /* Set ALPHA to 100% (opaque) */
- }
+ if (unlink (pathname) < 0 && errno != ENOENT) {
+ fprintf (stderr, " Error: Cannot remove %s: %s\n",
+ pathname, strerror (errno));
+ exit (1);
}
-
- return total_pixels_changed;
}
cairo_test_status_t
@@ -109,12 +101,14 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw)
cairo_t *cr;
int stride;
unsigned char *png_buf, *ref_buf, *diff_buf;
- char *png_name, *ref_name, *diff_name;
+ char *log_name, *png_name, *ref_name, *diff_name;
char *srcdir;
int pixels_changed;
int ref_width, ref_height, ref_stride;
read_png_status_t png_status;
cairo_test_status_t ret;
+ FILE *png_file;
+ FILE *log_file;
/* The cairo part of the test is the easiest part */
cr = cairo_create ();
@@ -142,57 +136,68 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw)
srcdir = getenv ("srcdir");
if (!srcdir)
srcdir = ".";
+ xasprintf (&log_name, "%s%s", test->name, CAIRO_TEST_LOG_SUFFIX);
xasprintf (&png_name, "%s%s", test->name, CAIRO_TEST_PNG_SUFFIX);
xasprintf (&ref_name, "%s/%s%s", srcdir, test->name, CAIRO_TEST_REF_SUFFIX);
xasprintf (&diff_name, "%s%s", test->name, CAIRO_TEST_DIFF_SUFFIX);
- write_png_argb32 (png_buf, png_name, test->width, test->height, stride);
+ png_file = fopen (png_name, "w");
+ write_png_argb32 (png_buf, png_file, test->width, test->height, stride);
+ fclose (png_file);
+
+ xunlink (log_name);
ref_buf = NULL;
png_status = (read_png_argb32 (ref_name, &ref_buf, &ref_width, &ref_height, &ref_stride));
if (png_status) {
+ log_file = fopen (log_name, "a");
switch (png_status)
{
case READ_PNG_FILE_NOT_FOUND:
- fprintf (stderr, " Error: No reference image found: %s\n", ref_name);
+ fprintf (log_file, "Error: No reference image found: %s\n", ref_name);
break;
case READ_PNG_FILE_NOT_PNG:
- fprintf (stderr, " Error: %s is not a png image\n", ref_name);
+ fprintf (log_file, "Error: %s is not a png image\n", ref_name);
break;
default:
- fprintf (stderr, " Error: Failed to read %s\n", ref_name);
+ fprintf (log_file, "Error: Failed to read %s\n", ref_name);
}
+ fclose (log_file);
ret = CAIRO_TEST_FAILURE;
goto BAIL;
+ } else {
}
if (test->width != ref_width || test->height != ref_height) {
- fprintf (stderr,
- " Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n"
- " for %s vs %s\n",
+ log_file = fopen (log_name, "a");
+ fprintf (log_file,
+ "Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n"
+ " for %s vs %s\n",
test->width, test->height,
ref_width, ref_height,
png_name, ref_name);
+ fclose (log_file);
+
ret = CAIRO_TEST_FAILURE;
goto BAIL;
}
- pixels_changed = image_diff (png_buf, ref_buf, diff_buf,
- test->width, test->height, stride);
+ pixels_changed = buffer_diff (png_buf, ref_buf, diff_buf,
+ test->width, test->height, stride);
if (pixels_changed) {
- fprintf (stderr, " Error: %d pixels differ from reference image %s\n",
+ log_file = fopen (log_name, "a");
+ fprintf (log_file, "Error: %d pixels differ from reference image %s\n",
pixels_changed, ref_name);
- write_png_argb32 (diff_buf, diff_name, test->width, test->height, stride);
+ png_file = fopen (diff_name, "w");
+ write_png_argb32 (diff_buf, png_file, test->width, test->height, stride);
+ fclose (png_file);
+ fclose (log_file);
+
ret = CAIRO_TEST_FAILURE;
goto BAIL;
} else {
- if (unlink (diff_name) < 0 && errno != ENOENT) {
- fprintf (stderr, " Error: Cannot remove %s: %s\n",
- diff_name, strerror (errno));
- ret = CAIRO_TEST_FAILURE;
- goto BAIL;
- }
+ xunlink (diff_name);
}
ret = CAIRO_TEST_SUCCESS;
@@ -201,9 +206,42 @@ BAIL:
free (png_buf);
free (ref_buf);
free (diff_buf);
+ free (log_name);
free (png_name);
free (ref_name);
free (diff_name);
return ret;
}
+
+cairo_pattern_t *
+cairo_test_create_png_pattern (cairo_t *cr, const char *filename)
+{
+ cairo_surface_t *image;
+ cairo_pattern_t *pattern;
+ unsigned char *buffer;
+ int w, h, stride;
+ read_png_status_t status;
+ char *srcdir = getenv ("srcdir");
+
+ status = read_png_argb32 (filename, &buffer, &w,&h, &stride);
+ if (status != READ_PNG_SUCCESS) {
+ if (srcdir) {
+ char *srcdir_filename;
+ xasprintf (&srcdir_filename, "%s/%s", srcdir, filename);
+ status = read_png_argb32 (srcdir_filename, &buffer, &w,&h, &stride);
+ free (srcdir_filename);
+ }
+ }
+ if (status != READ_PNG_SUCCESS)
+ return NULL;
+
+ image = cairo_surface_create_for_image (buffer, CAIRO_FORMAT_ARGB32,
+ w, h, stride);
+
+ cairo_surface_set_repeat (image, 1);
+
+ pattern = cairo_pattern_create_for_surface (image);
+
+ return pattern;
+}
diff --git a/test/cairo_test.h b/test/cairo_test.h
index 58936d56..912ce891 100644
--- a/test/cairo_test.h
+++ b/test/cairo_test.h
@@ -47,5 +47,9 @@ typedef void (*cairo_test_draw_function_t) (cairo_t *cr, int width, int height)
cairo_test_status_t
cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw);
+cairo_pattern_t *
+cairo_test_create_png_pattern (cairo_t *cr, const char *filename);
+
+
#endif
diff --git a/test/clip-twice-ref.png b/test/clip-twice-ref.png
new file mode 100644
index 00000000..ab0ae1ae
--- /dev/null
+++ b/test/clip-twice-ref.png
Binary files differ
diff --git a/test/clip-twice.c b/test/clip-twice.c
new file mode 100644
index 00000000..00215e62
--- /dev/null
+++ b/test/clip-twice.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2005 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: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo_test.h"
+
+#define WIDTH 64
+#define HEIGHT 64
+
+cairo_test_t test = {
+ "clip_twice",
+ "Verifies that the clip mask is updated correctly when it constructed by setting the clip path twice.",
+ WIDTH, HEIGHT
+};
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_alpha (cr, 1.0);
+ cairo_new_path (cr);
+ cairo_arc (cr, WIDTH / 2, HEIGHT / 2, WIDTH / 3, 0, 2 * M_PI);
+ cairo_clip (cr);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, WIDTH / 4, HEIGHT / 2);
+ cairo_line_to (cr, 0, HEIGHT);
+ cairo_line_to (cr, WIDTH, HEIGHT);
+ cairo_line_to (cr, 3 * WIDTH / 4, HEIGHT / 2);
+ cairo_line_to (cr, WIDTH, 0);
+ cairo_close_path (cr);
+ cairo_clip (cr);
+
+ cairo_set_rgb_color (cr, 0, 0, 0.6);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 0, HEIGHT);
+ cairo_line_to (cr, WIDTH / 2, 3 * HEIGHT / 4);
+ cairo_line_to (cr, WIDTH, HEIGHT);
+ cairo_line_to (cr, WIDTH, 0);
+ cairo_line_to (cr, WIDTH / 2, HEIGHT / 4);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/clip_twice-ref.png b/test/clip_twice-ref.png
new file mode 100644
index 00000000..ab0ae1ae
--- /dev/null
+++ b/test/clip_twice-ref.png
Binary files differ
diff --git a/test/clip_twice.c b/test/clip_twice.c
new file mode 100644
index 00000000..00215e62
--- /dev/null
+++ b/test/clip_twice.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2005 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: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo_test.h"
+
+#define WIDTH 64
+#define HEIGHT 64
+
+cairo_test_t test = {
+ "clip_twice",
+ "Verifies that the clip mask is updated correctly when it constructed by setting the clip path twice.",
+ WIDTH, HEIGHT
+};
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_alpha (cr, 1.0);
+ cairo_new_path (cr);
+ cairo_arc (cr, WIDTH / 2, HEIGHT / 2, WIDTH / 3, 0, 2 * M_PI);
+ cairo_clip (cr);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, WIDTH / 4, HEIGHT / 2);
+ cairo_line_to (cr, 0, HEIGHT);
+ cairo_line_to (cr, WIDTH, HEIGHT);
+ cairo_line_to (cr, 3 * WIDTH / 4, HEIGHT / 2);
+ cairo_line_to (cr, WIDTH, 0);
+ cairo_close_path (cr);
+ cairo_clip (cr);
+
+ cairo_set_rgb_color (cr, 0, 0, 0.6);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 0, HEIGHT);
+ cairo_line_to (cr, WIDTH / 2, 3 * HEIGHT / 4);
+ cairo_line_to (cr, WIDTH, HEIGHT);
+ cairo_line_to (cr, WIDTH, 0);
+ cairo_line_to (cr, WIDTH / 2, HEIGHT / 4);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/coverage-ref.png b/test/coverage-ref.png
new file mode 100644
index 00000000..9b710405
--- /dev/null
+++ b/test/coverage-ref.png
Binary files differ
diff --git a/test/coverage.c b/test/coverage.c
new file mode 100644
index 00000000..00c86a1d
--- /dev/null
+++ b/test/coverage.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2005 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: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include <math.h>
+#include "cairo_test.h"
+
+#define WIDTH 64
+#define HEIGHT 64
+#define PAD 10
+
+/* XXX The test image uses Bitstream Vera Sans as the font - how do we
+ * ensure that it's available? Can we ship it with this test? */
+
+const char fontname[] = "Bitstream Vera Sans";
+const int fontsize = 40;
+const char png_filename[] = "romedalen.png";
+
+static void
+set_solid_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_set_rgb_color (cr, 0, 0, 0.6);
+ cairo_set_alpha (cr, 1.0);
+}
+
+static void
+set_translucent_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_set_rgb_color (cr, 0, 0, 0.6);
+ cairo_set_alpha (cr, 0.5);
+}
+
+static void
+set_gradient_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern =
+ cairo_pattern_create_linear (x, y, x + WIDTH, y + HEIGHT);
+ cairo_pattern_add_color_stop (pattern, 0, 1, 1, 1, 1);
+ cairo_pattern_add_color_stop (pattern, 1, 0, 0, 0.4, 1);
+ cairo_set_pattern (cr, pattern);
+ cairo_set_alpha (cr, 1);
+}
+
+static void
+set_image_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_test_create_png_pattern (cr, png_filename);
+ cairo_set_pattern (cr, pattern);
+ cairo_set_alpha (cr, 1);
+}
+
+static void
+set_translucent_image_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_test_create_png_pattern (cr, png_filename);
+ cairo_set_pattern (cr, pattern);
+ cairo_set_alpha (cr, 0.5);
+}
+
+static void
+draw_text (cairo_t *cr, int x, int y)
+{
+ cairo_rel_move_to (cr, 0, fontsize);
+ cairo_show_text (cr, "Aa");
+}
+
+static void
+draw_polygon (cairo_t *cr, int x, int y)
+{
+ cairo_new_path (cr);
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x, y + HEIGHT);
+ cairo_line_to (cr, x + WIDTH / 2, y + 3 * HEIGHT / 4);
+ cairo_line_to (cr, x + WIDTH, y + HEIGHT);
+ cairo_line_to (cr, x + WIDTH, y);
+ cairo_line_to (cr, x + WIDTH / 2, y + HEIGHT / 4);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+}
+
+static void (*pattern_funcs[])(cairo_t *cr, int x, int y) = {
+ set_solid_pattern,
+ set_translucent_pattern,
+ set_gradient_pattern,
+ set_image_pattern,
+ set_translucent_image_pattern
+};
+
+static void (*draw_funcs[])(cairo_t *cr, int x, int y) = {
+ draw_text,
+ draw_polygon,
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+#define IMAGE_WIDTH (ARRAY_SIZE (pattern_funcs) * (WIDTH + PAD) + PAD)
+#define IMAGE_HEIGHT (ARRAY_SIZE (draw_funcs) * (HEIGHT + PAD) * 2 + PAD)
+
+static cairo_test_t test = {
+ "coverage",
+ "Various coverage test of cairo",
+ IMAGE_WIDTH, IMAGE_HEIGHT
+};
+
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ /* TODO: pattern fill, gradient fill, clipping, gradient clipping,
+ path+solid alpha mask clipping */
+
+ int i, j, x, y;
+
+ cairo_select_font (cr, fontname,
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+ cairo_scale_font (cr, fontsize);
+
+ for (j = 0; j < ARRAY_SIZE (draw_funcs); j++) {
+ for (i = 0; i < ARRAY_SIZE (pattern_funcs); i++) {
+ x = i * (WIDTH + PAD) + PAD;
+ y = j * (HEIGHT + PAD) + PAD;
+ cairo_move_to (cr, x, y);
+ pattern_funcs[i] (cr, x, y);
+ draw_funcs[j] (cr, x, y);
+ }
+ }
+
+ for (j = 0; j < ARRAY_SIZE (draw_funcs); j++) {
+ for (i = 0; i < ARRAY_SIZE (pattern_funcs); i++) {
+ x = i * (WIDTH + PAD) + PAD;
+ y = (ARRAY_SIZE (draw_funcs) + j) * (HEIGHT + PAD) + PAD;
+
+ cairo_save (cr);
+
+ cairo_set_alpha (cr, 1.0);
+ cairo_new_path (cr);
+ cairo_arc (cr, x + WIDTH / 2, y + HEIGHT / 2,
+ WIDTH / 3, 0, 2 * M_PI);
+ cairo_clip (cr);
+
+ cairo_move_to (cr, x, y);
+ pattern_funcs[i] (cr, x, y);
+ draw_funcs[j] (cr, x, y);
+
+ cairo_restore (cr);
+
+ }
+ }
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/imagediff.c b/test/imagediff.c
new file mode 100644
index 00000000..36962f11
--- /dev/null
+++ b/test/imagediff.c
@@ -0,0 +1,84 @@
+/* imagediff - Compare two images
+ *
+ * Copyright © 2004 Richard D. Worth
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Richard Worth
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Richard Worth makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * RICHARD WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RICHARD WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard D. Worth <richard@theworths.org> */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "buffer_diff.h"
+#include "read_png.h"
+#include "write_png.h"
+#include "xmalloc.h"
+
+int
+main (int argc, char *argv[])
+{
+ unsigned char *buffer_a;
+ unsigned int width_a, height_a, stride_a;
+ unsigned char *buffer_b;
+ unsigned int width_b, height_b, stride_b;
+
+ unsigned char *buffer;
+ unsigned int width, height, stride;
+ int buffer_size, total_pixels_changed;
+
+ if (argc < 2) {
+ fprintf (stderr, "Usage: %s image1.png image2.png\n", argv[0]);
+ fprintf (stderr, "Computes an output image designed to present a \"visual diff\" such that even\n");
+ fprintf (stderr, "small errors in single pixels are readily apparent in the output.\n");
+ fprintf (stderr, "The output image is written on stdout.\n");
+ exit (1);
+ }
+
+ read_png_argb32 (argv[1], &buffer_a, &width_a, &height_a, &stride_a);
+ read_png_argb32 (argv[2], &buffer_b, &width_b, &height_b, &stride_b);
+
+ if ((width_a == width_b) && (height_a == height_b) && (stride_a == stride_b))
+ {
+ width = width_a;
+ height = height_a;
+ stride = stride_a;
+ } else {
+ fprintf (stderr, "Error. Both images must be the same size\n");
+ return 1;
+ }
+
+ buffer_size = stride * height;
+ buffer = xmalloc (buffer_size);
+
+ total_pixels_changed = buffer_diff (buffer_a, buffer_b, buffer,
+ width_a, height_a, stride_a);
+
+
+ if (total_pixels_changed)
+ fprintf (stderr, "Total pixels changed: %d\n", total_pixels_changed);
+ write_png_argb32 (buffer, stdout, width, height, stride);
+
+ free (buffer);
+
+ return 0;
+}
+
+
+
diff --git a/test/linear-gradient-ref.png b/test/linear-gradient-ref.png
new file mode 100644
index 00000000..77904144
--- /dev/null
+++ b/test/linear-gradient-ref.png
Binary files differ
diff --git a/test/linear-gradient.c b/test/linear-gradient.c
new file mode 100644
index 00000000..189b5006
--- /dev/null
+++ b/test/linear-gradient.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2005 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: Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo_test.h"
+#include "stdio.h"
+
+/* The test matrix is
+ *
+ * A) Horizontal B) 5° C) 45° D) Vertical
+ * 1) Rotated 0° 2) Rotated 45° C) Rotated 90°
+ * a) 2 stop b) 3 stop
+ *
+ * A1a B1a C1a D1a
+ * A2a B2a C2a D2a
+ * A3a B3a C3a D3a
+ * A1b B1b C1b D1b
+ * A2b B2b C2b D2b
+ * A3b B3b C3b D3b
+ */
+
+static const double gradient_angles[] = { 0, 45, 90 };
+#define N_GRADIENT_ANGLES 3
+static const double rotate_angles[] = { 0, 45, 90 };
+#define N_ROTATE_ANGLES 3
+static const int n_stops[] = { 2, 3 };
+#define N_N_STOPS 2
+
+#define UNIT_SIZE 75
+#define UNIT_SIZE 75
+#define PAD 5
+
+#define WIDTH N_GRADIENT_ANGLES * UNIT_SIZE + (N_GRADIENT_ANGLES + 1) * PAD
+#define HEIGHT N_N_STOPS * N_ROTATE_ANGLES * UNIT_SIZE + (N_N_STOPS * N_ROTATE_ANGLES + 1) * PAD
+
+cairo_test_t test = {
+ "linear_gradient",
+ "Tests the drawing of linear gradients",
+ WIDTH, HEIGHT
+};
+
+static void
+draw_unit (cairo_t *cr,
+ double gradient_angle,
+ double rotate_angle,
+ int n_stops)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_clip (cr);
+ cairo_new_path(cr);
+
+ cairo_set_rgb_color (cr, 0.0, 0.0, 0.0);
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 0.5, 0.5);
+ cairo_scale (cr, 1 / 1.5, 1 / 1.5);
+ cairo_rotate (cr, rotate_angle);
+
+ pattern = cairo_pattern_create_linear (-0.5 * cos (gradient_angle), -0.5 * sin (gradient_angle),
+ 0.5 * cos (gradient_angle), 0.5 * sin (gradient_angle));
+
+ if (n_stops == 2) {
+ cairo_pattern_add_color_stop (pattern, 0.,
+ 0.3, 0.3, 0.3,
+ 1.0);
+ cairo_pattern_add_color_stop (pattern, 1.,
+ 1.0, 1.0, 1.0,
+ 1.0);
+ } else {
+ cairo_pattern_add_color_stop (pattern, 0.,
+ 1.0, 0.0, 0.0,
+ 1.0);
+ cairo_pattern_add_color_stop (pattern, 0.5,
+ 1.0, 1.0, 1.0,
+ 1.0);
+ cairo_pattern_add_color_stop (pattern, 1.,
+ 0.0, 0.0, 1.0,
+ 1.0);
+ }
+
+ cairo_set_pattern (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_rectangle (cr, -0.5, -0.5, 1, 1);
+ cairo_fill (cr);
+}
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ int i, j, k;
+
+ cairo_set_rgb_color (cr, 0.5, 0.5, 0.5);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ for (i = 0; i < N_GRADIENT_ANGLES; i++)
+ for (j = 0; j < N_ROTATE_ANGLES; j++)
+ for (k = 0; k < N_N_STOPS; k++) {
+ cairo_save (cr);
+ cairo_translate (cr,
+ PAD + (PAD + UNIT_SIZE) * i,
+ PAD + (PAD + UNIT_SIZE) * (N_ROTATE_ANGLES * k + j));
+ cairo_scale (cr, UNIT_SIZE, UNIT_SIZE);
+
+ draw_unit (cr,
+ gradient_angles[i] * M_PI / 180.,
+ rotate_angles[j] * M_PI / 180.,
+ n_stops[k]);
+ cairo_restore (cr);
+ }
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/linear_gradient-ref.png b/test/linear_gradient-ref.png
new file mode 100644
index 00000000..77904144
--- /dev/null
+++ b/test/linear_gradient-ref.png
Binary files differ
diff --git a/test/linear_gradient.c b/test/linear_gradient.c
new file mode 100644
index 00000000..189b5006
--- /dev/null
+++ b/test/linear_gradient.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2005 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: Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo_test.h"
+#include "stdio.h"
+
+/* The test matrix is
+ *
+ * A) Horizontal B) 5° C) 45° D) Vertical
+ * 1) Rotated 0° 2) Rotated 45° C) Rotated 90°
+ * a) 2 stop b) 3 stop
+ *
+ * A1a B1a C1a D1a
+ * A2a B2a C2a D2a
+ * A3a B3a C3a D3a
+ * A1b B1b C1b D1b
+ * A2b B2b C2b D2b
+ * A3b B3b C3b D3b
+ */
+
+static const double gradient_angles[] = { 0, 45, 90 };
+#define N_GRADIENT_ANGLES 3
+static const double rotate_angles[] = { 0, 45, 90 };
+#define N_ROTATE_ANGLES 3
+static const int n_stops[] = { 2, 3 };
+#define N_N_STOPS 2
+
+#define UNIT_SIZE 75
+#define UNIT_SIZE 75
+#define PAD 5
+
+#define WIDTH N_GRADIENT_ANGLES * UNIT_SIZE + (N_GRADIENT_ANGLES + 1) * PAD
+#define HEIGHT N_N_STOPS * N_ROTATE_ANGLES * UNIT_SIZE + (N_N_STOPS * N_ROTATE_ANGLES + 1) * PAD
+
+cairo_test_t test = {
+ "linear_gradient",
+ "Tests the drawing of linear gradients",
+ WIDTH, HEIGHT
+};
+
+static void
+draw_unit (cairo_t *cr,
+ double gradient_angle,
+ double rotate_angle,
+ int n_stops)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_clip (cr);
+ cairo_new_path(cr);
+
+ cairo_set_rgb_color (cr, 0.0, 0.0, 0.0);
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 0.5, 0.5);
+ cairo_scale (cr, 1 / 1.5, 1 / 1.5);
+ cairo_rotate (cr, rotate_angle);
+
+ pattern = cairo_pattern_create_linear (-0.5 * cos (gradient_angle), -0.5 * sin (gradient_angle),
+ 0.5 * cos (gradient_angle), 0.5 * sin (gradient_angle));
+
+ if (n_stops == 2) {
+ cairo_pattern_add_color_stop (pattern, 0.,
+ 0.3, 0.3, 0.3,
+ 1.0);
+ cairo_pattern_add_color_stop (pattern, 1.,
+ 1.0, 1.0, 1.0,
+ 1.0);
+ } else {
+ cairo_pattern_add_color_stop (pattern, 0.,
+ 1.0, 0.0, 0.0,
+ 1.0);
+ cairo_pattern_add_color_stop (pattern, 0.5,
+ 1.0, 1.0, 1.0,
+ 1.0);
+ cairo_pattern_add_color_stop (pattern, 1.,
+ 0.0, 0.0, 1.0,
+ 1.0);
+ }
+
+ cairo_set_pattern (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_rectangle (cr, -0.5, -0.5, 1, 1);
+ cairo_fill (cr);
+}
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ int i, j, k;
+
+ cairo_set_rgb_color (cr, 0.5, 0.5, 0.5);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ for (i = 0; i < N_GRADIENT_ANGLES; i++)
+ for (j = 0; j < N_ROTATE_ANGLES; j++)
+ for (k = 0; k < N_N_STOPS; k++) {
+ cairo_save (cr);
+ cairo_translate (cr,
+ PAD + (PAD + UNIT_SIZE) * i,
+ PAD + (PAD + UNIT_SIZE) * (N_ROTATE_ANGLES * k + j));
+ cairo_scale (cr, UNIT_SIZE, UNIT_SIZE);
+
+ draw_unit (cr,
+ gradient_angles[i] * M_PI / 180.,
+ rotate_angles[j] * M_PI / 180.,
+ n_stops[k]);
+ cairo_restore (cr);
+ }
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/pixman-rotate-ref.png b/test/pixman-rotate-ref.png
new file mode 100644
index 00000000..7e47a4d8
--- /dev/null
+++ b/test/pixman-rotate-ref.png
Binary files differ
diff --git a/test/pixman-rotate.c b/test/pixman-rotate.c
new file mode 100644
index 00000000..6a64a9a7
--- /dev/null
+++ b/test/pixman-rotate.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <cairo.h>
+#include <cairo-png.h>
+#include <cairo-pdf.h>
+
+#include "cairo_test.h"
+
+#define WIDTH 32
+#define HEIGHT WIDTH
+
+#define IMAGE_WIDTH (3 * WIDTH)
+#define IMAGE_HEIGHT IMAGE_WIDTH
+
+cairo_test_t test = {
+ "pixman_rotate",
+ "Exposes pixman off-by-one error when rotating",
+ IMAGE_WIDTH, IMAGE_HEIGHT
+};
+
+/* Draw the word cairo at NUM_TEXT different angles */
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *target, *stamp;
+
+ target = cairo_current_target_surface (cr);
+ cairo_surface_reference (target);
+
+ stamp = cairo_surface_create_similar (target, CAIRO_FORMAT_ARGB32,
+ WIDTH, HEIGHT);
+ cairo_set_target_surface (cr, stamp);
+ cairo_new_path (cr);
+ cairo_rectangle (cr, WIDTH / 4, HEIGHT / 4, WIDTH / 2, HEIGHT / 2);
+ cairo_set_rgb_color (cr, 1, 0, 0);
+ cairo_set_alpha (cr, 0.8);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_set_line_width (cr, 2);
+ cairo_set_rgb_color (cr, 0, 0, 0);
+ cairo_set_alpha (cr, 1);
+ cairo_stroke (cr);
+
+ cairo_set_target_surface (cr, target);
+
+ /* Draw a translucent rectangle for reference where the rotated
+ * image should be. */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, WIDTH, HEIGHT, WIDTH, HEIGHT);
+ cairo_set_rgb_color (cr, 1, 1, 0);
+ cairo_set_alpha (cr, 0.3);
+ cairo_fill (cr);
+
+#if 1 /* Set to 0 to generate reference image */
+ cairo_translate (cr, 2 * WIDTH, 2 * HEIGHT);
+ cairo_rotate (cr, M_PI);
+#else
+ cairo_translate (cr, WIDTH, HEIGHT);
+#endif
+
+ cairo_set_alpha (cr, 1);
+ cairo_show_surface (cr, stamp, WIDTH + 2, HEIGHT + 2);
+
+ cairo_show_page (cr);
+
+ cairo_surface_destroy (stamp);
+ cairo_surface_destroy (target);
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/pixman_rotate-ref.png b/test/pixman_rotate-ref.png
new file mode 100644
index 00000000..7e47a4d8
--- /dev/null
+++ b/test/pixman_rotate-ref.png
Binary files differ
diff --git a/test/pixman_rotate.c b/test/pixman_rotate.c
new file mode 100644
index 00000000..6a64a9a7
--- /dev/null
+++ b/test/pixman_rotate.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <cairo.h>
+#include <cairo-png.h>
+#include <cairo-pdf.h>
+
+#include "cairo_test.h"
+
+#define WIDTH 32
+#define HEIGHT WIDTH
+
+#define IMAGE_WIDTH (3 * WIDTH)
+#define IMAGE_HEIGHT IMAGE_WIDTH
+
+cairo_test_t test = {
+ "pixman_rotate",
+ "Exposes pixman off-by-one error when rotating",
+ IMAGE_WIDTH, IMAGE_HEIGHT
+};
+
+/* Draw the word cairo at NUM_TEXT different angles */
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *target, *stamp;
+
+ target = cairo_current_target_surface (cr);
+ cairo_surface_reference (target);
+
+ stamp = cairo_surface_create_similar (target, CAIRO_FORMAT_ARGB32,
+ WIDTH, HEIGHT);
+ cairo_set_target_surface (cr, stamp);
+ cairo_new_path (cr);
+ cairo_rectangle (cr, WIDTH / 4, HEIGHT / 4, WIDTH / 2, HEIGHT / 2);
+ cairo_set_rgb_color (cr, 1, 0, 0);
+ cairo_set_alpha (cr, 0.8);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_set_line_width (cr, 2);
+ cairo_set_rgb_color (cr, 0, 0, 0);
+ cairo_set_alpha (cr, 1);
+ cairo_stroke (cr);
+
+ cairo_set_target_surface (cr, target);
+
+ /* Draw a translucent rectangle for reference where the rotated
+ * image should be. */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, WIDTH, HEIGHT, WIDTH, HEIGHT);
+ cairo_set_rgb_color (cr, 1, 1, 0);
+ cairo_set_alpha (cr, 0.3);
+ cairo_fill (cr);
+
+#if 1 /* Set to 0 to generate reference image */
+ cairo_translate (cr, 2 * WIDTH, 2 * HEIGHT);
+ cairo_rotate (cr, M_PI);
+#else
+ cairo_translate (cr, WIDTH, HEIGHT);
+#endif
+
+ cairo_set_alpha (cr, 1);
+ cairo_show_surface (cr, stamp, WIDTH + 2, HEIGHT + 2);
+
+ cairo_show_page (cr);
+
+ cairo_surface_destroy (stamp);
+ cairo_surface_destroy (target);
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}
diff --git a/test/read-png.c b/test/read-png.c
index 23f91e83..e7e2a92c 100644
--- a/test/read-png.c
+++ b/test/read-png.c
@@ -47,9 +47,9 @@ premultiply_data (png_structp png,
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;
+ red = ((unsigned) red * (unsigned) alpha + 127) / 255;
+ green = ((unsigned) green * (unsigned) alpha + 127) / 255;
+ blue = ((unsigned) blue * (unsigned) alpha + 127) / 255;
p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
memcpy (base, &p, sizeof (unsigned long));
}
diff --git a/test/read_png.c b/test/read_png.c
index 23f91e83..e7e2a92c 100644
--- a/test/read_png.c
+++ b/test/read_png.c
@@ -47,9 +47,9 @@ premultiply_data (png_structp png,
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;
+ red = ((unsigned) red * (unsigned) alpha + 127) / 255;
+ green = ((unsigned) green * (unsigned) alpha + 127) / 255;
+ blue = ((unsigned) blue * (unsigned) alpha + 127) / 255;
p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
memcpy (base, &p, sizeof (unsigned long));
}
diff --git a/test/romedalen.png b/test/romedalen.png
new file mode 100644
index 00000000..0c41eb0c
--- /dev/null
+++ b/test/romedalen.png
Binary files differ
diff --git a/test/testsvg b/test/testsvg
new file mode 100755
index 00000000..52044294
--- /dev/null
+++ b/test/testsvg
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+IMAGEDIFF=./imagediff
+
+OUTDIR=testsvg-output
+REFDIR=testsvg-reference
+DIFFDIR=testsvg-diff
+IMAGELIST=testsvg-imagelist
+
+if [ $# -lt 1 ]; then
+ argv0=`basename $0`
+ echo "Usage: $argv0 file.svg [...]" >&2
+ exit 1;
+fi
+
+mkdir -p $OUTDIR
+mkdir -p $DIFFDIR
+rm -f $IMAGELIST
+
+err=0
+for svg in $@; do
+ svgbase=`basename $svg`
+ png=${svgbase/\.svg/.png}
+ outpng=$OUTDIR/$png
+ refpng=$REFDIR/$png
+ diffpng=$DIFFDIR/$png
+# if xsvg $svg -p $outpng ; then
+ if svg2png $svg $outpng ; then
+ if [ -e $refpng ]; then
+ if diff $refpng $outpng > /dev/null; then
+ echo "Rendering of $svg matches." >&2
+ else
+ echo "ERROR: Rendering of $svg differs from reference image." >&2
+ $IMAGEDIFF $refpng $outpng > $diffpng
+ echo $refpng $outpng $diffpng >> $IMAGELIST
+ err=$(($err+1))
+ fi
+ else
+ echo "WARNING: No reference file found for $svg (looked in $refpng)" >&2
+ fi
+ else
+ echo "ERROR: Failed to render $svg" >&2
+ err=$(($err+1))
+ fi
+done
+
+if [ $err -gt 0 ] ; then
+ echo "Differences found in $err renderings."
+else
+ echo "All renderings matched reference images."
+fi
diff --git a/test/write-png.c b/test/write-png.c
index 2ea29d06..0ff5bcd3 100644
--- a/test/write-png.c
+++ b/test/write-png.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2003 USC, Information Sciences Institute
+ * 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
@@ -22,7 +22,7 @@
* 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>
+ * Author: Carl D. Worth <cworth@cworth.org>
*/
#include <stdio.h>
@@ -46,26 +46,24 @@ unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
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[0] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
+ b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
+ b[2] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
b[3] = alpha;
}
}
}
void
-write_png_argb32 (char *buffer, char *filename,
+write_png_argb32 (char *buffer, FILE *file,
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++) {
@@ -75,7 +73,7 @@ write_png_argb32 (char *buffer, char *filename,
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
info = png_create_info_struct (png);
- png_init_io (png, f);
+ png_init_io (png, file);
png_set_IHDR (png, info,
width, height, 8,
PNG_COLOR_TYPE_RGB_ALPHA,
@@ -98,5 +96,4 @@ write_png_argb32 (char *buffer, char *filename,
png_destroy_write_struct (&png, &info);
free (rows);
- fclose (f);
}
diff --git a/test/write-png.h b/test/write-png.h
index a71ca6a3..fe0e92b2 100644
--- a/test/write-png.h
+++ b/test/write-png.h
@@ -1,5 +1,5 @@
/*
- * Copyright © 2003 USC, Information Sciences Institute
+ * 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
@@ -29,7 +29,7 @@
#define WRITE_PNG_H
void
-write_png_argb32 (char *buffer, char *filename,
+write_png_argb32 (char *buffer, FILE * file,
int width, int height, int stride);
#endif
diff --git a/test/write_png.c b/test/write_png.c
index 2ea29d06..0ff5bcd3 100644
--- a/test/write_png.c
+++ b/test/write_png.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2003 USC, Information Sciences Institute
+ * 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
@@ -22,7 +22,7 @@
* 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>
+ * Author: Carl D. Worth <cworth@cworth.org>
*/
#include <stdio.h>
@@ -46,26 +46,24 @@ unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
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[0] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
+ b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
+ b[2] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
b[3] = alpha;
}
}
}
void
-write_png_argb32 (char *buffer, char *filename,
+write_png_argb32 (char *buffer, FILE *file,
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++) {
@@ -75,7 +73,7 @@ write_png_argb32 (char *buffer, char *filename,
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
info = png_create_info_struct (png);
- png_init_io (png, f);
+ png_init_io (png, file);
png_set_IHDR (png, info,
width, height, 8,
PNG_COLOR_TYPE_RGB_ALPHA,
@@ -98,5 +96,4 @@ write_png_argb32 (char *buffer, char *filename,
png_destroy_write_struct (&png, &info);
free (rows);
- fclose (f);
}
diff --git a/test/write_png.h b/test/write_png.h
index a71ca6a3..fe0e92b2 100644
--- a/test/write_png.h
+++ b/test/write_png.h
@@ -1,5 +1,5 @@
/*
- * Copyright © 2003 USC, Information Sciences Institute
+ * 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
@@ -29,7 +29,7 @@
#define WRITE_PNG_H
void
-write_png_argb32 (char *buffer, char *filename,
+write_png_argb32 (char *buffer, FILE * file,
int width, int height, int stride);
#endif