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 420bd1b4..d78e091d 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 @@ -197,9 +197,7 @@ final class JPEGImage10MetadataCleaner { IIOMetadataNode unknown = new IIOMetadataNode("unknown"); unknown.setAttribute("MarkerTag", Integer.toString(segment.marker() & 0xff)); - DataInputStream stream = new DataInputStream(segment.data()); - - try { + try (DataInputStream stream = new DataInputStream(segment.data())) { String identifier = segment.identifier(); int off = identifier != null ? identifier.length() + 1 : 0; @@ -213,9 +211,6 @@ final class JPEGImage10MetadataCleaner { unknown.setUserObject(data); } - finally { - stream.close(); - } if (next == null) { // To be semi-compatible with the functionality in mergeTree, @@ -271,12 +266,12 @@ final class JPEGImage10MetadataCleaner { dht.getParentNode().insertBefore(acTables, dht.getNextSibling()); // Split into 2 dht nodes, one for AC and one for DC - for (int i = 0; i < dhtables.getLength(); i++) { + for (int i = dhtables.getLength() - 1; i >= 0 ; i--) { Element dhtable = (Element) dhtables.item(i); String tableClass = dhtable.getAttribute("class"); if ("1".equals(tableClass)) { dht.removeChild(dhtable); - acTables.appendChild(dhtable); + acTables.insertBefore(dhtable, acTables.getFirstChild()); } } } diff --git a/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleanerTest.java b/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleanerTest.java new file mode 100644 index 00000000..00145da9 --- /dev/null +++ b/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleanerTest.java @@ -0,0 +1,96 @@ +package com.twelvemonkeys.imageio.plugins.jpeg; + +import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi; +import org.junit.Test; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.metadata.IIOMetadataNode; +import javax.imageio.spi.IIORegistry; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStream; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * JPEGImage10MetadataCleanerTest. + * + * @author Harald Kuhr + * @author last modified by $Author: harald.kuhr$ + * @version $Id: JPEGImage10MetadataCleanerTest.java,v 1.0 08/08/16 harald.kuhr Exp$ + */ +public class JPEGImage10MetadataCleanerTest { + + static { + IIORegistry.getDefaultInstance().registerServiceProvider(new URLImageInputStreamSpi()); + ImageIO.setUseCache(false); + } + + protected static final JPEGImageReaderSpi SPI = new JPEGImageReaderSpi(lookupDelegateProvider()); + + protected static ImageReaderSpi lookupDelegateProvider() { + return JPEGImageReaderSpi.lookupDelegateProvider(IIORegistry.getDefaultInstance()); + } + + // Unit/regression test for #276 + @Test + public void cleanMetadataMoreThan4DHTSegments() throws Exception { + List testData = Arrays.asList("/jpeg/5dhtsegments.jpg", "/jpeg/6dhtsegments.jpg"); + + for (String data : testData) { + try (ImageInputStream origInput = ImageIO.createImageInputStream(getClass().getResource(data)); + ImageInputStream input = ImageIO.createImageInputStream(getClass().getResource(data))) { + + ImageReader origReader = SPI.delegateProvider.createReaderInstance(); + origReader.setInput(origInput); + + ImageReader reader = SPI.createReaderInstance(); + reader.setInput(input); + + IIOMetadata original = origReader.getImageMetadata(0); + IIOMetadataNode origTree = (IIOMetadataNode) original.getAsTree(JPEGImage10MetadataCleaner.JAVAX_IMAGEIO_JPEG_IMAGE_1_0); + + JPEGImage10MetadataCleaner cleaner = new JPEGImage10MetadataCleaner((JPEGImageReader) reader); + IIOMetadata cleaned = cleaner.cleanMetadata(origReader.getImageMetadata(0)); + + IIOMetadataNode cleanTree = (IIOMetadataNode) cleaned.getAsTree(JPEGImage10MetadataCleaner.JAVAX_IMAGEIO_JPEG_IMAGE_1_0); + + NodeList origDHT = origTree.getElementsByTagName("dht"); + assertEquals(1, origDHT.getLength()); + + NodeList cleanDHT = cleanTree.getElementsByTagName("dht"); + assertEquals(2, cleanDHT.getLength()); + + NodeList cleanDHTable = cleanTree.getElementsByTagName("dhtable"); + NodeList origDHTable = origTree.getElementsByTagName("dhtable"); + + assertEquals(origDHTable.getLength(), cleanDHTable.getLength()); + + // Note: This also tests that the order of the htables are the same, + // but that will only hold if they are already sorted by class. + // Luckily, they are in these cases... + for (int i = 0; i < origDHTable.getLength(); i++) { + Element cleanDHTableElem = (Element) cleanDHTable.item(i); + Element origDHTableElem = (Element) origDHTable.item(i); + + assertNotNull(cleanDHTableElem); + + assertNotNull(cleanDHTableElem.getAttribute("class")); + assertEquals(origDHTableElem.getAttribute("class"), cleanDHTableElem.getAttribute("class")); + + assertNotNull(cleanDHTableElem.getAttribute("htableId")); + assertEquals(origDHTableElem.getAttribute("htableId"), cleanDHTableElem.getAttribute("htableId")); + } + + reader.dispose(); + origReader.dispose(); + } + } + } +} \ No newline at end of file diff --git a/imageio/imageio-jpeg/src/test/resources/jpeg/5dhtsegments.jpg b/imageio/imageio-jpeg/src/test/resources/jpeg/5dhtsegments.jpg new file mode 100644 index 00000000..eab45b29 Binary files /dev/null and b/imageio/imageio-jpeg/src/test/resources/jpeg/5dhtsegments.jpg differ diff --git a/imageio/imageio-jpeg/src/test/resources/jpeg/6dhtsegments.jpg b/imageio/imageio-jpeg/src/test/resources/jpeg/6dhtsegments.jpg new file mode 100644 index 00000000..aaa6e8e7 Binary files /dev/null and b/imageio/imageio-jpeg/src/test/resources/jpeg/6dhtsegments.jpg differ