3 use Test::More tests => 76;
4 use Imager qw(:all :handy);
5 use Imager::Test qw(is_image);
7 init_log("testout/t69rubthru.log", 1);
13 my $targ = Imager::ImgRaw::new(100, 100, 3);
14 my $src = Imager::ImgRaw::new($src_height, $src_width, 4);
15 my $halfred = NC(255, 0, 0, 128);
16 i_box_filled($src, 20, 20, 60, 60, $halfred);
17 ok(i_rubthru($targ, $src, 10, 10, 0, 0, $src_width, $src_height),
18 "low level rubthrough");
19 my $c = Imager::i_get_pixel($targ, 10, 10);
20 ok($c, "get pixel at (10, 10)");
21 ok(color_cmp($c, NC(0, 0, 0)) == 0, "check for correct color");
22 $c = Imager::i_get_pixel($targ, 30, 30);
23 ok($c, "get pixel at (30, 30)");
24 ok(color_cmp($c, NC(128, 0, 0)) == 0, "check color");
26 my $black = NC(0, 0, 0);
27 # reset the target and try a grey+alpha source
28 i_box_filled($targ, 0, 0, 100, 100, $black);
29 my $gsrc = Imager::ImgRaw::new($src_width, $src_height, 2);
30 my $halfwhite = NC(255, 128, 0);
31 i_box_filled($gsrc, 20, 20, 60, 60, $halfwhite);
32 ok(i_rubthru($targ, $gsrc, 10, 10, 0, 0, $src_width, $src_height),
33 "low level with grey/alpha source");
34 $c = Imager::i_get_pixel($targ, 15, 15);
35 ok($c, "get at (15, 15)");
36 ok(color_cmp($c, NC(0, 0, 0)) == 0, "check color");
37 $c = Imager::i_get_pixel($targ, 30, 30);
38 ok($c, "get pixel at (30, 30)");
39 ok(color_cmp($c, NC(128, 128, 128)) == 0, "check color");
41 # try grey target and grey alpha source
42 my $gtarg = Imager::ImgRaw::new(100, 100, 1);
43 ok(i_rubthru($gtarg, $gsrc, 10, 10, 0, 0, $src_width, $src_height),
44 "low level with grey target and gray/alpha source");
45 $c = Imager::i_get_pixel($gtarg, 10, 10);
46 ok($c, "get pixel at 10, 10");
47 is(($c->rgba)[0], 0, "check grey level");
48 is((Imager::i_get_pixel($gtarg, 30, 30)->rgba)[0], 128,
49 "check grey level at 30, 30");
51 # simple test for 16-bit/sample images
52 my $targ16 = Imager::i_img_16_new(100, 100, 3);
53 ok(i_rubthru($targ16, $src, 10, 10, 0, 0, $src_width, $src_height),
54 "smoke test vs 16-bit/sample image");
55 $c = Imager::i_get_pixel($targ16, 30, 30);
56 ok($c, "get pixel at 30, 30");
57 ok(color_cmp($c, NC(128, 0, 0)) == 0, "check color");
59 # check the OO interface
60 my $ootarg = Imager->new(xsize=>100, ysize=>100);
61 my $oosrc = Imager->new(xsize=>80, ysize=>80, channels=>4);
62 $oosrc->box(color=>$halfred, xmin=>20, ymin=>20, xmax=>60, ymax=>60,
64 ok($ootarg->rubthrough(src=>$oosrc, tx=>10, ty=>10),
66 ok(color_cmp(Imager::i_get_pixel($ootarg->{IMG}, 10, 10), NC(0, 0, 0)) == 0,
67 "check pixel at 10, 10");
68 ok(color_cmp(Imager::i_get_pixel($ootarg->{IMG}, 30, 30), NC(128, 0, 0)) == 0,
69 "check pixel at 30, 30");
71 my $oogtarg = Imager->new(xsize=>100, ysize=>100, channels=>1);
73 { # check empty image errors
74 my $empty = Imager->new;
75 ok(!$empty->rubthrough(src => $oosrc), "check empty target");
76 is($empty->errstr, 'empty input image', "check error message");
77 ok(!$oogtarg->rubthrough(src=>$empty), "check empty source");
78 is($oogtarg->errstr, 'empty input image for src',
79 "check error message");
83 # alpha source and target
84 for my $method (qw/rubthrough compose/) {
86 my $src = Imager->new(xsize => 10, ysize => 1, channels => 4);
87 my $targ = Imager->new(xsize => 10, ysize => 2, channels => 4);
89 # simple initialization
90 $targ->setscanline('y' => 1, x => 1,
100 NC(255, 128, 0, 128),
103 $src->setscanline('y' => 0,
109 NC(0, 128, 255, 128),
110 NC(0, 128, 255, 128),
111 NC(0, 128, 255, 128),
112 NC(0, 128, 255, 255),
113 NC(0, 128, 255, 255),
114 NC(0, 128, 255, 255),
116 ok($targ->$method(src => $src, combine => 'normal',
117 tx => 1, ty => 1), "do 4 on 4 $method");
118 iscolora($targ->getpixel(x => 1, 'y' => 1), NC(255, 128, 0, 255),
119 "check at zero source coverage on full targ coverage");
120 iscolora($targ->getpixel(x => 2, 'y' => 1), NC(255, 128, 0, 128),
121 "check at zero source coverage on half targ coverage");
122 iscolora($targ->getpixel(x => 3, 'y' => 1), NC(255, 128, 0, 0),
123 "check at zero source coverage on zero targ coverage");
124 iscolora($targ->getpixel(x => 4, 'y' => 1), NC(127, 128, 128, 255),
125 "check at half source_coverage on full targ coverage");
126 iscolora($targ->getpixel(x => 5, 'y' => 1), NC(85, 128, 170, 191),
127 "check at half source coverage on half targ coverage");
128 iscolora($targ->getpixel(x => 6, 'y' => 1), NC(0, 128, 255, 128),
129 "check at half source coverage on zero targ coverage");
130 iscolora($targ->getpixel(x => 7, 'y' => 1), NC(0, 128, 255, 255),
131 "check at full source_coverage on full targ coverage");
132 iscolora($targ->getpixel(x => 8, 'y' => 1), NC(0, 128, 255, 255),
133 "check at full source coverage on half targ coverage");
134 iscolora($targ->getpixel(x => 9, 'y' => 1), NC(0, 128, 255, 255),
135 "check at full source coverage on zero targ coverage");
139 { # https://rt.cpan.org/Ticket/Display.html?id=30908
140 # we now adapt the source channels to the target
141 # check each combination works as expected
143 # various source images
144 my $src1 = Imager->new(xsize => 50, ysize => 50, channels => 1);
145 my $g_grey_full = Imager::Color->new(128, 255, 0, 0);
146 my $g_white_50 = Imager::Color->new(255, 128, 0, 0);
147 $src1->box(filled => 1, xmax => 24, color => $g_grey_full);
149 my $src2 = Imager->new(xsize => 50, ysize => 50, channels => 2);
150 $src2->box(filled => 1, xmax => 24, color => $g_grey_full);
151 $src2->box(filled => 1, xmin => 25, color => $g_white_50);
153 my $c_red_full = Imager::Color->new(255, 0, 0);
154 my $c_blue_full = Imager::Color->new(0, 0, 255);
155 my $src3 = Imager->new(xsize => 50, ysize => 50, channels => 3);
156 $src3->box(filled => 1, xmax => 24, color => $c_red_full);
157 $src3->box(filled => 1, xmin => 25, color => $c_blue_full);
159 my $c_green_50 = Imager::Color->new(0, 255, 0, 127);
160 my $src4 = Imager->new(xsize => 50, ysize => 50, channels => 4);
161 $src4->box(filled => 1, xmax => 24, color => $c_blue_full);
162 $src4->box(filled => 1, xmin => 25, color => $c_green_50);
164 my @left_box = ( box => [ 25, 25, 49, 74 ] );
165 my @right_box = ( box => [ 50, 25, 74, 74 ] );
168 my $base = Imager->new(xsize => 100, ysize => 100, channels => 1);
169 $base->box(filled => 1, color => Imager::Color->new(64, 255, 0, 0));
171 my $work = $base->copy;
172 ok($work->rubthrough(left => 25, top => 25, src => $src1), "rubthrough 1 to 1");
173 my $comp = $base->copy;
174 $comp->box(filled => 1, color => $g_grey_full, @left_box);
175 $comp->box(filled => 1, color => [ 0, 0, 0, 0 ], @right_box);
176 is_image($work, $comp, "compare rubthrough target to expected");
179 ok($work->rubthrough(left => 25, top => 25, src => $src2), "rubthrough 2 to 1");
181 $comp->box(filled => 1, @left_box, color => $g_grey_full);
182 $comp->box(filled => 1, @right_box, color => [ 159, 0, 0, 0 ]);
183 is_image($work, $comp, "compare rubthrough target to expected");
186 ok($work->rubthrough(left => 25, top => 25, src => $src3), "rubthrough 3 to 1");
188 $comp->box(filled => 1, @left_box, color => [ 57, 255, 0, 0 ]);
189 $comp->box(filled => 1, @right_box, color => [ 18, 255, 0, 0 ]);
190 is_image($work, $comp, "compare rubthrough target to expected");
193 ok($work->rubthrough(left => 25, top => 25, src => $src4), "rubthrough 4 to 1");
195 $comp->box(filled => 1, color => [ 18, 255, 0, 0 ], @left_box);
196 $comp->box(filled => 1, color => [ 121, 255, 0, 0 ], @right_box);
197 is_image($work, $comp, "compare rubthrough target to expected");
201 my $base = Imager->new(xsize => 100, ysize => 100, channels => 2);
202 $base->box(filled => 1, color => [ 128, 128, 0, 0 ]);
204 my $work = $base->copy;
205 ok($work->rubthrough(top => 25, left => 25, src => $src1), "rubthrough 1 to 2");
206 my $comp = $base->copy;
207 $comp->box(filled => 1, color => $g_grey_full, @left_box);
208 $comp->box(filled => 1, color => [ 0, 255, 0, 0 ], @right_box);
209 is_image($work, $comp, "compare rubthrough target to expected");
212 ok($work->rubthrough(top => 25, left => 25, src => $src2), "rubthrough 2 to 2");
214 $comp->box(filled => 1, color => $g_grey_full, @left_box);
215 $comp->box(filled => 1, color => [ 213, 191, 0, 0 ], @right_box);
216 is_image($work, $comp, "compare rubthrough target to expected");
219 ok($work->rubthrough(top => 25, left => 25, src => $src3), "rubthrough 3 to 2");
221 $comp->box(filled => 1, color => [ 57, 255, 0, 0 ], @left_box);
222 $comp->box(filled => 1, color => [ 18, 255, 0, 0 ], @right_box);
223 is_image($work, $comp, "compare rubthrough target to expected");
226 ok($work->rubthrough(top => 25, left => 25, src => $src4), "rubthrough 4 to 2");
228 $comp->box(filled => 1, color => [ 18, 255, 0, 0 ], @left_box);
229 $comp->box(filled => 1, color => [ 162, 191, 0, 0 ], @right_box);
230 is_image($work, $comp, "compare rubthrough target to expected");
234 my $base = Imager->new(xsize => 100, ysize => 100, channels => 3);
235 $base->box(filled => 1, color => [ 128, 255, 0, 0 ]);
237 my $work = $base->copy;
238 ok($work->rubthrough(top => 25, left => 25, src => $src1), "rubthrough 1 to 3");
239 my $comp = $base->copy;
240 $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
241 $comp->box(filled => 1, color => [ 0, 0, 0, 0 ], @right_box);
242 is_image($work, $comp, "compare rubthrough target to expected");
245 ok($work->rubthrough(top => 25, left => 25, src => $src2), "rubthrough 2 to 3");
247 $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
248 $comp->box(filled => 1, color => [ 191, 255, 128, 255 ], @right_box);
249 is_image($work, $comp, "compare rubthrough target to expected");
252 ok($work->rubthrough(top => 25, left => 25, src => $src3), "rubthrough 3 to 3");
254 $comp->box(filled => 1, color => [ 255, 0, 0 ], @left_box);
255 $comp->box(filled => 1, color => [ 0, 0, 255 ], @right_box);
256 is_image($work, $comp, "compare rubthrough target to expected");
259 ok($work->rubthrough(top => 25, left => 25, src => $src4), "rubthrough 4 to 3");
261 $comp->box(filled => 1, color => [ 0, 0, 255 ], @left_box);
262 $comp->box(filled => 1, color => [ 64, 255, 0 ], @right_box);
263 is_image($work, $comp, "compare rubthrough target to expected");
267 my $base = Imager->new(xsize => 100, ysize => 100, channels => 4);
268 $base->box(filled => 1, color => [ 128, 255, 64, 128 ]);
270 my $work = $base->copy;
271 ok($work->rubthrough(top => 25, left => 25, src => $src1), "rubthrough 1 to 4");
272 my $comp = $base->copy;
273 $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
274 $comp->box(filled => 1, color => [ 0, 0, 0, 255 ], @right_box);
275 is_image($work, $comp, "compare rubthrough target to expected");
278 ok($work->rubthrough(top => 25, left => 25, src => $src2), "rubthrough 2 to 4");
280 $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
281 $comp->box(filled => 1, color => [ 213, 255, 192, 191 ], @right_box);
282 is_image($work, $comp, "compare rubthrough target to expected");
285 ok($work->rubthrough(top => 25, left => 25, src => $src3), "rubthrough 3 to 4");
287 $comp->box(filled => 1, color => [ 255, 0, 0 ], @left_box);
288 $comp->box(filled => 1, color => [ 0, 0, 255 ], @right_box);
289 is_image($work, $comp, "compare rubthrough target to expected");
292 ok($work->rubthrough(top => 25, left => 25, src => $src4), "rubthrough 4 to 4");
294 $comp->box(filled => 1, color => $c_blue_full, @left_box);
295 $comp->box(filled => 1, color => [ 43, 255, 21, 191], @right_box);
296 is_image($work, $comp, "compare rubthrough target to expected");
304 print "# (",join(",", @l[0..2]),") <=> (",join(",", @r[0..2]),")\n";
305 return $l[0] <=> $r[0]
311 my ($c1, $c2, $msg) = @_;
313 my $builder = Test::Builder->new;
316 if (!$builder->ok($c1[0] == $c2[0] && $c1[1] == $c2[1] && $c1[2] == $c2[2]
319 $builder->diag(<<DIAG);
321 expected color: [ @c2 ]