document the difference() method's mindist parameter, and debug it.
authorTony Cook <tony@develop=help.com>
Sat, 14 Apr 2007 00:31:38 +0000 (00:31 +0000)
committerTony Cook <tony@develop=help.com>
Sat, 14 Apr 2007 00:31:38 +0000 (00:31 +0000)
Changes
Imager.xs
filters.c
imager.h
lib/Imager/Filters.pod
t/t61filters.t

diff --git a/Changes b/Changes
index 3a69225..eaf0388 100644 (file)
--- a/Changes
+++ b/Changes
@@ -13,6 +13,8 @@ Bug fixes:
    fixed size when performing a gaussian blur
    http://rt.cpan.org/Ticket/Display.html?id=25645
 
+ - document the difference() method's mindist parameter, and debug it.
+
 Imager 0.56 - 1 Apr 2007
 ===========
 
index 45c9cc0..94c4325 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -3272,7 +3272,7 @@ Imager::ImgRaw
 i_diff_image(im, im2, mindist=0)
     Imager::ImgRaw     im
     Imager::ImgRaw     im2
-               int     mindist
+            double     mindist
 
 undef_int
 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
index f68a029..704ea2d 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -1316,7 +1316,7 @@ i_unsharp_mask(i_img *im, double stddev, double scale) {
 }
 
 /*
-=item i_diff_image(im1, im2, mindiff)
+=item i_diff_image(im1, im2, mindist)
 
 Creates a new image that is transparent, except where the pixel in im2
 is different from im1, where it is the pixel from im2.
@@ -1327,7 +1327,7 @@ The samples must differ by at least mindiff to be considered different.
 */
 
 i_img *
-i_diff_image(i_img *im1, i_img *im2, int mindiff) {
+i_diff_image(i_img *im1, i_img *im2, double mindist) {
   i_img *out;
   int outchans, diffchans;
   int xsize, ysize;
@@ -1352,6 +1352,7 @@ i_diff_image(i_img *im1, i_img *im2, int mindiff) {
     i_color *line2 = mymalloc(xsize * sizeof(*line1)); /* checked 17feb2005 tonyc */
     i_color empty;
     int x, y, ch;
+    int imindist = (int)mindist;
 
     for (ch = 0; ch < MAXCHANNELS; ++ch)
       empty.channel[ch] = 0;
@@ -1368,7 +1369,7 @@ i_diff_image(i_img *im1, i_img *im2, int mindiff) {
         int diff = 0;
         for (ch = 0; ch < diffchans; ++ch) {
           if (line1[x].channel[ch] != line2[x].channel[ch]
-              && abs(line1[x].channel[ch] - line2[x].channel[ch]) > mindiff) {
+              && abs(line1[x].channel[ch] - line2[x].channel[ch]) > imindist) {
             diff = 1;
             break;
           }
@@ -1386,7 +1387,7 @@ i_diff_image(i_img *im1, i_img *im2, int mindiff) {
     i_fcolor *line2 = mymalloc(xsize * sizeof(*line2)); /* checked 17feb2005 tonyc */
     i_fcolor empty;
     int x, y, ch;
-    double dist = mindiff / 255;
+    double dist = mindist / 255.0;
 
     for (ch = 0; ch < MAXCHANNELS; ++ch)
       empty.channel[ch] = 0;
@@ -1403,7 +1404,7 @@ i_diff_image(i_img *im1, i_img *im2, int mindiff) {
         int diff = 0;
         for (ch = 0; ch < diffchans; ++ch) {
           if (line1[x].channel[ch] != line2[x].channel[ch]
-              && abs(line1[x].channel[ch] - line2[x].channel[ch]) > dist) {
+              && fabs(line1[x].channel[ch] - line2[x].channel[ch]) > dist) {
             diff = 1;
             break;
           }
index eb3d92e..211c516 100644 (file)
--- a/imager.h
+++ b/imager.h
@@ -448,7 +448,7 @@ void i_radnoise(i_img *im,int xo,int yo,float rscale,float ascale);
 void i_turbnoise(i_img *im,float xo,float yo,float scale);
 void i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
 int i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
-i_img *i_diff_image(i_img *im, i_img *im2, int mindist);
+i_img *i_diff_image(i_img *im, i_img *im2, double mindist);
 int
 i_fountain(i_img *im, double xa, double ya, double xb, double yb, 
            i_fountain_type type, i_fountain_repeat repeat, 
index 9b792c2..326ffa1 100644 (file)
@@ -653,9 +653,28 @@ This can be used for debugging image differences ("Where are they
 different?"), and for optimizing animated GIFs.
 
 Note that $img and $other_img must have the same number of channels.
-The width and heigh of $diff will be the minimum of each of the width
+The width and height of $diff will be the minimum of each of the width
 and height of $img and $other_img.
 
+Parameters:
+
+=over
+
+=item *
+
+other - the other image object to compare against
+
+=item *
+
+mindist - the difference between corresponding samples must be greater
+than I<mindist> for the pixel to be considered different.  So a value
+of zero returns all different pixels, not all pixels.  Range: 0 to 255
+inclusive.  Default: 0.
+
+For large sample images this is scaled down to the range 0 .. 1.
+
+=back
+
 =back
 
 =head1 AUTHOR
index f04c7fe..c378d62 100644 (file)
@@ -1,12 +1,13 @@
 #!perl -w
 use strict;
 use Imager qw(:handy);
-use Test::More tests => 69;
+use Test::More tests => 73;
 Imager::init_log("testout/t61filters.log", 1);
-use Imager::Test qw(is_image_similar);
+use Imager::Test qw(is_image_similar test_image is_image);
 # meant for testing the filters themselves
-my $imbase = Imager->new;
-$imbase->open(file=>'testout/t104.ppm') or die;
+
+my $imbase = test_image();
+
 my $im_other = Imager->new(xsize=>150, ysize=>150);
 $im_other->box(xmin=>30, ymin=>60, xmax=>120, ymax=>90, filled=>1);
 
@@ -239,6 +240,51 @@ is($name, "test gradient", "check the name matches");
   test($imbase, { type => 'perl_test' }, 'testout/t61perl.ppm');
 }
 
+{ # check the difference method out
+  my $im1 = Imager->new(xsize => 3, ysize => 2);
+  $im1->box(filled => 1, color => '#FF0000');
+  my $im2 = $im1->copy;
+  $im1->setpixel(x => 1, 'y' => 0, color => '#FF00FF');
+  $im2->setpixel(x => 1, 'y' => 0, color => '#FF01FF');
+  $im1->setpixel(x => 2, 'y' => 0, color => '#FF00FF');
+  $im2->setpixel(x => 2, 'y' => 0, color => '#FF02FF');
+
+  my $diff1 = $im1->difference(other => $im2);
+  my $cmp1 = Imager->new(xsize => 3, ysize => 2, channels => 4);
+  $cmp1->setpixel(x => 1, 'y' => 0, color => '#FF01FF');
+  $cmp1->setpixel(x => 2, 'y' => 0, color => '#FF02FF');
+  is_image($diff1, $cmp1, "difference() - check image with mindist 0");
+
+  my $diff2 = $im1->difference(other => $im2, mindist => 1);
+  $diff2->write(file=>'foo.png');
+  my $cmp2 = Imager->new(xsize => 3, ysize => 2, channels => 4);
+  $cmp2->setpixel(x => 2, 'y' => 0, color => '#FF02FF');
+  is_image($diff2, $cmp2, "difference() - check image with mindist 1");
+}
+
+{
+  # and again with large samples
+  my $im1 = Imager->new(xsize => 3, ysize => 2, bits => 'double');
+  $im1->box(filled => 1, color => '#FF0000');
+  my $im2 = $im1->copy;
+  $im1->setpixel(x => 1, 'y' => 0, color => '#FF00FF');
+  $im2->setpixel(x => 1, 'y' => 0, color => '#FF01FF');
+  $im1->setpixel(x => 2, 'y' => 0, color => '#FF00FF');
+  $im2->setpixel(x => 2, 'y' => 0, color => '#FF02FF');
+
+  my $diff1 = $im1->difference(other => $im2);
+  my $cmp1 = Imager->new(xsize => 3, ysize => 2, channels => 4);
+  $cmp1->setpixel(x => 1, 'y' => 0, color => '#FF01FF');
+  $cmp1->setpixel(x => 2, 'y' => 0, color => '#FF02FF');
+  is_image($diff1, $cmp1, "difference() - check image with mindist 0 - large samples");
+
+  my $diff2 = $im1->difference(other => $im2, mindist => 1.1);
+  $diff2->write(file=>'foo.png');
+  my $cmp2 = Imager->new(xsize => 3, ysize => 2, channels => 4);
+  $cmp2->setpixel(x => 2, 'y' => 0, color => '#FF02FF');
+  is_image($diff2, $cmp2, "difference() - check image with mindist 1.1 - large samples");
+}
+
 sub test {
   my ($in, $params, $out) = @_;