[cairo] [PATCH 1/2] buffer_diff rewrite
Jeff Muizelaar
jeff at infidigm.net
Thu Aug 4 19:13:10 PDT 2005
The following patch replaces buffer_diff with buffer_diff_core.
buffer_diff_core is a rewrite of the original buffer_diff in a endian
safe maner and with a comparison mask parameter.
The patch also creates two wrappers around the new buffer_diff_core
function. buffer_diff, which is the same as the old buffer_diff function
and buffer_diff_noalpha which ignores the alpha channel when comparing.
I also changed the api documentation to reflect the fact that
buffer_diff never returns -1 on error.
Index: test/buffer-diff.c
===================================================================
RCS file: /cvs/cairo/cairo/test/buffer-diff.c,v
retrieving revision 1.6
diff -u -r1.6 buffer-diff.c
--- test/buffer-diff.c 15 Jul 2005 17:39:59 -0000 1.6
+++ test/buffer-diff.c 5 Aug 2005 01:51:10 -0000
@@ -27,6 +27,7 @@
#include <unistd.h>
#include <errno.h>
#include <string.h>
+#include <pixman.h>
#include "cairo-test.h"
@@ -45,18 +46,23 @@
}
}
-int
-buffer_diff (unsigned char *buf_a,
- unsigned char *buf_b,
- unsigned char *buf_diff,
- int width,
- int height,
- int stride)
+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;
@@ -64,33 +70,54 @@
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 <richard at theworths.org>
* Returns number of pixels changed, (or -1 on error).
* Also saves a "diff" image intended to visually show where the
Index: test/buffer-diff.h
===================================================================
RCS file: /cvs/cairo/cairo/test/buffer-diff.h,v
retrieving revision 1.3
diff -u -r1.3 buffer-diff.h
--- test/buffer-diff.h 27 Apr 2005 20:33:25 -0000 1.3
+++ test/buffer-diff.h 5 Aug 2005 01:51:10 -0000
@@ -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 @@
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.
More information about the cairo
mailing list