fix for replacement fill producing the wrong colour
authorTony Cook <tony@develop=help.com>
Thu, 11 Mar 2010 05:59:44 +0000 (05:59 +0000)
committerTony Cook <tony@develop=help.com>
Thu, 11 Mar 2010 05:59:44 +0000 (05:59 +0000)
Changes
fills.c
render.im
t/t20fill.t

diff --git a/Changes b/Changes
index e03569d..969151f 100644 (file)
--- a/Changes
+++ b/Changes
@@ -6,6 +6,9 @@ Imager 0.73 - unreleased
  - implement outline circles, both anti-aliased and not
    https://rt.cpan.org/Ticket/Display.html?id=19755
 
+ - a combine => "none" fill to a 1 or 3 channel image would produce
+   the incorrect colour.
+
 Imager 0.72 - 09 Dec 2009
 ===========
 
diff --git a/fills.c b/fills.c
index 4298b64..fb6e410 100644 (file)
--- a/fills.c
+++ b/fills.c
@@ -938,7 +938,7 @@ static void
 fill_opacity(i_fill_t *fill, int x, int y, int width, int channels,
             i_color *data) {
   struct i_fill_opacity_t *f = (struct i_fill_opacity_t *)fill;
-  int alpha_chan = channels-1; /* channels is always 2 or 4 */
+  int alpha_chan = channels > 2 ? 3 : 1;
   i_color *datap = data;
   
   (f->other_fill->f_fill_with_color)(f->other_fill, x, y, width, channels, data);
@@ -957,7 +957,7 @@ static void
 fill_opacityf(i_fill_t *fill, int x, int y, int width, int channels,
            i_fcolor *data) {
   struct i_fill_opacity_t *f = (struct i_fill_opacity_t *)fill;
-  int alpha_chan = channels-1; /* channels is always 2 or 4 */
+  int alpha_chan = channels > 2 ? 3 : 1;
   i_fcolor *datap = data;
   
   (f->other_fill->f_fill_with_fcolor)(f->other_fill, x, y, width, channels, data);
index 41d66a4..44fef99 100644 (file)
--- a/render.im
+++ b/render.im
@@ -291,7 +291,7 @@ i_render_fill(i_render *r, int x, int y, int width, unsigned char const *src,
       }
     }
     else { /* if (src) */
-      IM_FILL_FILLER(fill)(fill, x, y, width, r->im->channels, r->IM_SUFFIX(line));
+      IM_FILL_FILLER(fill)(fill, x, y, width, fill_channels, r->IM_SUFFIX(line));
     }
   }
   IM_PLIN(im, x, x+width, y, r->IM_SUFFIX(line));
index 8e2bb21..1a680f5 100644 (file)
@@ -1,11 +1,11 @@
 #!perl -w
 use strict;
-use Test::More tests => 148;
+use Test::More tests => 153;
 
 use Imager ':handy';
 use Imager::Fill;
 use Imager::Color::Float;
-use Imager::Test qw(is_image is_color4 is_fcolor4);
+use Imager::Test qw(is_image is_color4 is_fcolor4 is_color3);
 use Config;
 
 Imager::init_log("testout/t20fill.log", 1);
@@ -498,20 +498,33 @@ SKIP:
     my $fill50 = Imager::Fill->new(type => "opacity", opacity => 0.5, other => $base_fill)
       or print "# ", Imager->errstr, "\n";
     ok($fill50, "make 50% alpha translation fill");
-    my $out = Imager->new(xsize => 10, ysize => 10, channels => 4);
-    $out->box(fill => $fill50);
-    is_color4($out->getpixel(x => 0, y => 0),
-             255, 0, 0, 16, "check alpha output");
-    is_color4($out->getpixel(x => 2, y => 1),
-             0, 255, 0, 64, "check alpha output");
-    $out->box(filled => 1, color => "000000");
-    is_color4($out->getpixel(x => 0, y => 0),
-             0, 0, 0, 255, "check after clear");
-    $out->box(fill => $fill50);
-    is_color4($out->getpixel(x => 4, y => 2),
-             16, 0, 0, 255, "check drawn against background");
-    is_color4($out->getpixel(x => 6, y => 3),
-             0, 64, 0, 255, "check drawn against background");
+
+    { # 4 channel image
+      my $out = Imager->new(xsize => 10, ysize => 10, channels => 4);
+      $out->box(fill => $fill50);
+      is_color4($out->getpixel(x => 0, y => 0),
+               255, 0, 0, 16, "check alpha output");
+      is_color4($out->getpixel(x => 2, y => 1),
+               0, 255, 0, 64, "check alpha output");
+      $out->box(filled => 1, color => "000000");
+      is_color4($out->getpixel(x => 0, y => 0),
+               0, 0, 0, 255, "check after clear");
+      $out->box(fill => $fill50);
+      is_color4($out->getpixel(x => 4, y => 2),
+               16, 0, 0, 255, "check drawn against background");
+      is_color4($out->getpixel(x => 6, y => 3),
+               0, 64, 0, 255, "check drawn against background");
+    }
+    { # 3 channel image
+      my $out = Imager->new(xsize => 10, ysize => 10, channels => 3);
+      $out->box(fill => $fill50);
+      is_color3($out->getpixel(x => 0, y => 0),
+               16, 0, 0, "check alpha output");
+      is_color3($out->getpixel(x => 2, y => 1),
+               0, 64, 0, "check alpha output");
+      is_color3($out->getpixel(x => 0, y => 1),
+               128, 128, 0, "check alpha output");
+    }
   }
   { # double/sample
     use Imager::Color::Float;
@@ -579,6 +592,22 @@ SKIP:
   ok(Imager::Fill->new(type => "opacity", other => { solid => "FF0000" }),
      "check we auto-create fills")
     or print "# ", Imager->errstr, "\n";
+
+  {
+    # fill with combine none was modifying the wrong channel for a
+    # no-alpha target image
+    my $fill = Imager::Fill->new(solid => "#FFF", combine => "none");
+    my $fill2 = Imager::Fill->new
+      (
+       type => "opacity", 
+       opacity => 0.5,
+       other => $fill
+      );
+    my $im = Imager->new(xsize => 1, ysize => 1);
+    ok($im->box(fill => $fill2), "fill with replacement opacity fill");
+    is_color3($im->getpixel(x => 0, y => 0), 255, 255, 255,
+             "check for correct colour");
+  }
 }
 
 sub color_close {