diff --git a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/StandardImageMetadataSupport.java b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/StandardImageMetadataSupport.java index 29c3c05b..99c89fc7 100644 --- a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/StandardImageMetadataSupport.java +++ b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/StandardImageMetadataSupport.java @@ -122,18 +122,14 @@ public class StandardImageMetadataSupport extends AbstractMetadata { return this; } - public Builder withCompressionName(String compressionName) { + public Builder withCompressionTypeName(String compressionName) { this.compressionName = notNull(compressionName, "compressionName").equalsIgnoreCase("none") ? null : compressionName; return this; } public Builder withCompressionLossless(boolean lossless) { - if (!lossless && compressionName == null) { - throw new IllegalStateException("Lossy compression requires compression name"); - } - - this.compressionLossless = lossless; + this.compressionLossless = isTrue(lossless || compressionName != null, lossless, "Lossy compression requires compression name"); return this; } diff --git a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/StandardImageMetadataSupportTest.java b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/StandardImageMetadataSupportTest.java index 94d8c90f..8e02c312 100644 --- a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/StandardImageMetadataSupportTest.java +++ b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/StandardImageMetadataSupportTest.java @@ -7,16 +7,24 @@ import com.twelvemonkeys.imageio.StandardImageMetadataSupport.SubimageInterpreta import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers; import org.junit.Test; +import org.w3c.dom.NodeList; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; import java.awt.image.*; +import java.util.AbstractMap.SimpleEntry; import java.util.Arrays; +import java.util.Calendar; import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import static com.twelvemonkeys.imageio.StandardImageMetadataSupport.builder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class StandardImageMetadataSupportTest { @@ -48,6 +56,173 @@ public class StandardImageMetadataSupportTest { assertNotNull(metadata); } + @Test + public void compressionValuesUnspecified() { + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .build(); + + assertNull(metadata.getStandardCompressionNode()); + } + + @Test + public void compressionValuesNone() { + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .withCompressionTypeName("nOnE") // Case-insensitive + .build(); + + assertNull(metadata.getStandardCompressionNode()); + } + + @Test + public void compressionValuesName() { + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .withCompressionTypeName("foo") + .build(); + + IIOMetadataNode compressionNode = metadata.getStandardCompressionNode(); + assertNotNull(compressionNode); + + IIOMetadataNode compressionName = (IIOMetadataNode) compressionNode.getElementsByTagName("CompressionTypeName").item(0); + assertEquals("foo", compressionName.getAttribute("value")); + + // Defaults to lossless true + IIOMetadataNode compressionLossless = (IIOMetadataNode) compressionNode.getElementsByTagName("Lossless").item(0); + assertEquals("TRUE", compressionLossless.getAttribute("value")); + } + + @Test(expected = IllegalArgumentException.class) + public void withCompressionLossyIllegal() { + builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .withCompressionLossless(false); + } + + @Test + public void compressionValuesLossy() { + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .withCompressionTypeName("bar") + .withCompressionLossless(false) + .build(); + + IIOMetadataNode compressionNode = metadata.getStandardCompressionNode(); + assertNotNull(compressionNode); + + IIOMetadataNode compressionName = (IIOMetadataNode) compressionNode.getElementsByTagName("CompressionTypeName").item(0); + assertEquals("bar", compressionName.getAttribute("value")); + + IIOMetadataNode compressionLossless = (IIOMetadataNode) compressionNode.getElementsByTagName("Lossless").item(0); + assertEquals("FALSE", compressionLossless.getAttribute("value")); + } + + @Test + public void withDocumentValuesDefault() { + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .build(); + + IIOMetadataNode documentNode = metadata.getStandardDocumentNode(); + assertNull(documentNode); + } + + @Test + public void withDocumentValues() { + Calendar creationTime = Calendar.getInstance(); + creationTime.set(2022, Calendar.SEPTEMBER, 8, 14, 5, 0); + + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .withFormatVersion("42") + .withDocumentCreationTime(creationTime) + .build(); + + IIOMetadataNode documentNode = metadata.getStandardDocumentNode(); + assertNotNull(documentNode); + + IIOMetadataNode formatVersion = (IIOMetadataNode) documentNode.getElementsByTagName("FormatVersion").item(0); + assertEquals("42", formatVersion.getAttribute("value")); + + IIOMetadataNode imageCreationTime = (IIOMetadataNode) documentNode.getElementsByTagName("ImageCreationTime").item(0); + assertEquals("2022", imageCreationTime.getAttribute("year")); + assertEquals("9", imageCreationTime.getAttribute("month")); + assertEquals("8", imageCreationTime.getAttribute("day")); + assertEquals("14", imageCreationTime.getAttribute("hour")); + assertEquals("5", imageCreationTime.getAttribute("minute")); + assertEquals("0", imageCreationTime.getAttribute("second")); + } + + @Test + public void withTextValuesDefault() { + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .build(); + + IIOMetadataNode textNode = metadata.getStandardTextNode(); + assertNull(textNode); + } + + @Test + public void withTextValuesSingle() { + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .withTextEntry("foo", "bar") + .build(); + + IIOMetadataNode textNode = metadata.getStandardTextNode(); + assertNotNull(textNode); + + IIOMetadataNode textEntry = (IIOMetadataNode) textNode.getElementsByTagName("TextEntry").item(0); + assertEquals("foo", textEntry.getAttribute("keyword")); + assertEquals("bar", textEntry.getAttribute("value")); + } + + @Test + public void withTextValuesMap() { + Map entries = new HashMap<>(); + entries.put("foo", "bar"); + entries.put("bar", "xyzzy"); + + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .withTextEntries(entries) + .build(); + + IIOMetadataNode textNode = metadata.getStandardTextNode(); + assertNotNull(textNode); + + NodeList textEntries = textNode.getElementsByTagName("TextEntry"); + assertEquals(entries.size(), textEntries.getLength()); + + int i = 0; + for (Entry entry : entries.entrySet()) { + IIOMetadataNode textEntry = (IIOMetadataNode) textEntries.item(i); + assertEquals(entry.getKey(), textEntry.getAttribute("keyword")); + assertEquals(entry.getValue(), textEntry.getAttribute("value")); + + i++; + } + } + + @Test + public void withTextValuesList() { + List> entries = Arrays.>asList( + new SimpleEntry<>((String) null, "foo"), // No key allowed + new SimpleEntry<>("foo", "bar"), + new SimpleEntry<>("bar", "xyzzy"), + new SimpleEntry<>("bar", "nothing happens...") // Duplicates allowed + ); + + StandardImageMetadataSupport metadata = (StandardImageMetadataSupport) builder(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY)) + .withTextEntries(entries) + .build(); + + IIOMetadataNode textNode = metadata.getStandardTextNode(); + assertNotNull(textNode); + + NodeList textEntries = textNode.getElementsByTagName("TextEntry"); + assertEquals(entries.size(), textEntries.getLength()); + + for (int i = 0; i < entries.size(); i++) { + Entry entry = entries.get(i); + IIOMetadataNode textEntry = (IIOMetadataNode) textEntries.item(i); + + assertEquals(entry.getKey(), textEntry.getAttribute("keyword")); + assertEquals(entry.getValue(), textEntry.getAttribute("value")); + } + } @Test public void withPlanarColorspaceType() { diff --git a/imageio/imageio-hdr/src/main/java/com/twelvemonkeys/imageio/plugins/hdr/HDRMetadata.java b/imageio/imageio-hdr/src/main/java/com/twelvemonkeys/imageio/plugins/hdr/HDRMetadata.java index ec35918f..c2f407fe 100755 --- a/imageio/imageio-hdr/src/main/java/com/twelvemonkeys/imageio/plugins/hdr/HDRMetadata.java +++ b/imageio/imageio-hdr/src/main/java/com/twelvemonkeys/imageio/plugins/hdr/HDRMetadata.java @@ -8,7 +8,7 @@ import javax.imageio.metadata.IIOMetadataNode; public class HDRMetadata extends StandardImageMetadataSupport { public HDRMetadata(ImageTypeSpecifier type, HDRHeader header) { super(builder(type) - .withCompressionName("RLE") + .withCompressionTypeName("RLE") .withTextEntry("Software", header.getSoftware())); } diff --git a/imageio/imageio-icns/src/main/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageMetadata.java b/imageio/imageio-icns/src/main/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageMetadata.java index 20cf3783..330123bb 100644 --- a/imageio/imageio-icns/src/main/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageMetadata.java +++ b/imageio/imageio-icns/src/main/java/com/twelvemonkeys/imageio/plugins/icns/ICNSImageMetadata.java @@ -36,6 +36,6 @@ import javax.imageio.ImageTypeSpecifier; final class ICNSImageMetadata extends StandardImageMetadataSupport { ICNSImageMetadata(ImageTypeSpecifier type, String compressionName) { - super(builder(type).withCompressionName(compressionName)); + super(builder(type).withCompressionTypeName(compressionName)); } } diff --git a/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageMetadata.java b/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageMetadata.java index 8ab39545..007513af 100644 --- a/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageMetadata.java +++ b/imageio/imageio-iff/src/main/java/com/twelvemonkeys/imageio/plugins/iff/IFFImageMetadata.java @@ -52,7 +52,7 @@ final class IFFImageMetadata extends StandardImageMetadataSupport { private IFFImageMetadata(Builder builder, Form header, IndexColorModel palette) { super(builder.withPalette(palette) - .withCompressionName(compressionName(header)) + .withCompressionTypeName(compressionName(header)) .withBitsPerSample(bitsPerSample(header)) .withPlanarConfiguration(planarConfiguration(header)) .withPixelAspectRatio(header.aspect() != 0 ? header.aspect() : null) diff --git a/imageio/imageio-pcx/src/main/java/com/twelvemonkeys/imageio/plugins/pcx/PCXMetadata.java b/imageio/imageio-pcx/src/main/java/com/twelvemonkeys/imageio/plugins/pcx/PCXMetadata.java index 68352b41..c7c314ee 100755 --- a/imageio/imageio-pcx/src/main/java/com/twelvemonkeys/imageio/plugins/pcx/PCXMetadata.java +++ b/imageio/imageio-pcx/src/main/java/com/twelvemonkeys/imageio/plugins/pcx/PCXMetadata.java @@ -8,7 +8,7 @@ final class PCXMetadata extends StandardImageMetadataSupport { public PCXMetadata(ImageTypeSpecifier type, PCXHeader header) { super(builder(type) .withPlanarConfiguration(planarConfiguration(header)) - .withCompressionName(compressionName(header)) + .withCompressionTypeName(compressionName(header)) .withFormatVersion(String.valueOf(header.getVersion()))); } diff --git a/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pntg/PNTGMetadata.java b/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pntg/PNTGMetadata.java index 70bdccdb..52e5cb27 100644 --- a/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pntg/PNTGMetadata.java +++ b/imageio/imageio-pict/src/main/java/com/twelvemonkeys/imageio/plugins/pntg/PNTGMetadata.java @@ -45,7 +45,7 @@ final class PNTGMetadata extends StandardImageMetadataSupport { public PNTGMetadata(ImageTypeSpecifier type) { super(builder(type) .withBlackIsZero(false) - .withCompressionName("PackBits") + .withCompressionTypeName("PackBits") .withFormatVersion("1.0")); } } diff --git a/imageio/imageio-sgi/src/main/java/com/twelvemonkeys/imageio/plugins/sgi/SGIMetadata.java b/imageio/imageio-sgi/src/main/java/com/twelvemonkeys/imageio/plugins/sgi/SGIMetadata.java index 8f613d46..6b3d3087 100755 --- a/imageio/imageio-sgi/src/main/java/com/twelvemonkeys/imageio/plugins/sgi/SGIMetadata.java +++ b/imageio/imageio-sgi/src/main/java/com/twelvemonkeys/imageio/plugins/sgi/SGIMetadata.java @@ -8,7 +8,7 @@ final class SGIMetadata extends StandardImageMetadataSupport { public SGIMetadata(ImageTypeSpecifier type, SGIHeader header) { super(builder(type) .withSignificantBitsPerSample(computeSignificantBits(header)) - .withCompressionName(compressionName(header)) + .withCompressionTypeName(compressionName(header)) .withOrientation(ImageOrientation.FlipV) .withTextEntry("DocumentName", header.getName()) ); diff --git a/imageio/imageio-tga/src/main/java/com/twelvemonkeys/imageio/plugins/tga/TGAMetadata.java b/imageio/imageio-tga/src/main/java/com/twelvemonkeys/imageio/plugins/tga/TGAMetadata.java index 08654426..713a77bf 100755 --- a/imageio/imageio-tga/src/main/java/com/twelvemonkeys/imageio/plugins/tga/TGAMetadata.java +++ b/imageio/imageio-tga/src/main/java/com/twelvemonkeys/imageio/plugins/tga/TGAMetadata.java @@ -10,7 +10,7 @@ import java.util.Map; final class TGAMetadata extends StandardImageMetadataSupport { TGAMetadata(ImageTypeSpecifier type, TGAHeader header, TGAExtensions extensions) { super(builder(type) - .withCompressionName(compressionName(header)) + .withCompressionTypeName(compressionName(header)) .withPixelAspectRatio(pixelAspectRatio(extensions)) .withOrientation(orientation(header)) .withFormatVersion(extensions == null ? "1.0" : "2.0") diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/WebPImageMetadata.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/WebPImageMetadata.java index 39842c93..5ddaa917 100644 --- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/WebPImageMetadata.java +++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/WebPImageMetadata.java @@ -9,7 +9,7 @@ import static com.twelvemonkeys.lang.Validate.notNull; final class WebPImageMetadata extends StandardImageMetadataSupport { WebPImageMetadata(ImageTypeSpecifier type, VP8xChunk header) { super(builder(type) - .withCompressionName(notNull(header, "header").isLossless ? "VP8L" : "VP8") + .withCompressionTypeName(notNull(header, "header").isLossless ? "VP8L" : "VP8") .withCompressionLossless(header.isLossless) .withPixelAspectRatio(1.0) .withFormatVersion("1.0")