From 37d4c035483b43bf513592afd363df24cbd51f83 Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Tue, 3 Mar 2015 14:44:24 +0100 Subject: [PATCH] TMI-104: Fixed metadata inconsistency, 1 channel SOF now always interpreted as color space Gray, regardless of Adobe App14 marker. --- .../jpeg/JPEGImage10MetadataCleaner.java | 6 ++- .../imageio/plugins/jpeg/JPEGImageReader.java | 5 +-- .../plugins/jpeg/JPEGImageReaderTest.java | 35 ++++++++++++++++-- .../invalid-adobe-ycc-gray-with-metadata.jpg | Bin 0 -> 299 bytes 4 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 imageio/imageio-jpeg/src/test/resources/jpeg/invalid-adobe-ycc-gray-with-metadata.jpg diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleaner.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleaner.java index 292a6bc8..5343c4a8 100644 --- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleaner.java +++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleaner.java @@ -156,10 +156,12 @@ final class JPEGImage10MetadataCleaner { } // Special case: Broken AdobeDCT segment, inconsistent with SOF, use values from SOF - if (adobeDCT != null && adobeDCT.getTransform() == AdobeDCTSegment.YCCK && sof.componentsInFrame() < 4) { + if (adobeDCT != null && (adobeDCT.getTransform() == AdobeDCTSegment.YCCK && sof.componentsInFrame() < 4 || + adobeDCT.getTransform() == AdobeDCTSegment.YCC && sof.componentsInFrame() < 3)) { reader.processWarningOccurred(String.format( - "Invalid Adobe App14 marker. Indicates YCCK/CMYK data, but SOF%d has %d color components. " + + "Invalid Adobe App14 marker. Indicates %s data, but SOF%d has %d color component(s). " + "Ignoring Adobe App14 marker.", + adobeDCT.getTransform() == AdobeDCTSegment.YCCK ? "YCCK/CMYK" : "YCC/RGB", sof.marker & 0xf, sof.componentsInFrame() )); diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReader.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReader.java index 68bc347e..d16a68ed 100644 --- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReader.java +++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReader.java @@ -323,7 +323,7 @@ public class JPEGImageReader extends ImageReaderBase { if (adobeDCT != null && (adobeDCT.getTransform() == AdobeDCTSegment.YCC && sof.componentsInFrame() != 3 || adobeDCT.getTransform() == AdobeDCTSegment.YCCK && sof.componentsInFrame() != 4)) { processWarningOccurred(String.format( - "Invalid Adobe App14 marker. Indicates %s data, but SOF%d has %d color components. " + + "Invalid Adobe App14 marker. Indicates %s data, but SOF%d has %d color component(s). " + "Ignoring Adobe App14 marker.", adobeDCT.getTransform() == AdobeDCTSegment.YCCK ? "YCCK/CMYK" : "YCC/RGB", sof.marker & 0xf, sof.componentsInFrame() @@ -1075,8 +1075,7 @@ public class JPEGImageReader extends ImageReaderBase { @Override public IIOMetadata getImageMetadata(int imageIndex) throws IOException { - // TMI-101: As we catch the IndexOutOfBoundsException below, we need to make sure that we don't catch the - // IndexOutOfBoundsException that should be thrown, if (imageIndex < 0 || imageIndex > numImages). + // checkBounds needed, as we catch the IndexOutOfBoundsException below. checkBounds(imageIndex); IIOMetadata imageMetadata; diff --git a/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReaderTest.java b/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReaderTest.java index f513b07d..dc220db2 100644 --- a/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReaderTest.java +++ b/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReaderTest.java @@ -80,6 +80,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTestCase getTestData() { + // While a lot of these files don't conform to any spec (Exif/JFIF), we will read these. return Arrays.asList( new TestData(getClassLoaderResource("/jpeg/cmm-exception-adobe-rgb.jpg"), new Dimension(626, 76)), new TestData(getClassLoaderResource("/jpeg/cmm-exception-srgb.jpg"), new Dimension(1800, 1200)), @@ -96,10 +97,11 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTestCase getBrokenTestData() { + // These files are considered too broken to be read (ie. most other software does not read them either). return Arrays.asList( - new TestData(getClassLoaderResource("/broken-jpeg/broken-bogus-segment-length.jpg"), new Dimension(467, 612)), - new TestData(getClassLoaderResource("/broken-jpeg/broken-adobe-marker-bad-length.jpg"), new Dimension(1800, 1200)), - new TestData(getClassLoaderResource("/broken-jpeg/broken-invalid-adobe-ycc-gray.jpg"), new Dimension(11, 440)) + new TestData(getClassLoaderResource("/broken-jpeg/broken-bogus-segment-length.jpg"), new Dimension(467, 612)), // Semi-readable, parts missing + new TestData(getClassLoaderResource("/broken-jpeg/broken-adobe-marker-bad-length.jpg"), new Dimension(1800, 1200)), // Unreadable, segment lengths are wrong + new TestData(getClassLoaderResource("/broken-jpeg/broken-invalid-adobe-ycc-gray.jpg"), new Dimension(11, 440)) // Image readable, broken metadata (fixable?) ); // More test data in specific tests below @@ -475,6 +477,33 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTestCaselam%vQ3nDQBU4jTBWpPLe}I9TgW(4Q2P2~(!~Y`;`V5SWj6f@p z03*8q&_)zdW(LNMMaE1l|8IdbGBDUPTxp#zn&Fs!G)f@yV_1t=Oz1+^=|F*0kU$|q zz~L!Sz!E6H2UNifRDlq%0Sfd31s(%cSOCr7g9$vc+M-Y>8zmsox0Zv)J*<_ne^Ru-a7lK{m4f|4jhM)=hB$ literal 0 HcmV?d00001