2 ######################### We start with some black magic to print on failure.
4 # this used to do the check for the load of Imager, but I want to be able
5 # to count tests, which means I need to load Imager first
6 # since many of the early tests already do this, we don't really need to
12 Imager::init("log"=>"testout/t50basicoo.log");
14 # single image/file types
15 my @types = qw( jpeg png raw ppm gif tiff bmp tga );
17 # multiple image/file formats
18 my @mtypes = qw(tiff gif);
20 my %hsh=%Imager::formats;
24 for my $type (@types) {
25 $count += 31 if $hsh{$type};
27 for my $type (@mtypes) {
28 $count += 7 if $hsh{$type};
33 print "# avaliable formats:\n";
34 for(keys %hsh) { print "# $_\n"; }
38 my $img = Imager->new();
41 @files{@types} = ({ file => "testout/t101.jpg" },
42 { file => "testout/t102.png" },
43 { file => "testout/t103.raw", xsize=>150, ysize=>150
44 #, type=>"raw" # TODO: was this there for a reason?
46 { file => "testout/t104.ppm" },
47 { file => "testout/t105.gif" },
48 { file => "testout/t106.tiff" },
49 { file => "testout/t107_24bit.bmp" },
50 { file => "testout/t108_24bit.tga" }, );
53 gif=> { make_colors=>'webmap', translate=>'closest', gifquant=>'gen' },
56 for my $type (@types) {
57 next unless $hsh{$type};
58 print "# type $type\n";
59 my %opts = %{$files{$type}};
60 my @a = map { "$_=>${opts{$_}}" } keys %opts;
61 print "#opening Format: $type, options: @a\n";
62 ok($img->read( %opts ), "reading from file", $img);
63 #or die "failed: ",$img->errstr,"\n";
68 # read from a file handle
69 my $fh = IO::File->new($opts{file}, "r");
70 if (ok($fh, "opening $opts{file}")) {
72 my $fhimg = Imager->new;
73 my $fhrc = $fhimg->read(fh=>$fh, %mopts);
74 if (ok(!$fhrc, "check that type is required")) {
75 ok ($fhimg->errstr =~ /type parameter missing/, "check for no type error");
78 skip("previous test failed");
80 if (ok($fhimg->read(fh=>$fh, %mopts, type=>$type), "read from fh")) {
81 ok(Imager::i_img_diff($img->{IMG}, $fhimg->{IMG}) == 0,
82 "image comparison after fh read");
85 skip("no image to compare");
87 ok($fh->seek(0, SEEK_SET), "seek after read");
90 my $fdimg = Imager->new;
91 if (ok($fdimg->read(fd=>fileno($fh), %mopts, type=>$type),
93 ok(Imager::i_img_diff($img->{IMG}, $fdimg->{IMG}) == 0,
94 "image comparistion after fd read");
97 skip("no image to compare");
99 ok($fh->seek(0, SEEK_SET), "seek after fd read");
100 ok($fh->close, "close fh after reads");
103 skip("couldn't open the damn file: $!", 7);
106 if ($type ne 'gif' || Imager::i_giflib_version() >= 4) {
107 # read from a memory buffer
108 open DATA, "< $opts{file}"
109 or die "Cannot open $opts{file}: $!";
111 my $data = do { local $/; <DATA> };
113 my $bimg = Imager->new;
115 if (ok($bimg->read(data=>$data, %mopts, type=>$type), "read from buffer",
117 ok(Imager::i_img_diff($img->{IMG}, $bimg->{IMG}) == 0,
118 "comparing buffer read image");
121 skip("nothing to compare");
124 # read from callbacks, both with minimum and maximum reads
129 my ($size, $maxread) = @_;
130 my $out = substr($buf, $seekpos, $size);
131 $seekpos += length $out;
136 my ($size, $maxread) = @_;
137 my $out = substr($buf, $seekpos, $maxread);
138 $seekpos += length $out;
143 my ($offset, $whence) = @_;
144 #print "io_seeker($offset, $whence)\n";
145 if ($whence == SEEK_SET) {
148 elsif ($whence == SEEK_CUR) {
152 $seekpos = length($buf) + $offset;
154 #print "-> $seekpos\n";
157 my $cbimg = Imager->new;
158 ok($cbimg->read(callback=>$reader_min, seekcb=>$seeker, type=>$type, %mopts),
159 "read from callback min", $cbimg);
160 ok(Imager::i_img_diff($cbimg->{IMG}, $img->{IMG}) == 0,
161 "comparing mincb image");
163 ok($cbimg->read(callback=>$reader_max, seekcb=>$seeker, type=>$type, %mopts),
164 "read from callback max", $cbimg);
165 ok(Imager::i_img_diff($cbimg->{IMG}, $img->{IMG}) == 0,
166 "comparing maxcb image");
169 skip("giflib < 4 doesn't support callbacks", 6);
173 for my $type (@types) {
174 next unless $hsh{$type};
176 print "# write tests for $type\n";
178 next unless $hsh{$type};
179 my $file = "testout/t50out.$type";
180 my $wimg = Imager->new;
181 # if this doesn't work, we're so screwed up anyway
183 ok($wimg->read(file=>"testout/t104.ppm"),
184 "cannot read base file", $wimg);
187 print "# writing $type to a file\n";
189 %extraopts = %{$writeopts{$type}} if $writeopts{$type};
190 ok($wimg->write(file=>$file, %extraopts),
191 "writing $type to a file $file", $wimg);
193 print "# writing $type to a FH\n";
195 my $fh = IO::File->new($file, "w+")
196 or die "Could not create $file: $!";
198 ok($wimg->write(fh=>$fh, %extraopts, type=>$type),
199 "writing $type to a FH", $wimg);
200 ok($fh->seek(0, SEEK_END) > 0,
201 "seek after writing $type to a FH");
202 ok(print($fh "SUFFIX\n"),
203 "write to FH after writing $type");
204 ok($fh->close, "closing FH after writing $type");
206 if ($type ne 'gif' || Imager::i_giflib_version() >= 4) {
207 if (ok(open(DATA, "< $file"), "opening data source")) {
209 my $data = do { local $/; <DATA> };
212 # writing to a buffer
213 print "# writing $type to a buffer\n";
215 ok($wimg->write(data=>\$buf, %extraopts, type=>$type),
216 "writing $type to a buffer", $wimg);
218 open DATA, "> testout/t50_buf.$type"
219 or die "Cannot create $type buffer file: $!";
223 ok($data eq $buf, "comparing file data to buffer");
231 if ($seekpos > length $buf) {
232 $buf .= "\0" x ($seekpos - length $buf);
234 substr($buf, $seekpos, length $what) = $what;
235 $seekpos += length $what;
236 $did_close = 0; # the close must be last
241 my ($size, $maxread) = @_;
242 my $out = substr($buf, $seekpos, $size);
243 $seekpos += length $out;
248 my ($size, $maxread) = @_;
249 my $out = substr($buf, $seekpos, $maxread);
250 $seekpos += length $out;
256 my ($offset, $whence) = @_;
257 #print "io_seeker($offset, $whence)\n";
258 if ($whence == SEEK_SET) {
261 elsif ($whence == SEEK_CUR) {
265 $seekpos = length($buf) + $offset;
267 #print "-> $seekpos\n";
271 my $closer = sub { ++$did_close; };
273 print "# writing $type via callbacks (mb=1)\n";
274 ok($wimg->write(writecb=>$writer, seekcb=>$seeker, closecb=>$closer,
276 %extraopts, type=>$type, maxbuffer=>1),
277 "writing $type to callback (mb=1)", $wimg);
279 ok($did_close, "checking closecb called");
281 ok($data eq $buf, "comparing callback output to file data");
282 print "# writing $type via callbacks (no mb)\n";
286 # we don't use the closecb here - used to make sure we don't get
287 # a warning/error on an attempt to call an undef close sub
288 ok($wimg->write(writecb=>$writer, seekcb=>$seeker, readcb=>$reader_min,
289 %extraopts, type=>$type),
290 "writing $type to callback (no mb)", $wimg);
292 ok($data eq $buf, "comparing callback output to file data");
295 skip("couldn't open data source", 7);
299 skip("giflib < 4 doesn't support callbacks", 8);
303 my $img2 = $img->crop(width=>50, height=>50);
304 $img2 -> write(file=> 'testout/t50.ppm', type=>'pnm');
308 # multi image/file tests
309 print "# multi-image write tests\n";
310 for my $type (@mtypes) {
311 next unless $hsh{$type};
314 my $file = "testout/t50out.$type";
315 my $wimg = Imager->new;
317 # if this doesn't work, we're so screwed up anyway
318 ok($wimg->read(file=>"testout/t50out.$type"),
319 "reading base file", $wimg);
321 ok(my $wimg2 = $wimg->copy, "copying base image", $wimg);
322 ok($wimg2->flip(dir=>'h'), "flipping base image", $wimg2);
324 my @out = ($wimg, $wimg2);
326 %extraopts = %{$writeopts{$type}} if $writeopts{$type};
327 ok(Imager->write_multi({ file=>"testout/t50_multi.$type", %extraopts },
329 "writing multiple to a file", "Imager");
331 # make sure we get the same back
332 my @images = Imager->read_multi(file=>"testout/t50_multi.$type");
333 if (ok(@images == @out, "checking read image count")) {
334 for my $i (0 .. $#out) {
335 my $diff = Imager::i_img_diff($out[$i]{IMG}, $images[$i]{IMG});
336 print "# diff $diff\n";
337 ok($diff == 0, "comparing image $i");
341 skip("wrong number of images read", 2);
346 Imager::malloc_state();
351 my ($ok, $msg, $img) = @_;
355 print "ok $test_num # $msg\n";
359 $err = $img->errstr if $img;
360 # VMS (if we ever support it) wants the whole line in one print
361 my $line = "not ok $test_num # line ".(caller)[2].": $msg";
362 $line .= ": $err" if $err;
370 my ($why, $skipcount) = @_;
373 for (1.. $skipcount) {
375 print "ok $test_num # skipped $why\n";