9 init_log("testout/t105gif.log",1);
11 my $green=i_color_new(0,255,0,255);
12 my $blue=i_color_new(0,0,255,255);
13 my $red=i_color_new(255,0,0,255);
15 my $img=Imager::ImgRaw::new(150,150,3);
17 i_box_filled($img,70,25,130,125,$green);
18 i_box_filled($img,20,25,80,125,$blue);
19 i_arc($img,75,75,30,0,361,$red);
20 i_conv($img,[0.1, 0.2, 0.4, 0.2, 0.1]);
22 my $timg = Imager::ImgRaw::new(20, 20, 4);
23 my $trans = i_color_new(255, 0, 0, 127);
24 i_box_filled($timg, 0, 0, 20, 20, $green);
25 i_box_filled($timg, 2, 2, 18, 18, $trans);
27 if (!i_has_format("gif")) {
28 for (1..40) { print "ok $_ # skip no gif support\n"; }
30 open(FH,">testout/t105.gif") || die "Cannot open testout/t105.gif\n";
32 i_writegifmc($img,fileno(FH),7) || die "Cannot write testout/t105.gif\n";
37 open(FH,"testout/t105.gif") || die "Cannot open testout/t105.gif\n";
39 $img=i_readgif(fileno(FH)) || die "Cannot read testout/t105.gif\n";
44 open(FH,"testout/t105.gif") || die "Cannot open testout/t105.gif\n";
46 ($img, my $palette)=i_readgif(fileno(FH));
47 $img || die "Cannot read testout/t105.gif\n";
50 $palette=''; # just to skip a warning.
54 # check that reading interlaced/non-interlaced versions of
55 # the same GIF produce the same image
56 # I could replace this with code that used Imager's built-in
57 # image comparison code, but I know this code revealed the error
58 open(FH, "<testimg/scalei.gif") || die "Cannot open testimg/scalei.gif";
60 my ($imgi) = i_readgif(fileno(FH));
61 $imgi || die "Cannot read testimg/scalei.gif";
64 open FH, "<testimg/scale.gif" or die "Cannot open testimg/scale.gif";
66 my ($imgni) = i_readgif(fileno(FH));
67 $imgni or die "Cannot read testimg/scale.gif";
71 open FH, ">testout/t105i.ppm" or die "Cannot create testout/t105i.ppm";
73 my $IO = Imager::io_new_fd( fileno(FH) );
74 i_writeppm_wiol($imgi, $IO) or die "Cannot write testout/t105i.ppm";
78 open FH, ">testout/t105ni.ppm" or die "Cannot create testout/t105ni.ppm";
80 $IO = Imager::io_new_fd( fileno(FH) );
81 i_writeppm_wiol($imgni, $IO) or die "Cannot write testout/t105ni.ppm";
85 open FH, "<testout/t105i.ppm" or die "Cannot open testout/t105i.ppm";
86 my $datai = do { local $/; <FH> };
89 open FH, "<testout/t105ni.ppm" or die "Cannot open testout/t105ni.ppm";
90 my $datani = do { local $/; <FH> };
92 if ($datai eq $datani) {
99 my $gifver = Imager::i_giflib_version();
100 if ($gifver >= 4.0) {
101 # reading with a callback
102 # various sizes to make sure the buffering works
104 open FH, "<testimg/scale.gif" or die "Cannot open testimg/scale.gif";
106 # no callback version in giflib3, so don't overwrite a good image
107 my $img2 = i_readgif_callback(sub { my $tmp; read(FH, $tmp, $_[0]) and $tmp });
109 print $img ? "ok 7\n" : "not ok 7\n";
111 print test_readgif_cb(1) ? "ok 8\n" : "not ok 8\n";
112 print test_readgif_cb(512) ? "ok 9\n" : "not ok 9\n";
113 print test_readgif_cb(1024) ? "ok 10\n" : "not ok 10\n";
117 print "ok $_ # skip giflib3 doesn't support callbacks\n";
120 open FH, ">testout/t105_mc.gif" or die "Cannot open testout/t105_mc.gif";
122 i_writegifmc($img, fileno(FH), 7) or print "not ";
127 # test webmap, custom errdiff map
128 # (looks fairly awful)
129 open FH, ">testout/t105_gen.gif" or die $!;
131 i_writegif_gen(fileno(FH), { make_colors=>'webmap',
132 translate=>'errdiff',
136 errdiff_map=>[0, 1, 1, 0]}, $img)
141 print "# the following tests are fairly slow\n";
143 # test animation, mc_addi, error diffusion, ordered transparency
145 my $sortagreen = i_color_new(0, 255, 0, 63);
147 my $im = Imager::ImgRaw::new(200, 200, 4);
148 for my $j (0..$i-1) {
149 my $fill = i_color_new(0, 128, 0, 255 * ($i-$j)/$i);
150 i_box_filled($im, 0, $j*40, 199, $j*40+40, $fill);
152 i_box_filled($im, 0, $i*40, 199, 199, $blue);
155 my @gif_delays = (50) x 5;
156 my @gif_disposal = (2) x 5;
157 open FH, ">testout/t105_anim.gif" or die $!;
159 i_writegif_gen(fileno(FH), { make_colors=>'addi',
160 translate=>'closest',
161 gif_delays=>\@gif_delays,
162 gif_disposal=>\@gif_disposal,
163 gif_positions=> [ map [ $_*10, $_*10 ], 0..4 ],
164 gif_user_input=>[ 1, 0, 1, 0, 1 ],
166 tr_orddith=>'dot8'}, @imgs)
167 or die "Cannot write anim gif";
171 my $can_write_callback = 0;
172 if ($gifver >= 4.0) {
173 ++$can_write_callback;
175 # this can SIGSEGV with some versions of giflib
176 open FH, ">testout/t105_anim_cb.gif" or die $!;
177 i_writegif_callback(sub {
181 { make_colors=>'webmap',
182 translate=>'closest',
183 gif_delays=>\@gif_delays,
184 gif_disposal=>\@gif_disposal,
186 tr_orddith=>'dot8'}, @imgs)
187 or die "Cannot write anim gif";
192 if (wait > 0 && $?) {
193 $can_write_callback = 0;
194 print "not ok 14 # you probably need to patch giflib\n";
196 #--- egif_lib.c 2000/12/11 07:33:12 1.1
197 #+++ egif_lib.c 2000/12/11 07:33:48
198 #@@ -167,6 +167,12 @@
199 # _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
202 #+ if ((Private->HashTable = _InitHashTable()) == NULL) {
205 #+ _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
209 # GifFile->Private = (VoidPtr) Private;
210 # Private->FileHandle = 0;
215 print "ok 14 # skip giflib3 doesn't support callbacks\n";
219 my $im = Imager::ImgRaw::new(200, 200, 3);
220 for my $x (0 .. 39) {
221 for my $y (0 .. 39) {
222 my $c = i_color_new($x * 6, $y * 6, 32*$g+$x+$y, 255);
223 i_box_filled($im, $x*5, $y*5, $x*5+4, $y*5+4, $c);
228 # test giflib with multiple palettes
229 # (it was meant to test the NS loop extension too, but that's broken)
230 # this looks better with make_colors=>'addi', translate=>'errdiff'
231 # this test aims to overload the palette for each image, so the
232 # output looks moderately horrible
233 open FH, ">testout/t105_mult_pall.gif" or die "Cannot create file: $!";
235 if (i_writegif_gen(fileno(FH), { make_colors=>'webmap',
237 gif_delays=>[ 50, 50, 50, 50 ],
238 #gif_loop_count => 50,
239 gif_each_palette => 1,
244 print "not ok 15 # ", join(":", map $_->[1], Imager::i_errors()),"\n";
248 # regression test: giflib doesn't like 1 colour images
249 my $img1 = Imager::ImgRaw::new(100, 100, 3);
250 i_box_filled($img1, 0, 0, 100, 100, $red);
251 open FH, ">testout/t105_onecol.gif" or die $!;
253 if (i_writegif_gen(fileno(FH), { translate=>'giflib'}, $img1)) {
254 print "ok 16 # single colour write regression\n";
256 print "not ok 16 # single colour write regression\n";
261 # previously it was harder do write transparent images
262 # tests the improvements
263 my $timg = Imager::ImgRaw::new(20, 20, 4);
264 my $trans = i_color_new(255, 0, 0, 127);
265 i_box_filled($timg, 0, 0, 20, 20, $green);
266 i_box_filled($timg, 2, 2, 18, 18, $trans);
267 open FH, ">testout/t105_trans.gif" or die $!;
269 i_writegif_gen(fileno(FH), { make_colors=>'addi',
270 translate=>'closest',
272 }, $timg) or print "not ";
276 # some error handling tests
277 # open a file handle for read and try to save to it
278 # is this idea portable?
279 # whether or not it is, giflib segfaults on this <sigh>
280 #open FH, "<testout/t105_trans.gif" or die $!;
281 #binmode FH; # habit, I suppose
282 #if (i_writegif_gen(fileno(FH), {}, $timg)) {
283 # # this is meant to _fail_
284 # print "not ok 18 # writing to read-only should fail";
287 # print "ok 18 # ",Imager::_error_as_msg(),"\n";
291 # try to read a file of the wrong format - the script will do
292 open FH, "<t/t105gif.t"
293 or die "Cannot open this script!: $!";
295 my $im2 = i_readgif(fileno(FH));
297 # this should have failed
298 print "not ok 18 # giflib think script if a GIF file\n";
301 print "ok 18 # ",Imager::_error_as_msg(),"\n";
305 # try to save no images :)
306 open FH, ">testout/t105_none.gif"
307 or die "Cannot open testout/t105_none.gif: $!";
309 if (i_writegif_gen(fileno(FH), {}, "hello")) {
310 print "not ok 19 # shouldn't be able to save strings\n";
313 print "ok 19 # ",Imager::_error_as_msg(),"\n";
316 # try to read a truncated gif (no image descriptors)
317 read_failure('testimg/trimgdesc.gif', 20);
318 # file truncated just after the image descriptor tag
319 read_failure('testimg/trmiddesc.gif', 21);
320 # image has no colour map
321 read_failure('testimg/nocmap.gif', 22);
323 # image has a local colour map
324 open FH, "< testimg/loccmap.gif"
325 or die "Cannot open testimg/loccmap.gif: $!";
327 if (i_readgif(fileno(FH))) {
331 print "not ok 23 # failed to read image with only a local colour map";
335 # image has global and local colour maps
336 open FH, "< testimg/screen2.gif"
337 or die "Cannot open testimg/screen2.gif: $!";
339 my $ims = i_readgif(fileno(FH));
344 print "not ok 24 # ",Imager::_error_as_msg(),"\n";
347 open FH, "< testimg/expected.gif"
348 or die "Cannot open testimg/expected.gif: $!";
350 my $ime = i_readgif(fileno(FH));
356 print "not ok 25 # ",Imager::_error_as_msg(),"\n";
359 if (i_img_diff($ime, $ims)) {
360 print "not ok 26 # mismatch ",i_img_diff($ime, $ims),"\n";
362 open FH, "> testout/t105_screen2.gif"
363 or die "Cannot create testout/t105_screen.gif: $!";
365 i_writegifmc($ims, fileno(FH), 7)
366 or print "# could not save t105_screen.gif\n";
374 print "ok 26 # skipped\n";
377 # test reading a multi-image file into multiple images
378 open FH, "< testimg/screen2.gif"
379 or die "Cannot open testimg/screen2.gif: $!";
381 @imgs = Imager::i_readgif_multi(fileno(FH))
385 @imgs == 2 or print "not ";
387 for my $img (@imgs) {
388 unless (Imager::i_img_type($img) == 1) {
394 Imager::i_colorcount($imgs[0]) == 4 or print "not ";
396 Imager::i_colorcount($imgs[1]) == 2 or print "not ";
398 Imager::i_tags_find($imgs[0], "gif_left", 0) or print "not ";
400 my @tags = map {[ Imager::i_tags_get($imgs[1], $_) ]} 0..Imager::i_tags_count($imgs[1])-1;
401 my ($left) = grep $_->[0] eq 'gif_left', @tags;
402 $left && $left->[1] == 3 or print "not ";
405 # screen3.gif was saved with
406 open FH, "< testimg/screen3.gif"
407 or die "Cannot open testimg/screen3.gif: $!";
409 @imgs = Imager::i_readgif_multi(fileno(FH))
414 require 'Data/Dumper.pm';
415 Data::Dumper->import();
418 # build a big map of all tags for all images
423 map { join ",", map { defined() ? $_ : "undef" } Imager::i_tags_get($im, $_) }
424 0..Imager::i_tags_count($_)-1
427 my $dump = Dumper(\@tags);
429 print "# tags from gif\n", $dump;
432 # at this point @imgs should contain only paletted images
433 ok(35, Imager::i_img_type($imgs[0]) == 1, "imgs[0] not paletted");
434 ok(36, Imager::i_img_type($imgs[1]) == 1, "imgs[1] not paletted");
436 # see how we go saving it
437 open FH, ">testout/t105_pal.gif" or die $!;
439 ok(37, i_writegif_gen(fileno(FH), { make_colors=>'addi',
440 translate=>'closest',
442 }, @imgs), "write from paletted");
445 # make sure nothing bad happened
446 open FH, "< testout/t105_pal.gif" or die $!;
448 ok(38, (my @imgs2 = Imager::i_readgif_multi(fileno(FH))) == 2,
449 "re-reading saved paletted images");
450 ok(39, i_img_diff($imgs[0], $imgs2[0]) == 0, "imgs[0] mismatch");
451 ok(40, i_img_diff($imgs[1], $imgs2[1]) == 0, "imgs[1] mismatch");
455 my ($num, $ok, $comment) = @_;
461 print "not ok $num # line ",(caller)[2],": $comment \n";
465 sub test_readgif_cb {
468 open FH, "<testimg/scale.gif" or die "Cannot open testimg/scale.gif";
470 my $img = i_readgif_callback(sub { my $tmp; read(FH, $tmp, $size) and $tmp });
475 # tests for reading bad gif files
477 my ($filename, $testnum) = @_;
479 open FH, "< $filename"
480 or die "Cannot open $filename: $!";
482 my ($result, $map) = i_readgif(fileno(FH));
484 print "not ok $testnum # this is an invalid file, we succeeded\n";
487 print "ok $testnum # ",Imager::_error_as_msg(),"\n";