diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFReader.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFReader.java index 9c130368..3cdb0253 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFReader.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/EXIFReader.java @@ -80,10 +80,10 @@ public final class EXIFReader extends MetadataReader { long directoryOffset = input.readUnsignedInt(); - return readDirectory(input, directoryOffset); + return readDirectory(input, directoryOffset, true); } - protected Directory readDirectory(final ImageInputStream pInput, final long pOffset) throws IOException { + protected Directory readDirectory(final ImageInputStream pInput, final long pOffset, final boolean readLinked) throws IOException { List ifds = new ArrayList(); List entries = new ArrayList(); @@ -104,15 +104,18 @@ public final class EXIFReader extends MetadataReader { entries.add(entry); } - if (nextOffset == -1) { - nextOffset = pInput.readUnsignedInt(); - } + if (readLinked) { + if (nextOffset == -1) { + nextOffset = pInput.readUnsignedInt(); + } - // Read linked IFDs - if (nextOffset != 0) { - CompoundDirectory next = (CompoundDirectory) readDirectory(pInput, nextOffset); - for (int i = 0; i < next.directoryCount(); i++) { - ifds.add((IFD) next.getDirectory(i)); + // Read linked IFDs + if (nextOffset != 0) { + CompoundDirectory next = (CompoundDirectory) readDirectory(pInput, nextOffset, true); + + for (int i = 0; i < next.directoryCount(); i++) { + ifds.add((IFD) next.getDirectory(i)); + } } } @@ -149,7 +152,7 @@ public final class EXIFReader extends MetadataReader { List subIFDs = new ArrayList(pointerOffsets.length); for (long pointerOffset : pointerOffsets) { - CompoundDirectory subDirectory = (CompoundDirectory) readDirectory(input, pointerOffset); + CompoundDirectory subDirectory = (CompoundDirectory) readDirectory(input, pointerOffset, false); for (int j = 0; j < subDirectory.directoryCount(); j++) { subIFDs.add((IFD) subDirectory.getDirectory(j)); @@ -461,7 +464,7 @@ public final class EXIFReader extends MetadataReader { Directory directory; if (args.length > 1) { - directory = reader.readDirectory(stream, pos); + directory = reader.readDirectory(stream, pos, false); } else { directory = reader.read(stream); diff --git a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/TIFF.java b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/TIFF.java index c6904e76..d169e690 100644 --- a/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/TIFF.java +++ b/imageio/imageio-metadata/src/main/java/com/twelvemonkeys/imageio/metadata/exif/TIFF.java @@ -76,7 +76,6 @@ public interface TIFF { 11 = FLOAT Single precision (4-byte) IEEE format. 12 = DOUBLE Double precision (8-byte) IEEE format. - TODO: Verify IFD type See http://www.awaresystems.be/imaging/tiff/tifftags/subifds.html 13 = IFD, same as LONG diff --git a/imageio/imageio-metadata/src/test/java/com/twelvemonkeys/imageio/metadata/exif/EXIFReaderTest.java b/imageio/imageio-metadata/src/test/java/com/twelvemonkeys/imageio/metadata/exif/EXIFReaderTest.java index 5e184bd4..b7770e11 100644 --- a/imageio/imageio-metadata/src/test/java/com/twelvemonkeys/imageio/metadata/exif/EXIFReaderTest.java +++ b/imageio/imageio-metadata/src/test/java/com/twelvemonkeys/imageio/metadata/exif/EXIFReaderTest.java @@ -190,4 +190,21 @@ public class EXIFReaderTest extends MetadataReaderAbstractTest { assertNotNull(exif); assertEquals(0, exif.size()); // EXIFTool reports "Warning: Bad ExifIFD directory" } + + @Test + public void testReadExifJPEGWithInteropSubDir() throws IOException { + ImageInputStream stream = ImageIO.createImageInputStream(getResource("/jpeg/exif-with-interop-subdir.jpg")); + stream.seek(30); + + Directory directory = createReader().read(new SubImageInputStream(stream, 65535)); + assertEquals(11, directory.size()); + + Directory exif = (Directory) directory.getEntryById(TIFF.TAG_EXIF_IFD).getValue(); + assertNotNull(exif); + assertEquals(24, exif.size()); + + Directory interop = (Directory) exif.getEntryById(TIFF.TAG_INTEROP_IFD).getValue(); + assertNotNull(interop); + assertEquals(0, interop.size()); + } } diff --git a/imageio/imageio-metadata/src/test/resources/jpeg/exif-with-interop-subdir.jpg b/imageio/imageio-metadata/src/test/resources/jpeg/exif-with-interop-subdir.jpg new file mode 100644 index 00000000..3572745e Binary files /dev/null and b/imageio/imageio-metadata/src/test/resources/jpeg/exif-with-interop-subdir.jpg differ