]> git.imager.perl.org - imager.git/blob - t/250-draw/030-paste.t
allow Imager::IO->new_buffer() to accept a reference
[imager.git] / t / 250-draw / 030-paste.t
1 #!perl -w
2 use strict;
3 use Test::More tests => 60;
4
5 use Imager;
6 use Imager::Test qw(is_image);
7
8 #$Imager::DEBUG=1;
9
10 -d "testout" or mkdir "testout";
11
12 Imager::init('log'=>'testout/t66paste.log');
13
14 # the original smoke tests
15 my $img=Imager->new() || die "unable to create image object\n";
16
17 ok($img->open(file=>'testimg/scale.ppm',type=>'pnm'), "load test img");
18
19 my $nimg=Imager->new() or die "Unable to create image object\n";
20 ok($nimg->open(file=>'testimg/scale.ppm',type=>'pnm'), "load test img again");
21
22 ok($img->paste(img=>$nimg, top=>30, left=>30), "paste it")
23   or print "# ", $img->errstr, "\n";;
24
25 ok($img->write(type=>'pnm',file=>'testout/t66.ppm'), "save it")
26   or print "# ", $img->errstr, "\n";
27
28 {
29   my $empty = Imager->new;
30   ok(!$empty->paste(src => $nimg), "paste into empty image");
31   is($empty->errstr, "paste: empty input image",
32      "check error message");
33
34   ok(!$img->paste(src => $empty), "paste from empty image");
35   is($img->errstr, "paste: empty input image (for src)",
36      "check error message");
37
38   ok(!$img->paste(), "no source image");
39   is($img->errstr, "no source image");
40 }
41
42 # more stringent tests
43 {
44   my $src = Imager->new(xsize => 100, ysize => 110);
45   $src->box(filled=>1, color=>'FF0000');
46
47   $src->box(filled=>1, color=>'0000FF', xmin => 20, ymin=>20,
48             xmax=>79, ymax=>79);
49
50   my $targ = Imager->new(xsize => 100, ysize => 110);
51   $targ->box(filled=>1, color =>'00FFFF');
52   $targ->box(filled=>1, color=>'00FF00', xmin=>20, ymin=>20, xmax=>79,
53              ymax=>79);
54   my $work = $targ->copy;
55   ok($work->paste(src=>$src, left => 15, top => 10), "paste whole image");
56   # build comparison image
57   my $cmp = $targ->copy;
58   $cmp->box(filled=>1, xmin=>15, ymin => 10, color=>'FF0000');
59   $cmp->box(filled=>1, xmin=>35, ymin => 30, xmax=>94, ymax=>89, 
60             color=>'0000FF');
61
62   is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
63      "compare pasted and expected");
64
65   $work = $targ->copy;
66   ok($work->paste(src=>$src, left=>2, top=>7, src_minx => 10, src_miny => 15),
67      "paste from inside src");
68   $cmp = $targ->copy;
69   $cmp->box(filled=>1, xmin=>2, ymin=>7, xmax=>91, ymax=>101, color=>'FF0000');
70   $cmp->box(filled=>1, xmin=>12, ymin=>12, xmax=>71, ymax=>71, 
71             color=>'0000FF');
72   is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
73      "compare pasted and expected");
74
75   # paste part source
76   $work = $targ->copy;
77   ok($work->paste(src=>$src, left=>15, top=>20, 
78                   src_minx=>10, src_miny=>15, src_maxx=>80, src_maxy =>70),
79      "paste src cropped all sides");
80   $cmp = $targ->copy;
81   $cmp->box(filled=>1, xmin=>15, ymin=>20, xmax=>84, ymax=>74, 
82             color=>'FF0000');
83   $cmp->box(filled=>1, xmin=>25, ymin=>25, xmax=>84, ymax=>74,
84             color=>'0000FF');
85   is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
86      "compare pasted and expected");
87
88   # go by width instead
89   $work = $targ->copy;
90   ok($work->paste(src=>$src, left=>15, top=>20,
91                   src_minx=>10, src_miny => 15, width => 70, height => 55),
92      "same but specify width/height instead");
93   is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
94      "compare pasted and expected");
95
96   # use src_coords
97   $work = $targ->copy;
98   ok($work->paste(src=>$src, left => 15, top => 20,
99                   src_coords => [ 10, 15, 80, 70 ]),
100      "using src_coords");
101   is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
102      "compare pasted and expected");
103
104   {
105     # Issue #18712
106     # supplying just src_maxx would set the internal maxy to undef
107     # supplying just src_maxy would be ignored
108     # src_maxy (or it's derived value) was being bounds checked against 
109     # the image width instead of the image height
110     $work = $targ->copy;
111     my @warns;
112     local $SIG{__WARN__} = sub { push @warns, "@_"; print "# @_"; };
113     
114     ok($work->paste(src=>$src, left => 15, top => 20,
115                     src_maxx => 50),
116        "paste with just src_maxx");
117     ok(!@warns, "shouldn't warn");
118     my $cmp = $targ->copy;
119     $cmp->box(filled=>1, color => 'FF0000', xmin => 15, ymin => 20,
120               xmax => 64, ymax => 109);
121     $cmp->box(filled=>1, color => '0000FF', xmin => 35, ymin => 40,
122               xmax => 64, ymax => 99);
123     is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
124        "check correctly pasted");
125
126     $work = $targ->copy;
127     @warns = ();
128     ok($work->paste(src=>$src, left=>15, top=>20,
129                     src_maxy => 60),
130        "paste with just src_maxy");
131     ok(!@warns, "shouldn't warn");
132     $cmp = $targ->copy;
133     $cmp->box(filled => 1, color => 'FF0000', xmin => 15, ymin => 20,
134               xmax => 99, ymax => 79);
135     $cmp->box(filled => 1, color => '0000FF', xmin => 35, ymin => 40,
136               xmax => 94, ymax => 79);
137     is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
138        "check pasted correctly");
139
140     $work = $targ->copy;
141     @warns = ();
142     ok($work->paste(src=>$src, left=>15, top=>20,
143                     src_miny => 20, src_maxy => 105),
144        "paste with src_maxy > source width");
145
146     $cmp = $targ->copy;
147     $cmp->box(filled => 1, color => 'FF0000', xmin => 15, ymin => 20,
148               ymax => 104);
149     $cmp->box(filled => 1, color => '0000FF', xmin => 35, ymin => 20,
150               xmax => 94, ymax => 79);
151     is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
152        "check pasted correctly");
153   }
154 }
155
156 { # https://rt.cpan.org/Ticket/Display.html?id=30908
157   # we now adapt the source channels to the target
158   # check each combination works as expected
159
160   # various source images
161   my $src1 = Imager->new(xsize => 50, ysize => 50, channels => 1);
162   my $g_grey_full = Imager::Color->new(128, 255, 0, 0);
163   my $g_white_50 = Imager::Color->new(255, 128, 0, 0);
164   $src1->box(filled => 1, xmax => 24, color => $g_grey_full);
165
166   my $src2 = Imager->new(xsize => 50, ysize => 50, channels => 2);
167   $src2->box(filled => 1, xmax => 24, color => $g_grey_full);
168   $src2->box(filled => 1, xmin => 25, color => $g_white_50);
169
170   my $c_red_full = Imager::Color->new(255, 0, 0);
171   my $c_blue_full = Imager::Color->new(0, 0, 255);
172   my $src3 = Imager->new(xsize => 50, ysize => 50, channels => 3);
173   $src3->box(filled => 1, xmax => 24, color => $c_red_full);
174   $src3->box(filled => 1, xmin => 25, color => $c_blue_full);
175
176   my $c_green_50 = Imager::Color->new(0, 255, 0, 127);
177   my $src4 = Imager->new(xsize => 50, ysize => 50, channels => 4);
178   $src4->box(filled => 1, xmax => 24, color => $c_blue_full);
179   $src4->box(filled => 1, xmin => 25, color => $c_green_50);
180
181   my @left_box = ( box => [ 25, 25, 49, 74 ] );
182   my @right_box = ( box => [ 50, 25, 74, 74 ] );
183
184   { # 1 channel output
185     my $base = Imager->new(xsize => 100, ysize => 100, channels => 1);
186     $base->box(filled => 1, color => Imager::Color->new(64, 255, 0, 0));
187
188     my $work = $base->copy;
189     ok($work->paste(left => 25, top => 25, src => $src1), "paste 1 to 1");
190     my $comp = $base->copy;
191     $comp->box(filled => 1, color => $g_grey_full, @left_box);
192     $comp->box(filled => 1, color => [ 0, 0, 0, 0 ], @right_box);
193     is_image($work, $comp, "compare paste target to expected");
194
195     $work = $base->copy;
196     ok($work->paste(left => 25, top => 25, src => $src2), "paste 2 to 1");
197     $comp = $base->copy;
198     $comp->box(filled => 1, @left_box, color => $g_grey_full);
199     $comp->box(filled => 1, @right_box, color => [ 128, 0, 0, 0 ]);
200     is_image($work, $comp, "compare paste target to expected");
201
202     $work = $base->copy;
203     ok($work->paste(left => 25, top => 25, src => $src3), "paste 3 to 1");
204      $comp = $base->copy;
205     $comp->box(filled => 1, @left_box, color => [ 57, 255, 0, 0 ]);
206     $comp->box(filled => 1, @right_box, color => [ 18, 255, 0, 0 ]);
207     is_image($work, $comp, "compare paste target to expected");
208
209     $work = $base->copy;
210     ok($work->paste(left => 25, top => 25, src => $src4), "paste 4 to 1");
211     $comp = $base->copy;
212     $comp->box(filled => 1, color => [ 18, 255, 0, 0 ], @left_box);
213     $comp->box(filled => 1, color => [ 90, 255, 0, 0 ], @right_box);
214     is_image($work, $comp, "compare paste target to expected");
215   }
216
217   { # 2 channel output
218     my $base = Imager->new(xsize => 100, ysize => 100, channels => 2);
219     $base->box(filled => 1, color => [ 128, 128, 0, 0 ]);
220     
221     my $work = $base->copy;
222     ok($work->paste(top => 25, left => 25, src => $src1), "paste 1 to 2");
223     my $comp = $base->copy;
224     $comp->box(filled => 1, color => $g_grey_full, @left_box);
225     $comp->box(filled => 1, color => [ 0, 255, 0, 0 ], @right_box);
226     is_image($work, $comp, "compare paste target to expected");
227
228     $work = $base->copy;
229     ok($work->paste(top => 25, left => 25, src => $src2), "paste 2 to 2");
230     $comp = $base->copy;
231     $comp->box(filled => 1, color => $g_grey_full, @left_box);
232     $comp->box(filled => 1, color => $g_white_50, @right_box);
233     is_image($work, $comp, "compare paste target to expected");
234
235     $work = $base->copy;
236     ok($work->paste(top => 25, left => 25, src => $src3), "paste 3 to 2");
237     $comp = $base->copy;
238     $comp->box(filled => 1, color => [ 57, 255, 0, 0 ], @left_box);
239     $comp->box(filled => 1, color => [ 18, 255, 0, 0 ], @right_box);
240     is_image($work, $comp, "compare paste target to expected");
241
242     $work = $base->copy;
243     ok($work->paste(top => 25, left => 25, src => $src4), "paste 4 to 2");
244     $comp = $base->copy;
245     $comp->box(filled => 1, color => [ 18, 255, 0, 0 ], @left_box);
246     $comp->box(filled => 1, color => [ 180, 127, 0, 0 ], @right_box);
247     is_image($work, $comp, "compare paste target to expected");
248   }
249
250   { # 3 channel output
251     my $base = Imager->new(xsize => 100, ysize => 100, channels => 3);
252     $base->box(filled => 1, color => [ 128, 255, 0, 0 ]);
253     
254     my $work = $base->copy;
255     ok($work->paste(top => 25, left => 25, src => $src1), "paste 1 to 3");
256     my $comp = $base->copy;
257     $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
258     $comp->box(filled => 1, color => [ 0, 0, 0, 0 ], @right_box);
259     is_image($work, $comp, "compare paste target to expected");
260
261     $work = $base->copy;
262     ok($work->paste(top => 25, left => 25, src => $src2), "paste 2 to 3");
263     $comp = $base->copy;
264     $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
265     $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @right_box);
266     is_image($work, $comp, "compare paste target to expected");
267
268     $work = $base->copy;
269     ok($work->paste(top => 25, left => 25, src => $src3), "paste 3 to 3");
270     $comp = $base->copy;
271     $comp->box(filled => 1, color => [ 255, 0, 0 ], @left_box);
272     $comp->box(filled => 1, color => [ 0, 0, 255 ], @right_box);
273     is_image($work, $comp, "compare paste target to expected");
274
275     $work = $base->copy;
276     ok($work->paste(top => 25, left => 25, src => $src4), "paste 4 to 3");
277     $comp = $base->copy;
278     $comp->box(filled => 1, color => [ 0, 0, 255 ], @left_box);
279     $comp->box(filled => 1, color => [ 0, 127, 0 ], @right_box);
280     is_image($work, $comp, "compare paste target to expected");
281   }
282
283   { # 4 channel output
284     my $base = Imager->new(xsize => 100, ysize => 100, channels => 4);
285     $base->box(filled => 1, color => [ 128, 255, 64, 128 ]);
286     
287     my $work = $base->copy;
288     ok($work->paste(top => 25, left => 25, src => $src1), "paste 1 to 4");
289     my $comp = $base->copy;
290     $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
291     $comp->box(filled => 1, color => [ 0, 0, 0, 255 ], @right_box);
292     is_image($work, $comp, "compare paste target to expected");
293
294     $work = $base->copy;
295     ok($work->paste(top => 25, left => 25, src => $src2), "paste 2 to 4");
296     $comp = $base->copy;
297     $comp->box(filled => 1, color => [ 128, 128, 128, 255 ], @left_box);
298     $comp->box(filled => 1, color => [ 255, 255, 255, 128 ], @right_box);
299     is_image($work, $comp, "compare paste target to expected");
300
301     $work = $base->copy;
302     ok($work->paste(top => 25, left => 25, src => $src3), "paste 3 to 4");
303     $comp = $base->copy;
304     $comp->box(filled => 1, color => [ 255, 0, 0 ], @left_box);
305     $comp->box(filled => 1, color => [ 0, 0, 255 ], @right_box);
306     is_image($work, $comp, "compare paste target to expected");
307
308     $work = $base->copy;
309     ok($work->paste(top => 25, left => 25, src => $src4), "paste 4 to 4");
310     $comp = $base->copy;
311     $comp->box(filled => 1, color => $c_blue_full, @left_box);
312     $comp->box(filled => 1, color => $c_green_50, @right_box);
313     is_image($work, $comp, "compare paste target to expected");
314   }
315 }