]> git.imager.perl.org - imager.git/commitdiff
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 c921375f69a0745e90020d7d769f3bd728dce811..5d11352755bcd0520c4c37329ec18f3ff3c47e27 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
 
  - 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
 ===========
 
 Imager 0.75 - 20 Jun 2010
 ===========
 
index e61086927243f109e3775244d35b5f5817d1db67..c0fc39127e82ce38afcc3c26ebde21040774eb61 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -225,6 +225,13 @@ BEGIN {
                         callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
                        };
 
                         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 },
   $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)">
 
 
 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">
 
 
 JPEG - L<Imager::Files/"JPEG">
 
index 22395eb09114176b2f3699219eed8fd37b4d4482..d5e898e52474c0e2b2b57a4641dafbe14156cda0 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -3290,6 +3290,10 @@ void
 i_hardinvert(im)
     Imager::ImgRaw     im
 
 i_hardinvert(im)
     Imager::ImgRaw     im
 
+void
+i_hardinvertall(im)
+    Imager::ImgRaw     im
+
 void
 i_noise(im,amount,type)
     Imager::ImgRaw     im
 void
 i_noise(im,amount,type)
     Imager::ImgRaw     im
index e4ebf5d992936412ac6d45324f54df278c80f1d9..b27514e0976a0caf14cabe9131bbd6131b215076 100644 (file)
@@ -14,8 +14,9 @@ filters.im - implements filters that operate on images
   
   i_contrast(im, 0.8);
   i_hardinvert(im);
   
   i_contrast(im, 0.8);
   i_hardinvert(im);
+  i_hardinvertall(im);
   i_unsharp_mask(im, 2.0, 1.0);
   i_unsharp_mask(im, 2.0, 1.0);
-  // and more
+  ... and more
 
 =head1 DESCRIPTION
 
 
 =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 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));
   
 
   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++) {
     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;
        entry->channel[ch] = IM_SAMPLE_MAX - entry->channel[ch];
       }
       ++entry;
@@ -131,9 +122,39 @@ i_hardinvert(i_img *im) {
   }  
   myfree(row);
 #/code
   }  
   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)
 
 /*
 =item i_noise(im, amount, type)
index be47dabb37ae64c91446521e5dc4e29ce13a5acf..ec508c4b11c16b0777c655393c879fc369dfb533 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_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, 
 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 79b7d4caf23912d94ae68bfcbd47b3f15017e88e..cdff7d1c03f973f830028f3bd51e7fa4382564bb 100644 (file)
@@ -96,6 +96,8 @@ that comes with the module source.
 
   hardinvert
 
 
   hardinvert
 
+  hardinvertall
+
   mosaic          size         20
 
   noise           amount       3
   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>
                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.
 
 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;
 
   $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>.
 =item C<mosaic>
 
 produces averaged tiles of the given C<size>.
index fc76b047c32d7d813638181281aff0d8f6168c6b..d3e53df6630c20a2eb382b0e93a01ee4602533d4 100644 (file)
@@ -1,9 +1,9 @@
 #!perl -w
 use strict;
 use Imager qw(:handy);
 #!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);
 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();
 # 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');
 
 
 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');
 test($imbase, {type=>'noise'}, 'testout/t61_noise.ppm');
 
 test($imbase, {type=>'radnoise'}, 'testout/t61_radnoise.ppm');