#276 Fix DHT inconsistency

This commit is contained in:
Harald Kuhr 2016-08-09 11:47:25 +02:00
parent c7208c2c97
commit 13bea23550
4 changed files with 99 additions and 8 deletions

View File

@ -197,9 +197,7 @@ final class JPEGImage10MetadataCleaner {
IIOMetadataNode unknown = new IIOMetadataNode("unknown"); IIOMetadataNode unknown = new IIOMetadataNode("unknown");
unknown.setAttribute("MarkerTag", Integer.toString(segment.marker() & 0xff)); unknown.setAttribute("MarkerTag", Integer.toString(segment.marker() & 0xff));
DataInputStream stream = new DataInputStream(segment.data()); try (DataInputStream stream = new DataInputStream(segment.data())) {
try {
String identifier = segment.identifier(); String identifier = segment.identifier();
int off = identifier != null ? identifier.length() + 1 : 0; int off = identifier != null ? identifier.length() + 1 : 0;
@ -213,9 +211,6 @@ final class JPEGImage10MetadataCleaner {
unknown.setUserObject(data); unknown.setUserObject(data);
} }
finally {
stream.close();
}
if (next == null) { if (next == null) {
// To be semi-compatible with the functionality in mergeTree, // To be semi-compatible with the functionality in mergeTree,
@ -271,12 +266,12 @@ final class JPEGImage10MetadataCleaner {
dht.getParentNode().insertBefore(acTables, dht.getNextSibling()); dht.getParentNode().insertBefore(acTables, dht.getNextSibling());
// Split into 2 dht nodes, one for AC and one for DC // 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); Element dhtable = (Element) dhtables.item(i);
String tableClass = dhtable.getAttribute("class"); String tableClass = dhtable.getAttribute("class");
if ("1".equals(tableClass)) { if ("1".equals(tableClass)) {
dht.removeChild(dhtable); dht.removeChild(dhtable);
acTables.appendChild(dhtable); acTables.insertBefore(dhtable, acTables.getFirstChild());
} }
} }
} }

View File

@ -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 <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @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<String> 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();
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB