diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java index 6f55f192..d6eb9247 100755 --- a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java +++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java @@ -340,17 +340,7 @@ public class TIFFImageReader extends ImageReaderBase { throw new IIOException("Missing ColorMap for Palette TIFF"); } - int[] cmapShort = (int[]) colorMap.getValue(); - int[] cmap = new int[colorMap.valueCount() / 3]; - - // All reds, then greens, and finally blues - for (int i = 0; i < cmap.length; i++) { - cmap[i] = (cmapShort[i ] / 256) << 16 - | (cmapShort[i + cmap.length] / 256) << 8 - | (cmapShort[i + 2 * cmap.length] / 256); - } - - IndexColorModel icm = new IndexColorModel(bitsPerSample, cmap.length, cmap, 0, false, -1, dataType); + IndexColorModel icm = createIndexColorModel(bitsPerSample, dataType, (int[]) colorMap.getValue()); return IndexedImageTypeSpecifier.createFromIndexColorModel(icm); @@ -413,6 +403,43 @@ public class TIFFImageReader extends ImageReaderBase { } } + private IndexColorModel createIndexColorModel(final int bitsPerSample, final int dataType, final int[] cmapShort) { + // According to the spec, there should be exactly 3 * bitsPerSample^2 entries in the color map for TIFF. + // Should we enforce this? + + int[] cmap = new int[cmapShort.length / 3]; + + // We'll detect whether the color map data is 8 bit, rather than 16 bit while converting + boolean cmapIs8Bit = true; + + // All reds, then greens, and finally blues + for (int i = 0; i < cmap.length; i++) { + cmap[i] = (cmapShort[i ] / 256) << 16 + | (cmapShort[i + cmap.length] / 256) << 8 + | (cmapShort[i + 2 * cmap.length] / 256); + + if (cmapIs8Bit && cmap[i] != 0) { + cmapIs8Bit = false; + } + } + + if (cmapIs8Bit) { + // This color map is using only the lower 8 bits, making the image all black. + // We'll create a new color map, based on the non-scaled 8 bit values. + + processWarningOccurred("8 bit ColorMap detected."); + + // All reds, then greens, and finally blues + for (int i = 0; i < cmap.length; i++) { + cmap[i] = (cmapShort[i ]) << 16 + | (cmapShort[i + cmap.length]) << 8 + | (cmapShort[i + 2 * cmap.length]); + } + } + + return new IndexColorModel(bitsPerSample, cmap.length, cmap, 0, false, -1, dataType); + } + private int getSampleFormat() throws IIOException { long[] value = getValueAsLongArray(TIFF.TAG_SAMPLE_FORMAT, "SampleFormat", false); diff --git a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java index b20c23cf..7122b900 100644 --- a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java +++ b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java @@ -29,6 +29,7 @@ package com.twelvemonkeys.imageio.plugins.tiff;/* import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase; import org.junit.Test; +import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.event.IIOReadWarningListener; import javax.imageio.spi.ImageReaderSpi; @@ -176,4 +177,31 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTestCase