#!perl -w
use strict;
-use lib 't';
-use Test::More tests => 38;
-BEGIN { use_ok(Imager => qw(:all :handy)); }
+use Test::More tests => 76;
+use Imager qw(:all :handy);
+use Imager::Test qw(is_image);
+
+-d "testout" or mkdir "testout";
init_log("testout/t69rubthru.log", 1);
is((Imager::i_get_pixel($gtarg, 30, 30)->rgba)[0], 128,
"check grey level at 30, 30");
-# an attempt rub a 4 channel image over 1 channel should fail
-ok(!i_rubthru($gtarg, $src, 10, 10, 0, 0, $src_width, $src_height),
- "check failure of 4 channel over 1 channel image");
-
# simple test for 16-bit/sample images
my $targ16 = Imager::i_img_16_new(100, 100, 3);
ok(i_rubthru($targ16, $src, 10, 10, 0, 0, $src_width, $src_height),
ok(color_cmp(Imager::i_get_pixel($ootarg->{IMG}, 30, 30), NC(128, 0, 0)) == 0,
"check pixel at 30, 30");
-# make sure we fail as expected
my $oogtarg = Imager->new(xsize=>100, ysize=>100, channels=>1);
-ok(!$oogtarg->rubthrough(src=>$oosrc), "check oo fails correctly");
-
-is($oogtarg->errstr,
- 'rubthru can only work where (dest, src) channels are (3,4), (4,4), (3,2), (4,2), (1,2) or (2,2)',
- "check error message");
{ # check empty image errors
my $empty = Imager->new;
{
# alpha source and target
- my $src = Imager->new(xsize => 10, ysize => 1, channels => 4);
- my $targ = Imager->new(xsize => 10, ysize => 2, channels => 4);
-
- # simple initialization
- $targ->setscanline('y' => 1, x => 1,
- pixels =>
- [
- NC(255, 128, 0, 255),
- NC(255, 128, 0, 128),
- NC(255, 128, 0, 0),
- NC(255, 128, 0, 255),
- NC(255, 128, 0, 128),
- NC(255, 128, 0, 0),
- NC(255, 128, 0, 255),
- NC(255, 128, 0, 128),
- NC(255, 128, 0, 0),
- ]);
- $src->setscanline('y' => 0,
- pixels =>
- [
- NC(0, 128, 255, 0),
- NC(0, 128, 255, 0),
- NC(0, 128, 255, 0),
- NC(0, 128, 255, 128),
- NC(0, 128, 255, 128),
- NC(0, 128, 255, 128),
- NC(0, 128, 255, 255),
- NC(0, 128, 255, 255),
- NC(0, 128, 255, 255),
- ]);
- ok($targ->rubthrough(src => $src,
- tx => 1, ty => 1), "do 4 on 4 rubthrough");
- iscolora($targ->getpixel(x => 1, y => 1), NC(255, 128, 0, 255),
- "check at zero source coverage on full targ coverage");
- iscolora($targ->getpixel(x => 2, y => 1), NC(255, 128, 0, 128),
- "check at zero source coverage on half targ coverage");
- iscolora($targ->getpixel(x => 3, y => 1), NC(255, 128, 0, 0),
- "check at zero source coverage on zero targ coverage");
- iscolora($targ->getpixel(x => 4, y => 1), NC(127, 128, 128, 255),
- "check at half source_coverage on full targ coverage");
- iscolora($targ->getpixel(x => 5, y => 1), NC(85, 128, 170, 191),
- "check at half source coverage on half targ coverage");
- iscolora($targ->getpixel(x => 6, y => 1), NC(0, 128, 255, 128),
- "check at half source coverage on zero targ coverage");
- iscolora($targ->getpixel(x => 7, y => 1), NC(0, 128, 255, 255),
- "check at full source_coverage on full targ coverage");
- iscolora($targ->getpixel(x => 8, y => 1), NC(0, 128, 255, 255),
- "check at full source coverage on half targ coverage");
- iscolora($targ->getpixel(x => 9, y => 1), NC(0, 128, 255, 255),
- "check at full source coverage on zero targ coverage");
+ for my $method (qw/rubthrough compose/) {
+
+ my $src = Imager->new(xsize => 10, ysize => 1, channels => 4);
+ my $targ = Imager->new(xsize => 10, ysize => 2, channels => 4);
+
+ # simple initialization
+ $targ->setscanline('y' => 1, x => 1,
+ pixels =>
+ [
+ NC(255, 128, 0, 255),
+ NC(255, 128, 0, 128),
+ NC(255, 128, 0, 0),
+ NC(255, 128, 0, 255),
+ NC(255, 128, 0, 128),
+ NC(255, 128, 0, 0),
+ NC(255, 128, 0, 255),
+ NC(255, 128, 0, 128),
+ NC(255, 128, 0, 0),
+ ]);
+ $src->setscanline('y' => 0,
+ pixels =>
+ [
+ NC(0, 128, 255, 0),
+ NC(0, 128, 255, 0),
+ NC(0, 128, 255, 0),
+ NC(0, 128, 255, 128),
+ NC(0, 128, 255, 128),
+ NC(0, 128, 255, 128),
+ NC(0, 128, 255, 255),
+ NC(0, 128, 255, 255),
+ NC(0, 128, 255, 255),
+ ]);
+ ok($targ->$method(src => $src, combine => 'normal',
+ tx => 1, ty => 1), "do 4 on 4 $method");
+ iscolora($targ->getpixel(x => 1, 'y' => 1), NC(255, 128, 0, 255),
+ "check at zero source coverage on full targ coverage");
+ iscolora($targ->getpixel(x => 2, 'y' => 1), NC(255, 128, 0, 128),
+ "check at zero source coverage on half targ coverage");
+ iscolora($targ->getpixel(x => 3, 'y' => 1), NC(255, 128, 0, 0),
+ "check at zero source coverage on zero targ coverage");
+ iscolora($targ->getpixel(x => 4, 'y' => 1), NC(127, 128, 128, 255),
+ "check at half source_coverage on full targ coverage");
+ iscolora($targ->getpixel(x => 5, 'y' => 1), NC(85, 128, 170, 191),
+ "check at half source coverage on half targ coverage");
+ iscolora($targ->getpixel(x => 6, 'y' => 1), NC(0, 128, 255, 128),
+ "check at half source coverage on zero targ coverage");
+ iscolora($targ->getpixel(x => 7, 'y' => 1), NC(0, 128, 255, 255),
+ "check at full source_coverage on full targ coverage");
+ iscolora($targ->getpixel(x => 8, 'y' => 1), NC(0, 128, 255, 255),
+ "check at full source coverage on half targ coverage");
+ iscolora($targ->getpixel(x => 9, 'y' => 1), NC(0, 128, 255, 255),
+ "check at full source coverage on zero targ coverage");
+ }
+}
+
+{ # https://rt.cpan.org/Ticket/Display.html?id=30908
+ # we now adapt the source channels to the target
+ # check each combination works as expected
+
+ # various source images
+ my $src1 = Imager->new(xsize => 50, ysize => 50, channels => 1);
+ my $g_grey_full = Imager::Color->new(128, 255, 0, 0);
+ my $g_white_50 = Imager::Color->new(255, 128, 0, 0);
+ $src1->box(filled => 1, xmax => 24, color => $g_grey_full);
+
+ my $src2 = Imager->new(xsize => 50, ysize => 50, channels => 2);
+ $src2->box(filled => 1, xmax => 24, color => $g_grey_full);
+ $src2->box(filled => 1, xmin => 25, color => $g_white_50);
+
+ my $c_red_full = Imager::Color->new(255, 0, 0);
+ my $c_blue_full = Imager::Color->new(0, 0, 255);
+ my $src3 = Imager->new(xsize => 50, ysize => 50, channels => 3);
+ $src3->box(filled => 1, xmax => 24, color => $c_red_full);
+ $src3->box(filled => 1, xmin => 25, color => $c_blue_full);
+
+ my $c_green_50 = Imager::Color->new(0, 255, 0, 127);
+ my $src4 = Imager->new(xsize => 50, ysize => 50, channels => 4);
+ $src4->box(filled => 1, xmax => 24, color => $c_blue_full);
+ $src4->box(filled => 1, xmin => 25, color => $c_green_50);
+
+ my @left_box = ( box => [ 25, 25, 49, 74 ] );
+ my @right_box = ( box => [ 50, 25, 74, 74 ] );
+
+ { # 1 channel output
+ my $base = Imager->new(xsize => 100, ysize => 100, channels => 1);
+ $base->box(filled => 1, color => Imager::Color->new(64, 255, 0, 0));
+
+ my $work = $base->copy;
+ ok($work->rubthrough(left => 25, top => 25, src => $src1), "rubthrough 1 to 1");
+ my $comp = $base->copy;
+ $comp->box(filled => 1, color => $g_grey_full, @left_box);
+ $comp->box(filled => 1, color => [ 0, 0, 0, 0 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(left => 25, top => 25, src => $src2), "rubthrough 2 to 1");
+ $comp = $base->copy;
+ $comp->box(filled => 1, @left_box, color => $g_grey_full);
+ $comp->box(filled => 1, @right_box, color => [ 159, 0, 0, 0 ]);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(left => 25, top => 25, src => $src3), "rubthrough 3 to 1");
+ $comp = $base->copy;
+ $comp->box(filled => 1, @left_box, color => [ 57, 255, 0, 0 ]);
+ $comp->box(filled => 1, @right_box, color => [ 18, 255, 0, 0 ]);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(left => 25, top => 25, src => $src4), "rubthrough 4 to 1");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 18, 255, 0, 0 ], @left_box);
+ $comp->box(filled => 1, color => [ 121, 255, 0, 0 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+ }
+
+ { # 2 channel output
+ my $base = Imager->new(xsize => 100, ysize => 100, channels => 2);
+ $base->box(filled => 1, color => [ 128, 128, 0, 0 ]);
+
+ my $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src1), "rubthrough 1 to 2");
+ my $comp = $base->copy;
+ $comp->box(filled => 1, color => $g_grey_full, @left_box);
+ $comp->box(filled => 1, color => [ 0, 255, 0, 0 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src2), "rubthrough 2 to 2");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => $g_grey_full, @left_box);
+ $comp->box(filled => 1, color => [ 213, 191, 0, 0 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src3), "rubthrough 3 to 2");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 57, 255, 0, 0 ], @left_box);
+ $comp->box(filled => 1, color => [ 18, 255, 0, 0 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src4), "rubthrough 4 to 2");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 18, 255, 0, 0 ], @left_box);
+ $comp->box(filled => 1, color => [ 162, 191, 0, 0 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+ }
+
+ { # 3 channel output
+ my $base = Imager->new(xsize => 100, ysize => 100, channels => 3);
+ $base->box(filled => 1, color => [ 128, 255, 0, 0 ]);
+
+ my $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src1), "rubthrough 1 to 3");
+ my $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
+ $comp->box(filled => 1, color => [ 0, 0, 0, 0 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src2), "rubthrough 2 to 3");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
+ $comp->box(filled => 1, color => [ 191, 255, 128, 255 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src3), "rubthrough 3 to 3");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 255, 0, 0 ], @left_box);
+ $comp->box(filled => 1, color => [ 0, 0, 255 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src4), "rubthrough 4 to 3");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 0, 0, 255 ], @left_box);
+ $comp->box(filled => 1, color => [ 64, 255, 0 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+ }
+
+ { # 4 channel output
+ my $base = Imager->new(xsize => 100, ysize => 100, channels => 4);
+ $base->box(filled => 1, color => [ 128, 255, 64, 128 ]);
+
+ my $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src1), "rubthrough 1 to 4");
+ my $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
+ $comp->box(filled => 1, color => [ 0, 0, 0, 255 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src2), "rubthrough 2 to 4");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
+ $comp->box(filled => 1, color => [ 213, 255, 192, 191 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src3), "rubthrough 3 to 4");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => [ 255, 0, 0 ], @left_box);
+ $comp->box(filled => 1, color => [ 0, 0, 255 ], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+
+ $work = $base->copy;
+ ok($work->rubthrough(top => 25, left => 25, src => $src4), "rubthrough 4 to 4");
+ $comp = $base->copy;
+ $comp->box(filled => 1, color => $c_blue_full, @left_box);
+ $comp->box(filled => 1, color => [ 43, 255, 21, 191], @right_box);
+ is_image($work, $comp, "compare rubthrough target to expected");
+ }
}
sub color_cmp {