mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-05 04:25:29 -04:00
TMI-73: Now handles TIFF files using only the lower 8 bits of each 16 bit entry in the ColorMap.
This commit is contained in:
parent
706b8a8631
commit
ecc896f80d
@ -340,17 +340,7 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
throw new IIOException("Missing ColorMap for Palette TIFF");
|
throw new IIOException("Missing ColorMap for Palette TIFF");
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] cmapShort = (int[]) colorMap.getValue();
|
IndexColorModel icm = createIndexColorModel(bitsPerSample, dataType, (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);
|
|
||||||
|
|
||||||
return IndexedImageTypeSpecifier.createFromIndexColorModel(icm);
|
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 {
|
private int getSampleFormat() throws IIOException {
|
||||||
long[] value = getValueAsLongArray(TIFF.TAG_SAMPLE_FORMAT, "SampleFormat", false);
|
long[] value = getValueAsLongArray(TIFF.TAG_SAMPLE_FORMAT, "SampleFormat", false);
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ package com.twelvemonkeys.imageio.plugins.tiff;/*
|
|||||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
|
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.imageio.ImageReadParam;
|
||||||
import javax.imageio.ImageReader;
|
import javax.imageio.ImageReader;
|
||||||
import javax.imageio.event.IIOReadWarningListener;
|
import javax.imageio.event.IIOReadWarningListener;
|
||||||
import javax.imageio.spi.ImageReaderSpi;
|
import javax.imageio.spi.ImageReaderSpi;
|
||||||
@ -176,4 +177,31 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTestCase<TIFFImageRe
|
|||||||
stream.close();
|
stream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testColorMap8Bit() throws IOException {
|
||||||
|
TestData testData = new TestData(getClassLoaderResource("/tiff/scan-lzw-8bit-colormap.tiff"), new Dimension(2550, 3300));
|
||||||
|
|
||||||
|
ImageInputStream stream = testData.getInputStream();
|
||||||
|
|
||||||
|
try {
|
||||||
|
TIFFImageReader reader = createReader();
|
||||||
|
reader.setInput(stream);
|
||||||
|
|
||||||
|
IIOReadWarningListener warningListener = mock(IIOReadWarningListener.class);
|
||||||
|
reader.addIIOReadWarningListener(warningListener);
|
||||||
|
|
||||||
|
ImageReadParam param = reader.getDefaultReadParam();
|
||||||
|
param.setSourceRegion(new Rectangle(8, 8));
|
||||||
|
BufferedImage image = reader.read(0, param);
|
||||||
|
|
||||||
|
assertNotNull(image);
|
||||||
|
assertEquals(new Dimension(8, 8), new Dimension(image.getWidth(), image.getHeight()));
|
||||||
|
assertEquals(0xffffffff, image.getRGB(0, 0)); // The pixel at 0, 0 should be white, not black
|
||||||
|
verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("ColorMap"));
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user