5 use Imager::Test qw(test_image_raw);
7 init_log("testout/t102png.log",1);
10 or skip_all("No png support");
14 my $green = i_color_new(0, 255, 0, 255);
15 my $blue = i_color_new(0, 0, 255, 255);
16 my $red = i_color_new(255, 0, 0, 255);
18 my $img = test_image_raw();
20 my $timg = Imager::ImgRaw::new(20, 20, 4);
21 my $trans = i_color_new(255, 0, 0, 127);
22 i_box_filled($timg, 0, 0, 20, 20, $green);
23 i_box_filled($timg, 2, 2, 18, 18, $trans);
25 Imager::i_tags_add($img, "i_xres", 0, "300", 0);
26 Imager::i_tags_add($img, "i_yres", 0, undef, 200);
27 # the following confuses the GIMP
28 #Imager::i_tags_add($img, "i_aspect_only", 0, undef, 1);
29 open(FH,">testout/t102.png") || die "cannot open testout/t102.png for writing\n";
31 my $IO = Imager::io_new_fd(fileno(FH));
32 ok(i_writepng_wiol($img, $IO), "write");
35 open(FH,"testout/t102.png") || die "cannot open testout/t102.png\n";
37 $IO = Imager::io_new_fd(fileno(FH));
38 my $cmpimg = i_readpng_wiol($IO, -1);
40 ok($cmpimg, "read png");
42 print "# png average mean square pixel difference: ",sqrt(i_img_diff($img,$cmpimg))/150*150,"\n";
43 is(i_img_diff($img, $cmpimg), 0, "compare saved and original images");
45 my %tags = map { Imager::i_tags_get($cmpimg, $_) }
46 0..Imager::i_tags_count($cmpimg) - 1;
47 ok(abs($tags{i_xres} - 300) < 1, "i_xres: $tags{i_xres}");
48 ok(abs($tags{i_yres} - 200) < 1, "i_yres: $tags{i_yres}");
49 is($tags{i_format}, "png", "i_format: $tags{i_format}");
51 open FH, "> testout/t102_trans.png"
52 or die "Cannot open testout/t102_trans.png: $!";
54 $IO = Imager::io_new_fd(fileno(FH));
55 ok(i_writepng_wiol($timg, $IO), "write tranparent");
58 open FH,"testout/t102_trans.png"
59 or die "cannot open testout/t102_trans.png\n";
61 $IO = Imager::io_new_fd(fileno(FH));
62 $cmpimg = i_readpng_wiol($IO, -1);
63 ok($cmpimg, "read transparent");
66 print "# png average mean square pixel difference: ",sqrt(i_img_diff($timg,$cmpimg))/150*150,"\n";
67 is(i_img_diff($timg, $cmpimg), 0, "compare saved and original transparent");
70 # png.c 1.1 would produce an incorrect image when loading images with
71 # less than 8 bits/pixel with a transparent palette entry
72 open FH, "< testimg/palette.png"
73 or die "cannot open testimg/palette.png: $!\n";
75 $IO = Imager::io_new_fd(fileno(FH));
76 # 1.1 may segfault here (it does with libefence)
77 my $pimg = i_readpng_wiol($IO,-1);
78 ok($pimg, "read transparent paletted image");
81 open FH, "< testimg/palette_out.png"
82 or die "cannot open testimg/palette_out.png: $!\n";
84 $IO = Imager::io_new_fd(fileno(FH));
85 my $poimg = i_readpng_wiol($IO, -1);
86 ok($poimg, "read palette_out image");
88 if (!is(i_img_diff($pimg, $poimg), 0, "images the same")) {
90 # this tests a bug in Imager's png.c v1.1
91 # if also tickles a bug in libpng before 1.0.5, so you may need to
96 { # check file limits are checked
97 my $limit_file = "testout/t102.png";
98 ok(Imager->set_file_limits(reset=>1, width=>149), "set width limit 149");
100 ok(!$im->read(file=>$limit_file),
101 "should fail read due to size limits");
102 print "# ",$im->errstr,"\n";
103 like($im->errstr, qr/image width/, "check message");
105 ok(Imager->set_file_limits(reset=>1, height=>149), "set height limit 149");
106 ok(!$im->read(file=>$limit_file),
107 "should fail read due to size limits");
108 print "# ",$im->errstr,"\n";
109 like($im->errstr, qr/image height/, "check message");
111 ok(Imager->set_file_limits(reset=>1, width=>150), "set width limit 150");
112 ok($im->read(file=>$limit_file),
113 "should succeed - just inside width limit");
114 ok(Imager->set_file_limits(reset=>1, height=>150), "set height limit 150");
115 ok($im->read(file=>$limit_file),
116 "should succeed - just inside height limit");
118 # 150 x 150 x 3 channel image uses 67500 bytes
119 ok(Imager->set_file_limits(reset=>1, bytes=>67499),
120 "set bytes limit 67499");
121 ok(!$im->read(file=>$limit_file),
122 "should fail - too many bytes");
123 print "# ",$im->errstr,"\n";
124 like($im->errstr, qr/storage size/, "check error message");
125 ok(Imager->set_file_limits(reset=>1, bytes=>67500),
126 "set bytes limit 67500");
127 ok($im->read(file=>$limit_file),
128 "should succeed - just inside bytes limit");
129 Imager->set_file_limits(reset=>1);
132 { # check if the read_multi fallback works
133 my @imgs = Imager->read_multi(file => 'testout/t102.png');
134 is(@imgs, 1, "check the image was loaded");
135 is(i_img_diff($img, $imgs[0]), 0, "check image matches");
137 # check the write_multi fallback
138 ok(Imager->write_multi({ file => 'testout/t102m.png', type => 'png' },
140 'test write_multi() callback');
142 # check that we fail if we actually write 2
143 ok(!Imager->write_multi({ file => 'testout/t102m.png', type => 'png' },
145 'test write_multi() callback failure');
149 ok(grep($_ eq 'png', Imager->read_types), "check png in read types");
150 ok(grep($_ eq 'png', Imager->write_types), "check png in write types");