#290 TIFF Stream Medata support

This commit is contained in:
Harald Kuhr
2016-11-22 20:51:07 +01:00
parent 18705be7f6
commit 0b030dde52
6 changed files with 280 additions and 10 deletions
@@ -34,16 +34,19 @@ import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.event.IIOReadWarningListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import static org.junit.internal.matchers.StringContains.containsString;
import static org.mockito.Matchers.contains;
@@ -560,4 +563,44 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
}
}
}
@Test
public void testStreamMetadataNonNull() {
ImageReader reader = createReader();
for (TestData data : getTestData()) {
reader.setInput(data.getInputStream());
try {
IIOMetadata streamMetadata = reader.getStreamMetadata();
assertNotNull(streamMetadata);
assertThat(streamMetadata, is(TIFFStreamMetadata.class));
}
catch (Exception e) {
failBecause(String.format("Image %s could not be read: %s", data.getInput(), e), e);
}
}
}
@Test
public void testStreamMetadataII() throws IOException {
ImageReader reader = createReader();
try (ImageInputStream stream = ImageIO.createImageInputStream(getClassLoaderResource("/tiff/ccitt_tolessrows.tif"))) {
reader.setInput(stream);
TIFFStreamMetadata streamMetadata = (TIFFStreamMetadata) reader.getStreamMetadata();
assertEquals(ByteOrder.LITTLE_ENDIAN, streamMetadata.byteOrder);
}
}
@Test
public void testStreamMetadataMM() throws IOException {
ImageReader reader = createReader();
try (ImageInputStream stream = ImageIO.createImageInputStream(getClassLoaderResource("/tiff/sm_colors_pb.tif"))) {
reader.setInput(stream);
TIFFStreamMetadata streamMetadata = (TIFFStreamMetadata) reader.getStreamMetadata();
assertEquals(ByteOrder.BIG_ENDIAN, streamMetadata.byteOrder);
}
}
}
@@ -48,10 +48,11 @@ import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.List;
@@ -789,4 +790,68 @@ public class TIFFImageWriterTest extends ImageWriterAbstractTestCase {
}
}
}
@Test
public void testWriteStreamMetadataDefaultMM() throws IOException {
ImageWriter writer = createImageWriter();
ByteArrayOutputStream output = new ByteArrayOutputStream();
try (ImageOutputStream stream = ImageIO.createImageOutputStream(output)) {
stream.setByteOrder(ByteOrder.BIG_ENDIAN); // Should pass through
writer.setOutput(stream);
writer.write(null, new IIOImage(getTestData(0), null, null), null);
}
byte[] bytes = output.toByteArray();
assertArrayEquals(new byte[] {'M', 'M', 0, 42}, Arrays.copyOf(bytes, 4));
}
@Test
public void testWriteStreamMetadataDefaultII() throws IOException {
ImageWriter writer = createImageWriter();
ByteArrayOutputStream output = new ByteArrayOutputStream();
try (ImageOutputStream stream = ImageIO.createImageOutputStream(output)) {
stream.setByteOrder(ByteOrder.LITTLE_ENDIAN); // Should pass through
writer.setOutput(stream);
writer.write(null, new IIOImage(getTestData(0), null, null), null);
}
byte[] bytes = output.toByteArray();
assertArrayEquals(new byte[] {'I', 'I', 42, 0}, Arrays.copyOf(bytes, 4));
}
@Test
public void testWriteStreamMetadataMM() throws IOException {
ImageWriter writer = createImageWriter();
ByteArrayOutputStream output = new ByteArrayOutputStream();
try (ImageOutputStream stream = ImageIO.createImageOutputStream(output)) {
stream.setByteOrder(ByteOrder.LITTLE_ENDIAN); // Should be overridden by stream metadata
writer.setOutput(stream);
writer.write(new TIFFStreamMetadata(ByteOrder.BIG_ENDIAN), new IIOImage(getTestData(0), null, null), null);
}
byte[] bytes = output.toByteArray();
assertArrayEquals(new byte[] {'M', 'M', 0, 42}, Arrays.copyOf(bytes, 4));
}
@Test
public void testWriteStreamMetadataII() throws IOException {
ImageWriter writer = createImageWriter();
ByteArrayOutputStream output = new ByteArrayOutputStream();
try (ImageOutputStream stream = ImageIO.createImageOutputStream(output)) {
stream.setByteOrder(ByteOrder.BIG_ENDIAN); // Should be overridden by stream metadata
writer.setOutput(stream);
writer.write(new TIFFStreamMetadata(ByteOrder.LITTLE_ENDIAN), new IIOImage(getTestData(0), null, null), null);
}
byte[] bytes = output.toByteArray();
assertArrayEquals(new byte[] {'I', 'I', 42, 0}, Arrays.copyOf(bytes, 4));
}
}
@@ -0,0 +1,139 @@
package com.twelvemonkeys.imageio.plugins.tiff;
import org.junit.Test;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import java.nio.ByteOrder;
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFStreamMetadata.SUN_NATIVE_STREAM_METADATA_FORMAT_NAME;
import static java.nio.ByteOrder.BIG_ENDIAN;
import static java.nio.ByteOrder.LITTLE_ENDIAN;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
/**
* TIFFStreamMetadataTest
*/
public class TIFFStreamMetadataTest {
// Test that we configure byte order of stream correctly (MM + II)
@Test(expected = IllegalArgumentException.class)
public void testConfigureStreamNullStream() throws IIOInvalidTreeException {
TIFFStreamMetadata.configureStreamByteOrder(new TIFFStreamMetadata(), null);
}
@Test
public void testConfigureStreamNullMetadata() throws IIOInvalidTreeException {
ImageOutputStream stream = mock(ImageOutputStream.class);
TIFFStreamMetadata.configureStreamByteOrder(null, stream);
verify(stream, never()).setByteOrder(any(ByteOrder.class));
}
@Test
public void testConfigureStreamMM() throws IIOInvalidTreeException {
ImageOutputStream stream = mock(ImageOutputStream.class);
TIFFStreamMetadata.configureStreamByteOrder(new TIFFStreamMetadata(BIG_ENDIAN), stream);
verify(stream, only()).setByteOrder(BIG_ENDIAN);
}
@Test
public void testConfigureStreamII() throws IIOInvalidTreeException {
ImageOutputStream stream = mock(ImageOutputStream.class);
TIFFStreamMetadata.configureStreamByteOrder(new TIFFStreamMetadata(LITTLE_ENDIAN), stream);
verify(stream, only()).setByteOrder(LITTLE_ENDIAN);
}
@Test
public void testConfigureStreamForegin() throws IIOInvalidTreeException {
ImageOutputStream stream = mock(ImageOutputStream.class);
IIOMetadata metadata = mock(IIOMetadata.class);
when(metadata.getAsTree(eq(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME))).thenReturn(createForeignTree(LITTLE_ENDIAN));
TIFFStreamMetadata.configureStreamByteOrder(metadata, stream);
verify(stream, only()).setByteOrder(LITTLE_ENDIAN);
}
private IIOMetadataNode createForeignTree(ByteOrder order) {
IIOMetadataNode root = new IIOMetadataNode(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME);
IIOMetadataNode byteOrder = new IIOMetadataNode("ByteOrder");
byteOrder.setAttribute("value", order == LITTLE_ENDIAN ? "LITTLE_ENDIAN" : "BIG_ENDIAN");
root.appendChild(byteOrder);
return root;
}
// Test that we merge correctly with "forreign" metadata class, as long as format names are the same (MM + II)
@Test(expected = IllegalArgumentException.class)
public void testMergeNull() throws IIOInvalidTreeException {
new TIFFStreamMetadata().mergeTree(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME, null);
}
@Test(expected = IllegalArgumentException.class)
public void testMergeIllegal() throws IIOInvalidTreeException {
new TIFFStreamMetadata().mergeTree("com.foo.bar", createForeignTree(BIG_ENDIAN));
}
@Test
public void testMergeII() throws IIOInvalidTreeException {
TIFFStreamMetadata metadata = new TIFFStreamMetadata();
metadata.mergeTree(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME, createForeignTree(LITTLE_ENDIAN));
assertEquals(LITTLE_ENDIAN, metadata.byteOrder);
}
@Test
public void testMergeMM() throws IIOInvalidTreeException {
TIFFStreamMetadata metadata = new TIFFStreamMetadata();
metadata.byteOrder = LITTLE_ENDIAN;
metadata.mergeTree(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME, createForeignTree(BIG_ENDIAN));
assertEquals(BIG_ENDIAN, metadata.byteOrder);
}
@Test(expected = IllegalArgumentException.class)
public void testGetAsTreeNull() {
new TIFFStreamMetadata().getAsTree(null);
}
@Test(expected = IllegalArgumentException.class)
public void testGetAsTreeIllegal() {
new TIFFStreamMetadata().getAsTree("com.foo.bar");
}
@Test
public void testGetAsTreeNative() {
Node root = new TIFFStreamMetadata().getAsTree(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME);
assertNotNull(root);
assertThat(root, is(IIOMetadataNode.class));
assertEquals(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME, root.getNodeName());
NodeList childNodes = root.getChildNodes();
assertEquals(1, childNodes.getLength());
assertThat(childNodes.item(0), is(IIOMetadataNode.class));
IIOMetadataNode byteOrder = (IIOMetadataNode) childNodes.item(0);
assertEquals("ByteOrder", byteOrder.getNodeName());
assertEquals("BIG_ENDIAN", byteOrder.getAttribute("value"));
}
@Test
public void testGetAsTreeNativeII() {
Node root = new TIFFStreamMetadata(LITTLE_ENDIAN).getAsTree(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME);
assertNotNull(root);
assertThat(root, is(IIOMetadataNode.class));
assertEquals(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME, root.getNodeName());
NodeList childNodes = root.getChildNodes();
assertEquals(1, childNodes.getLength());
assertThat(childNodes.item(0), is(IIOMetadataNode.class));
IIOMetadataNode byteOrder = (IIOMetadataNode) childNodes.item(0);
assertEquals("ByteOrder", byteOrder.getNodeName());
assertEquals("LITTLE_ENDIAN", byteOrder.getAttribute("value"));
}
}