[cairo-commit] 2 commits - test/buffer-diff.c test/buffer-diff.h test/pdiff test/xlib-surface.c

Carl Worth cworth at kemper.freedesktop.org
Tue Dec 12 04:22:12 PST 2006


 test/buffer-diff.c    |  103 +++++++++++++++++++++++++++++----------------
 test/buffer-diff.h    |    8 ---
 test/pdiff/Metric.cpp |  112 ++++++++++++++++++++++++++++++++------------------
 test/xlib-surface.c   |    4 -
 4 files changed, 139 insertions(+), 88 deletions(-)

New commits:
diff-tree 41e01d95edd7eb573a8b79acd0ab2b9de8cdab40 (from b50b8db6d7d3d0a887ee18ad5e8e0455ed794429)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Dec 12 03:13:38 2006 -0800

    pdiff: Factor out a comparison function that doesn't read the 'args' structure
    
    This is one small step in "libifying" pdiff which will make it
    easier to share this code inside cairo's test suite.

diff --git a/test/pdiff/Metric.cpp b/test/pdiff/Metric.cpp
index 58d67c7..7974fa5 100644
--- a/test/pdiff/Metric.cpp
+++ b/test/pdiff/Metric.cpp
@@ -122,6 +122,13 @@ void XYZToLAB(float x, float y, float z,
 	B = 200.0f * (f[1] - f[2]);
 }
 
+int Yee_Compare_Images(RGBAImage *image_a,
+		       RGBAImage *image_b,
+		       float gamma,
+		       float luminance,
+		       float field_of_view,
+		       bool verbose);
+
 bool Yee_Compare(CompareArgs &args)
 {
 	if ((args.ImgA->Get_Width() != args.ImgB->Get_Width()) ||
@@ -130,7 +137,7 @@ bool Yee_Compare(CompareArgs &args)
 		return false;
 	}
 	
-	unsigned int i, dim;
+	unsigned int i, dim, pixels_failed;
 	dim = args.ImgA->Get_Width() * args.ImgA->Get_Height();
 	bool identical = true;
 	for (i = 0; i < dim; i++) {
@@ -143,7 +150,49 @@ bool Yee_Compare(CompareArgs &args)
 		args.ErrorStr = "Images are binary identical\n";
 		return true;
 	}
+
+	pixels_failed = Yee_Compare_Images (args.ImgA, args.ImgB,
+					    args.Gamma, args.Luminance,
+					    args.FieldOfView, args.Verbose);
+
+	if (pixels_failed < args.ThresholdPixels) {
+		args.ErrorStr = "Images are perceptually indistinguishable\n";
+		return true;
+	}
 	
+	char different[100];
+	sprintf(different, "%d pixels are different\n", pixels_failed);
+
+	args.ErrorStr = "Images are visibly different\n";
+	args.ErrorStr += different;
+
+	if (args.ImgDiff) {
+#if IMAGE_DIFF_CODE_ENABLED
+		if (args.ImgDiff->WritePPM()) {
+			args.ErrorStr += "Wrote difference image to ";
+			args.ErrorStr+= args.ImgDiff->Get_Name();
+			args.ErrorStr += "\n";
+		} else {
+			args.ErrorStr += "Could not write difference image to ";
+			args.ErrorStr+= args.ImgDiff->Get_Name();
+			args.ErrorStr += "\n";
+		}
+#endif
+		args.ErrorStr += "Generation of image \"difference\" is currently disabled\n";
+	}
+	return false;
+}
+
+int Yee_Compare_Images(RGBAImage *image_a,
+		       RGBAImage *image_b,
+		       float gamma,
+		       float luminance,
+		       float field_of_view,
+		       bool verbose)
+{
+	unsigned int i, dim;
+	dim = image_a->Get_Width() * image_a->Get_Height();
+
 	// assuming colorspaces are in Adobe RGB (1998) convert to XYZ
 	float *aX = new float[dim];
 	float *aY = new float[dim];
@@ -159,39 +208,41 @@ bool Yee_Compare(CompareArgs &args)
 	float *aB = new float[dim];
 	float *bB = new float[dim];
 
-	if (args.Verbose) printf("Converting RGB to XYZ\n");
+	if (verbose) printf("Converting RGB to XYZ\n");
 	
 	unsigned int x, y, w, h;
-	w = args.ImgA->Get_Width();
-	h = args.ImgA->Get_Height();
+	w = image_a->Get_Width();
+	h = image_a->Get_Height();
 	for (y = 0; y < h; y++) {
 		for (x = 0; x < w; x++) {
 			float r, g, b, l;
 			i = x + y * w;
-			r = powf(args.ImgA->Get_Red(i) / 255.0f, args.Gamma);
-			g = powf(args.ImgA->Get_Green(i) / 255.0f, args.Gamma);
-			b = powf(args.ImgA->Get_Blue(i) / 255.0f, args.Gamma);						
-			AdobeRGBToXYZ(r,g,b,aX[i],aY[i],aZ[i]);			
+			r = powf(image_a->Get_Red(i) / 255.0f, gamma);
+			g = powf(image_a->Get_Green(i) / 255.0f, gamma);
+			b = powf(image_a->Get_Blue(i) / 255.0f, gamma);
+
+			AdobeRGBToXYZ(r,g,b,aX[i],aY[i],aZ[i]);
 			XYZToLAB(aX[i], aY[i], aZ[i], l, aA[i], aB[i]);
-			r = powf(args.ImgB->Get_Red(i) / 255.0f, args.Gamma);
-			g = powf(args.ImgB->Get_Green(i) / 255.0f, args.Gamma);
-			b = powf(args.ImgB->Get_Blue(i) / 255.0f, args.Gamma);						
+			r = powf(image_b->Get_Red(i) / 255.0f, gamma);
+			g = powf(image_b->Get_Green(i) / 255.0f, gamma);
+			b = powf(image_b->Get_Blue(i) / 255.0f, gamma);
+
 			AdobeRGBToXYZ(r,g,b,bX[i],bY[i],bZ[i]);
 			XYZToLAB(bX[i], bY[i], bZ[i], l, bA[i], bB[i]);
-			aLum[i] = aY[i] * args.Luminance;
-			bLum[i] = bY[i] * args.Luminance;
+			aLum[i] = aY[i] * luminance;
+			bLum[i] = bY[i] * luminance;
 		}
 	}
 	
-	if (args.Verbose) printf("Constructing Laplacian Pyramids\n");
+	if (verbose) printf("Constructing Laplacian Pyramids\n");
 	
 	LPyramid *la = new LPyramid(aLum, w, h);
 	LPyramid *lb = new LPyramid(bLum, w, h);
 	
-	float num_one_degree_pixels = (float) (2 * tan( args.FieldOfView * 0.5 * M_PI / 180) * 180 / M_PI);
+	float num_one_degree_pixels = (float) (2 * tan(field_of_view * 0.5 * M_PI / 180) * 180 / M_PI);
 	float pixels_per_degree = w / num_one_degree_pixels;
 	
-	if (args.Verbose) printf("Performing test\n");
+	if (verbose) printf("Performing test\n");
 	
 	float num_pixels = 1;
 	unsigned int adaptation_level = 0;
@@ -262,8 +313,10 @@ bool Yee_Compare(CompareArgs &args)
 				pass = false;
 			}
 		}
-		if (!pass) {
+		if (!pass)
 			pixels_failed++;
+#if IMAGE_DIFF_ENABLED
+		if (!pass) {
 			if (args.ImgDiff) {
 				args.ImgDiff->Set(255, 0, 0, 255, index);
 			}
@@ -272,6 +325,7 @@ bool Yee_Compare(CompareArgs &args)
 				args.ImgDiff->Set(0, 0, 0, 255, index);
 			}
 		}
+#endif
 	  }
 	}
 	
@@ -289,28 +343,6 @@ bool Yee_Compare(CompareArgs &args)
 	if (bA) delete bA;
 	if (aB) delete aB;
 	if (bB) delete bB;
-	
-	if (pixels_failed < args.ThresholdPixels) {
-		args.ErrorStr = "Images are perceptually indistinguishable\n";
-		return true;
-	}
-	
-	char different[100];
-	sprintf(different, "%d pixels are different\n", pixels_failed);
 
-	args.ErrorStr = "Images are visibly different\n";
-	args.ErrorStr += different;
-	
-	if (args.ImgDiff) {
-		if (args.ImgDiff->WritePPM()) {
-			args.ErrorStr += "Wrote difference image to ";
-			args.ErrorStr+= args.ImgDiff->Get_Name();
-			args.ErrorStr += "\n";
-		} else {
-			args.ErrorStr += "Could not write difference image to ";
-			args.ErrorStr+= args.ImgDiff->Get_Name();
-			args.ErrorStr += "\n";
-		}
-	}
-	return false;
+	return pixels_failed;
 }
diff-tree b50b8db6d7d3d0a887ee18ad5e8e0455ed794429 (from 1781e6018c17909311295a9cc74b70500c6b4d0a)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Dec 12 02:17:19 2006 -0800

    test: Simplify buffer_diff by handling device offset in advance
    
    In a manner similar to flattening in advance, we now extract the sub-
    surface of interest (when testing with device offsets) before calling
    into the buffer_diff functions. This allows these functions to accept
    a single stride value once again instead of one for each of the three
    images.

diff --git a/test/buffer-diff.c b/test/buffer-diff.c
index 1a51ea9..819ba16 100644
--- a/test/buffer-diff.c
+++ b/test/buffer-diff.c
@@ -64,9 +64,7 @@ buffer_diff_core (unsigned char *_buf_a,
 		  unsigned char *_buf_diff,
 		  int		width,
 		  int		height,
-		  int		stride_a,
-		  int		stride_b,
-		  int		stride_diff,
+		  int		stride,
 		  pixman_bits_t mask,
 		  buffer_diff_result_t *result_ret)
 {
@@ -77,14 +75,12 @@ buffer_diff_core (unsigned char *_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);
+    stride /= 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;
+	row_a = buf_a + y * stride;
+	row_b = buf_b + y * stride;
+	row = buf_diff + y * stride;
 	for (x = 0; x < width; x++)
 	{
 	    /* check if the pixels are the same */
@@ -126,13 +122,11 @@ buffer_diff (unsigned char *buf_a,
 	     unsigned char *buf_diff,
 	     int	   width,
 	     int	   height,
-	     int	   stride_a,
-	     int	   stride_b,
-	     int	   stride_diff,
+	     int	   stride,
 	     buffer_diff_result_t *result)
 {
     buffer_diff_core(buf_a, buf_b, buf_diff,
-		     width, height, stride_a, stride_b, stride_diff, 0xffffffff,
+		     width, height, stride, 0xffffffff,
 		     result);
 }
 
@@ -142,13 +136,11 @@ buffer_diff_noalpha (unsigned char *buf_
 		     unsigned char *buf_diff,
 		     int	   width,
 		     int	   height,
-		     int	   stride_a,
-		     int	   stride_b,
-		     int	   stride_diff,
+		     int	   stride,
 		     buffer_diff_result_t *result)
 {
     buffer_diff_core(buf_a, buf_b, buf_diff,
-		     width, height, stride_a, stride_b, stride_diff, 0x00ffffff,
+		     width, height, stride, 0x00ffffff,
 		     result);
 }
 
@@ -195,6 +187,35 @@ flatten_surface (cairo_surface_t **surfa
     *surface = flat;
 }
 
+/* Given an image surface, create a new surface that has the same
+ * contents as the sub-surface with its origin at x,y.
+ *
+ * The original surface will be destroyed.
+ */
+static void
+extract_sub_surface (cairo_surface_t **surface, int x, int y)
+{
+    cairo_surface_t *sub;
+    cairo_t *cr;
+
+    sub = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+				      cairo_image_surface_get_width (*surface) - x,
+				      cairo_image_surface_get_height (*surface) - y);
+
+    /* We don't use a device offset like flatten_surface. That's not
+     * for any important reason, (the results should be
+     * identical). This style just seemed more natural to me this
+     * time, so I'm leaving both here so I can look at both to see
+     * which I like better. */
+    cr = cairo_create (sub);
+    cairo_set_source_surface (cr, *surface, -x, -y);
+    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+    cairo_paint (cr);
+
+    cairo_surface_destroy (*surface);
+    *surface = sub;
+}
+
 /* 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
@@ -243,13 +264,32 @@ image_diff_core (const char *filename_a,
 	return status;
     }
 
-    width_a = cairo_image_surface_get_width (surface_a) - ax;
-    height_a = cairo_image_surface_get_height (surface_a) - ay;
-    width_b = cairo_image_surface_get_width (surface_b) - bx;
-    height_b = cairo_image_surface_get_height (surface_b) - by;
+    if (flatten) {
+	flatten_surface (&surface_a, ax, ay);
+	flatten_surface (&surface_b, bx, by);
+	ax = ay = bx = by = 0;
+    }
+
+    if (ax || ay) {
+	extract_sub_surface (&surface_a, ax, ay);
+	ax = ay = 0;
+    }
+
+    if (bx || by) {
+	extract_sub_surface (&surface_b, bx, by);
+	bx = by = 0;
+    }
+
+    width_a = cairo_image_surface_get_width (surface_a);
+    height_a = cairo_image_surface_get_height (surface_a);
+    stride_a = cairo_image_surface_get_stride (surface_a);
+    width_b = cairo_image_surface_get_width (surface_b);
+    height_b = cairo_image_surface_get_height (surface_b);
+    stride_b = cairo_image_surface_get_stride (surface_b);
 
     if (width_a  != width_b  ||
-	height_a != height_b)
+	height_a != height_b ||
+	stride_a != stride_b)
     {
 	cairo_test_log ("Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n"
 			"       for %s vs. %s\n",
@@ -261,26 +301,13 @@ image_diff_core (const char *filename_a,
 	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
     }
 
-    if (flatten) {
-	flatten_surface (&surface_a, ax, ay);
-	flatten_surface (&surface_b, bx, by);
-	ax = ay = bx = by = 0;
-    }
-
     surface_diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
 					       width_a, height_a);
 
-    stride_a = cairo_image_surface_get_stride (surface_a);
-    stride_b = cairo_image_surface_get_stride (surface_b);
-
-    buffer_diff (cairo_image_surface_get_data (surface_a)
-		 + (ay * stride_a) + ax * 4,
-		 cairo_image_surface_get_data (surface_b)
-		 + (by * stride_b) + by * 4,
+    buffer_diff (cairo_image_surface_get_data (surface_a),
+		 cairo_image_surface_get_data (surface_b),
 		 cairo_image_surface_get_data (surface_diff),
-		 width_a, height_a,
-		 stride_a, stride_b,
-		 cairo_image_surface_get_stride (surface_diff),
+		 width_a, height_a, stride_a,
 		 result);
 
     if (result->pixels_changed) {
diff --git a/test/buffer-diff.h b/test/buffer-diff.h
index bef42cf..d95c213 100644
--- a/test/buffer-diff.h
+++ b/test/buffer-diff.h
@@ -50,9 +50,7 @@ buffer_diff (unsigned char *buf_a,
 	     unsigned char *buf_diff,
 	     int	    width,
 	     int	    height,
-	     int	    stride_a,
-	     int	    stride_b,
-	     int	    stride_diff,
+	     int	    stride,
 	     buffer_diff_result_t *result);
 
 /* Compares two image buffers ignoring the alpha channel.
@@ -69,9 +67,7 @@ buffer_diff_noalpha (unsigned char *buf_
 		     unsigned char *buf_diff,
 		     int	    width,
 		     int	    height,
-		     int	    stride_a,
-		     int	    stride_b,
-		     int	    stride_diff,
+		     int	    stride,
 		     buffer_diff_result_t *result);
 
 /* Compares two image buffers ignoring the alpha channel. A return
diff --git a/test/xlib-surface.c b/test/xlib-surface.c
index ccde14c..44bea92 100644
--- a/test/xlib-surface.c
+++ b/test/xlib-surface.c
@@ -166,8 +166,6 @@ do_test (Display        *dpy,
 			     SIZE - OFFSCREEN_OFFSET,
 			     SIZE - OFFSCREEN_OFFSET,
 			     4 * SIZE,
-			     4 * SIZE,
-			     4 * SIZE,
 			     &result);
     } else {
 	buffer_diff_noalpha (reference_data,
@@ -176,8 +174,6 @@ do_test (Display        *dpy,
 			     SIZE,
 			     SIZE,
 			     4 * SIZE,
-			     4 * SIZE,
-			     4 * SIZE,
 			     &result);
     }
 


More information about the cairo-commit mailing list