]> git.imager.perl.org - imager.git/blame - t/t01introvert.t
- new example for convert() method based on Leolo's query
[imager.git] / t / t01introvert.t
CommitLineData
faa9b3e7
TC
1#!perl -w
2# t/t01introvert.t - tests internals of image formats
3# to make sure we get expected values
faa9b3e7
TC
4
5use strict;
61753090 6use lib 't';
241defe8 7use Test::More tests=>124;
faa9b3e7 8
61753090 9BEGIN { use_ok(Imager => qw(:handy :all)) }
faa9b3e7 10
1501d9b3
TC
11require "t/testtools.pl";
12
faa9b3e7
TC
13init_log("testout/t01introvert.log",1);
14
15my $im_g = Imager::ImgRaw::new(100, 101, 1);
16
61753090
TC
17is(Imager::i_img_getchannels($im_g), 1, "1 channel image channel count");
18ok(Imager::i_img_getmask($im_g) & 1, "1 channel image mask");
19ok(!Imager::i_img_virtual($im_g), "1 channel image not virtual");
20is(Imager::i_img_bits($im_g), 8, "1 channel image has 8 bits/sample");
21is(Imager::i_img_type($im_g), 0, "1 channel image is direct");
faa9b3e7
TC
22
23my @ginfo = Imager::i_img_info($im_g);
61753090
TC
24is($ginfo[0], 100, "1 channel image width");
25is($ginfo[1], 101, "1 channel image height");
faa9b3e7
TC
26
27undef $im_g; # can we check for release after this somehow?
28
29my $im_rgb = Imager::ImgRaw::new(100, 101, 3);
30
61753090
TC
31is(Imager::i_img_getchannels($im_rgb), 3, "3 channel image channel count");
32is((Imager::i_img_getmask($im_rgb) & 7), 7, "3 channel image mask");
33is(Imager::i_img_bits($im_rgb), 8, "3 channel image has 8 bits/sample");
34is(Imager::i_img_type($im_rgb), 0, "3 channel image is direct");
faa9b3e7
TC
35
36undef $im_rgb;
37
38my $im_pal = Imager::i_img_pal_new(100, 101, 3, 256);
39
61753090
TC
40ok($im_pal, "make paletted image");
41is(Imager::i_img_getchannels($im_pal), 3, "pal img channel count");
42is(Imager::i_img_bits($im_pal), 8, "pal img bits");
43is(Imager::i_img_type($im_pal), 1, "pal img is paletted");
faa9b3e7
TC
44
45my $red = NC(255, 0, 0);
46my $green = NC(0, 255, 0);
47my $blue = NC(0, 0, 255);
48
61753090
TC
49my $red_idx = check_add($im_pal, $red, 0);
50my $green_idx = check_add($im_pal, $green, 1);
51my $blue_idx = check_add($im_pal, $blue, 2);
faa9b3e7
TC
52
53# basic writing of palette indicies
54# fill with red
61753090
TC
55is(Imager::i_ppal($im_pal, 0, 0, ($red_idx) x 100), 100,
56 "write red 100 times");
faa9b3e7 57# and blue
61753090
TC
58is(Imager::i_ppal($im_pal, 50, 0, ($blue_idx) x 50), 50,
59 "write blue 50 times");
faa9b3e7
TC
60
61# make sure we get it back
62my @pals = Imager::i_gpal($im_pal, 0, 100, 0);
61753090
TC
63ok(!grep($_ != $red_idx, @pals[0..49]), "check for red");
64ok(!grep($_ != $blue_idx, @pals[50..99]), "check for blue");
65is(Imager::i_gpal($im_pal, 0, 100, 0), "\0" x 50 . "\2" x 50,
66 "gpal in scalar context");
faa9b3e7 67my @samp = Imager::i_gsamp($im_pal, 0, 100, 0, 0, 1, 2);
61753090 68is(@samp, 300, "gsamp count in list context");
faa9b3e7 69my @samp_exp = ((255, 0, 0) x 50, (0, 0, 255) x 50);
61753090 70is_deeply(\@samp, \@samp_exp, "gsamp list deep compare");
faa9b3e7 71my $samp = Imager::i_gsamp($im_pal, 0, 100, 0, 0, 1, 2);
61753090
TC
72is(length($samp), 300, "gsamp scalar length");
73is($samp, "\xFF\0\0" x 50 . "\0\0\xFF" x 50, "gsamp scalar bytes");
faa9b3e7
TC
74
75# reading indicies as colors
61753090
TC
76my $c_red = Imager::i_get_pixel($im_pal, 0, 0);
77ok($c_red, "got the red pixel");
78ok(color_cmp($red, $c_red) == 0, "and it's red");
79my $c_blue = Imager::i_get_pixel($im_pal, 50, 0);
80ok($c_blue, "got the blue pixel");
81ok(color_cmp($blue, $c_blue) == 0, "and it's blue");
faa9b3e7
TC
82
83# drawing with colors
61753090 84ok(Imager::i_ppix($im_pal, 0, 0, $green) == 0, "draw with color in palette");
faa9b3e7 85# that was in the palette, should still be paletted
61753090 86is(Imager::i_img_type($im_pal), 1, "image still paletted");
faa9b3e7 87
61753090
TC
88my $c_green = Imager::i_get_pixel($im_pal, 0, 0);
89ok($c_green, "got green pixel");
90ok(color_cmp($green, $c_green) == 0, "and it's green");
faa9b3e7 91
61753090
TC
92is(Imager::i_colorcount($im_pal), 3, "still 3 colors in palette");
93is(Imager::i_findcolor($im_pal, $green), 1, "and green is the second");
faa9b3e7
TC
94
95my $black = NC(0, 0, 0);
96# this should convert the image to RGB
61753090
TC
97ok(Imager::i_ppix($im_pal, 1, 0, $black) == 0, "draw with black (not in palette)");
98is(Imager::i_img_type($im_pal), 0, "pal img shouldn't be paletted now");
faa9b3e7
TC
99
100my %quant =
101 (
102 colors => [$red, $green, $blue, $black],
103 makemap => 'none',
104 );
105my $im_pal2 = Imager::i_img_to_pal($im_pal, \%quant);
61753090
TC
106ok($im_pal2, "got an image from quantizing");
107is(@{$quant{colors}}, 4, "has the right number of colours");
108is(Imager::i_gsamp($im_pal2, 0, 100, 0, 0, 1, 2),
109 "\0\xFF\0\0\0\0"."\xFF\0\0" x 48 . "\0\0\xFF" x 50,
110 "colors are still correct");
faa9b3e7
TC
111
112# test the OO interfaces
61753090
TC
113my $impal2 = Imager->new(type=>'pseudo', xsize=>200, ysize=>201);
114ok($impal2, "make paletted via OO");
115is($impal2->getchannels, 3, "check channels");
116is($impal2->bits, 8, "check bits");
117is($impal2->type, 'paletted', "check type");
faa9b3e7
TC
118
119{
61753090
TC
120 my $red_idx = $impal2->addcolors(colors=>[$red]);
121 ok($red_idx, "add red to OO");
122 is(0+$red_idx, 0, "and it's expected index for red");
123 my $blue_idx = $impal2->addcolors(colors=>[$blue, $green]);
124 ok($blue_idx, "add blue/green via OO");
125 is($blue_idx, 1, "and it's expected index for blue");
faa9b3e7
TC
126 my $green_idx = $blue_idx + 1;
127 my $c = $impal2->getcolors(start=>$green_idx);
61753090 128 ok(color_cmp($green, $c) == 0, "found green where expected");
faa9b3e7 129 my @cols = $impal2->getcolors;
61753090 130 is(@cols, 3, "got 3 colors");
faa9b3e7 131 my @exp = ( $red, $blue, $green );
61753090 132 my $good = 1;
faa9b3e7
TC
133 for my $i (0..2) {
134 if (color_cmp($cols[$i], $exp[$i])) {
61753090 135 $good = 0;
faa9b3e7
TC
136 last;
137 }
138 }
61753090
TC
139 ok($good, "all colors in palette as expected");
140 is($impal2->colorcount, 3, "and colorcount returns 3");
141 is($impal2->maxcolors, 256, "maxcolors as expected");
142 is($impal2->findcolor(color=>$blue), 1, "findcolors found blue");
143 ok($impal2->setcolors(start=>0, colors=>[ $blue, $red ]),
144 "we can setcolors");
faa9b3e7
TC
145
146 # make an rgb version
147 my $imrgb2 = $impal2->to_rgb8();
61753090 148 is($imrgb2->type, 'direct', "converted is direct");
faa9b3e7
TC
149
150 # and back again, specifying the palette
151 my @colors = ( $red, $blue, $green );
152 my $impal3 = $imrgb2->to_paletted(colors=>\@colors,
153 make_colors=>'none',
61753090
TC
154 translate=>'closest');
155 ok($impal3, "got a paletted image from conversion");
faa9b3e7
TC
156 dump_colors(@colors);
157 print "# in image\n";
158 dump_colors($impal3->getcolors);
61753090
TC
159 is($impal3->colorcount, 3, "new image has expected color table size");
160 is($impal3->type, 'paletted', "and is paletted");
faa9b3e7
TC
161}
162
61753090
TC
163ok(!Imager->new(xsize=>0, ysize=>1), "fail to create 0 height image");
164cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
1501d9b3 165 "0 height error message check");
61753090
TC
166ok(!Imager->new(xsize=>1, ysize=>0), "fail to create 0 width image");
167cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
1501d9b3 168 "0 width error message check");
61753090
TC
169ok(!Imager->new(xsize=>-1, ysize=>1), "fail to create -ve height image");
170cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
1501d9b3 171 "-ve width error message check");
61753090
TC
172ok(!Imager->new(xsize=>1, ysize=>-1), "fail to create -ve width image");
173cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
1501d9b3 174 "-ve height error message check");
61753090
TC
175ok(!Imager->new(xsize=>-1, ysize=>-1), "fail to create -ve width/height image");
176cmp_ok(Imager->errstr, '=~', qr/Image sizes must be positive/,
1501d9b3
TC
177 "-ve width/height error message check");
178
61753090
TC
179ok(!Imager->new(xsize=>1, ysize=>1, channels=>0),
180 "fail to create a zero channel image");
181cmp_ok(Imager->errstr, '=~', qr/channels must be between 1 and 4/,
1501d9b3 182 "out of range channel message check");
61753090
TC
183ok(!Imager->new(xsize=>1, ysize=>1, channels=>5),
184 "fail to create a five channel image");
185cmp_ok(Imager->errstr, '=~', qr/channels must be between 1 and 4/,
1501d9b3
TC
186 "out of range channel message check");
187
653ea321
TC
188{
189 # https://rt.cpan.org/Ticket/Display.html?id=8213
190 # check for handling of memory allocation of very large images
191 # only test this on 32-bit machines - on a 64-bit machine it may
192 # result in trying to allocate 4Gb of memory, which is unfriendly at
193 # least and may result in running out of memory, causing a different
194 # type of exit
61753090
TC
195 SKIP:
196 {
197 use Config;
198 skip("don't want to allocate 4Gb", 8) unless $Config{intsize} == 4;
199
f8906310 200 my $uint_range = 256 ** $Config{intsize};
653ea321
TC
201 print "# range $uint_range\n";
202 my $dim1 = int(sqrt($uint_range))+1;
203
204 my $im_b = Imager->new(xsize=>$dim1, ysize=>$dim1, channels=>1);
61753090 205 is($im_b, undef, "integer overflow check - 1 channel");
653ea321
TC
206
207 $im_b = Imager->new(xisze=>$dim1, ysize=>1, channels=>1);
61753090 208 ok($im_b, "but same width ok");
653ea321 209 $im_b = Imager->new(xisze=>1, ysize=>$dim1, channels=>1);
61753090
TC
210 ok($im_b, "but same height ok");
211 cmp_ok(Imager->errstr, '=~', qr/integer overflow/,
653ea321
TC
212 "check the error message");
213
214 # do a similar test with a 3 channel image, so we're sure we catch
215 # the same case where the third dimension causes the overflow
216 my $dim3 = int(sqrt($uint_range / 3))+1;
217
218 $im_b = Imager->new(xsize=>$dim3, ysize=>$dim3, channels=>3);
61753090 219 is($im_b, undef, "integer overflow check - 3 channel");
653ea321
TC
220
221 $im_b = Imager->new(xisze=>$dim3, ysize=>1, channels=>3);
61753090 222 ok($im_b, "but same width ok");
653ea321 223 $im_b = Imager->new(xisze=>1, ysize=>$dim3, channels=>3);
61753090 224 ok($im_b, "but same height ok");
653ea321 225
61753090 226 cmp_ok(Imager->errstr, '=~', qr/integer overflow/,
653ea321
TC
227 "check the error message");
228 }
653ea321 229}
1501d9b3 230
34b3f7e6
TC
231{ # http://rt.cpan.org/NoAuth/Bug.html?id=9672
232 my $warning;
233 local $SIG{__WARN__} =
234 sub {
235 $warning = "@_";
236 my $printed = $warning;
237 $printed =~ s/\n$//;
238 $printed =~ s/\n/\n\#/g;
239 print "# ",$printed, "\n";
240 };
241 my $img = Imager->new(xsize=>10, ysize=>10);
242 $img->to_rgb8(); # doesn't really matter what the source is
243 cmp_ok($warning, '=~', 'void', "correct warning");
244 cmp_ok($warning, '=~', 't01introvert\\.t', "correct file");
245}
246
12b1fac2
TC
247{ # http://rt.cpan.org/NoAuth/Bug.html?id=11860
248 my $im = Imager->new(xsize=>2, ysize=>2);
249 $im->setpixel(x=>0, 'y'=>0, color=>$red);
250 $im->setpixel(x=>1, 'y'=>0, color=>$blue);
251
252 my @row = Imager::i_glin($im->{IMG}, 0, 2, 0);
253 is(@row, 2, "got 2 pixels from i_glin");
254 ok(color_cmp($row[0], $red) == 0, "red first");
255 ok(color_cmp($row[1], $blue) == 0, "then blue");
256}
257
241defe8
TC
258{ # general tag tests
259
260 # we don't care much about the image itself
261 my $im = Imager::ImgRaw::new(10, 10, 1);
262
263 ok(Imager::i_tags_addn($im, 'alpha', 0, 101), "i_tags_addn(...alpha, 0, 101)");
264 ok(Imager::i_tags_addn($im, undef, 99, 102), "i_tags_addn(...undef, 99, 102)");
265 is(Imager::i_tags_count($im), 2, "should have 2 tags");
266 ok(Imager::i_tags_addn($im, undef, 99, 103), "i_tags_addn(...undef, 99, 103)");
267 is(Imager::i_tags_count($im), 3, "should have 3 tags, despite the dupe");
268 is(Imager::i_tags_find($im, 'alpha', 0), '0 but true', "find alpha");
269 is(Imager::i_tags_findn($im, 99, 0), 1, "find 99");
270 is(Imager::i_tags_findn($im, 99, 2), 2, "find 99 again");
271 is(Imager::i_tags_get($im, 0), 101, "check first");
272 is(Imager::i_tags_get($im, 1), 102, "check second");
273 is(Imager::i_tags_get($im, 2), 103, "check third");
274
275 ok(Imager::i_tags_add($im, 'beta', 0, "hello", 0),
276 "add string with string key");
277 ok(Imager::i_tags_add($im, 'gamma', 0, "goodbye", 0),
278 "add another one");
279 ok(Imager::i_tags_add($im, undef, 199, "aloha", 0),
280 "add one keyed by number");
281 is(Imager::i_tags_find($im, 'beta', 0), 3, "find beta");
282 is(Imager::i_tags_find($im, 'gamma', 0), 4, "find gamma");
283 is(Imager::i_tags_findn($im, 199, 0), 5, "find 199");
284 ok(Imager::i_tags_delete($im, 2), "delete");
285 is(Imager::i_tags_find($im, 'beta', 0), 2, 'find beta after deletion');
286 ok(Imager::i_tags_delbyname($im, 'beta'), 'delete beta by name');
287 is(Imager::i_tags_find($im, 'beta', 0), undef, 'beta not there now');
288 is(Imager::i_tags_get_string($im, "gamma"), "goodbye",
289 'i_tags_get_string() on a string');
290 is(Imager::i_tags_get_string($im, 99), 102,
291 'i_tags_get_string() on a number entry');
292 ok(Imager::i_tags_delbycode($im, 99), 'delete by code');
293 is(Imager::i_tags_findn($im, 99, 0), undef, '99 not there now');
294 is(Imager::i_tags_count($im), 3, 'final count of 3');
295}
296
faa9b3e7 297sub check_add {
61753090
TC
298 my ($im, $color, $expected) = @_;
299 my $index = Imager::i_addcolors($im, $color);
300 ok($index, "got index");
faa9b3e7 301 print "# $index\n";
61753090
TC
302 is(0+$index, $expected, "index matched expected");
303 my ($new) = Imager::i_getcolors($im, $index);
304 ok($new, "got the color");
305 ok(color_cmp($new, $color) == 0, "color matched what was added");
faa9b3e7
TC
306
307 $index;
308}
309
310sub color_cmp {
311 my ($l, $r) = @_;
312 my @l = $l->rgba;
313 my @r = $r->rgba;
314 return $l[0] <=> $r[0]
315 || $l[1] <=> $r[1]
316 || $l[2] <=> $r[2];
317}
318
61753090
TC
319# sub array_ncmp {
320# my ($a1, $a2) = @_;
321# my $len = @$a1 < @$a2 ? @$a1 : @$a2;
322# for my $i (0..$len-1) {
323# my $diff = $a1->[$i] <=> $a2->[$i]
324# and return $diff;
325# }
326# return @$a1 <=> @$a2;
327# }
faa9b3e7
TC
328
329sub dump_colors {
330 for my $col (@_) {
331 print "# ", map(sprintf("%02X", $_), ($col->rgba)[0..2]),"\n";
332 }
333}