TMI #170 Fix General CMM error517/LCMS error 13 (Ignore incompatible ICC profile)

This commit is contained in:
Harald Kuhr 2015-08-25 14:13:35 +02:00
parent 25bef72ac0
commit d4e34d6109
2 changed files with 38 additions and 21 deletions

View File

@ -61,6 +61,7 @@ import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ServiceRegistry; import javax.imageio.spi.ServiceRegistry;
import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageInputStream;
import java.awt.*; import java.awt.*;
import java.awt.color.CMMException;
import java.awt.color.ColorSpace; import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile; import java.awt.color.ICC_Profile;
import java.awt.image.*; import java.awt.image.*;
@ -1562,14 +1563,22 @@ public class TIFFImageReader extends ImageReaderBase {
return value; return value;
} }
public ICC_Profile getICCProfile() { private ICC_Profile getICCProfile() {
Entry entry = currentIFD.getEntryById(TIFF.TAG_ICC_PROFILE); Entry entry = currentIFD.getEntryById(TIFF.TAG_ICC_PROFILE);
if (entry == null) {
return null; if (entry != null) {
byte[] value = (byte[]) entry.getValue();
ICC_Profile profile = ICC_Profile.getInstance(value);
try {
return ColorSpaces.validateProfile(profile);
}
catch (CMMException ignore) {
processWarningOccurred("Ignoring broken/incompatible ICC profile: " + ignore.getMessage());
}
} }
byte[] value = (byte[]) entry.getValue(); return null;
return ICC_Profile.getInstance(value);
} }
// TODO: Tiling support // TODO: Tiling support

View File

@ -84,6 +84,7 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
new TestData(getClassLoaderResource("/tiff/grayscale-alpha.tiff"), new Dimension(248, 351)), // Gray + unassociated alpha new TestData(getClassLoaderResource("/tiff/grayscale-alpha.tiff"), new Dimension(248, 351)), // Gray + unassociated alpha
new TestData(getClassLoaderResource("/tiff/signed-integral-8bit.tif"), new Dimension(439, 167)), // Gray, 8 bit *signed* integral new TestData(getClassLoaderResource("/tiff/signed-integral-8bit.tif"), new Dimension(439, 167)), // Gray, 8 bit *signed* integral
new TestData(getClassLoaderResource("/tiff/floatingpoint-32bit.tif"), new Dimension(300, 100)), // RGB, 32 bit floating point new TestData(getClassLoaderResource("/tiff/floatingpoint-32bit.tif"), new Dimension(300, 100)), // RGB, 32 bit floating point
new TestData(getClassLoaderResource("/tiff/general-cmm-error.tif"), new Dimension(1181, 860)), // RGB, LZW compression with broken/incompatible ICC profile
// CCITT // CCITT
new TestData(getClassLoaderResource("/tiff/ccitt/group3_1d.tif"), new Dimension(6, 4)), // B/W, CCITT T4 1D new TestData(getClassLoaderResource("/tiff/ccitt/group3_1d.tif"), new Dimension(6, 4)), // B/W, CCITT T4 1D
new TestData(getClassLoaderResource("/tiff/ccitt/group3_1d_fill.tif"), new Dimension(6, 4)), // B/W, CCITT T4 1D new TestData(getClassLoaderResource("/tiff/ccitt/group3_1d_fill.tif"), new Dimension(6, 4)), // B/W, CCITT T4 1D
@ -152,9 +153,8 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
@Test @Test
public void testReadOldStyleJPEGGrayscale() throws IOException { public void testReadOldStyleJPEGGrayscale() throws IOException {
TestData testData = new TestData(getClassLoaderResource("/tiff/grayscale-old-style-jpeg.tiff"), new Dimension(600, 600)); TestData testData = new TestData(getClassLoaderResource("/tiff/grayscale-old-style-jpeg.tiff"), new Dimension(600, 600));
ImageInputStream stream = testData.getInputStream();
try { try (ImageInputStream stream = testData.getInputStream()) {
TIFFImageReader reader = createReader(); TIFFImageReader reader = createReader();
reader.setInput(stream); reader.setInput(stream);
BufferedImage image = reader.read(0); BufferedImage image = reader.read(0);
@ -162,18 +162,13 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
assertNotNull(image); assertNotNull(image);
assertEquals(testData.getDimension(0), new Dimension(image.getWidth(), image.getHeight())); assertEquals(testData.getDimension(0), new Dimension(image.getWidth(), image.getHeight()));
} }
finally {
stream.close();
}
} }
@Test @Test
public void testReadIncompatibleICCProfileIgnoredWithWarning() throws IOException { public void testReadIncompatibleICCProfileIgnoredWithWarning() throws IOException {
TestData testData = new TestData(getClassLoaderResource("/tiff/rgb-with-embedded-cmyk-icc.tif"), new Dimension(1500, 1500)); TestData testData = new TestData(getClassLoaderResource("/tiff/rgb-with-embedded-cmyk-icc.tif"), new Dimension(1500, 1500));
ImageInputStream stream = testData.getInputStream(); try (ImageInputStream stream = testData.getInputStream()) {
try {
TIFFImageReader reader = createReader(); TIFFImageReader reader = createReader();
reader.setInput(stream); reader.setInput(stream);
@ -186,18 +181,13 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
assertEquals(testData.getDimension(0), new Dimension(image.getWidth(), image.getHeight())); assertEquals(testData.getDimension(0), new Dimension(image.getWidth(), image.getHeight()));
verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("ICC")); verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("ICC"));
} }
finally {
stream.close();
}
} }
@Test @Test
public void testColorMap8Bit() throws IOException { public void testColorMap8Bit() throws IOException {
TestData testData = new TestData(getClassLoaderResource("/tiff/scan-lzw-8bit-colormap.tiff"), new Dimension(2550, 3300)); TestData testData = new TestData(getClassLoaderResource("/tiff/scan-lzw-8bit-colormap.tiff"), new Dimension(2550, 3300));
ImageInputStream stream = testData.getInputStream(); try (ImageInputStream stream = testData.getInputStream()) {
try {
TIFFImageReader reader = createReader(); TIFFImageReader reader = createReader();
reader.setInput(stream); reader.setInput(stream);
@ -213,8 +203,26 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
assertEquals(0xffffffff, image.getRGB(0, 0)); // The pixel at 0, 0 should be white, not black assertEquals(0xffffffff, image.getRGB(0, 0)); // The pixel at 0, 0 should be white, not black
verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("ColorMap")); verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("ColorMap"));
} }
finally { }
stream.close();
@Test
public void testBadICCProfile() throws IOException {
TestData testData = new TestData(getClassLoaderResource("/tiff/general-cmm-error.tif"), new Dimension(1181, 864));
try (ImageInputStream stream = testData.getInputStream()) {
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()));
verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("ICC profile"));
} }
} }
} }