2 # t/t01introvert.t - tests internals of image formats
3 # to make sure we get expected values
6 use Test::More tests => 466;
8 BEGIN { use_ok(Imager => qw(:handy :all)) }
10 use Imager::Test qw(image_bounds_checks is_color3 is_color4 is_fcolor4 color_cmp mask_tests is_fcolor3);
12 -d "testout" or mkdir "testout";
14 Imager->open_log(log => "testout/t01introvert.log");
16 my $im_g = Imager::ImgRaw::new(100, 101, 1);
18 my $red = NC(255, 0, 0);
19 my $green = NC(0, 255, 0);
20 my $blue = NC(0, 0, 255);
22 use Imager::Color::Float;
23 my $f_black = Imager::Color::Float->new(0, 0, 0);
24 my $f_red = Imager::Color::Float->new(1.0, 0, 0);
25 my $f_green = Imager::Color::Float->new(0, 1.0, 0);
26 my $f_blue = Imager::Color::Float->new(0, 0, 1.0);
28 is(Imager::i_img_getchannels($im_g), 1, "1 channel image channel count");
29 ok(Imager::i_img_getmask($im_g) & 1, "1 channel image mask");
30 ok(!Imager::i_img_virtual($im_g), "1 channel image not virtual");
31 is(Imager::i_img_bits($im_g), 8, "1 channel image has 8 bits/sample");
32 is(Imager::i_img_type($im_g), 0, "1 channel image is direct");
33 is(Imager::i_img_get_width($im_g), 100, "100 pixels wide");
34 is(Imager::i_img_get_height($im_g), 101, "101 pixels high");
36 my @ginfo = Imager::i_img_info($im_g);
37 is($ginfo[0], 100, "1 channel image width");
38 is($ginfo[1], 101, "1 channel image height");
40 undef $im_g; # can we check for release after this somehow?
42 my $im_rgb = Imager::ImgRaw::new(100, 101, 3);
44 is(Imager::i_img_getchannels($im_rgb), 3, "3 channel image channel count");
45 is((Imager::i_img_getmask($im_rgb) & 7), 7, "3 channel image mask");
46 is(Imager::i_img_bits($im_rgb), 8, "3 channel image has 8 bits/sample");
47 is(Imager::i_img_type($im_rgb), 0, "3 channel image is direct");
51 my $im_pal = Imager::i_img_pal_new(100, 101, 3, 256);
53 ok($im_pal, "make paletted image");
54 is(Imager::i_img_getchannels($im_pal), 3, "pal img channel count");
55 is(Imager::i_img_bits($im_pal), 8, "pal img bits");
56 is(Imager::i_img_type($im_pal), 1, "pal img is paletted");
58 my $red_idx = check_add($im_pal, $red, 0);
59 my $green_idx = check_add($im_pal, $green, 1);
60 my $blue_idx = check_add($im_pal, $blue, 2);
62 # basic writing of palette indicies
64 is(Imager::i_ppal($im_pal, 0, 0, ($red_idx) x 100), 100,
65 "write red 100 times");
67 is(Imager::i_ppal($im_pal, 50, 0, ($blue_idx) x 50), 50,
68 "write blue 50 times");
70 # make sure we get it back
71 my @pals = Imager::i_gpal($im_pal, 0, 100, 0);
72 ok(!grep($_ != $red_idx, @pals[0..49]), "check for red");
73 ok(!grep($_ != $blue_idx, @pals[50..99]), "check for blue");
74 is(Imager::i_gpal($im_pal, 0, 100, 0), "\0" x 50 . "\2" x 50,
75 "gpal in scalar context");
76 my @samp = Imager::i_gsamp($im_pal, 0, 100, 0, [ 0, 1, 2 ]);
77 is(@samp, 300, "gsamp count in list context");
78 my @samp_exp = ((255, 0, 0) x 50, (0, 0, 255) x 50);
79 is_deeply(\@samp, \@samp_exp, "gsamp list deep compare");
80 my $samp = Imager::i_gsamp($im_pal, 0, 100, 0, [ 0, 1, 2 ]);
81 is(length($samp), 300, "gsamp scalar length");
82 is($samp, "\xFF\0\0" x 50 . "\0\0\xFF" x 50, "gsamp scalar bytes");
84 # reading indicies as colors
85 my $c_red = Imager::i_get_pixel($im_pal, 0, 0);
86 ok($c_red, "got the red pixel");
87 is_color3($c_red, 255, 0, 0, "and it's red");
88 my $c_blue = Imager::i_get_pixel($im_pal, 50, 0);
89 ok($c_blue, "got the blue pixel");
90 is_color3($c_blue, 0, 0, 255, "and it's blue");
93 ok(Imager::i_ppix($im_pal, 0, 0, $green) == 0, "draw with color in palette");
94 # that was in the palette, should still be paletted
95 is(Imager::i_img_type($im_pal), 1, "image still paletted");
97 my $c_green = Imager::i_get_pixel($im_pal, 0, 0);
98 ok($c_green, "got green pixel");
99 is_color3($c_green, 0, 255, 0, "and it's green");
101 is(Imager::i_colorcount($im_pal), 3, "still 3 colors in palette");
102 is(Imager::i_findcolor($im_pal, $green), 1, "and green is the second");
104 my $black = NC(0, 0, 0);
105 # this should convert the image to RGB
106 ok(Imager::i_ppix($im_pal, 1, 0, $black) == 0, "draw with black (not in palette)");
107 is(Imager::i_img_type($im_pal), 0, "pal img shouldn't be paletted now");
112 colors => [$red, $green, $blue, $black],
113 make_colors => 'none',
115 my $im_pal2 = Imager::i_img_to_pal($im_pal, \%quant);
116 ok($im_pal2, "got an image from quantizing");
117 is(@{$quant{colors}}, 4, "quant has the right number of colours");
118 is(Imager::i_colorcount($im_pal2), 4, "and so does the image");
119 my @colors = Imager::i_getcolors($im_pal2, 0, 4);
120 my ($first) = Imager::i_getcolors($im_pal2, 0);
121 my @first = $colors[0]->rgba;
122 is_color3($first, $first[0], $first[1], $first[2],
123 "check first color is first for multiple or single fetch");
124 is_color3($colors[0], 255, 0, 0, "still red");
125 is_color3($colors[1], 0, 255, 0, "still green");
126 is_color3($colors[2], 0, 0, 255, "still blue");
127 is_color3($colors[3], 0, 0, 0, "still black");
128 my @samples = Imager::i_gsamp($im_pal2, 0, 100, 0, [ 0, 1, 2 ]);
129 my @expect = unpack("C*", "\0\xFF\0\0\0\0"."\xFF\0\0" x 48 . "\0\0\xFF" x 50);
130 my $match_list = is_deeply(\@samples, \@expect, "colors are still correct");
131 my $samples = Imager::i_gsamp($im_pal2, 0, 100, 0, [ 0, 1, 2 ]);
132 my $match_scalar = is_deeply([ unpack("C*", $samples) ],
133 \@expect, "colors are still correct (scalar)");
134 unless ($match_list && $match_scalar) {
135 # this has been failing on a particular smoker, provide more
136 # diagnostic information
137 print STDERR "Pallete:\n";
138 print STDERR " $_: ", join(",", $colors[$_]->rgba), "\n" for 0..$#colors;
139 print STDERR "Samples (list): ", join(",", @samples), "\n";
140 print STDERR "Samples (scalar): ", join(",", unpack("C*", $samples)), "\n";
141 print STDERR "Indexes: ", join(",", Imager::i_gpal($im_pal2, 0, 100, 0)), "\n";
145 # test the OO interfaces
146 my $impal2 = Imager->new(type=>'pseudo', xsize=>200, ysize=>201);
147 ok($impal2, "make paletted via OO")
148 or diag(Imager->errstr);
149 is($impal2->getchannels, 3, "check channels");
150 is($impal2->bits, 8, "check bits");
151 is($impal2->type, 'paletted', "check type");
152 is($impal2->getwidth, 200, "check width");
153 is($impal2->getheight, 201, "check height");
156 my $red_idx = $impal2->addcolors(colors=>[$red]);
157 ok($red_idx, "add red to OO");
158 is(0+$red_idx, 0, "and it's expected index for red");
159 my $blue_idx = $impal2->addcolors(colors=>[$blue, $green]);
160 ok($blue_idx, "add blue/green via OO");
161 is($blue_idx, 1, "and it's expected index for blue");
162 my $green_idx = $blue_idx + 1;
163 my $c = $impal2->getcolors(start=>$green_idx);
164 is_color3($c, 0, 255, 0, "found green where expected");
165 my @cols = $impal2->getcolors;
166 is(@cols, 3, "got 3 colors");
167 my @exp = ( $red, $blue, $green );
170 if (color_cmp($cols[$i], $exp[$i])) {
175 ok($good, "all colors in palette as expected");
176 is($impal2->colorcount, 3, "and colorcount returns 3");
177 is($impal2->maxcolors, 256, "maxcolors as expected");
178 is($impal2->findcolor(color=>$blue), 1, "findcolors found blue");
179 ok($impal2->setcolors(start=>0, colors=>[ $blue, $red ]),
182 # make an rgb version
183 my $imrgb2 = $impal2->to_rgb8()
184 or diag($impal2->errstr);
185 is($imrgb2->type, 'direct', "converted is direct");
187 # and back again, specifying the palette
188 my @colors = ( $red, $blue, $green );
189 my $impal3 = $imrgb2->to_paletted(colors=>\@colors,
191 translate=>'closest');
192 ok($impal3, "got a paletted image from conversion");
193 dump_colors(@colors);
194 print "# in image\n";
195 dump_colors($impal3->getcolors);
196 is($impal3->colorcount, 3, "new image has expected color table size");
197 is($impal3->type, 'paletted', "and is paletted");
201 my $im = Imager->new;
202 ok($im, "make empty image");
203 ok(!$im->to_rgb8, "convert to rgb8");
204 is($im->errstr, "to_rgb8: empty input image", "check message");
205 is($im->bits, undef, "can't call bits on an empty image");
206 is($im->errstr, "bits: empty input image", "check message");
207 is($im->type, undef, "can't call type on an empty image");
208 is($im->errstr, "type: empty input image", "check message");
209 is($im->virtual, undef, "can't call virtual on an empty image");
210 is($im->errstr, "virtual: empty input image", "check message");
211 is($im->is_bilevel, undef, "can't call virtual on an empty image");
212 is($im->errstr, "is_bilevel: empty input image", "check message");
213 ok(!$im->getscanline(y => 0), "can't call getscanline on an empty image");
214 is($im->errstr, "getscanline: empty input image", "check message");
215 ok(!$im->setscanline(y => 0, pixels => [ $red, $blue ]),
216 "can't call setscanline on an empty image");
217 is($im->errstr, "setscanline: empty input image", "check message");
218 ok(!$im->getsamples(y => 0), "can't call getsamples on an empty image");
219 is($im->errstr, "getsamples: empty input image", "check message");
220 is($im->getwidth, undef, "can't get width of empty image");
221 is($im->errstr, "getwidth: empty input image", "check message");
222 is($im->getheight, undef, "can't get height of empty image");
223 is($im->errstr, "getheight: empty input image", "check message");
224 is($im->getchannels, undef, "can't get channels of empty image");
225 is($im->errstr, "getchannels: empty input image", "check message");
226 is($im->getmask, undef, "can't get mask of empty image");
227 is($im->errstr, "getmask: empty input image", "check message");
228 is($im->setmask, undef, "can't set mask of empty image");
229 is($im->errstr, "setmask: empty input image", "check message");
232 { # basic checks, 8-bit direct images
233 my $im = Imager->new(xsize => 2, ysize => 3);
234 ok($im, 'create 8-bit direct image');
235 is($im->bits, 8, '8 bits');
236 ok(!$im->virtual, 'not virtual');
237 is($im->type, 'direct', 'direct image');
238 ok(!$im->is_bilevel, 'not mono');
241 ok(!Imager->new(xsize=>0, ysize=>1), "fail to create 0 height image");
242 cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
243 "0 height error message check");
244 ok(!Imager->new(xsize=>1, ysize=>0), "fail to create 0 width image");
245 cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
246 "0 width error message check");
247 ok(!Imager->new(xsize=>-1, ysize=>1), "fail to create -ve height image");
248 cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
249 "-ve width error message check");
250 ok(!Imager->new(xsize=>1, ysize=>-1), "fail to create -ve width image");
251 cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
252 "-ve height error message check");
253 ok(!Imager->new(xsize=>-1, ysize=>-1), "fail to create -ve width/height image");
254 cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
255 "-ve width/height error message check");
257 ok(!Imager->new(xsize=>1, ysize=>1, channels=>0),
258 "fail to create a zero channel image");
259 cmp_ok(Imager->errstr, '=~', qr/channels must be between 1 and 4/,
260 "out of range channel message check");
261 ok(!Imager->new(xsize=>1, ysize=>1, channels=>5),
262 "fail to create a five channel image");
263 cmp_ok(Imager->errstr, '=~', qr/channels must be between 1 and 4/,
264 "out of range channel message check");
267 # https://rt.cpan.org/Ticket/Display.html?id=8213
268 # check for handling of memory allocation of very large images
269 # only test this on 32-bit machines - on a 64-bit machine it may
270 # result in trying to allocate 4Gb of memory, which is unfriendly at
271 # least and may result in running out of memory, causing a different
276 skip("don't want to allocate 4Gb", 8) unless $Config{ptrsize} == 4;
278 my $uint_range = 256 ** $Config{intsize};
279 print "# range $uint_range\n";
280 my $dim1 = int(sqrt($uint_range))+1;
282 my $im_b = Imager->new(xsize=>$dim1, ysize=>$dim1, channels=>1);
283 is($im_b, undef, "integer overflow check - 1 channel");
285 $im_b = Imager->new(xisze=>$dim1, ysize=>1, channels=>1);
286 ok($im_b, "but same width ok");
287 $im_b = Imager->new(xisze=>1, ysize=>$dim1, channels=>1);
288 ok($im_b, "but same height ok");
289 cmp_ok(Imager->errstr, '=~', qr/integer overflow/,
290 "check the error message");
292 # do a similar test with a 3 channel image, so we're sure we catch
293 # the same case where the third dimension causes the overflow
294 my $dim3 = int(sqrt($uint_range / 3))+1;
296 $im_b = Imager->new(xsize=>$dim3, ysize=>$dim3, channels=>3);
297 is($im_b, undef, "integer overflow check - 3 channel");
299 $im_b = Imager->new(xisze=>$dim3, ysize=>1, channels=>3);
300 ok($im_b, "but same width ok");
301 $im_b = Imager->new(xisze=>1, ysize=>$dim3, channels=>3);
302 ok($im_b, "but same height ok");
304 cmp_ok(Imager->errstr, '=~', qr/integer overflow/,
305 "check the error message");
309 { # http://rt.cpan.org/NoAuth/Bug.html?id=9672
311 local $SIG{__WARN__} =
314 my $printed = $warning;
316 $printed =~ s/\n/\n\#/g;
317 print "# ",$printed, "\n";
319 my $img = Imager->new(xsize=>10, ysize=>10);
320 $img->to_rgb8(); # doesn't really matter what the source is
321 cmp_ok($warning, '=~', 'void', "correct warning");
322 cmp_ok($warning, '=~', 't01introvert\\.t', "correct file");
325 { # http://rt.cpan.org/NoAuth/Bug.html?id=11860
326 my $im = Imager->new(xsize=>2, ysize=>2);
327 $im->setpixel(x=>0, 'y'=>0, color=>$red);
328 $im->setpixel(x=>1, 'y'=>0, color=>$blue);
330 my @row = Imager::i_glin($im->{IMG}, 0, 2, 0);
331 is(@row, 2, "got 2 pixels from i_glin");
332 is_color3($row[0], 255, 0, 0, "red first");
333 is_color3($row[1], 0, 0, 255, "then blue");
336 { # general tag tests
338 # we don't care much about the image itself
339 my $im = Imager::ImgRaw::new(10, 10, 1);
341 ok(Imager::i_tags_addn($im, 'alpha', 0, 101), "i_tags_addn(...alpha, 0, 101)");
342 ok(Imager::i_tags_addn($im, undef, 99, 102), "i_tags_addn(...undef, 99, 102)");
343 is(Imager::i_tags_count($im), 2, "should have 2 tags");
344 ok(Imager::i_tags_addn($im, undef, 99, 103), "i_tags_addn(...undef, 99, 103)");
345 is(Imager::i_tags_count($im), 3, "should have 3 tags, despite the dupe");
346 is(Imager::i_tags_find($im, 'alpha', 0), '0 but true', "find alpha");
347 is(Imager::i_tags_findn($im, 99, 0), 1, "find 99");
348 is(Imager::i_tags_findn($im, 99, 2), 2, "find 99 again");
349 is(Imager::i_tags_get($im, 0), 101, "check first");
350 is(Imager::i_tags_get($im, 1), 102, "check second");
351 is(Imager::i_tags_get($im, 2), 103, "check third");
353 ok(Imager::i_tags_add($im, 'beta', 0, "hello", 0),
354 "add string with string key");
355 ok(Imager::i_tags_add($im, 'gamma', 0, "goodbye", 0),
357 ok(Imager::i_tags_add($im, undef, 199, "aloha", 0),
358 "add one keyed by number");
359 is(Imager::i_tags_find($im, 'beta', 0), 3, "find beta");
360 is(Imager::i_tags_find($im, 'gamma', 0), 4, "find gamma");
361 is(Imager::i_tags_findn($im, 199, 0), 5, "find 199");
362 ok(Imager::i_tags_delete($im, 2), "delete");
363 is(Imager::i_tags_find($im, 'beta', 0), 2, 'find beta after deletion');
364 ok(Imager::i_tags_delbyname($im, 'beta'), 'delete beta by name');
365 is(Imager::i_tags_find($im, 'beta', 0), undef, 'beta not there now');
366 is(Imager::i_tags_get_string($im, "gamma"), "goodbye",
367 'i_tags_get_string() on a string');
368 is(Imager::i_tags_get_string($im, 99), 102,
369 'i_tags_get_string() on a number entry');
370 ok(Imager::i_tags_delbycode($im, 99), 'delete by code');
371 is(Imager::i_tags_findn($im, 99, 0), undef, '99 not there now');
372 is(Imager::i_tags_count($im), 3, 'final count of 3');
376 print "# low-level scan line function tests\n";
377 my $im = Imager::ImgRaw::new(10, 10, 4);
378 Imager::i_ppix($im, 5, 0, $red);
381 my @colors = Imager::i_glin($im, 0, 10, 0);
382 is_deeply([ (0) x 20, (255, 0, 0, 255), (0) x 16 ],
383 [ map $_->rgba, @colors ],
384 "i_glin - list context");
385 my $colors = Imager::i_glin($im, 0, 10, 0);
386 is("00" x 20 . "FF0000FF" . "00" x 16,
387 uc unpack("H*", $colors), "i_glin - scalar context");
388 my @fcolors = Imager::i_glinf($im, 0, 10, 0);
389 is_deeply([ (0.0) x 20, (1.0, 0, 0, 1.0) , (0) x 16 ],
390 [ map $_->rgba, @fcolors ],
391 "i_glinf - list context");
392 my $fcolors = Imager::i_glinf($im, 0, 10, 0);
393 is_deeply([ (0.0) x 20, (1.0, 0, 0, 1.0) , (0) x 16 ],
394 [ unpack "d*", $fcolors ],
395 "i_glinf - scalar context");
398 my @plin_colors = (($black) x 4, $red, $blue, ($black) x 4);
399 is(Imager::i_plin($im, 0, 1, @plin_colors),
400 10, "i_plin - pass in a list");
401 # make sure we get it back
402 is_deeply([ map [ $_->rgba ], @plin_colors ],
403 [ map [ $_->rgba ], Imager::i_glin($im, 0, 10, 1) ],
404 "check i_plin wrote to the image");
412 is(Imager::i_plin($im, 0, 2, pack("C*", @scalar_plin)),
413 10, "i_plin - pass in a scalar");
414 is_deeply(\@scalar_plin,
415 [ map $_->rgba , Imager::i_glin($im, 0, 10, 2) ],
416 "check i_plin scalar wrote to the image");
418 my @plinf_colors = # Note: only 9 pixels
425 is(Imager::i_plinf($im, 0, 3, @plinf_colors), 9,
427 is_deeply([ map $_->rgba, Imager::i_glinf($im, 0, 9, 3) ],
428 [ map $_->rgba, @plinf_colors ],
429 "check colors were written");
432 ( 1.0, 1.0, 0, 1.0 ) x 3,
433 ( 0, 1.0, 1.0, 1.0 ) x 2,
435 ( 1.0, 0, 1.0, 1.0 ),
437 is(Imager::i_plinf($im, 2, 4, pack("d*", @scalar_plinf)),
438 7, "i_plinf - scalar");
439 is_deeply(\@scalar_plinf,
440 [ map $_->rgba, Imager::i_glinf($im, 2, 9, 4) ],
441 "check colors were written");
443 is_deeply([ Imager::i_gsamp($im, 0, 10, 0, [ 0, 3 ]) ],
444 [ (0, 0) x 5, (255, 255), (0, 0) x 4 ],
445 "i_gsamp list context");
446 is("0000" x 5 . "FFFF" . "0000" x 4,
447 uc unpack("H*", Imager::i_gsamp($im, 0, 10, 0, [ 0, 3 ])),
448 "i_gsamp scalar context");
449 is_deeply([ Imager::i_gsampf($im, 2, 9, 4, [ 0, 2, 3 ]) ],
450 [ (1.0, 0, 1.0) x 3, (0, 1.0, 1.0) x 2, (0, 0, 0),
451 (1.0, 1.0, 1.0) ], "i_gsampf - list context");
452 is_deeply([ unpack("d*", Imager::i_gsampf($im, 2, 9, 4, [ 0, 2, 3 ])) ],
453 [ (1.0, 0, 1.0) x 3, (0, 1.0, 1.0) x 2, (0, 0, 0),
454 (1.0, 1.0, 1.0) ], "i_gsampf - scalar context");
455 print "# end low-level scan-line function tests\n";
458 my $psamp_outside_error = "Image position outside of image";
461 my $imraw = Imager::ImgRaw::new(10, 20, 3);
463 is(Imager::i_psamp($imraw, 0, 2, undef, [ 255, 128, 64 ]), 3,
464 "i_psamp def channels, 3 samples");
465 is_color3(Imager::i_get_pixel($imraw, 0, 2), 255, 128, 64,
466 "check color written");
467 Imager::i_img_setmask($imraw, 5);
468 is(Imager::i_psamp($imraw, 1, 3, undef, [ 64, 128, 192 ]), 3,
469 "i_psamp def channels, 3 samples, masked");
470 is_color3(Imager::i_get_pixel($imraw, 1, 3), 64, 0, 192,
471 "check color written");
472 is(Imager::i_psamp($imraw, 1, 7, [ 0, 1, 2 ], [ 64, 128, 192 ]), 3,
473 "i_psamp channels listed, 3 samples, masked");
474 is_color3(Imager::i_get_pixel($imraw, 1, 7), 64, 0, 192,
475 "check color written");
476 Imager::i_img_setmask($imraw, ~0);
477 is(Imager::i_psamp($imraw, 2, 4, [ 0, 1 ], [ 255, 128, 64, 32 ]), 4,
478 "i_psamp channels [0, 1], 4 samples");
479 is_color3(Imager::i_get_pixel($imraw, 2, 4), 255, 128, 0,
480 "check first color written");
481 is_color3(Imager::i_get_pixel($imraw, 3, 4), 64, 32, 0,
482 "check second color written");
483 is(Imager::i_psamp($imraw, 0, 5, [ 0, 1, 2 ], [ (128, 63, 32) x 10 ]), 30,
485 is_deeply([ Imager::i_gsamp($imraw, 0, 10, 5, [ 0, 1, 2 ]) ],
486 [ (128, 63, 32) x 10 ],
488 is(Imager::i_psamp($imraw, 8, 8, [ 0, 1, 2 ],
489 [ 255, 128, 32, 64, 32, 16, 32, 16, 8 ]),
490 6, "i_psamp channels [0, 1, 2], 9 samples, but room for 6");
491 is(Imager::i_psamp($imraw, 4, 6, undef, [ 0 .. 18 ], 1), 18,
492 "psamp with offset");
493 is_deeply([ Imager::i_gsamp($imraw, 0, 10, 6, undef) ],
494 [ (0) x 12, 1 .. 18 ],
496 is(Imager::i_psamp($imraw, 4, 11, undef, [ 0 .. 18 ], 1, 3), 9,
497 "psamp with offset and width");
498 is_deeply([ Imager::i_gsamp($imraw, 0, 10, 11, undef) ],
499 [ (0) x 12, 1 .. 9, (0) x 9 ],
503 is(Imager::i_psamp($imraw, 6, 8, [ 0, 1, 3 ], [ 255, 128, 32 ]),
504 undef, "i_psamp channels [0, 1, 3], 3 samples (invalid channel number)");
505 is(_get_error(), "No channel 3 in this image",
506 "check error message");
507 is(Imager::i_psamp($imraw, 6, 8, [ 0, 1, -1 ], [ 255, 128, 32 ]),
508 undef, "i_psamp channels [0, 1, -1], 3 samples (invalid channel number)");
509 is(_get_error(), "No channel -1 in this image",
510 "check error message");
511 is(Imager::i_psamp($imraw, 0, -1, undef, [ 0, 0, 0 ]), undef,
513 is(_get_error(), $psamp_outside_error,
514 "check error message");
515 is(Imager::i_psamp($imraw, 0, 20, undef, [ 0, 0, 0 ]), undef,
517 is(_get_error(), $psamp_outside_error,
518 "check error message");
519 is(Imager::i_psamp($imraw, -1, 0, undef, [ 0, 0, 0 ]), undef,
521 is(_get_error(), $psamp_outside_error,
522 "check error message");
523 is(Imager::i_psamp($imraw, 10, 0, undef, [ 0, 0, 0 ]), undef,
525 is(_get_error(), $psamp_outside_error,
526 "check error message");
528 { # test the im_sample_list typemap
529 ok(!eval { Imager::i_psamp($imraw, 9, 9, [ 0 ], undef); 1 },
530 "pass undef as the sample list");
531 like($@, qr/data must be a scalar or an arrayref/,
533 ok(!eval { Imager::i_psamp($imraw, 9, 9, [ 0 ], { a => 1 }); 1 },
534 "hashref as the sample list");
535 like($@, qr/data must be a scalar or an arrayref/,
537 ok(!eval { Imager::i_psamp($imraw, 9, 9, [ 0 ], []); 1 },
538 "empty sample list");
539 like($@, qr/i_psamp: no samples provided in data/,
541 ok(!eval { Imager::i_psamp($imraw, 9, 9, [ 0 ], ""); 1 },
542 "empty scalar sample list");
543 like($@, qr/i_psamp: no samples provided in data/,
547 is(Imager::i_psamp($imraw, 0, 8, undef, [ (0) x 3 ], -1), undef,
549 is(_get_error(), "offset must be non-negative",
552 is(Imager::i_psamp($imraw, 0, 8, undef, [ (0) x 3 ], 4), undef,
554 is(_get_error(), "offset greater than number of samples supplied",
557 print "# end psamp tests\n";
562 my $imraw = Imager::ImgRaw::new(10, 20, 3);
564 is(Imager::i_psampf($imraw, 0, 2, undef, [ 1, 0.5, 0.25 ]), 3,
565 "i_psampf def channels, 3 samples");
566 is_color3(Imager::i_get_pixel($imraw, 0, 2), 255, 128, 64,
567 "check color written");
568 Imager::i_img_setmask($imraw, 5);
569 is(Imager::i_psampf($imraw, 1, 3, undef, [ 0.25, 0.5, 0.75 ]), 3,
570 "i_psampf def channels, 3 samples, masked");
571 is_color3(Imager::i_get_pixel($imraw, 1, 3), 64, 0, 191,
572 "check color written");
573 is(Imager::i_psampf($imraw, 1, 7, [ 0, 1, 2 ], [ 0.25, 0.5, 0.75 ]), 3,
574 "i_psampf channels listed, 3 samples, masked");
575 is_color3(Imager::i_get_pixel($imraw, 1, 7), 64, 0, 191,
576 "check color written");
577 Imager::i_img_setmask($imraw, ~0);
578 is(Imager::i_psampf($imraw, 2, 4, [ 0, 1 ], [ 1, 0.5, 0.25, 0.125 ]), 4,
579 "i_psampf channels [0, 1], 4 samples");
580 is_color3(Imager::i_get_pixel($imraw, 2, 4), 255, 128, 0,
581 "check first color written");
582 is_color3(Imager::i_get_pixel($imraw, 3, 4), 64, 32, 0,
583 "check second color written");
584 is(Imager::i_psampf($imraw, 0, 5, [ 0, 1, 2 ], [ (0.5, 0.25, 0.125) x 10 ]), 30,
586 is_deeply([ Imager::i_gsamp($imraw, 0, 10, 5, [ 0, 1, 2 ]) ],
587 [ (128, 64, 32) x 10 ],
589 is(Imager::i_psampf($imraw, 8, 8, [ 0, 1, 2 ],
590 [ 1.0, 0.5, 0.125, 0.25, 0.125, 0.0625, 0.125, 0, 1 ]),
591 6, "i_psampf channels [0, 1, 2], 9 samples, but room for 6");
592 is(Imager::i_psampf($imraw, 4, 6, undef, [ map $_/254.9, 0 .. 18 ], 1), 18,
593 "psampf with offset");
594 is_deeply([ Imager::i_gsamp($imraw, 0, 10, 6, undef) ],
595 [ (0) x 12, 1 .. 18 ],
597 is(Imager::i_psampf($imraw, 4, 11, undef, [ map $_/254.9, 0 .. 18 ], 1, 3), 9,
598 "psampf with offset and width");
599 is_deeply([ Imager::i_gsamp($imraw, 0, 10, 11, undef) ],
600 [ (0) x 12, 1 .. 9, (0) x 9 ],
604 is(Imager::i_psampf($imraw, 6, 8, [ 0, 1, 3 ], [ 1, 0.5, 0.125 ]),
605 undef, "i_psampf channels [0, 1, 3], 3 samples (invalid channel number)");
606 is(_get_error(), "No channel 3 in this image",
607 "check error message");
608 is(Imager::i_psampf($imraw, 6, 8, [ 0, 1, -1 ], [ 1, 0.5, 0.125 ]),
609 undef, "i_psampf channels [0, 1, -1], 3 samples (invalid channel number)");
610 is(_get_error(), "No channel -1 in this image",
611 "check error message");
612 is(Imager::i_psampf($imraw, 0, -1, undef, [ 0, 0, 0 ]), undef,
614 is(_get_error(), $psamp_outside_error,
615 "check error message");
616 is(Imager::i_psampf($imraw, 0, 20, undef, [ 0, 0, 0 ]), undef,
618 is(_get_error(), $psamp_outside_error,
619 "check error message");
620 is(Imager::i_psampf($imraw, -1, 0, undef, [ 0, 0, 0 ]), undef,
622 is(_get_error(), $psamp_outside_error,
623 "check error message");
624 is(Imager::i_psampf($imraw, 10, 0, undef, [ 0, 0, 0 ]), undef,
626 is(_get_error(), $psamp_outside_error,
627 "check error message");
629 { # test the im_fsample_list typemap
630 ok(!eval { Imager::i_psampf($imraw, 9, 9, [ 0 ], undef); 1 },
631 "pass undef as the sample list");
632 like($@, qr/data must be a scalar or an arrayref/,
634 ok(!eval { Imager::i_psampf($imraw, 9, 9, [ 0 ], { a => 1 }); 1 },
635 "hashref as the sample list");
636 like($@, qr/data must be a scalar or an arrayref/,
638 ok(!eval { Imager::i_psampf($imraw, 9, 9, [ 0 ], []); 1 },
639 "empty sample list");
640 like($@, qr/i_psampf: no samples provided in data/,
642 ok(!eval { Imager::i_psampf($imraw, 9, 9, [ 0 ], ""); 1 },
643 "empty scalar sample list");
644 like($@, qr/i_psampf: no samples provided in data/,
648 is(Imager::i_psampf($imraw, 0, 8, undef, [ (0) x 3 ], -1), undef,
650 is(_get_error(), "offset must be non-negative",
653 is(Imager::i_psampf($imraw, 0, 8, undef, [ (0) x 3 ], 4), undef,
655 is(_get_error(), "offset greater than number of samples supplied",
658 print "# end psampf tests\n";
662 print "# OO level scanline function tests\n";
663 my $im = Imager->new(xsize=>10, ysize=>10, channels=>4);
664 $im->setpixel(color=>$red, 'x'=>5, 'y'=>0);
665 ok(!$im->getscanline(), "getscanline() - supply nothing, get nothing");
666 is($im->errstr, "missing y parameter", "check message");
667 is_deeply([ map [ $_->rgba ], $im->getscanline('y'=>0) ],
668 [ ([ 0,0,0,0]) x 5, [ 255, 0, 0, 255 ], ([ 0,0,0,0]) x 4 ],
669 "getscanline, list context, default x, width");
670 is_deeply([ map [ $_->rgba ], $im->getscanline('y'=>0, 'x'=>3) ],
671 [ ([0,0,0,0]) x 2, [ 255, 0, 0, 255 ], ([0,0,0,0]) x 4 ],
672 "getscanline, list context, default width");
673 is_deeply([ map [ $_->rgba ], $im->getscanline('y'=>0, 'x'=>4, width=>4) ],
674 [ [0,0,0,0], [ 255, 0, 0, 255 ], ([0,0,0,0]) x 2 ],
675 "getscanline, list context, no defaults");
676 is(uc unpack("H*", $im->getscanline('y'=>0)),
677 "00000000" x 5 . "FF0000FF" . "00000000" x 4,
678 "getscanline, scalar context, default x, width");
679 is_deeply([ map [ $_->rgba ],
680 $im->getscanline('y'=>0, 'x'=>4, width=>4, type=>'float') ],
681 [ [0,0,0,0], [ 1.0, 0, 0, 1.0 ], ([0,0,0,0]) x 2 ],
682 "getscanline float, list context, no defaults");
683 is_deeply([ unpack "d*",
684 $im->getscanline('y'=>0, 'x'=>4, width=>4, type=>'float') ],
685 [ (0,0,0,0), ( 1.0, 0, 0, 1.0 ), (0,0,0,0) x 2 ],
686 "getscanline float, scalar context, no defaults");
688 ok(!$im->getscanline('y'=>0, type=>'invalid'),
689 "check invalid type checking");
690 like($im->errstr, qr/invalid type parameter/,
691 "check message for invalid type");
693 my @plin_colors = (($black) x 4, $red, $blue, ($green) x 4);
694 is($im->setscanline('y'=>1, pixels=>\@plin_colors), 10,
695 "setscanline - arrayref, default x");
696 is_deeply([ map [ $_->rgba ], @plin_colors ],
697 [ map [ $_->rgba ], $im->getscanline('y'=>1) ],
698 "check colors were written");
700 my @plin_colors2 = ( $green, $red, $blue, $red );
701 is($im->setscanline('y'=>2, 'x'=>3, pixels=>\@plin_colors2), 4,
702 "setscanline - arrayref");
704 # using map instead of x here due to a bug in some versions of Test::More
705 # fixed in the latest Test::More
706 is_deeply([ ( map [ 0,0,0,0 ], 1..3), (map [ $_->rgba ], @plin_colors2),
707 ( map [ 0,0,0,0 ], 1..3) ],
708 [ map [ $_->rgba ], $im->getscanline('y'=>2) ],
709 "check write to middle of line");
711 my $raw_colors = pack "H*", "FF00FFFF"."FF0000FF"."FFFFFFFF";
712 is($im->setscanline('y'=>3, 'x'=>2, pixels=>$raw_colors), 3,
713 "setscanline - scalar, default raw type")
714 or print "# ",$im->errstr,"\n";
715 is(uc unpack("H*", $im->getscanline('y'=>3, 'x'=>1, 'width'=>5)),
716 "00000000".uc(unpack "H*", $raw_colors)."00000000",
720 my @fcolors = ( $f_red, $f_blue, $f_black, $f_green );
721 is($im->setscanline('y'=>4, 'x'=>3, pixels=>\@fcolors), 4,
722 "setscanline - float arrayref");
723 is_deeply([ map [ $_->rgba ], @fcolors ],
724 [ map [ $_->rgba ], $im->getscanline('y'=>4, 'x'=>3, width=>4, type=>'float') ],
727 my $packed_fcolors = pack "d*", map $_->rgba, @fcolors;
728 is($im->setscanline('y'=>5, 'x'=>4, pixels=>$packed_fcolors, type=>'float'), 4,
729 "setscanline - float scalar");
730 is_deeply([ map [ $_->rgba ], @fcolors ],
731 [ map [ $_->rgba ], $im->getscanline('y'=>5, 'x'=>4, width=>4, type=>'float') ],
735 is_deeply([ $im->getsamples('y'=>1, channels=>[ 0 ]) ],
736 [ map +($_->rgba)[0], @plin_colors ],
737 "get channel 0, list context, default x, width");
738 is_deeply([ unpack "C*", $im->getsamples('y'=>1, channels=>[0, 2]) ],
739 [ map { ($_->rgba)[0, 2] } @plin_colors ],
740 "get channel 0, 1, scalar context");
741 is_deeply([ $im->getsamples('y'=>4, 'x'=>3, width=>4, type=>'float',
743 [ map { ($_->rgba)[1,3] } @fcolors ],
744 "get channels 1,3, list context, float samples");
745 is_deeply([ unpack "d*",
746 $im->getsamples('y'=>4, 'x'=>3, width=>4,
747 type=>'float', channels=>[3,2,1,0]) ],
748 [ map { ($_->rgba)[3,2,1,0] } @fcolors ],
749 "get channels 3..0 as scalar, float samples");
751 print "# end OO level scanline function tests\n";
755 # for the non-gsamp_bits case with a target parameter it was
756 # treating the target parameter as a hashref
758 my $im = Imager->new(xsize => 10, ysize => 10);
759 my $c1 = NC(0, 63, 255);
760 my $c2 = NC(255, 128, 255);
761 is($im->setscanline(y => 1, pixels => [ ( $c1, $c2 ) x 5 ]),
762 10, "set some test data")
763 or diag "setscanline: ", $im->errstr;
765 is($im->getsamples(y => 1, x => 1, target => \@target, width => 3),
766 9, "getsamples to target");
767 is_deeply(\@target, [ 255, 128, 255, 0, 63, 255, 255, 128, 255 ],
771 my $im = Imager->new(xsize => 10, ysize => 10, bits => "double");
772 my $c1 = NCF(0, 0.25, 1.0);
773 my $c2 = NCF(1.0, 0.5, 1.0);
774 is($im->setscanline(y => 1, pixels => [ ( $c1, $c2 ) x 5 ]),
775 10, "set some test data")
776 or diag "setscanline: ", $im->errstr;
778 is($im->getsamples(y => 1, x => 1, target => \@target, width => 3, type => "float"),
779 9, "getsamples to target");
780 is_deeply(\@target, [ 1.0, 0.5, 1.0, 0, 0.25, 1.0, 1.0, 0.5, 1.0 ],
785 { # to avoid confusion, i_glin/i_glinf modified to return 0 in unused
786 # channels at the perl level
787 my $im = Imager->new(xsize => 4, ysize => 4, channels => 2);
788 my $fill = Imager::Color->new(128, 255, 0, 0);
789 ok($im->box(filled => 1, color => $fill), 'fill it up');
790 my $data = $im->getscanline('y' => 0);
791 is(unpack("H*", $data), "80ff000080ff000080ff000080ff0000",
792 "check we get zeros");
793 my @colors = $im->getscanline('y' => 0);
794 is_color4($colors[0], 128, 255, 0, 0, "check object interface[0]");
795 is_color4($colors[1], 128, 255, 0, 0, "check object interface[1]");
796 is_color4($colors[2], 128, 255, 0, 0, "check object interface[2]");
797 is_color4($colors[3], 128, 255, 0, 0, "check object interface[3]");
799 my $dataf = $im->getscanline('y' => 0, type => 'float');
800 # the extra pack/unpack is to force double precision rather than long
801 # double, otherwise the test fails
802 is_deeply([ unpack("d*", $dataf) ],
803 [ unpack("d*", pack("d*", ( 128.0 / 255.0, 1.0, 0, 0, ) x 4)) ],
804 "check we get zeroes (double)");
805 my @fcolors = $im->getscanline('y' => 0, type => 'float');
806 is_fcolor4($fcolors[0], 128.0/255.0, 1.0, 0, 0, "check object interface[0]");
807 is_fcolor4($fcolors[1], 128.0/255.0, 1.0, 0, 0, "check object interface[1]");
808 is_fcolor4($fcolors[2], 128.0/255.0, 1.0, 0, 0, "check object interface[2]");
809 is_fcolor4($fcolors[3], 128.0/255.0, 1.0, 0, 0, "check object interface[3]");
812 { # check the channel mask function
814 my $im = Imager->new(xsize => 10, ysize=>10, bits=>8);
816 mask_tests($im, 0.005);
819 { # check bounds checking
820 my $im = Imager->new(xsize => 10, ysize => 10);
822 image_bounds_checks($im);
825 { # setsamples() interface to psamp()
826 my $im = Imager->new(xsize => 10, ysize => 10);
827 is($im->setsamples(y => 1, x => 2, data => [ 1 .. 6 ]), 6,
828 "simple put (array), default channels");
829 is_deeply([ $im->getsamples(y => 1, x => 0) ],
830 [ (0) x 6, 1 .. 6, (0) x 18 ], "check they were stored");
831 is($im->setsamples(y => 3, x => 3, data => pack("C*", 2 .. 10 )), 9,
832 "simple put (scalar), default channels")
834 is_deeply([ $im->getsamples(y => 3, x => 0) ],
835 [ (0) x 9, 2 .. 10, (0) x 12 ], "check they were stored");
836 is($im->setsamples(y => 4, x => 4, data => [ map $_ / 254.5, 1 .. 6 ], type => 'float'),
837 6, "simple put (float array), default channels");
838 is_deeply([ $im->getsamples(y => 4, x => 0) ],
839 [ (0) x 12, 1 .. 6, (0) x 12 ], "check they were stored");
841 is($im->setsamples(y => 5, x => 3, data => pack("d*", map $_ / 254.5, 1 .. 6), type => 'float'),
842 6, "simple put (float scalar), default channels");
843 is_deeply([ $im->getsamples(y => 5, x => 0) ],
844 [ (0) x 9, 1 .. 6, (0) x 15 ], "check they were stored");
846 is($im->setsamples(y => 7, x => 3, data => [ 0 .. 18 ], offset => 1), 18,
847 "setsamples offset");
848 is_deeply([ $im->getsamples(y => 7) ],
849 [ (0) x 9, 1 .. 18, (0) x 3 ],
852 is($im->setsamples(y => 8, x => 3, data => [ map $_ / 254.9, 0 .. 18 ],
853 offset => 1, type => 'float'),
854 18, "setsamples offset (float)");
855 is_deeply([ $im->getsamples(y => 8) ],
856 [ (0) x 9, 1 .. 18, (0) x 3 ],
859 is_deeply([ $im->setsamples(y => 6, x => 10, data => [ (0) x 3 ]) ],
860 [], "check out of range result (8bit)");
861 is($im->errstr, $psamp_outside_error, "check error message");
863 is_deeply([ $im->setsamples(y => 6, x => 10, data => [ (0) x 3 ], type => "float") ],
864 [], "check out of range result (float)");
865 is($im->errstr, $psamp_outside_error, "check error message");
867 is_deeply([ $im->setsamples(y => 6, x => 2, channels => [0, 1, 3 ],
868 data => [ (0) x 3 ]) ],
869 [], "check bad channels (8bit)");
870 is($im->errstr, "No channel 3 in this image",
871 "check error message");
873 is_deeply([ $im->setsamples(y => 6, x => 2, channels => [0, 1, 3 ],
874 data => [ (0) x 3 ], type => "float") ],
875 [], "check bad channels (float)");
876 is($im->errstr, "No channel 3 in this image",
877 "check error message");
879 is($im->setsamples(y => 5, data => [ (0) x 3 ], type => "bad"),
880 undef, "setsamples with bad type");
881 is($im->errstr, "setsamples: type parameter invalid",
882 "check error message");
883 is($im->setsamples(y => 5),
884 undef, "setsamples with no data");
885 is($im->errstr, "setsamples: data parameter missing",
886 "check error message");
888 is($im->setsamples(y => 5, data => undef),
889 undef, "setsamples with undef data");
890 is($im->errstr, "setsamples: data parameter not defined",
891 "check error message");
893 my $imempty = Imager->new;
894 is($imempty->setsamples(y => 0, data => [ (0) x 3 ]), undef,
895 "setsamples to empty image");
896 is($imempty->errstr, "setsamples: empty input image",
897 "check error message");
900 { # getpixel parameters
901 my $im = Imager->new(xsize => 10, ysize => 10);
902 $im->box(filled => 1, xmax => 4, color => NC(255, 0, 0));
903 $im->box(filled => 1, xmin => 5, ymax => 4, color => NC(0, 255, 255));
904 $im->box(filled => 1, xmin => 5, ymin => 5, color => NC(255, 0, 255));
906 my $empty = Imager->new;
907 ok(!$empty->getpixel(x => 0, y => 0), "getpixel empty image");
908 is($empty->errstr, "getpixel: empty input image", "check message");
910 ok(!$im->getpixel(y => 0), "missing x");
911 is($im->errstr, "getpixel: missing x or y parameter", "check message");
913 $im->_set_error("something different");
914 ok(!$im->getpixel(x => 0), "missing y");
915 is($im->errstr, "getpixel: missing x or y parameter", "check message");
917 ok(!$im->getpixel(x => [], y => 0), "empty x array ref");
918 is($im->errstr, "getpixel: x is a reference to an empty array",
921 ok(!$im->getpixel(x => 0, y => []), "empty y array ref");
922 is($im->errstr, "getpixel: y is a reference to an empty array",
925 ok(!$im->getpixel(x => 0, y => 0, type => "bad"), "bad type (scalar path)");
926 is($im->errstr, "getpixel: type must be '8bit' or 'float'",
929 $im->_set_error("something different");
930 ok(!$im->getpixel(x => [ 0 ], y => [ 0 ], type => "bad"),
931 "bad type (array path)");
932 is($im->errstr, "getpixel: type must be '8bit' or 'float'",
937 is_color3($im->getpixel(x => 1, y => 0), 255, 0, 0,
939 is_color3($im->getpixel(x => 8, y => 1), 0, 255, 255,
941 is_color3($im->getpixel(x => 8, y => 7), 255, 0, 255,
946 my @colors = $im->getpixel(x => [ 0, 8, 7 ], y => [ 0, 7, 3 ]);
947 is(@colors, 3, "getpixel 2 3 element array refs");
948 is_color3($colors[0], 255, 0, 0, "check first color");
949 is_color3($colors[1], 255, 0, 255, "check second color");
950 is_color3($colors[2], 0, 255, 255, "check third color");
955 my @colors = $im->getpixel(x => 5, y => [ 4, 5, 9 ]);
956 is(@colors, 3, "getpixel x scalar, y arrayref of 3");
957 is_color3($colors[0], 0, 255, 255, "check first color");
958 is_color3($colors[1], 255, 0, 255, "check second color");
959 is_color3($colors[2], 255, 0, 255, "check third color");
963 my @colors = $im->getpixel(x => [ 0, 4, 5 ], y => 2);
964 is(@colors, 3, "getpixel y scalar, x arrayref of 3");
965 is_color3($colors[0], 255, 0, 0, "check first color");
966 is_color3($colors[1], 255, 0, 0, "check second color");
967 is_color3($colors[2], 0, 255, 255, "check third color");
971 is_fcolor3($im->getpixel(x => 1, y => 0, type => 'float'),
972 1.0, 0, 0, "getpixel(1,0) float");
973 is_fcolor3($im->getpixel(x => 8, y => 1, type => 'float'),
974 0, 1.0, 1.0, "getpixel(8,1) float");
975 is_fcolor3($im->getpixel(x => 8, y => 7, type => 'float'),
976 1.0, 0, 1.0, "getpixel(8,7) float");
978 my @colors = $im->getpixel(x => [ 0, 8, 7 ], y => [ 0, 7, 3 ], type => 'float');
979 is(@colors, 3, "getpixel 2 3 element array refs (float)");
980 is_fcolor3($colors[0], 1, 0, 0, "check first color");
981 is_fcolor3($colors[1], 1, 0, 1, "check second color");
982 is_fcolor3($colors[2], 0, 1, 1, "check third color");
986 my @colors = $im->getpixel(x => [ 0, -1, 5, 10 ], y => 0);
987 is(@colors, 4, "should be 4 entries")
989 is_color3($colors[0], 255, 0, 0, "first red");
990 is($colors[1], undef, "second undef");
991 is_color3($colors[2], 0, 255, 255, "third cyan");
992 is($colors[3], undef, "fourth undef");
996 my @colors = $im->getpixel(x => [ 0, -1, 5, 10 ], y => 0, type => "float");
997 is(@colors, 4, "should be 4 entries")
999 is_fcolor3($colors[0], 1.0, 0, 0, "first red");
1000 is($colors[1], undef, "second undef");
1001 is_fcolor3($colors[2], 0, 1.0, 1.0, "third cyan");
1002 is($colors[3], undef, "fourth undef");
1007 my $im = Imager->new(xsize => 10, ysize => 10);
1009 my $empty = Imager->new;
1010 ok(!$empty->setpixel(x => 0, y => 0, color => $red),
1011 "setpixel on empty image");
1012 is($empty->errstr, "setpixel: empty input image", "check message");
1014 ok(!$im->setpixel(y => 0, color => $red), "missing x");
1015 is($im->errstr, "setpixel: missing x or y parameter", "check message");
1017 $im->_set_error("something different");
1018 ok(!$im->setpixel(x => 0, color => $red), "missing y");
1019 is($im->errstr, "setpixel: missing x or y parameter", "check message");
1021 ok(!$im->setpixel(x => [], y => 0, color => $red), "empty x array ref");
1022 is($im->errstr, "setpixel: x is a reference to an empty array",
1025 ok(!$im->setpixel(x => 0, y => [], color => $red), "empty y array ref");
1026 is($im->errstr, "setpixel: y is a reference to an empty array",
1029 ok(!$im->setpixel(x => 0, y => 0, color => "not really a color"),
1030 "color not a color");
1031 is($im->errstr, "setpixel: No color named not really a color found",
1036 is($im->setpixel(x => 0, y => 0, color => $red), $im,
1038 or diag "simple set float: ", $im->errstr;
1039 is_color3($im->getpixel(x => 0, y => 0), 255, 0, 0, "check stored pixel");
1041 is($im->setpixel(x => 1, y => 2, color => $f_red), $im,
1042 "simple setpixel (float)")
1043 or diag "simple set float: ", $im->errstr;
1044 is_color3($im->getpixel(x => 1, y => 2), 255, 0, 0, "check stored pixel");
1046 is($im->setpixel(x => -1, y => 0, color => $red), undef,
1047 "simple setpixel outside of image");
1048 is($im->setpixel(x => 0, y => -1, color => $f_red), undef,
1049 "simple setpixel (float) outside of image");
1052 is($im->setpixel( x => [ 0, 8, 7 ], y => [ 0, 7, 3 ], color => $blue),
1053 3, "setpixel with 3 element array refs");
1054 my @colors = $im->getpixel(x => [ 8, 7, 0 ], y => [ 7, 3, 0 ]);
1055 is_color3($colors[0], 0, 0, 255, "check first color");
1056 is_color3($colors[1], 0, 0, 255, "check second color");
1057 is_color3($colors[2], 0, 0, 255, "check third color");
1061 is($im->setpixel(x => 5, y => [ 4, 5, 9 ], color => $green), 3,
1062 "setpixel with x scalar, y arrayref of 3");
1063 my @colors = $im->getpixel(x => [ 5, 5, 5 ], y => [ 4, 5, 9 ]);
1064 is_color3($colors[0], 0, 255, 0, "check first color");
1065 is_color3($colors[1], 0, 255, 0, "check second color");
1066 is_color3($colors[2], 0, 255, 0, "check third color");
1070 is($im->setpixel(x => [ 0, 4, 5 ], y => 2, color => $blue), 3,
1071 "setpixel with y scalar, x arrayref of 3");
1072 my @colors = $im->getpixel(x => [ 0, 4, 5 ], y => [ 2, 2, 2 ]);
1073 is_color3($colors[0], 0, 0, 255, "check first color");
1074 is_color3($colors[1], 0, 0, 255, "check second color");
1075 is_color3($colors[2], 0, 0, 255, "check third color");
1079 is($im->setpixel(x => [ 0, -1, 10, 5, 0 ], y => [ 0, 1, 2, 3, 1 ], color => $blue), 3,
1080 "set array with two bad locations")
1081 or diag "set array bad locations: ", $im->errstr;
1082 my @colors = $im->getpixel(x => [ 0, 5, 0 ], y => [ 0, 3, 1 ]);
1083 is_color3($colors[0], 0, 0, 255, "check first color");
1084 is_color3($colors[1], 0, 0, 255, "check second color");
1085 is_color3($colors[2], 0, 0, 255, "check third color");
1088 is($im->setpixel(x => [ 0, -1, 10, 5, 0 ], y => [ 0, 1, 2, 3, 1 ], color => $f_green), 3,
1089 "set array with two bad locations (float)")
1090 or diag "set array bad locations (float): ", $im->errstr;
1091 my @colors = $im->getpixel(x => [ 0, 5, 0 ], y => [ 0, 3, 1 ]);
1092 is_color3($colors[0], 0, 255, 0, "check first color");
1093 is_color3($colors[1], 0, 255, 0, "check second color");
1094 is_color3($colors[2], 0, 255, 0, "check third color");
1097 is($im->setpixel(x => 0, y => 9), $im, "setpixel() default color")
1098 or diag "setpixel default color: ", $im->errstr;
1099 is_color3($im->getpixel(x => 0, y => 9), 255, 255, 255,
1105 my $empty = Imager->new;
1106 ok(!$empty->addtag(name => "foo", value => 1),
1107 "can't addtag on an empty image");
1108 is($empty->errstr, "addtag: empty input image",
1109 "check error message");
1110 ok(!$empty->settag(name => "foo", value => 1),
1111 "can't settag on an empty image");
1112 is($empty->errstr, "settag: empty input image",
1113 "check error message");
1114 ok(!$empty->deltag(name => "foo"), "can't deltag on an empty image");
1115 is($empty->errstr, "deltag: empty input image",
1116 "check error message");
1117 ok(!$empty->tags(name => "foo"), "can't tags on an empty image");
1118 is($empty->errstr, "tags: empty input image",
1119 "check error message");
1122 Imager->close_log();
1124 unless ($ENV{IMAGER_KEEP_FILES}) {
1125 unlink "testout/t01introvert.log";
1129 my ($im, $color, $expected) = @_;
1130 my $index = Imager::i_addcolors($im, $color);
1131 ok($index, "got index");
1133 is(0+$index, $expected, "index matched expected");
1134 my ($new) = Imager::i_getcolors($im, $index);
1135 ok($new, "got the color");
1136 ok(color_cmp($new, $color) == 0, "color matched what was added");
1142 # my ($a1, $a2) = @_;
1143 # my $len = @$a1 < @$a2 ? @$a1 : @$a2;
1144 # for my $i (0..$len-1) {
1145 # my $diff = $a1->[$i] <=> $a2->[$i]
1148 # return @$a1 <=> @$a2;
1153 print "# ", map(sprintf("%02X", $_), ($col->rgba)[0..2]),"\n";
1158 my @errors = Imager::i_errors();
1159 return join(": ", map $_->[0], @errors);