Bug ID: 5106550; State: 3-Accepted, bug; Priority: 4-Low http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5106550
The bug lies in the fact that for TextEntry nodes in standard metadata format, PNGMetadata requires additional attributes besides the ones marked #REQUIRED in the DTD. Namely missing encoding, language or compression will result in an IIOInvalidTreeException: > Exception in thread "main" javax.imageio.metadata.IIOInvalidTreeException: > Required attribute encoding not present! > at com.sun.imageio.plugins.png.PNGMetadata.fatal(PNGMetadata.java:1085) > at > com.sun.imageio.plugins.png.PNGMetadata.getAttribute(PNGMetadata.java:1208) > at > com.sun.imageio.plugins.png.PNGMetadata.getAttribute(PNGMetadata.java:1217) > at > com.sun.imageio.plugins.png.PNGMetadata.mergeStandardTree(PNGMetadata.java:1921) > at > com.sun.imageio.plugins.png.PNGMetadata.mergeTree(PNGMetadata.java:1232) > at MergeStdCommentTest.main(MergeStdCommentTest.java:37) The patch fixes this by 1. not reading the "encoding" attribute at all, as it isn't even used in the following code 2. having the "language" attribute default to "", as http://www.w3.org/TR/PNG/#11iTXt states that "if the language tag is empty, the language is unspecified" 3. having the "compression" attribute default to "none", as this is the default given in the DTD 4. ignore any node with missing or empty "keyword", as the PNG standard requires a keyword of length at least 1 according to http://www.w3.org/TR/PNG/#11tEXt I changed invocations from the previously used private String getAttribute(Node node, String name) which implied a required argument to the more flexible private String getStringAttribute(Node node, String name, String defaultValue, boolean required) Open question: Do you agree in dropping nodes with missing keywords? This follows the concept of not merging parts of the standard metadata model which have no counterpart in a specific file format, but might still lead to unexpected behaviour. I previously had this fix submitted to jdk7-dev, and mentioned in a posting "Bug fixes for com.sun.imageio.plugins.png.PNGMetadata" here. http://mail.openjdk.java.net/pipermail/jdk7-dev/2008-October/000272.html http://mail.openjdk.java.net/pipermail/2d-dev/2008-November/000540.html In the meantime, I have had a look at the mq extension of mercurial. Thus the attached patch is now a single patch straight out of my patch queue. I submit it here, waiting for comments, discussion, sponsorship. Once you consider it ready for inclusion, I can commit it localy and post a patch exported by hg. Greetings, Martin von Gagern
diff --git a/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java b/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java --- a/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java +++ b/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java @@ -1931,14 +1931,17 @@ while (child != null) { String childName = child.getNodeName(); if (childName.equals("TextEntry")) { - String keyword = getAttribute(child, "keyword"); + String keyword = + getAttribute(child, "keyword", "", false); String value = getAttribute(child, "value"); - String encoding = getAttribute(child, "encoding"); - String language = getAttribute(child, "language"); + String language = + getAttribute(child, "language", "", false); String compression = - getAttribute(child, "compression"); + getAttribute(child, "compression", "none", false); - if (isISOLatin(value)) { + if (keyword.length() == 0) { + // Just ignore this node, PNG requires keywords + } else if (isISOLatin(value)) { if (compression.equals("zip")) { // Use a zTXt node zTXt_keyword.add(keyword); diff --git a/test/javax/imageio/plugins/png/MergeStdCommentTest.java b/test/javax/imageio/plugins/png/MergeStdCommentTest.java new file mode 100644 --- /dev/null +++ b/test/javax/imageio/plugins/png/MergeStdCommentTest.java @@ -0,0 +1,42 @@ +/** + * @test + * @bug 5106550 + * @summary Merge a comment using the standard metdata format + * and only a minimal set of attributes + */ + +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; + +public class MergeStdCommentTest { + + public static void main(String[] args) throws Exception { + String format = "javax_imageio_1.0"; + BufferedImage img = + new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB); + ImageWriter iw = ImageIO.getImageWritersByMIMEType("image/png").next(); + IIOMetadata meta = + iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), null); + DOMImplementationRegistry registry; + registry = DOMImplementationRegistry.newInstance(); + DOMImplementation impl = registry.getDOMImplementation("XML 3.0"); + Document doc = impl.createDocument(null, format, null); + Element root, text, entry; + root = doc.getDocumentElement(); + root.appendChild(text = doc.createElement("Text")); + text.appendChild(entry = doc.createElement("TextEntry")); + // keyword isn't #REQUIRED by the standard metadata format. + // However, it is required by the PNG format, so we include it here. + entry.setAttribute("keyword", "Comment"); + entry.setAttribute("value", "Some demo comment"); + meta.mergeTree(format, root); + } + +}