add the hardinvertall filter
authorTony Cook <tony@develop=help.com>
Tue, 3 Aug 2010 12:16:10 +0000 (12:16 +0000)
committerTony Cook <tony@develop=help.com>
Tue, 3 Aug 2010 12:16:10 +0000 (12:16 +0000)
Changes
Imager.pm
Imager.xs
filters.im
imager.h
lib/Imager/Filters.pod
t/t61filters.t

diff --git a/Changes b/Changes
index c921375..5d11352 100644 (file)
--- a/Changes
+++ b/Changes
@@ -22,6 +22,9 @@ Bugs:
  - update the documentation of hardinvert to match the change in 0.62.
    https://rt.cpan.org/Ticket/Display.html?id=59785
 
+ - added hardinvertall filter which also inverts the alpha channel
+   (sorry for the mess)
+
 Imager 0.75 - 20 Jun 2010
 ===========
 
index e610869..c0fc391 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -225,6 +225,13 @@ BEGIN {
                         callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
                        };
 
+  $filters{hardinvertall} =
+    {
+     callseq => ['image'],
+     defaults => { },
+     callsub => sub { my %hsh=@_; i_hardinvertall($hsh{image}); }
+    };
+
   $filters{autolevels} ={
                         callseq => ['image','lsat','usat','skew'],
                         defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
@@ -4417,7 +4424,8 @@ hatch fills - L<Imager::Fill/"Hatched fills">
 
 ICO files - L<Imager::Files/"ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)">
 
-invert image - L<Imager::Filters/hardinvert>
+invert image - L<Imager::Filters/hardinvert>,
+L<Imager::Filters/hardinvertall>
 
 JPEG - L<Imager::Files/"JPEG">
 
index 22395eb..d5e898e 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -3290,6 +3290,10 @@ void
 i_hardinvert(im)
     Imager::ImgRaw     im
 
+void
+i_hardinvertall(im)
+    Imager::ImgRaw     im
+
 void
 i_noise(im,amount,type)
     Imager::ImgRaw     im
index e4ebf5d..b27514e 100644 (file)
@@ -14,8 +14,9 @@ filters.im - implements filters that operate on images
   
   i_contrast(im, 0.8);
   i_hardinvert(im);
+  i_hardinvertall(im);
   i_unsharp_mask(im, 2.0, 1.0);
-  // and more
+  ... and more
 
 =head1 DESCRIPTION
 
@@ -94,21 +95,11 @@ i_contrast(i_img *im, float intensity) {
 }
 
 
-/* 
-=item i_hardinvert(im)
-
-Inverts the pixel values of the input image.
-
-  im        - image object
-
-=cut
-*/
-
-void
-i_hardinvert(i_img *im) {
+static int
+s_hardinvert_low(i_img *im, int all) {
   int x, y;
   int ch;
-  int color_channels = i_img_color_channels(im);
+  int invert_channels = all ? im->channels : i_img_color_channels(im);
 
   mm_log((1,"i_hardinvert(im %p)\n", im));
   
@@ -122,7 +113,7 @@ i_hardinvert(i_img *im) {
     IM_GLIN(im, 0, im->xsize, y, row);
     entry = row;
     for(x = 0; x < im->xsize; x++) {
-      for(ch = 0; ch < color_channels; ch++) {
+      for(ch = 0; ch < invert_channels; ch++) {
        entry->channel[ch] = IM_SAMPLE_MAX - entry->channel[ch];
       }
       ++entry;
@@ -131,9 +122,39 @@ i_hardinvert(i_img *im) {
   }  
   myfree(row);
 #/code
+
+  return 1;
+}
+
+/* 
+=item i_hardinvert(im)
+
+Inverts the color channels of the input image.
+
+  im        - image object
+
+=cut
+*/
+
+void
+i_hardinvert(i_img *im) {
+  s_hardinvert_low(im, 0);
 }
 
+/* 
+=item i_hardinvertall(im)
+
+Inverts all channels of the input image.
 
+  im        - image object
+
+=cut
+*/
+
+void
+i_hardinvertall(i_img *im) {
+  s_hardinvert_low(im, 1);
+}
 
 /*
 =item i_noise(im, amount, type)
index be47dab..ec508c4 100644 (file)
--- a/imager.h
+++ b/imager.h
@@ -463,6 +463,7 @@ i_img * i_transform2(int width, int height, int channels,
 
 void i_contrast(i_img *im, float intensity);
 void i_hardinvert(i_img *im);
+void i_hardinvertall(i_img *im);
 void i_noise(i_img *im, float amount, unsigned char type);
 void i_bumpmap(i_img *im,i_img *bump,int channel,int light_x,int light_y,int strength);
 void i_bumpmap_complex(i_img *im, i_img *bump, int channel, int tx, int ty, float Lx, float Ly, 
index 79b7d4c..cdff7d1 100644 (file)
@@ -96,6 +96,8 @@ that comes with the module source.
 
   hardinvert
 
+  hardinvertall
+
   mosaic          size         20
 
   noise           amount       3
@@ -436,6 +438,7 @@ for Euclidean squared, and 2 for Manhattan distance.
                colors=>[ qw(red blue green) ]);
 
 =item C<hardinvert>
+X<filters, hardinvert>X<hardinvert>
 
 inverts the image, black to white, white to black.  All color channels
 are inverted, excluding the alpha channel if any.
@@ -443,6 +446,15 @@ are inverted, excluding the alpha channel if any.
   $img->filter(type=>"hardinvert")
     or die $img->errstr;
 
+=item C<hardinvertall>
+X<filters, hardinvertall>X<hardinvertall>
+
+inverts the image, black to white, white to black.  All channels are
+inverted, including the alpha channel if any.
+
+  $img->filter(type=>"hardinvertall")
+    or die $img->errstr;
+
 =item C<mosaic>
 
 produces averaged tiles of the given C<size>.
index fc76b04..d3e53df 100644 (file)
@@ -1,9 +1,9 @@
 #!perl -w
 use strict;
 use Imager qw(:handy);
-use Test::More tests => 79;
+use Test::More tests => 91;
 Imager::init_log("testout/t61filters.log", 1);
-use Imager::Test qw(is_image_similar test_image is_image);
+use Imager::Test qw(is_image_similar test_image is_image is_color4 is_fcolor4);
 # meant for testing the filters themselves
 
 my $imbase = test_image();
@@ -64,6 +64,36 @@ test($imbase, {type=>'mosaic', size=>8}, 'testout/t61_mosaic.ppm');
 
 test($imbase, {type=>'hardinvert'}, 'testout/t61_hardinvert.ppm');
 
+{ # invert - 8 bit
+  my $im = Imager->new(xsize => 1, ysize => 1, channels => 4);
+  ok($im, "make test image for invert test");
+  ok($im->setpixel(x => 0, y => 0, color => "000010C0"),
+     "set a test pixel");
+  my $copy = $im->copy;
+  ok($im->filter(type => "hardinvert"), "hardinvert it");
+  is_color4($im->getpixel(x => 0, y => 0), 255, 255, 0xEF, 0xC0,
+           "check only colour inverted");
+  ok($copy->filter(type => "hardinvertall"), "hardinvertall copy");
+  is_color4($copy->getpixel(x => 0, y => 0), 255, 255, 0xEF, 0x3f,
+           "check all inverted");
+}
+
+{ # invert - double image
+  my $im = Imager->new(xsize => 1, ysize => 1, channels => 4, bits => "double");
+  ok($im, "make double test image for invert test");
+  ok($im->setpixel(x => 0, y => 0, color => Imager::Color::Float->new(0, 0, 0.125, 0.75)),
+     "set a test pixel");
+  my $copy = $im->copy;
+  ok($im->filter(type => "hardinvert"), "hardinvert it");
+  is_fcolor4($im->getpixel(x => 0, y => 0, type => "double"),
+            1.0, 1.0, 0.875, 0.75, 1e-5,
+            "check only colour inverted");
+  ok($copy->filter(type => "hardinvertall"), "hardinvertall copy");
+  is_fcolor4($copy->getpixel(x => 0, y => 0, type =>"double"),
+            1.0, 1.0, 0.875, 0.25, 1e-5,
+            "check all inverted");
+}
+
 test($imbase, {type=>'noise'}, 'testout/t61_noise.ppm');
 
 test($imbase, {type=>'radnoise'}, 'testout/t61_radnoise.ppm');