summaryrefslogtreecommitdiff
path: root/test/buffer-diff.c
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2006-08-30 15:34:27 -0700
committerCarl Worth <cworth@cworth.org>2006-08-30 15:34:27 -0700
commit7f4e83ceeba912167df05f62ddd0798b112979a3 (patch)
tree2d54714470dbec2f8b772150302a3dfc09c4b745 /test/buffer-diff.c
parenta5f068e10d72c20a55d20ca9f79508361d13fb80 (diff)
downloadcairo-7f4e83ceeba912167df05f62ddd0798b112979a3.tar.gz
Split libcairotest files out from test/ and into boilerplate/
The idea here is to setup boilerplate to allow code sharing between test/ and the upcoming perf/
Diffstat (limited to 'test/buffer-diff.c')
-rw-r--r--test/buffer-diff.c348
1 files changed, 0 insertions, 348 deletions
diff --git a/test/buffer-diff.c b/test/buffer-diff.c
deleted file mode 100644
index ade0cc800..000000000
--- a/test/buffer-diff.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/* 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> */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <errno.h>
-#include <string.h>
-#include <pixman.h>
-
-#include "cairo-test.h"
-
-#include "buffer-diff.h"
-#include "read-png.h"
-#include "write-png.h"
-#include "xmalloc.h"
-
-static void
-xunlink (const char *pathname)
-{
- if (unlink (pathname) < 0 && errno != ENOENT) {
- cairo_test_log (" Error: Cannot remove %s: %s\n",
- pathname, strerror (errno));
- exit (1);
- }
-}
-
-/* This function should be rewritten to compare all formats supported by
- * cairo_format_t instead of taking a mask as a parameter.
- */
-static int
-buffer_diff_core (unsigned char *_buf_a,
- unsigned char *_buf_b,
- unsigned char *_buf_diff,
- int width,
- int height,
- int stride_a,
- int stride_b,
- int stride_diff,
- pixman_bits_t mask)
-{
- int x, y;
- pixman_bits_t *row_a, *row_b, *row;
- int pixels_changed = 0;
- pixman_bits_t *buf_a = (pixman_bits_t*)_buf_a;
- pixman_bits_t *buf_b = (pixman_bits_t*)_buf_b;
- pixman_bits_t *buf_diff = (pixman_bits_t*)_buf_diff;
-
- stride_a /= sizeof(pixman_bits_t);
- stride_b /= sizeof(pixman_bits_t);
- stride_diff /= sizeof(pixman_bits_t);
- for (y = 0; y < height; y++)
- {
- row_a = buf_a + y * stride_a;
- row_b = buf_b + y * stride_b;
- row = buf_diff + y * stride_diff;
- for (x = 0; x < width; x++)
- {
- /* check if the pixels are the same */
- if ((row_a[x] & mask) != (row_b[x] & mask)) {
- int channel;
- pixman_bits_t diff_pixel = 0;
-
- /* calculate a difference value for all 4 channels */
- for (channel = 0; channel < 4; channel++) {
- int value_a = (row_a[x] >> (channel*8)) & 0xff;
- int value_b = (row_b[x] >> (channel*8)) & 0xff;
- unsigned int diff;
- diff = abs (value_a - value_b);
- diff *= 4; /* emphasize */
- if (diff)
- diff += 128; /* make sure it's visible */
- if (diff > 255)
- diff = 255;
- diff_pixel |= diff << (channel*8);
- }
-
- pixels_changed++;
- row[x] = diff_pixel;
- } else {
- row[x] = 0;
- }
- row[x] |= 0xff000000; /* Set ALPHA to 100% (opaque) */
- }
- }
-
- return pixels_changed;
-}
-
-int
-buffer_diff (unsigned char *buf_a,
- unsigned char *buf_b,
- unsigned char *buf_diff,
- int width,
- int height,
- int stride_a,
- int stride_b,
- int stride_diff)
-{
- return buffer_diff_core(buf_a, buf_b, buf_diff,
- width, height, stride_a, stride_b, stride_diff, 0xffffffff);
-}
-
-int
-buffer_diff_noalpha (unsigned char *buf_a,
- unsigned char *buf_b,
- unsigned char *buf_diff,
- int width,
- int height,
- int stride_a,
- int stride_b,
- int stride_diff)
-{
- return buffer_diff_core(buf_a, buf_b, buf_diff,
- width, height, stride_a, stride_b, stride_diff, 0x00ffffff);
-}
-
-/* Image comparison code courtesy of Richard Worth <richard@theworths.org>
- * Returns number of pixels changed, (or -1 on error).
- * Also saves a "diff" image intended to visually show where the
- * images differ.
- */
-int
-image_diff (const char *filename_a,
- const char *filename_b,
- const char *filename_diff,
- int ax,
- int ay,
- int bx,
- int by)
-{
- int pixels_changed;
- unsigned int width_a, height_a, stride_a;
- unsigned int width_b, height_b, stride_b;
- unsigned int stride_diff;
- unsigned char *buf_a, *buf_b, *buf_diff;
- read_png_status_t status;
-
- status = read_png_argb32 (filename_a, &buf_a, &width_a, &height_a, &stride_a);
- if (status)
- return -1;
-
- status = read_png_argb32 (filename_b, &buf_b, &width_b, &height_b, &stride_b);
- if (status) {
- free (buf_a);
- return -1;
- }
-
- width_a -= ax;
- height_a -= ay;
- width_b -= bx;
- height_b -= by;
-
- if (width_a != width_b ||
- height_a != height_b)
- {
- cairo_test_log ("Error: Image size mismatch: (%dx%d@%d) vs. (%dx%d@%d)\n"
- " for %s vs. %s\n",
- width_a, height_a, stride_a,
- width_b, height_b, stride_b,
- filename_a, filename_b);
- free (buf_a);
- free (buf_b);
- return -1;
- }
-
- stride_diff = 4 * width_a;
- buf_diff = xcalloc (stride_diff * height_a, 1);
-
- pixels_changed = buffer_diff (buf_a + (ay * stride_a) + ax * 4,
- buf_b + (by * stride_b) + by * 4,
- buf_diff,
- width_a, height_a,
- stride_a, stride_b, stride_diff);
-
- if (pixels_changed) {
- FILE *png_file;
- if (filename_diff)
- png_file = fopen (filename_diff, "wb");
- else
- png_file = stdout;
- write_png_argb32 (buf_diff, png_file, width_a, height_a, stride_diff);
- if (png_file != stdout)
- fclose (png_file);
- } else {
- if (filename_diff)
- xunlink (filename_diff);
- }
-
- free (buf_a);
- free (buf_b);
- free (buf_diff);
-
- return pixels_changed;
-}
-
-/* Like image_diff, but first "flatten" the contents of filename_b by
- * blending over white.
- *
- * Yes, this is an ugly copy-and-paste of another function. I'm doing
- * this for two reasons:
- *
- * 1) I want to rewrite all of the image_diff interfaces anyway
- * (should use cairo_image_surface_create_from_png, should save
- * loaded buffers for re-use).
- *
- * 2) There is a second reason no more.
- */
-int
-image_diff_flattened (const char *filename_a,
- const char *filename_b,
- const char *filename_diff,
- int ax,
- int ay,
- int bx,
- int by)
-{
- int pixels_changed;
- unsigned int width_a, height_a, stride_a;
- unsigned int width_b, height_b, stride_b;
- unsigned char *buf_a, *buf_b, *buf_diff;
- unsigned char *a_flat, *b_flat;
- cairo_surface_t *buf_a_surface, *a_flat_surface;
- cairo_surface_t *buf_b_surface, *b_flat_surface;
- cairo_t *cr;
- read_png_status_t status;
-
- status = read_png_argb32 (filename_a, &buf_a, &width_a, &height_a, &stride_a);
- if (status)
- return -1;
-
- status = read_png_argb32 (filename_b, &buf_b, &width_b, &height_b, &stride_b);
- if (status) {
- free (buf_a);
- return -1;
- }
-
- width_a -= ax;
- height_a -= ay;
- width_b -= bx;
- height_b -= by;
-
- if (width_a != width_b ||
- height_a != height_b)
- {
- cairo_test_log ("Error: Image size mismatch: (%dx%d@%d) vs. (%dx%d@%d)\n"
- " for %s vs. %s\n",
- width_a, height_a, stride_a,
- width_b, height_b, stride_b,
- filename_a, filename_b);
- free (buf_a);
- free (buf_b);
- return -1;
- }
-
- buf_a_surface = cairo_image_surface_create_for_data (buf_a,
- CAIRO_FORMAT_ARGB32,
- width_a + ax, height_a + ay,
- stride_a);
- buf_b_surface = cairo_image_surface_create_for_data (buf_b,
- CAIRO_FORMAT_ARGB32,
- width_b + bx, height_b + by,
- stride_b);
-
- buf_diff = xcalloc (stride_a * height_a, 1);
-
- a_flat = xcalloc (stride_a * height_a, 1);
- b_flat = xcalloc (stride_b * height_b, 1);
-
- a_flat_surface = cairo_image_surface_create_for_data (a_flat,
- CAIRO_FORMAT_ARGB32,
- width_a, height_a,
- stride_a);
- cairo_surface_set_device_offset (a_flat_surface, -ax, -ay);
- b_flat_surface = cairo_image_surface_create_for_data (b_flat,
- CAIRO_FORMAT_ARGB32,
- width_b, height_b,
- stride_b);
- cairo_surface_set_device_offset (b_flat_surface, -bx, -by);
-
- cr = cairo_create (a_flat_surface);
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_paint (cr);
- cairo_set_source_surface (cr, buf_a_surface, 0, 0);
- cairo_paint (cr);
- cairo_destroy (cr);
- cairo_surface_destroy (a_flat_surface);
- cairo_surface_destroy (buf_a_surface);
-
- cr = cairo_create (b_flat_surface);
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_paint (cr);
- cairo_set_source_surface (cr, buf_b_surface, 0, 0);
- cairo_paint (cr);
- cairo_destroy (cr);
- cairo_surface_destroy (b_flat_surface);
- cairo_surface_destroy (buf_b_surface);
-
- pixels_changed = buffer_diff (a_flat,
- b_flat,
- buf_diff,
- width_a, height_a,
- stride_a, stride_b, stride_a);
-
- if (pixels_changed) {
- FILE *png_file = fopen (filename_diff, "wb");
- write_png_argb32 (buf_diff, png_file, width_a, height_a, stride_a);
- fclose (png_file);
- } else {
- xunlink (filename_diff);
- }
-
- free (buf_a);
- free (buf_b);
- free (a_flat);
- free (b_flat);
- free (buf_diff);
-
- return pixels_changed;
-}