http://rt.cpan.org/Ticket/Display.html?id=20415
authorTony Cook <tony@develop=help.com>
Thu, 13 Jul 2006 11:04:53 +0000 (11:04 +0000)
committerTony Cook <tony@develop=help.com>
Thu, 13 Jul 2006 11:04:53 +0000 (11:04 +0000)
Reading a CMYK TIFF with no alpha would result in a 4-channel image.

Also, reading a CMYK TIFF with an alpha channel would fail to read.

Reading a CMYK TIFF with 2 alpha channels would fail to read.

Reading a RGB TIFF with 2 alpha channels would also fail to read.

MANIFEST
lib/Imager/Files.pod
t/t106tiff.t
testimg/scmyk.tif [new file with mode: 0644]
testimg/scmyka.tif [new file with mode: 0644]
testimg/scmykaa.tif [new file with mode: 0644]
testimg/slab.tif [new file with mode: 0644]
testimg/srgb.tif [new file with mode: 0644]
testimg/srgba.tif [new file with mode: 0644]
testimg/srgbaa.tif [new file with mode: 0644]
tiff.c

index 643f993..cd4a635 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -294,6 +294,9 @@ testimg/penguin-base.ppm
 testimg/scale.gif
 testimg/scale.ppm
 testimg/scalei.gif
+testimg/scmyk.tif      Simple CMYK image
+testimg/scmyka.tif     CMYK with one alpha channel
+testimg/scmykaa.tif    CMYK with 2 alpha channels
 testimg/screen2.gif
 testimg/screen3.gif
 testimg/short1.bmp      1-bit/pixel, data missing from EOF
@@ -303,6 +306,10 @@ testimg/short4rle.bmp   truncated 4bit/pixel compressed BMP
 testimg/short8.bmp      8-bit/pixel, data missing from EOF
 testimg/short8rle.bmp   8-bit/pixel compressed, data missing from EOF
 testimg/simple.pbm
+testimg/slab.tif       Lab color image
+testimg/srgb.tif       Simple RGB image
+testimg/srgba.tif      RGB with one alpha
+testimg/srgbaa.tif     RGB with 2 alpha
 testimg/test_gimp_pal   A simple GIMP palette file
 testimg/tiffwarn.tif   Generates a warning while being read
 testimg/trimgdesc.gif
index db14624..7700197 100644 (file)
@@ -694,6 +694,24 @@ some page other than the first.  The page is 0 based:
 
 =back
 
+Note: Imager uses the TIFF*RGBA* family of libtiff functions,
+unfortunately these don't support alpha channels on CMYK images.  This
+will result in a full coverage alpha channel on CMYK images with an
+alpha channel, until this is implemented in libtiff (or Imager's TIFF
+implementation changes.)
+
+If you read an image with multiple alpha channels, then only the first
+alpha channel will be read.
+
+Currently Imager's TIFF support reads all direct color images as 8-bit
+RGB images, this may change in the future to reading 16-bit/sample
+images.
+
+Currently tags that control the output color type and compression are
+ignored when writing, this may change in the future.  If you have
+processes that rely upon Imager always producing packbits compressed
+RGB images, you should strip any tags before writing.
+
 =head2 BMP (BitMaP)
 
 Imager can write 24-bit RGB, and 8, 4 and 1-bit per pixel paletted
index b9cd83f..8c7793a 100644 (file)
@@ -1,7 +1,7 @@
 #!perl -w
 use strict;
 use lib 't';
-use Test::More tests => 106;
+use Test::More tests => 127;
 use Imager qw(:all);
 $^W=1; # warnings during command-line tests
 $|=1;  # give us some progress in the test harness
@@ -32,7 +32,7 @@ SKIP:
     $im = Imager->new(xsize=>2, ysize=>2);
     ok(!$im->write(file=>"testout/notiff.tif"), "should fail to write tiff");
     is($im->errstr, 'format not supported', "check no tiff message");
-    skip("no tiff support", 102);
+    skip("no tiff support", 123);
   }
 
   Imager::i_tags_add($img, "i_xres", 0, "300", 0);
@@ -423,5 +423,29 @@ SKIP:
     is(Imager::i_img_diff($im[1]{IMG}, $im->{IMG}), 0,
        "check second image");
   }
+
+  { # handling of an alpha channel for various images
+    my $photo_rgb = 2;
+    my $photo_cmyk = 5;
+    my $photo_cielab = 8;
+    my @alpha_images =
+      (
+       [ 'srgb.tif',    3, $photo_rgb ],
+       [ 'srgba.tif',   4, $photo_rgb  ],
+       [ 'srgbaa.tif',  4, $photo_rgb  ],
+       [ 'scmyk.tif',   3, $photo_cmyk ],
+       [ 'scmyka.tif',  4, $photo_cmyk ],
+       [ 'scmykaa.tif', 4, $photo_cmyk ],
+       [ 'slab.tif',    3, $photo_cielab ],
+      );
+    for my $test (@alpha_images) {
+      my $im = Imager->new;
+      ok($im->read(file => "testimg/$test->[0]"),
+        "read alpha test $test->[0]");
+      is($im->getchannels, $test->[1], "channels for $test->[0] match");
+      is($im->tags(name=>'tiff_photometric'), $test->[2],
+        "photometric for $test->[0] match");
+    }
+  }
 }
 
diff --git a/testimg/scmyk.tif b/testimg/scmyk.tif
new file mode 100644 (file)
index 0000000..58a39c7
Binary files /dev/null and b/testimg/scmyk.tif differ
diff --git a/testimg/scmyka.tif b/testimg/scmyka.tif
new file mode 100644 (file)
index 0000000..2cda4aa
Binary files /dev/null and b/testimg/scmyka.tif differ
diff --git a/testimg/scmykaa.tif b/testimg/scmykaa.tif
new file mode 100644 (file)
index 0000000..4f2971c
Binary files /dev/null and b/testimg/scmykaa.tif differ
diff --git a/testimg/slab.tif b/testimg/slab.tif
new file mode 100644 (file)
index 0000000..1750daa
Binary files /dev/null and b/testimg/slab.tif differ
diff --git a/testimg/srgb.tif b/testimg/srgb.tif
new file mode 100644 (file)
index 0000000..003c9ea
Binary files /dev/null and b/testimg/srgb.tif differ
diff --git a/testimg/srgba.tif b/testimg/srgba.tif
new file mode 100644 (file)
index 0000000..a1431e7
Binary files /dev/null and b/testimg/srgba.tif differ
diff --git a/testimg/srgbaa.tif b/testimg/srgbaa.tif
new file mode 100644 (file)
index 0000000..72d8273
Binary files /dev/null and b/testimg/srgbaa.tif differ
diff --git a/tiff.c b/tiff.c
index 586f3b7..48f4870 100644 (file)
--- a/tiff.c
+++ b/tiff.c
@@ -178,6 +178,26 @@ static i_img *read_one_tiff(TIFF *tif) {
   mm_log((1, "i_readtiff_wiol: %stiled\n", tiled?"":"not "));
   mm_log((1, "i_readtiff_wiol: %sbyte swapped\n", TIFFIsByteSwapped(tif)?"":"not "));
 
+  /* separated defaults to CMYK, but if the user is using some strange
+     ink system we can't work out the color anyway */
+  if (photometric == PHOTOMETRIC_SEPARATED && channels >= 4) {
+    /* TIFF can have more than one alpha channel on an image,
+       but Imager can't, only store the first one */
+    
+    channels = channels == 4 ? 3 : 4;
+
+    /* unfortunately the RGBA functions don't try to deal with the alpha
+       channel on CMYK images, at some point I'm planning on expanding
+       TIFF support to handle 16-bit/sample images and I'll deal with
+       it then */
+  }
+
+  /* TIFF images can have more than one alpha channel, but Imager can't
+     this ignores the possibility of 2 channel images with 2 alpha,
+     but there's not much I can do about that */
+  if (channels > 4)
+    channels = 4;
+
   if (photometric == PHOTOMETRIC_PALETTE && bits_per_sample <= 8) {
     channels = 3;
     im = i_img_pal_new(width, height, channels, 256);