]> git.imager.perl.org - imager.git/commitdiff
add an internal i_img_samef() and adapt is_imaged() to use it
authorTony Cook <tony@develop-help.com>
Mon, 16 May 2011 12:44:09 +0000 (22:44 +1000)
committerTony Cook <tony@develop-help.com>
Mon, 16 May 2011 12:53:51 +0000 (22:53 +1000)
This makes the is_imaged() function more useful, since exact matching
on doubles is unlikely.

Imager.xs
image.c
imager.h
lib/Imager/Test.pm

index 6fef57e54788702ab01c97eb6317b7e8610c6f1f..8aa49d4d8dc3586a9afe41f55eb06c137aa33599 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -20,6 +20,7 @@ extern "C" {
 #include "regmach.h"
 #include "imextdef.h"
 #include "imextpltypes.h"
+#include <float.h>
 
 #if i_int_hlines_testing()
 #include "imageri.h"
@@ -954,6 +955,8 @@ static im_pl_ext_funcs im_perl_funcs =
 #define i_img_get_width(im) ((im)->xsize)
 #define i_img_get_height(im) ((im)->ysize)
 
+#define i_img_epsilonf() (DBL_EPSILON * 4)
+
 MODULE = Imager                PACKAGE = Imager::Color PREFIX = ICL_
 
 Imager::Color
@@ -2002,6 +2005,16 @@ i_img_diffd(im1,im2)
     Imager::ImgRaw     im1
     Imager::ImgRaw     im2
 
+int
+i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
+    Imager::ImgRaw    im1
+    Imager::ImgRaw    im2
+    double epsilon
+    const char *what
+
+double
+i_img_epsilonf()
+
 bool
 _is_color_object(sv)
        SV* sv
diff --git a/image.c b/image.c
index bf25b7d253b70e872e4858b337d2c7feab0acd8b..85a305e43d67f2e783d8b9edf4c92468e8543afa 100644 (file)
--- a/image.c
+++ b/image.c
@@ -1182,6 +1182,41 @@ i_img_diffd(i_img *im1,i_img *im2) {
   return tdiff;
 }
 
+int
+i_img_samef(i_img *im1,i_img *im2, double epsilon, char const *what) {
+  int x,y,ch,xb,yb,chb;
+  i_fcolor val1,val2;
+
+  if (what == NULL)
+    what = "(null)";
+
+  mm_log((1,"i_img_samef(im1 0x%x,im2 0x%x, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
+
+  xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
+  yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
+  chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
+
+  mm_log((1,"i_img_samef: xb=%d xy=%d chb=%d\n",xb,yb,chb));
+
+  for(y = 0; y < yb; y++) {
+    for(x = 0; x < xb; x++) {
+      i_gpixf(im1, x, y, &val1);
+      i_gpixf(im2, x, y, &val2);
+      
+      for(ch = 0; ch < chb; ch++) {
+       double sdiff = val1.channel[ch] - val2.channel[ch];
+       if (fabs(sdiff) > epsilon) {
+         mm_log((1,"i_img_samef <- different %g @(%d,%d)\n", sdiff, x, y));
+         return 0;
+       }
+      }
+    }
+  }
+  mm_log((1,"i_img_samef <- same\n"));
+
+  return 1;
+}
+
 /* just a tiny demo of haar wavelets */
 
 i_img*
index a803382fd6d443bd3649b2ee2b19c8e05efae575..5e9669e32d45062a9806cb6e8b857c083e0486e1 100644 (file)
--- a/imager.h
+++ b/imager.h
@@ -222,6 +222,7 @@ extern void i_map(i_img *im, unsigned char (*maps)[256], unsigned int mask);
 
 float i_img_diff   (i_img *im1,i_img *im2);
 double i_img_diffd(i_img *im1,i_img *im2);
+int i_img_samef(i_img *im1,i_img *im2, double epsilon, const char *what);
 
 /* font routines */
 
index c9d7f5070810528da1921e23af4fa522c1ca95aa..abc797932794cba533f185d9869badb4d7171351 100644 (file)
@@ -436,6 +436,11 @@ sub is_image($$$) {
 }
 
 sub is_imaged($$$) {
+  my $epsilon = Imager::i_img_epsilonf();
+  if (@_ > 3) {
+    ($epsilon) = splice @_, 2, 1;
+  }
+
   my ($left, $right, $comment) = @_;
 
   {
@@ -447,17 +452,17 @@ sub is_imaged($$$) {
 
   my $builder = Test::Builder->new;
 
-  my $diff = Imager::i_img_diffd($left->{IMG}, $right->{IMG});
-  if ($diff > 0) {
+  my $same = Imager::i_img_samef($left->{IMG}, $right->{IMG}, $epsilon, $comment);
+  if (!$same) {
     $builder->ok(0, $comment);
-    $builder->diag("image data difference: $diff");
-   
+    $builder->diag("images different");
+
     # find the first mismatch
   PIXELS:
     for my $y (0 .. $left->getheight()-1) {
       for my $x (0.. $left->getwidth()-1) {
-       my @lsamples = $left->getsamples(x => $x, y => $y, width => 1);
-       my @rsamples = $right->getsamples(x => $x, y => $y, width => 1);
+       my @lsamples = $left->getsamples(x => $x, y => $y, width => 1, type => "float");
+       my @rsamples = $right->getsamples(x => $x, y => $y, width => 1, type => "float");
        if ("@lsamples" ne "@rsamples") {
          $builder->diag("first mismatch at ($x, $y) - @lsamples vs @rsamples");
          last PIXELS;
@@ -732,8 +737,11 @@ not checked.  Equivalent to is_image_similar($im1, $im2, 0, $comment).
 
 =item is_imaged($im, $im2, $comment)
 
+=item is_imaged($im, $im2, $epsilon, $comment)
+
 Tests if the two images have the same content at the double/sample
-level.
+level.  C<$epsilon> defaults to the platform DBL_EPSILON multiplied by
+four.
 
 =item is_image_similar($im1, $im2, $maxdiff, $comment)