diff --git a/imageio/imageio-tiff-jai-interop/pom.xml b/imageio/imageio-tiff-jai-interop/pom.xml new file mode 100644 index 00000000..29037ff9 --- /dev/null +++ b/imageio/imageio-tiff-jai-interop/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + com.twelvemonkeys.imageio + imageio + 3.8.0-SNAPSHOT + + imageio-tiff-jai-interop + TwelveMonkeys :: ImageIO :: TIFF/JAI Metadata Interop + + Test TIFF plugin and JAI TIFF plugin Metadata interoperability + + + + com.twelvemonkeys.imageio.jaiinterop + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + + + + com.github.jai-imageio + jai-imageio-core + 1.4.0 + + + com.twelvemonkeys.imageio + imageio-core + + + com.twelvemonkeys.imageio + imageio-core + test-jar + test + + + com.twelvemonkeys.imageio + imageio-metadata + + + com.twelvemonkeys.imageio + imageio-tiff + + + diff --git a/imageio/imageio-tiff-jai-interop/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/jaiinterop/TIFFImageMetadataJAInteroperabilityTest.java b/imageio/imageio-tiff-jai-interop/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/jaiinterop/TIFFImageMetadataJAInteroperabilityTest.java new file mode 100644 index 00000000..31cdce2c --- /dev/null +++ b/imageio/imageio-tiff-jai-interop/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/jaiinterop/TIFFImageMetadataJAInteroperabilityTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021, Harald Kuhr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.twelvemonkeys.imageio.plugins.tiff.jaiinterop; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.awt.image.BufferedImage; +import java.util.Arrays; +import java.util.Iterator; + +import javax.imageio.ImageIO; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.metadata.IIOMetadataFormatImpl; +import javax.imageio.metadata.IIOMetadataNode; + +import org.junit.Test; + +import com.twelvemonkeys.imageio.metadata.tiff.Rational; +import com.twelvemonkeys.imageio.metadata.tiff.TIFF; +import com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry; +import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadata; + +/** + * Tests our TIFFImageMetadata works with JAI TIFFImageWriter. + * + * @author Harald Kuhr + * @author last modified by $Author: haraldk$ + * @version $Id: TIFFImageReaderJDKJPEGInteroperabilityTest.java,v 1.0 08.05.12 15:25 haraldk Exp$ + */ +public class TIFFImageMetadataJAInteroperabilityTest { + private static final String JAI_TIFF_PROVIDER_CLASS_NAME = "com.github.jaiimageio.impl.plugins.tiff.TIFFImageWriterSpi"; + + private ImageWriter getJAIImageWriter() { + Iterator writers = ImageIO.getImageWritersByFormatName("TIFF"); + + if (writers.hasNext()) { + ImageWriter writer = writers.next(); + + if (JAI_TIFF_PROVIDER_CLASS_NAME.equals(writer.getOriginatingProvider().getClass().getName())) { + return writer; + } + } + + throw new AssertionError("Expected Spi not found (dependency issue?): " + JAI_TIFF_PROVIDER_CLASS_NAME); + } + + + @Test + public void testRationalNeedsDenominator() { + // Set the resolution to 200 dpi + IIOMetadata ourMetadata = new TIFFImageMetadata(Arrays.asList(new TIFFEntry(TIFF.TAG_RESOLUTION_UNIT, 2), // Unit DPI (default) + new TIFFEntry(TIFF.TAG_X_RESOLUTION, new Rational(200)), + new TIFFEntry(TIFF.TAG_Y_RESOLUTION, new Rational(200)))); + + ImageTypeSpecifier type = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY); + ImageWriter writer = getJAIImageWriter(); + IIOMetadata converted = writer.convertImageMetadata(ourMetadata, type, null); + + assertNotNull(converted); + + // Make sure we have x/y resolution in converted metadata + IIOMetadataNode standardTree = (IIOMetadataNode) converted.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName); + String horizontalPixelSize = ((IIOMetadataNode) standardTree.getElementsByTagName("HorizontalPixelSize").item(0)).getAttribute("value"); + String verticalPixelSize = ((IIOMetadataNode) standardTree.getElementsByTagName("VerticalPixelSize").item(0)).getAttribute("value"); + + // For some reason this is *pixel size* in *mm*... + String expected = String.valueOf(2.54 / 200 * 10); + assertEquals(expected, horizontalPixelSize); + assertEquals(expected, verticalPixelSize); + } +} diff --git a/imageio/imageio-tiff-jdk-interop/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/jdkinterop/TIFFImageReaderJDKJPEGInteroperabilityTest.java b/imageio/imageio-tiff-jdk-interop/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/jdkinterop/TIFFImageReaderJDKJPEGInteroperabilityTest.java similarity index 98% rename from imageio/imageio-tiff-jdk-interop/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/jdkinterop/TIFFImageReaderJDKJPEGInteroperabilityTest.java rename to imageio/imageio-tiff-jdk-interop/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/jdkinterop/TIFFImageReaderJDKJPEGInteroperabilityTest.java index cce05aa5..78e74370 100644 --- a/imageio/imageio-tiff-jdk-interop/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/jdkinterop/TIFFImageReaderJDKJPEGInteroperabilityTest.java +++ b/imageio/imageio-tiff-jdk-interop/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/jdkinterop/TIFFImageReaderJDKJPEGInteroperabilityTest.java @@ -28,25 +28,26 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package com.twelvemonkeys.imageio.plugins.jpeg.jdkinterop; +package com.twelvemonkeys.imageio.plugins.tiff.jdkinterop; -import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReader; -import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi; -import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest; +import static org.junit.Assert.fail; -import org.junit.Ignore; -import org.junit.Test; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.spi.ImageReaderSpi; import java.awt.*; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; -import static org.junit.Assert.fail; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.spi.ImageReaderSpi; + +import org.junit.Ignore; +import org.junit.Test; + +import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReader; +import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi; +import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest; /** * Tests our TIFFImageReader delegating to the JDK JPEGImageReader. diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageMetadata.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageMetadata.java index 41d45c40..21872699 100644 --- a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageMetadata.java +++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageMetadata.java @@ -100,7 +100,7 @@ public final class TIFFImageMetadata extends AbstractMetadata { * {@link #setFromTree(String, Node)} * or {@link #mergeTree(String, Node)} methods. */ - public TIFFImageMetadata(final Collection entries) { + public TIFFImageMetadata(final Collection entries) { this(new IFD(entries)); } @@ -196,7 +196,12 @@ public final class TIFFImageMetadata extends AbstractMetadata { elementNode.setAttribute("value", String.valueOf((Short) value & 0xFFFF)); } else if (unsigned && value instanceof Integer) { - elementNode.setAttribute("value", String.valueOf((Integer) value & 0xFFFFFFFFl)); + elementNode.setAttribute("value", String.valueOf((Integer) value & 0xFFFFFFFFL)); + } + else if (value instanceof Rational) { + // For compatibility with JAI format, we need denominator + String rational = String.valueOf(value); + elementNode.setAttribute("value", rational.indexOf('/') < 0 && !"NaN".equals(rational) ? rational + "/1" : rational); } else { elementNode.setAttribute("value", String.valueOf(value)); diff --git a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageMetadataTest.java b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageMetadataTest.java index f081e929..cb812472 100644 --- a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageMetadataTest.java +++ b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageMetadataTest.java @@ -238,8 +238,8 @@ public class TIFFImageMetadataTest { assertSingleNodeWithValue(entries, TIFF.TAG_ROWS_PER_STRIP, TIFF.TYPE_LONG, "5"); assertSingleNodeWithValue(entries, TIFF.TAG_STRIP_BYTE_COUNTS, TIFF.TYPE_LONG, stripByteCounts); assertSingleNodeWithValue(entries, TIFF.TAG_PLANAR_CONFIGURATION, TIFF.TYPE_SHORT, "1"); - assertSingleNodeWithValue(entries, TIFF.TAG_X_POSITION, TIFF.TYPE_RATIONAL, "0"); - assertSingleNodeWithValue(entries, TIFF.TAG_Y_POSITION, TIFF.TYPE_RATIONAL, "0"); + assertSingleNodeWithValue(entries, TIFF.TAG_X_POSITION, TIFF.TYPE_RATIONAL, "0/1"); + assertSingleNodeWithValue(entries, TIFF.TAG_Y_POSITION, TIFF.TYPE_RATIONAL, "0/1"); assertSingleNodeWithValue(entries, 32995, TIFF.TYPE_SHORT, "0"); // Matteing tag, obsoleted by ExtraSamples tag in TIFF 6.0 } @@ -299,7 +299,7 @@ public class TIFFImageMetadataTest { // Validate there's one and only one resolution unit, x res and y res // Validate resolution unit == 1, x res & y res assertSingleNodeWithValue(fields, TIFF.TAG_RESOLUTION_UNIT, TIFF.TYPE_SHORT, String.valueOf(TIFFBaseline.RESOLUTION_UNIT_DPI)); - assertSingleNodeWithValue(fields, TIFF.TAG_X_RESOLUTION, TIFF.TYPE_RATIONAL, "300"); + assertSingleNodeWithValue(fields, TIFF.TAG_X_RESOLUTION, TIFF.TYPE_RATIONAL, "300/1"); assertSingleNodeWithValue(fields, TIFF.TAG_Y_RESOLUTION, TIFF.TYPE_RATIONAL, "30001/100"); } diff --git a/imageio/pom.xml b/imageio/pom.xml index 8c47a349..28a95309 100644 --- a/imageio/pom.xml +++ b/imageio/pom.xml @@ -55,6 +55,7 @@ imageio-reference imageio-jpeg-jep262-interop imageio-jpeg-jai-interop + imageio-tiff-jai-interop imageio-tiff-jdk-interop