3 use Test::More tests => 247;
5 use Imager::Test qw(is_image is_image_similar test_image test_image_16 test_image_double test_image_raw);
7 BEGIN { use_ok("Imager::File::TIFF"); }
12 $|=1; # give us some progress in the test harness
13 init_log("testout/t106tiff.log",1);
15 my $green=i_color_new(0,255,0,255);
16 my $blue=i_color_new(0,0,255,255);
17 my $red=i_color_new(255,0,0,255);
19 my $img=test_image_raw();
21 my $ver_string = Imager::File::TIFF::i_tiff_libversion();
22 ok(my ($full, $major, $minor, $point) =
23 $ver_string =~ /Version +((\d+)\.(\d+).(\d+))/,
24 "extract library version")
25 or diag("Could not extract from:\n$ver_string");
26 diag("libtiff release $full") if $full;
27 # make something we can compare
28 my $cmp_ver = sprintf("%03d%03d%03d", $major, $minor, $point);
29 if ($cmp_ver lt '003007000') {
30 diag("You have an old version of libtiff - $full, some tests will be skipped");
33 Imager::i_tags_add($img, "i_xres", 0, "300", 0);
34 Imager::i_tags_add($img, "i_yres", 0, undef, 250);
35 # resolutionunit is centimeters
36 Imager::i_tags_add($img, "tiff_resolutionunit", 0, undef, 3);
37 Imager::i_tags_add($img, "tiff_software", 0, "t106tiff.t", 0);
38 open(FH,">testout/t106.tiff") || die "cannot open testout/t106.tiff for writing\n";
40 my $IO = Imager::io_new_fd(fileno(FH));
41 ok(Imager::File::TIFF::i_writetiff_wiol($img, $IO), "write low level")
42 or print "# ", Imager->_error_as_msg, "\n";
45 open(FH,"testout/t106.tiff") or die "cannot open testout/t106.tiff\n";
47 $IO = Imager::io_new_fd(fileno(FH));
48 my $cmpimg = Imager::File::TIFF::i_readtiff_wiol($IO);
49 ok($cmpimg, "read low-level");
53 print "# tiff average mean square pixel difference: ",sqrt(i_img_diff($img,$cmpimg))/150*150,"\n";
55 ok(!i_img_diff($img, $cmpimg), "compare written and read image");
57 # check the tags are ok
58 my %tags = map { Imager::i_tags_get($cmpimg, $_) }
59 0 .. Imager::i_tags_count($cmpimg) - 1;
60 ok(abs($tags{i_xres} - 300) < 0.5, "i_xres in range");
61 ok(abs($tags{i_yres} - 250) < 0.5, "i_yres in range");
62 is($tags{tiff_resolutionunit}, 3, "tiff_resolutionunit");
63 is($tags{tiff_software}, 't106tiff.t', "tiff_software");
64 is($tags{tiff_photometric}, 2, "tiff_photometric"); # PHOTOMETRIC_RGB is 2
65 is($tags{tiff_bitspersample}, 8, "tiff_bitspersample");
67 $IO = Imager::io_new_bufchain();
69 ok(Imager::File::TIFF::i_writetiff_wiol($img, $IO), "write to buffer chain");
70 my $tiffdata = Imager::io_slurp($IO);
72 open(FH,"testout/t106.tiff");
79 is($odata, $tiffdata, "same data in file as in memory");
81 # test Micksa's tiff writer
83 my $faximg = Imager::ImgRaw::new(1728, 2000, 1);
84 my $black = i_color_new(0,0,0,255);
85 my $white = i_color_new(255,255,255,255);
86 # vaguely test-patterny
87 i_box_filled($faximg, 0, 0, 1728, 2000, $white);
88 i_box_filled($faximg, 100,100,1628, 200, $black);
91 while ($width+$pos < 1628) {
92 i_box_filled($faximg, $pos, 300, $pos+$width-1, 400, $black);
96 open FH, "> testout/t106tiff_fax.tiff"
97 or die "Cannot create testout/t106tiff_fax.tiff: $!";
99 $IO = Imager::io_new_fd(fileno(FH));
100 ok(Imager::File::TIFF::i_writetiff_wiol_faxable($faximg, $IO, 1), "write faxable, low level");
103 # test the OO interface
104 my $ooim = Imager->new;
105 ok($ooim->read(file=>'testout/t106.tiff'), "read OO");
106 ok($ooim->write(file=>'testout/t106_oo.tiff'), "write OO");
108 # OO with the fax image
109 my $oofim = Imager->new;
110 ok($oofim->read(file=>'testout/t106tiff_fax.tiff'),
113 # this should have tags set for the resolution
114 %tags = map @$_, $oofim->tags;
115 is($tags{i_xres}, 204, "fax i_xres");
116 is($tags{i_yres}, 196, "fax i_yres");
117 ok(!$tags{i_aspect_only}, "i_aspect_only");
119 is($tags{tiff_resolutionunit}, 2, "tiff_resolutionunit");
120 is($tags{tiff_bitspersample}, 1, "tiff_bitspersample");
121 is($tags{tiff_photometric}, 0, "tiff_photometric");
123 ok($oofim->write(file=>'testout/t106_oo_fax.tiff', class=>'fax'),
124 "write OO, faxable");
126 # the following should fail since there's no type and no filename
128 ok(!$ooim->write(data=>\$oodata), "write with no type and no filename to guess with");
131 ok($ooim->write(data=>\$oodata, type=>'tiff'), "write to data")
132 or print "# ",$ooim->errstr, "\n";
133 is($oodata, $tiffdata, "check data matches between memory and file");
135 # make sure we can write non-fine mode
136 ok($oofim->write(file=>'testout/t106_oo_faxlo.tiff', class=>'fax', fax_fine=>0), "write OO, fax standard mode");
139 my $img4 = Imager->new;
140 ok($img4->read(file=>'testimg/comp4.tif'), "reading 4-bit paletted")
141 or print "# ", $img4->errstr, "\n";
142 is($img4->type, 'paletted', "image isn't paletted");
143 print "# colors: ", $img4->colorcount,"\n";
144 cmp_ok($img4->colorcount, '<=', 16, "more than 16 colors!");
145 #ok($img4->write(file=>'testout/t106_was4.ppm'),
146 # "Cannot write img4");
147 # I know I'm using BMP before it's test, but comp4.tif started life
149 my $bmp4 = Imager->new;
150 ok($bmp4->read(file=>'testimg/comp4.bmp'), "reading 4-bit bmp!");
151 my $diff = i_img_diff($img4->{IMG}, $bmp4->{IMG});
152 print "# diff $diff\n";
153 ok($diff == 0, "image mismatch");
154 my $img4t = Imager->new;
155 ok($img4t->read(file => 'testimg/comp4t.tif'), "read 4-bit paletted, tiled")
156 or print "# ", $img4t->errstr, "\n";
157 is_image($bmp4, $img4t, "check tiled version matches");
158 my $img8 = Imager->new;
159 ok($img8->read(file=>'testimg/comp8.tif'), "reading 8-bit paletted");
160 is($img8->type, 'paletted', "image isn't paletted");
161 print "# colors: ", $img8->colorcount,"\n";
162 #ok($img8->write(file=>'testout/t106_was8.ppm'),
163 # "Cannot write img8");
164 ok($img8->colorcount == 256, "more colors than expected");
165 my $bmp8 = Imager->new;
166 ok($bmp8->read(file=>'testimg/comp8.bmp'), "reading 8-bit bmp!");
167 $diff = i_img_diff($img8->{IMG}, $bmp8->{IMG});
168 print "# diff $diff\n";
169 ok($diff == 0, "image mismatch");
170 my $bad = Imager->new;
171 ok($bad->read(file=>'testimg/comp4bad.tif',
172 allow_incomplete=>1), "bad image not returned");
173 ok(scalar $bad->tags(name=>'i_incomplete'), "incomplete tag not set");
174 ok($img8->write(file=>'testout/t106_pal8.tif'), "writing 8-bit paletted");
175 my $cmp8 = Imager->new;
176 ok($cmp8->read(file=>'testout/t106_pal8.tif'),
177 "reading 8-bit paletted");
178 #print "# ",$cmp8->errstr,"\n";
179 is($cmp8->type, 'paletted', "pal8 isn't paletted");
180 is($cmp8->colorcount, 256, "pal8 bad colorcount");
181 $diff = i_img_diff($img8->{IMG}, $cmp8->{IMG});
182 print "# diff $diff\n";
183 ok($diff == 0, "written image doesn't match read");
184 ok($img4->write(file=>'testout/t106_pal4.tif'), "writing 4-bit paletted");
185 ok(my $cmp4 = Imager->new->read(file=>'testout/t106_pal4.tif'),
186 "reading 4-bit paletted");
187 is($cmp4->type, 'paletted', "pal4 isn't paletted");
188 is($cmp4->colorcount, 16, "pal4 bad colorcount");
189 $diff = i_img_diff($img4->{IMG}, $cmp4->{IMG});
190 print "# diff $diff\n";
191 ok($diff == 0, "written image doesn't match read");
197 if ($seekpos > length $work) {
198 $work .= "\0" x ($seekpos - length $work);
200 substr($work, $seekpos, length $what) = $what;
201 $seekpos += length $what;
206 my ($size, $maxread) = @_;
207 print "# io_reader($size, $maxread) pos $seekpos\n";
208 if ($seekpos + $maxread > length $work) {
209 $maxread = length($work) - $seekpos;
211 my $out = substr($work, $seekpos, $maxread);
212 $seekpos += length $out;
216 my ($size, $maxread) = @_;
217 print "# io_reader2($size, $maxread) pos $seekpos\n";
218 my $out = substr($work, $seekpos, $size);
219 $seekpos += length $out;
224 my ($offset, $whence) = @_;
225 print "# io_seeker($offset, $whence)\n";
226 if ($whence == SEEK_SET) {
229 elsif ($whence == SEEK_CUR) {
233 $seekpos = length($work) + $offset;
235 #print "-> $seekpos\n";
246 my $IO2 = Imager::io_new_cb(undef, \&io_reader, \&io_seeker, undef);
247 ok($IO2, "new readcb obj");
248 my $img5 = Imager::File::TIFF::i_readtiff_wiol($IO2);
249 ok($img5, "read via cb");
250 ok(i_img_diff($img5, $img) == 0, "read from cb diff");
255 my $IO3 = Imager::io_new_cb(undef, \&io_reader2, \&io_seeker, undef);
256 ok($IO3, "new readcb2 obj");
257 my $img6 = Imager::File::TIFF::i_readtiff_wiol($IO3);
258 ok($img6, "read via cb2");
259 ok(i_img_diff($img6, $img) == 0, "read from cb2 diff");
264 my $IO4 = Imager::io_new_cb(\&io_writer, \&io_reader, \&io_seeker,
266 ok($IO4, "new writecb obj");
267 ok(Imager::File::TIFF::i_writetiff_wiol($img, $IO4), "write to cb");
268 is($work, $odata, "write cb match");
269 ok($did_close, "write cb did close");
270 open D1, ">testout/d1.tiff" or die;
273 open D2, ">testout/d2.tiff" or die;
281 my $IO5 = Imager::io_new_cb(\&io_writer, \&io_reader, \&io_seeker,
283 ok($IO5, "new writecb obj 2");
284 ok(Imager::File::TIFF::i_writetiff_wiol($img, $IO5), "write to cb2");
285 is($work, $odata, "write cb2 match");
286 ok($did_close, "write cb2 did close");
288 open D3, ">testout/d3.tiff" or die;
293 { # check close failures are handled correctly
295 my $im = test_image();
296 my $fail_close = sub {
297 Imager::i_push_error(0, "synthetic close failure");
302 ok(!$im->write(type => "tiff",
303 readcb => \&io_reader,
304 writecb => \&io_writer,
305 seekcb => \&io_seeker,
306 closecb => $fail_close),
307 "check failing close fails");
308 like($im->errstr, qr/synthetic close failure/,
309 "check error message");
312 my $im = test_image();
313 my $fail_close = sub {
314 Imager::i_push_error(0, "synthetic close failure");
319 ok(!Imager->write_multi({type => "tiff",
320 readcb => \&io_reader,
321 writecb => \&io_writer,
322 seekcb => \&io_seeker,
323 closecb => $fail_close}, $im, $im),
324 "check failing close fails");
325 like(Imager->errstr, qr/synthetic close failure/,
326 "check error message");
330 # multi-image write/read
332 push(@imgs, map $ooim->copy(), 1..3);
333 for my $i (0..$#imgs) {
334 $imgs[$i]->addtag(name=>"tiff_pagename", value=>"Page ".($i+1));
336 my $rc = Imager->write_multi({file=>'testout/t106_multi.tif'}, @imgs);
337 ok($rc, "writing multiple images to tiff");
338 my @out = Imager->read_multi(file=>'testout/t106_multi.tif');
339 ok(@out == @imgs, "reading multiple images from tiff");
340 @out == @imgs or print "# ",scalar @out, " ",Imager->errstr,"\n";
341 for my $i (0..$#imgs) {
342 ok(i_img_diff($imgs[$i]{IMG}, $out[$i]{IMG}) == 0,
343 "comparing image $i");
344 my ($tag) = $out[$i]->tags(name=>'tiff_pagename');
345 is($tag, "Page ".($i+1),
346 "tag doesn't match original image");
349 # writing even more images to tiff - we weren't handling more than five
351 @imgs = map $ooim->copy(), 1..40;
352 $rc = Imager->write_multi({file=>'testout/t106_multi2.tif'}, @imgs);
353 ok($rc, "writing 40 images to tiff")
354 or diag("writing 40 images: " . Imager->errstr);
355 @out = Imager->read_multi(file=>'testout/t106_multi2.tif');
356 ok(@imgs == @out, "reading 40 images from tiff")
357 or diag("reading 40 images:" . Imager->errstr);
358 # force some allocation activity - helps crash here if it's the problem
361 # multi-image fax files
362 ok(Imager->write_multi({file=>'testout/t106_faxmulti.tiff', class=>'fax'},
363 $oofim, $oofim), "write multi fax image")
364 or diag("writing 40 fax pages: " . Imager->errstr);
365 @imgs = Imager->read_multi(file=>'testout/t106_faxmulti.tiff');
366 ok(@imgs == 2, "reading multipage fax")
367 or diag("reading 40 fax pages: " . Imager->errstr);
368 ok(Imager::i_img_diff($imgs[0]{IMG}, $oofim->{IMG}) == 0,
369 "compare first fax image");
370 ok(Imager::i_img_diff($imgs[1]{IMG}, $oofim->{IMG}) == 0,
371 "compare second fax image");
373 my ($format) = $imgs[0]->tags(name=>'i_format');
374 is($format, 'tiff', "check i_format tag");
376 my $unit = $imgs[0]->tags(name=>'tiff_resolutionunit');
377 ok(defined $unit && $unit == 2, "check tiff_resolutionunit tag");
378 my $unitname = $imgs[0]->tags(name=>'tiff_resolutionunit_name');
379 is($unitname, 'inch', "check tiff_resolutionunit_name tag");
381 my $warned = Imager->new;
382 ok($warned->read(file=>"testimg/tiffwarn.tif"), "read tiffwarn.tif");
383 my ($warning) = $warned->tags(name=>'i_warning');
384 ok(defined $warning, "check warning is set");
385 like($warning, qr/[Uu]nknown field with tag 28712/,
386 "check that warning tag correct");
388 { # support for reading a given page
389 # first build a simple test image
390 my $im1 = Imager->new(xsize=>50, ysize=>50);
391 $im1->box(filled=>1, color=>$blue);
392 $im1->addtag(name=>'tiff_pagename', value => "Page One");
393 my $im2 = Imager->new(xsize=>60, ysize=>60);
394 $im2->box(filled=>1, color=>$green);
395 $im2->addtag(name=>'tiff_pagename', value=>"Page Two");
398 my $page_file = 'testout/t106_pages.tif';
399 ok(Imager->write_multi({ file=> $page_file}, $im1, $im2),
400 "build simple multiimage for page tests");
401 my $imwork = Imager->new;
402 ok($imwork->read(file=>$page_file, page=>1),
404 is($im2->getwidth, $imwork->getwidth, "check width");
405 is($im2->getwidth, $imwork->getheight, "check height");
406 is(i_img_diff($imwork->{IMG}, $im2->{IMG}), 0,
407 "check image content");
408 my ($page_name) = $imwork->tags(name=>'tiff_pagename');
409 is($page_name, 'Page Two', "check tag we set");
411 # try an out of range page
412 ok(!$imwork->read(file=>$page_file, page=>2),
413 "check out of range page");
414 is($imwork->errstr, "could not switch to page 2", "check message");
417 { # test writing returns an error message correctly
418 # open a file read only and try to write to it
419 open TIFF, "> testout/t106_empty.tif" or die;
421 open TIFF, "< testout/t106_empty.tif"
422 or skip "Cannot open testout/t106_empty.tif for reading", 8;
424 my $im = Imager->new(xsize=>100, ysize=>100);
425 ok(!$im->write(fh => \*TIFF, type=>'tiff', buffered => 0),
426 "fail to write to read only handle");
427 cmp_ok($im->errstr, '=~', 'Could not create TIFF object: Error writing TIFF header: write\(\)',
428 "check error message");
429 ok(!Imager->write_multi({ type => 'tiff', fh => \*TIFF, buffered => 0 }, $im),
430 "fail to write multi to read only handle");
431 cmp_ok(Imager->errstr, '=~', 'Could not create TIFF object: Error writing TIFF header: write\(\)',
432 "check error message");
433 ok(!$im->write(fh => \*TIFF, type=>'tiff', class=>'fax', buffered => 0),
434 "fail to write to read only handle (fax)");
435 cmp_ok($im->errstr, '=~', 'Could not create TIFF object: Error writing TIFF header: write\(\)',
436 "check error message");
437 ok(!Imager->write_multi({ type => 'tiff', fh => \*TIFF, class=>'fax', buffered => 0 }, $im),
438 "fail to write multi to read only handle (fax)");
439 cmp_ok(Imager->errstr, '=~', 'Could not create TIFF object: Error writing TIFF header: write\(\)',
440 "check error message");
443 { # test reading returns an error correctly - use test script as an
445 my $im = Imager->new;
446 ok(!$im->read(file=>'t/t10tiff.t', type=>'tiff'),
447 "fail to read script as image");
448 # we get different magic number values depending on the platform
450 cmp_ok($im->errstr, '=~',
451 "Error opening file: Not a TIFF (?:or MDI )?file, bad magic number (8483 \\(0x2123\\)|8993 \\(0x2321\\))",
452 "check error message");
453 my @ims = Imager->read_multi(file =>'t/t106tiff.t', type=>'tiff');
454 ok(!@ims, "fail to read_multi script as image");
455 cmp_ok($im->errstr, '=~',
456 "Error opening file: Not a TIFF (?:or MDI )?file, bad magic number (8483 \\(0x2123\\)|8993 \\(0x2321\\))",
457 "check error message");
460 { # write_multi to data
462 my $im = Imager->new(xsize => 50, ysize => 50);
463 ok(Imager->write_multi({ data => \$data, type=>'tiff' }, $im, $im),
464 "write multi to in memory");
465 ok(length $data, "make sure something written");
466 my @im = Imager->read_multi(data => $data);
467 is(@im, 2, "make sure we can read it back");
468 is(Imager::i_img_diff($im[0]{IMG}, $im->{IMG}), 0,
469 "check first image");
470 is(Imager::i_img_diff($im[1]{IMG}, $im->{IMG}), 0,
471 "check second image");
474 { # handling of an alpha channel for various images
477 my $photo_cielab = 8;
480 [ 'srgb.tif', 3, $photo_rgb, '003005005' ],
481 [ 'srgba.tif', 4, $photo_rgb, '003005005' ],
482 [ 'srgbaa.tif', 4, $photo_rgb, '003005005' ],
483 [ 'scmyk.tif', 3, $photo_cmyk, '003005005' ],
484 [ 'scmyka.tif', 4, $photo_cmyk, '003005005' ],
485 [ 'scmykaa.tif', 4, $photo_cmyk, '003005005' ],
486 [ 'slab.tif', 3, $photo_cielab, '003006001' ],
489 for my $test (@alpha_images) {
490 my ($input, $channels, $photo, $need_ver) = @$test;
493 my $skipped = $channels == 4 ? 4 : 3;
494 $need_ver le $cmp_ver
495 or skip("Your ancient tifflib is buggy/limited for this test", $skipped);
496 my $im = Imager->new;
497 ok($im->read(file => "testimg/$input"),
498 "read alpha test $input")
499 or print "# ", $im->errstr, "\n";
500 is($im->getchannels, $channels, "channels for $input match");
501 is($im->tags(name=>'tiff_photometric'), $photo,
502 "photometric for $input match");
505 my $c = $im->getpixel(x => 0, 'y' => 7);
506 is(($c->rgba)[3], 0, "bottom row should have 0 alpha");
512 ok(grep($_ eq 'tiff', Imager->read_types), "check tiff in read types");
513 ok(grep($_ eq 'tiff', Imager->write_types), "check tiff in write types");
516 { # reading tile based images
517 my $im = Imager->new;
518 ok($im->read(file => 'testimg/pengtile.tif'), "read tiled image")
519 or print "# ", $im->errstr, "\n";
521 my $comp = Imager->new;
522 ok($comp->read(file => 'testimg/penguin-base.ppm'), 'read comparison image');
523 is_image($im, $comp, 'compare them');
527 { # failing to read tile based images
528 # we grab our tiled image and patch a tile offset to nowhere
529 ok(open(TIFF, '< testimg/pengtile.tif'), 'open pengtile.tif')
530 or skip 'cannot open testimg/pengtile.tif', 4;
532 $cmp_ver ge '003005007'
533 or skip("Your ancient tifflib has bad error handling", 4);
535 my $data = do { local $/; <TIFF>; };
537 # patch a tile offset
538 substr($data, 0x1AFA0, 4) = pack("H*", "00000200");
540 #open PIPE, "| bytedump -a | less" or die;
544 my $allow = Imager->new;
545 ok($allow->read(data => $data, allow_incomplete => 1),
546 "read incomplete tiled");
547 ok($allow->tags(name => 'i_incomplete'), 'i_incomplete set');
548 is($allow->tags(name => 'i_lines_read'), 173,
549 'check i_lines_read set appropriately');
551 my $fail = Imager->new;
552 ok(!$fail->read(data => $data), "read fail tiled");
555 { # read 16-bit/sample
556 my $im16 = Imager->new;
557 ok($im16->read(file => 'testimg/rgb16.tif'), "read 16-bit rgb");
558 is($im16->bits, 16, 'got a 16-bit image');
559 my $im16t = Imager->new;
560 ok($im16t->read(file => 'testimg/rgb16t.tif'), "read 16-bit rgb tiled");
561 is($im16t->bits, 16, 'got a 16-bit image');
562 is_image($im16, $im16t, 'check they match');
564 my $grey16 = Imager->new;
565 ok($grey16->read(file => 'testimg/grey16.tif'), "read 16-bit grey")
566 or print "# ", $grey16->errstr, "\n";
567 is($grey16->bits, 16, 'got a 16-bit image');
568 is($grey16->getchannels, 1, 'and its grey');
569 my $comp16 = $im16->convert(matrix => [ [ 0.299, 0.587, 0.114 ] ]);
570 is_image($grey16, $comp16, 'compare grey to converted');
572 my $grey32 = Imager->new;
573 ok($grey32->read(file => 'testimg/grey32.tif'), "read 32-bit grey")
574 or print "# ", $grey32->errstr, "\n";
575 is($grey32->bits, 'double', 'got a double image');
576 is($grey32->getchannels, 2, 'and its grey + alpha');
577 is($grey32->tags(name => 'tiff_bitspersample'), 32,
578 "check bits per sample");
579 my $base = test_image_double->convert(preset =>'grey')
580 ->convert(preset => 'addalpha');
581 is_image($grey32, $base, 'compare to original');
584 { # read 16, 32-bit/sample and compare to the original
585 my $rgba = Imager->new;
586 ok($rgba->read(file => 'testimg/srgba.tif'),
587 "read base rgba image");
588 my $rgba16 = Imager->new;
589 ok($rgba16->read(file => 'testimg/srgba16.tif'),
590 "read 16-bit/sample rgba image");
591 is_image($rgba, $rgba16, "check they match");
592 is($rgba16->bits, 16, 'check we got the right type');
594 my $rgba32 = Imager->new;
595 ok($rgba32->read(file => 'testimg/srgba32.tif'),
596 "read 32-bit/sample rgba image");
597 is_image($rgba, $rgba32, "check they match");
598 is($rgba32->bits, 'double', 'check we got the right type');
600 my $cmyka16 = Imager->new;
601 ok($cmyka16->read(file => 'testimg/scmyka16.tif'),
603 or print "# ", $cmyka16->errstr, "\n";
604 is($cmyka16->bits, 16, "check we got the right type");
605 is_image_similar($rgba, $cmyka16, 10, "check image data");
607 # tiled, non-contig, should fallback to RGBA code
608 my $rgbatsep = Imager->new;
609 ok($rgbatsep->read(file => 'testimg/rgbatsep.tif'),
610 "read tiled, separated rgba image")
611 or diag($rgbatsep->errstr);
612 is_image($rgba, $rgbatsep, "check they match");
615 my $pbm = Imager->new;
616 ok($pbm->read(file => 'testimg/imager.pbm'), "read original pbm");
617 my $tif = Imager->new;
618 ok($tif->read(file => 'testimg/imager.tif'), "read mono tif");
619 is_image($pbm, $tif, "compare them");
620 is($tif->type, 'paletted', 'check image type');
621 is($tif->colorcount, 2, 'check we got a "mono" image');
624 { # check alpha channels scaled correctly for fallback handler
625 my $im = Imager->new;
626 ok($im->read(file=>'testimg/alpha.tif'), 'read alpha check image');
634 my @alphas = ( 255, 191, 127, 63 );
636 my $msg = 'alpha check ok';
640 my $c = $im->getpixel(x => $x, 'y' => $y);
643 if ($alpha != $alphas[$y]) {
645 $msg = "($x,$y) alpha mismatch $alpha vs $alphas[$y]";
648 my $expect = $colors[$x];
649 for my $ch (0 .. 2) {
650 if (abs($expect->[$ch]-$c[$ch]) > 3) {
652 $msg = "($x,$y)[$ch] color mismatch got $c[$ch] vs expected $expect->[$ch]";
661 { # check alpha channels scaled correctly for greyscale
662 my $im = Imager->new;
663 ok($im->read(file=>'testimg/gralpha.tif'), 'read alpha check grey image');
664 my @greys = ( 0, 255, 52, 112 );
665 my @alphas = ( 255, 191, 127, 63 );
667 my $msg = 'alpha check ok';
671 my $c = $im->getpixel(x => $x, 'y' => $y);
672 my ($grey, $alpha) = $c->rgba;
673 if ($alpha != $alphas[$y]) {
675 $msg = "($x,$y) alpha mismatch $alpha vs $alphas[$y]";
678 if (abs($greys[$x] - $grey) > 3) {
680 $msg = "($x,$y) grey mismatch $grey vs $greys[$x]";
689 my $orig = test_image_16();
691 ok($orig->write(data => \$data, type => 'tiff',
692 tiff_compression => 'none'), "write 16-bit/sample");
693 my $im = Imager->new;
694 ok($im->read(data => $data), "read it back");
695 is_image($im, $orig, "check read data matches");
696 is($im->tags(name => 'tiff_bitspersample'), 16, "correct bits");
697 is($im->bits, 16, 'check image bits');
698 is($im->tags(name => 'tiff_photometric'), 2, "correct photometric");
699 is($im->tags(name => 'tiff_compression'), 'none', "no compression");
700 is($im->getchannels, 3, 'correct channels');
704 # and check compression
705 my $compress = Imager::File::TIFF::i_tiff_has_compression('lzw') ? 'lzw' : 'packbits';
706 my $orig = test_image()->convert(preset=>'grey')
707 ->convert(preset => 'addalpha');
709 ok($orig->write(data => \$data, type => 'tiff',
710 tiff_compression=> $compress),
712 or print "# ", $orig->errstr, "\n";
713 my $im = Imager->new;
714 ok($im->read(data => $data), "read it back");
715 is_image($im, $orig, "check read data matches");
716 is($im->tags(name => 'tiff_bitspersample'), 8, 'correct bits');
717 is($im->bits, 8, 'check image bits');
718 is($im->tags(name => 'tiff_photometric'), 1, 'correct photometric');
719 is($im->tags(name => 'tiff_compression'), $compress,
720 "$compress compression");
721 is($im->getchannels, 2, 'correct channels');
725 my $orig = test_image_double()->convert(preset=>'addalpha');
727 ok($orig->write(data => \$data, type => 'tiff',
728 tiff_compression => 'none'),
729 "write 32-bit/sample from double")
730 or print "# ", $orig->errstr, "\n";
731 my $im = Imager->new;
732 ok($im->read(data => $data), "read it back");
733 is_image($im, $orig, "check read data matches");
734 is($im->tags(name => 'tiff_bitspersample'), 32, "correct bits");
735 is($im->bits, 'double', 'check image bits');
736 is($im->tags(name => 'tiff_photometric'), 2, "correct photometric");
737 is($im->tags(name => 'tiff_compression'), 'none', "no compression");
738 is($im->getchannels, 4, 'correct channels');
742 my $im = test_image()->convert(preset => 'grey')
743 ->to_paletted(make_colors => 'mono',
744 translate => 'errdiff');
747 # fax compression is written as miniswhite
748 ok($im->write(data => \$faxdata, type => 'tiff',
749 tiff_compression => 'fax3'),
750 "write bilevel fax compressed");
751 my $fax = Imager->new;
752 ok($fax->read(data => $faxdata), "read it back");
753 ok($fax->is_bilevel, "got a bi-level image back");
754 is($fax->tags(name => 'tiff_compression'), 'fax3',
755 "check fax compression used");
756 is_image($fax, $im, "compare to original");
758 # other compresion written as minisblack
760 ok($im->write(data => \$packdata, type => 'tiff',
761 tiff_compression => 'jpeg'),
762 "write bilevel packbits compressed");
763 my $packim = Imager->new;
764 ok($packim->read(data => $packdata), "read it back");
765 ok($packim->is_bilevel, "got a bi-level image back");
766 is($packim->tags(name => 'tiff_compression'), 'packbits',
767 "check fallback compression used");
768 is_image($packim, $im, "compare to original");
771 { # fallback handling of tiff
772 is(Imager::File::TIFF::i_tiff_has_compression('none'), 1, "can always do uncompresed");
773 is(Imager::File::TIFF::i_tiff_has_compression('xxx'), '', "can't do xxx compression");
777 { # check file limits are checked
778 my $limit_file = "testout/t106.tiff";
779 ok(Imager->set_file_limits(reset=>1, width=>149), "set width limit 149");
780 my $im = Imager->new;
781 ok(!$im->read(file=>$limit_file),
782 "should fail read due to size limits");
783 print "# ",$im->errstr,"\n";
784 like($im->errstr, qr/image width/, "check message");
786 ok(Imager->set_file_limits(reset=>1, height=>149), "set height limit 149");
787 ok(!$im->read(file=>$limit_file),
788 "should fail read due to size limits");
789 print "# ",$im->errstr,"\n";
790 like($im->errstr, qr/image height/, "check message");
792 ok(Imager->set_file_limits(reset=>1, width=>150), "set width limit 150");
793 ok($im->read(file=>$limit_file),
794 "should succeed - just inside width limit");
795 ok(Imager->set_file_limits(reset=>1, height=>150), "set height limit 150");
796 ok($im->read(file=>$limit_file),
797 "should succeed - just inside height limit");
799 # 150 x 150 x 3 channel image uses 67500 bytes
800 ok(Imager->set_file_limits(reset=>1, bytes=>67499),
801 "set bytes limit 67499");
802 ok(!$im->read(file=>$limit_file),
803 "should fail - too many bytes");
804 print "# ",$im->errstr,"\n";
805 like($im->errstr, qr/storage size/, "check error message");
806 ok(Imager->set_file_limits(reset=>1, bytes=>67500),
807 "set bytes limit 67500");
808 ok($im->read(file=>$limit_file),
809 "should succeed - just inside bytes limit");
810 Imager->set_file_limits(reset=>1);
814 # this image has an IFD loop, which sends some TIFF readers into a
815 # loop, including Corel PhotoPaint and the GIMP's tiff reader.
816 my $ifdloop_hex = <<HEX;
817 49 49 2A 00 0A 00 00 00 FE 00 0A 00 00 01 03 00
818 01 00 00 00 01 00 00 00 01 01 03 00 01 00 00 00
819 01 00 00 00 02 01 03 00 03 00 00 00 88 00 00 00
820 03 01 03 00 01 00 00 00 05 80 00 00 06 01 03 00
821 01 00 00 00 02 00 00 00 11 01 04 00 01 00 00 00
822 08 00 00 00 12 01 03 00 01 00 00 00 01 00 00 00
823 15 01 03 00 01 00 00 00 03 00 00 00 17 01 04 00
824 01 00 00 00 02 00 00 00 1C 01 03 00 01 00 00 00
825 01 00 00 00 90 00 00 00 08 00 08 00 08 00 FE 00
826 0A 00 00 01 03 00 01 00 00 00 01 00 00 00 01 01
827 03 00 01 00 00 00 01 00 00 00 02 01 03 00 03 00
828 00 00 0E 01 00 00 03 01 03 00 01 00 00 00 05 80
829 00 00 06 01 03 00 01 00 00 00 02 00 00 00 11 01
830 04 00 01 00 00 00 8E 00 00 00 12 01 03 00 01 00
831 00 00 01 00 00 00 15 01 03 00 01 00 00 00 03 00
832 00 00 17 01 04 00 01 00 00 00 02 00 00 00 1C 01
833 03 00 01 00 00 00 01 00 00 00 0A 00 00 00 08 00
836 $ifdloop_hex =~ tr/0-9A-F//cd;
837 my $ifdloop = pack("H*", $ifdloop_hex);
839 my $im = Imager->new;
840 ok($im->read(data => $ifdloop, type => "tiff", page => 1),
841 "read what should be valid");
842 ok(!$im->read(data => $ifdloop, type => "tiff", page => 2),
843 "third page is after looping back to the start, if this fails, upgrade tifflib")
844 or skip("tifflib is broken", 1);
845 print "# ", $im->errstr, "\n";
846 my @im = Imager->read_multi(type => "tiff", data => $ifdloop);
847 is(@im, 2, "should be only 2 images");
852 Imager::File::TIFF::i_tiff_has_compression("lzw")
853 or skip "No LZW support", 8;
854 Imager::File::TIFF::i_tiff_ieeefp()
855 or skip "No IEEE FP type", 8;
859 my $cmp = Imager->new(file => "testimg/grey16.tif", filetype => "tiff")
860 or skip "Cannot read grey16.tif: ". Imager->errstr, 4;
861 my $im = Imager->new(file => "testimg/grey16sg.tif", filetype => "tiff");
862 ok($im, "read image with SampleFormat = signed int")
863 or skip "Couldn't read the file", 3;
864 is_image($im, $cmp, "check the images match");
865 my %tags = map @$_, $im->tags;
866 is($tags{tiff_sample_format}, 2, "check sample format");
867 is($tags{tiff_sample_format_name}, "int", "check sample format name");
872 my $cmp = Imager->new(file => "testimg/srgba32.tif", filetype => "tiff")
873 or skip "Cannot read srgaba32f.tif: ". Imager->errstr, 4;
874 my $im = Imager->new(file => "testimg/srgba32f.tif", filetype => "tiff");
875 ok($im, "read image with SampleFormat = float")
876 or skip "Couldn't read the file", 3;
877 is_image($im, $cmp, "check the images match");
878 my %tags = map @$_, $im->tags;
879 is($tags{tiff_sample_format}, 3, "check sample format");
880 is($tags{tiff_sample_format_name}, "ieeefp", "check sample format name");