From 5f78feda5d9819f82ff99911b90cd09e228466a9 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 5 Aug 2005 11:15:04 +0000 Subject: [PATCH] rewrite buffer_diff to be endian safe and add a new fuction buffer_diff_noalpha --- ChangeLog | 7 ++++ test/buffer-diff.c | 83 +++++++++++++++++++++++++++++++--------------- test/buffer-diff.h | 14 +++++++- 3 files changed, 77 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd0152abc..3863d93e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-08-05 Jeff Muizelaar + + * test/buffer-diff.c: (buffer_diff_core), (buffer_diff), + (buffer_diff_noalpha): + * test/buffer-diff.h: rewrite buffer_diff to be endian safe + and add a new fuction buffer_diff_noalpha + 2005-08-05 Carl Worth * doc/public/cairo-sections.txt: Remove CAIRO_BEGIN_DECLS and diff --git a/test/buffer-diff.c b/test/buffer-diff.c index 8e0031b1f..78284efcd 100644 --- a/test/buffer-diff.c +++ b/test/buffer-diff.c @@ -33,6 +33,7 @@ #endif #include #include +#include #include "cairo-test.h" @@ -51,18 +52,27 @@ xunlink (const char *pathname) } } -int -buffer_diff (unsigned char *buf_a, - unsigned char *buf_b, - unsigned char *buf_diff, - int width, - int height, - int stride) + +/* 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, + pixman_bits_t mask) { int x, y; - unsigned char *row_a, *row_b, *row; + 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 /= sizeof(pixman_bits_t); for (y = 0; y < height; y++) { row_a = buf_a + y * stride; @@ -70,33 +80,54 @@ buffer_diff (unsigned char *buf_a, row = buf_diff + y * stride; for (x = 0; x < width; x++) { - int channel; - unsigned char value_a, value_b; - int pixel_differs = 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_differs = 1; - diff = value_a - value_b; - row[x * 4 + channel] = 128 + diff / 3.0; - } - if (pixel_differs) { + /* 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++) { + unsigned char value_a = (row_a[x] >> (channel*8)); + unsigned char value_b = (row_b[x] >> (channel*8)); + double diff; + diff = value_a - value_b; + diff_pixel |= (unsigned char)(128 + diff / 3.0) << (channel*8); + } + pixels_changed++; + row[x] = diff_pixel; } else { - row[x*4+0] = 0; - row[x*4+1] = 0; - row[x*4+2] = 0; + row[x] = 0; } - row[x * 4 + 3] = 0xff; /* Set ALPHA to 100% (opaque) */ + 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) +{ + return buffer_diff_core(buf_a, buf_b, buf_diff, width, height, stride, 0xffffffff); +} + +int +buffer_diff_noalpha (unsigned char *buf_a, + unsigned char *buf_b, + unsigned char *buf_diff, + int width, + int height, + int stride) +{ + return buffer_diff_core(buf_a, buf_b, buf_diff, width, height, stride, 0x00ffffff); +} + /* Image comparison code courtesy of Richard Worth * Returns number of pixels changed, (or -1 on error). * Also saves a "diff" image intended to visually show where the diff --git a/test/buffer-diff.h b/test/buffer-diff.h index a02834f3d..2734713a3 100644 --- a/test/buffer-diff.h +++ b/test/buffer-diff.h @@ -26,7 +26,7 @@ #ifndef BUFFER_DIFF_H #define BUFFER_DIFF_H -/* Returns number of pixels changed, (or -1 on error). +/* Returns number of pixels changed. * Also fills in a "diff" buffer intended to visually show where the * images differ. */ @@ -38,6 +38,18 @@ buffer_diff (unsigned char *buf_a, int height, int stride); +/* Returns number of pixels changed ignoring the alpha channel. + * Also fills in a "diff" buffer intended to visually show where the + * images differ. + */ +int +buffer_diff_noalpha (unsigned char *buf_a, + unsigned char *buf_b, + unsigned char *buf_diff, + int width, + int height, + int stride); + /* Returns number of pixels changed, (or -1 on error). * Also saves a "diff" image intended to visually show where the * images differ.