]> git.imager.perl.org - imager.git/blobdiff - ICO/t/t10icon.t
add support for file write plugins
[imager.git] / ICO / t / t10icon.t
index c89ae9ab43fd42489c5eba874376a6116383031e..dd378586d4662c592596ef2332c2cf4c0bca0b8a 100644 (file)
@@ -1,12 +1,14 @@
 #!perl -w
 use strict;
-use Test::More tests => 60;
+use Test::More tests => 94;
 
 BEGIN { use_ok('Imager::File::ICO'); }
 
 -d 'testout' or mkdir 'testout';
 
 my $im = Imager->new;
+# type=>'ico' or 'cur' and read ico and cur since they're pretty much
+# the same
 ok($im->read(file => "testimg/rgba3232.ico", type=>"ico"),
    "read 32 bit")
   or print "# ", $im->errstr, "\n";
@@ -15,7 +17,6 @@ is($im->getwidth, 32, "check height");
 is($im->type, 'direct', "check type");
 is($im->tags(name => 'ico_bits'), 32, "check ico_bits tag");
 is($im->tags(name => 'i_format'), 'ico', "check i_format tag");
-is($im->tags(name => 'ico_type'), 'icon', "check ico_type tag");
 my $mask = '.*
 ..........................******
 ..........................******
@@ -72,7 +73,6 @@ is($im->type, 'paletted', "check type");
 is($im->colorcount, 256, "color count");
 is($im->tags(name => 'ico_bits'), 8, "check ico_bits tag");
 is($im->tags(name => 'i_format'), 'ico', "check i_format tag");
-is($im->tags(name => 'ico_type'), 'icon', "check ico_type tag");
 SKIP:
 {
   my $comp = Imager->new;
@@ -92,7 +92,6 @@ is($im->type, 'paletted', "check type");
 is($im->colorcount, 16, "color count");
 is($im->tags(name => 'ico_bits'), 4, "check ico_bits tag");
 is($im->tags(name => 'i_format'), 'ico', "check i_format tag");
-is($im->tags(name => 'ico_type'), 'icon', "check ico_type tag");
 SKIP:
 {
   my $comp = Imager->new;
@@ -110,9 +109,8 @@ is($im->getwidth, 32, "check width");
 is($im->getwidth, 32, "check height");
 is($im->type, 'paletted', "check type");
 is($im->colorcount, 2, "color count");
-is($im->tags(name => 'ico_bits'), 1, "check ico_bits tag");
-is($im->tags(name => 'i_format'), 'ico', "check i_format tag");
-is($im->tags(name => 'ico_type'), 'cursor', "check ico_type tag");
+is($im->tags(name => 'cur_bits'), 1, "check ico_bits tag");
+is($im->tags(name => 'i_format'), 'cur', "check i_format tag");
 $im->write(file=>'testout/pal13232.ppm');
 
 # combo was created with the GIMP, which has a decent mechanism for selecting
@@ -159,3 +157,167 @@ is_deeply([ $imgs[1]->getpixel(x=>31, 'y'=>31)->rgba ], [ 17, 231, 177, 255 ],
          "check image data 1(31,31)");
 is_deeply([ $imgs[2]->getpixel(x=>15, 'y'=>15)->rgba ], [ 17, 231, 177, 255 ],
          "check image data 2(15,15)");
+
+$im = Imager->new(xsize=>32, ysize=>32);
+$im->box(filled=>1, color=>'FF0000');
+$im->box(filled=>1, color=>'0000FF', xmin => 6, ymin=>0, xmax => 21, ymax=>15);
+$im->box(filled=>1, color=>'00FF00', xmin => 10, ymin=>16, xmax => 25, ymax=>31);
+
+ok($im->write(file=>'testout/t10_32.ico', type=>'ico'),
+   "write 32-bit icon");
+
+my $im2 = Imager->new;
+ok($im2->read(file=>'testout/t10_32.ico', type=>'ico'),
+   "read it back in");
+
+is(Imager::i_img_diff($im->{IMG}, $im2->{IMG}), 0,
+   "check they're the same");
+is($im->bits, $im2->bits, "check same bits");
+
+{
+  my $im = Imager->new(xsize => 32, ysize => 32);
+  $im->box(filled=>1, color=>'#FF00FF');
+  my $data;
+  ok(Imager->write_multi({ data => \$data, type=>'ico' }, $im, $im),
+     "write multi icons");
+  ok(length $data, "and it wrote data");
+  my @im = Imager->read_multi(data => $data);
+  is(@im, 2, "got all the images back");
+  is(Imager::i_img_diff($im->{IMG}, $im[0]{IMG}), 0, "check first image");
+  is(Imager::i_img_diff($im->{IMG}, $im[1]{IMG}), 0, "check second image");
+}
+
+{ # 1 channel image
+  my $im = Imager->new(xsize => 32, ysize => 32, channels => 1);
+  $im->box(filled=>1, color => [ 128, 0, 0 ]);
+  my $data;
+  ok($im->write(data => \$data, type=>'ico'), "write 1 channel image");
+  my $im2 = Imager->new;
+  ok($im2->read(data => $data), "read it back");
+  is($im2->getchannels, 4, "check channels");
+  my $imrgb = $im->convert(preset => 'rgb')
+    ->convert(preset => 'addalpha');
+  is(Imager::i_img_diff($imrgb->{IMG}, $im2->{IMG}), 0,
+     "check image matches expected");
+}
+
+{ # 2 channel image
+  my $base = Imager->new(xsize => 32, ysize => 32, channels => 2);
+  $base->box(filled => 1, color => [ 64, 192, 0 ]);
+  my $data;
+  ok($base->write(data => \$data, type=>'ico'), "write 2 channel image");
+  my $read = Imager->new;
+  ok($read->read(data => $data), "read it back");
+  is($read->getchannels, 4, "check channels");
+  my $imrgb = $base->convert(preset => 'rgb');
+  is(Imager::i_img_diff($imrgb->{IMG}, $read->{IMG}), 0,
+     "check image matches expected");
+}
+
+{ # 4 channel image
+  my $base = Imager->new(xsize => 32, ysize => 32, channels => 4);
+  $base->box(filled=>1, ymax => 15, color => [ 255, 0, 255, 128 ]);
+  $base->box(filled=>1, ymin => 16, color => [ 0, 255, 255, 255 ]);
+  my $data;
+  ok($base->write(data => \$data, type=>'ico'), "write 4 channel image");
+  my $read = Imager->new;
+  ok($read->read(data => $data, type=>'ico'), "read it back")
+    or print "# ", $read->errstr, "\n";
+  is(Imager::i_img_diff($base->{IMG}, $read->{IMG}), 0,
+     "check image matches expected");
+}
+
+{ # mask handling
+  my $base = Imager->new(xsize => 16, ysize => 16, channels => 3);
+  $base->box(filled=>1, xmin => 5, xmax => 10, color => '#0000FF');
+  $base->box(filled=>1, ymin => 5, ymax => 10, color => '#0000FF');
+  my $mask = <<EOS; # CR in this to test it's skipped correctly
+01
+0000011111100000
+00000111111 00000xx
+00000111111000  
+00000111111000
+0000011111100000
+1111111111111111
+1111111111111111
+1111111111111111
+1111111111111111
+1111111111111111
+1111111111111111
+1010101010101010
+1010101010101010
+1010101010101010
+1010101010101010
+1010101010101010
+EOS
+  $mask =~ s/\n/\r\n/g; # to test alternate newline handling is correct
+  $base->settag(name => 'ico_mask', value => $mask);
+  my $saved_mask = $base->tags(name => 'ico_mask');
+  my $data;
+  ok($base->write(data => \$data, type => 'ico'),
+     "write with mask tag set");
+  my $read = Imager->new;
+  ok($read->read(data => $data), "read it back");
+  my $mask2 = $mask;
+  $mask2 =~ tr/01/.*/;
+  $mask2 =~ s/\n$//;
+  $mask2 =~ tr/\r x//d;
+  $mask2 =~ s/^(.{3,19})$/$1 . "." x (16 - length $1)/gem;
+  my $read_mask = $read->tags(name => 'ico_mask');
+  is($read_mask, $mask2, "check mask is correct");
+}
+
+{ # mask too short to handle
+  my $mask = "xx";
+  my $base = Imager->new(xsize => 16, ysize => 16, channels => 3);
+  $base->box(filled=>1, xmin => 5, xmax => 10, color => '#0000FF');
+  $base->box(filled=>1, ymin => 5, ymax => 10, color => '#0000FF');
+  $base->settag(name => 'ico_mask', value => $mask);
+  my $data;
+  ok($base->write(data => \$data, type=>'ico'),
+     "save icon with short mask tag");
+  my $read = Imager->new;
+  ok($read->read(data => $data), "read it back");
+  my $read_mask = $read->tags(name => 'ico_mask');
+  my $expected_mask = ".*" . ( "\n" . "." x 16 ) x 16;
+  is($read_mask, $expected_mask, "check the mask");
+
+  # mask that doesn't match what we expect
+  $base->settag(name => 'ico_mask', value => 'abcd');
+  ok($base->write(data => \$data, type => 'ico'), 
+     "write with bad format mask tag");
+  ok($read->read(data => $data), "read it back");
+  $read_mask = $read->tags(name => 'ico_mask');
+  is($read_mask, $expected_mask, "check the mask");
+
+  # mask with invalid char
+  $base->settag(name => 'ico_mask', value => ".*\n....xxx..");
+  ok($base->write(data => \$data, type => 'ico'), 
+     "write with unexpected chars in mask");
+  ok($read->read(data => $data), "read it back");
+  $read_mask = $read->tags(name => 'ico_mask');
+  is($read_mask, $expected_mask, "check the mask");
+}
+
+{ # check handling of greyscale paletted
+  my $base = Imager->new(xsize => 16, ysize => 16, channels => 1, 
+                         type => 'paletted');
+  my @grays = map Imager::Color->new($_),
+    "000000", "666666", "CCCCCC", "FFFFFF";
+  ok($base->addcolors(colors => \@grays), "add some colors");
+  $base->box(filled => 1, color => $grays[1], xmax => 7, ymax => 7);
+  $base->box(filled => 1, color => $grays[1], xmax => 7, ymin => 8);
+  $base->box(filled => 1, color => $grays[1], xmin => 8, ymax => 7);
+  $base->box(filled => 1, color => $grays[1], xmin => 8, ymax => 8);
+  my $data;
+  ok($base->write(data => \$data, type => 'ico'),
+     "write grayscale paletted");
+  my $read = Imager->new;
+  ok($read->read(data => $data), "read it back")
+    or print "# ", $read->errstr, "\n";
+  is($read->type, 'paletted', "check type");
+  is($read->getchannels, 3, "check channels");
+  my $as_rgb = $base->convert(preset => 'rgb');
+  is(Imager::i_img_diff($base->{IMG}, $read->{IMG}), 0,
+     "check the image");
+}