提交 94da4a46 编写于 作者: B bae

5106550: PNG writer merge standard metadata fails for TextEntry sans #IMPLIED attributes

Reviewed-by: igor, prr
Contributed-by: NMartin von Gagern <martin.vgagern@gmx.net>
上级 a1b03ca3
...@@ -1040,7 +1040,7 @@ public class PNGMetadata extends IIOMetadata implements Cloneable { ...@@ -1040,7 +1040,7 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
node.setAttribute("language", node.setAttribute("language",
iTXt_languageTag.get(i)); iTXt_languageTag.get(i));
if (iTXt_compressionFlag.get(i)) { if (iTXt_compressionFlag.get(i)) {
node.setAttribute("compression", "deflate"); node.setAttribute("compression", "zip");
} else { } else {
node.setAttribute("compression", "none"); node.setAttribute("compression", "none");
} }
...@@ -1052,7 +1052,7 @@ public class PNGMetadata extends IIOMetadata implements Cloneable { ...@@ -1052,7 +1052,7 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
node = new IIOMetadataNode("TextEntry"); node = new IIOMetadataNode("TextEntry");
node.setAttribute("keyword", (String)zTXt_keyword.get(i)); node.setAttribute("keyword", (String)zTXt_keyword.get(i));
node.setAttribute("value", (String)zTXt_text.get(i)); node.setAttribute("value", (String)zTXt_text.get(i));
node.setAttribute("compression", "deflate"); node.setAttribute("compression", "zip");
text_node.appendChild(node); text_node.appendChild(node);
} }
...@@ -1421,6 +1421,7 @@ public class PNGMetadata extends IIOMetadata implements Cloneable { ...@@ -1421,6 +1421,7 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
} }
String keyword = getAttribute(iTXt_node, "keyword"); String keyword = getAttribute(iTXt_node, "keyword");
if (isValidKeyword(keyword)) {
iTXt_keyword.add(keyword); iTXt_keyword.add(keyword);
boolean compressionFlag = boolean compressionFlag =
...@@ -1442,6 +1443,9 @@ public class PNGMetadata extends IIOMetadata implements Cloneable { ...@@ -1442,6 +1443,9 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
String text = getAttribute(iTXt_node, "text"); String text = getAttribute(iTXt_node, "text");
iTXt_text.add(text); iTXt_text.add(text);
}
// silently skip invalid text entry
iTXt_node = iTXt_node.getNextSibling(); iTXt_node = iTXt_node.getNextSibling();
} }
} else if (name.equals("pHYs")) { } else if (name.equals("pHYs")) {
...@@ -1692,13 +1696,47 @@ public class PNGMetadata extends IIOMetadata implements Cloneable { ...@@ -1692,13 +1696,47 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
} }
} }
private boolean isISOLatin(String s) { /*
* Accrding to PNG spec, keywords are restricted to 1 to 79 bytes
* in length. Keywords shall contain only printable Latin-1 characters
* and spaces; To reduce the chances for human misreading of a keyword,
* leading spaces, trailing spaces, and consecutive spaces are not
* permitted in keywords.
*
* See: http://www.w3.org/TR/PNG/#11keywords
*/
private boolean isValidKeyword(String s) {
int len = s.length();
if (len < 1 || len >= 80) {
return false;
}
if (s.startsWith(" ") || s.endsWith(" ") || s.contains(" ")) {
return false;
}
return isISOLatin(s, false);
}
/*
* According to PNG spec, keyword shall contain only printable
* Latin-1 [ISO-8859-1] characters and spaces; that is, only
* character codes 32-126 and 161-255 decimal are allowed.
* For Latin-1 value fields the 0x10 (linefeed) control
* character is aloowed too.
*
* See: http://www.w3.org/TR/PNG/#11keywords
*/
private boolean isISOLatin(String s, boolean isLineFeedAllowed) {
int len = s.length(); int len = s.length();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (s.charAt(i) > 255) { char c = s.charAt(i);
if (c < 32 || c > 255 || (c > 126 && c < 161)) {
// not printable. Check whether this is an allowed
// control char
if (!isLineFeedAllowed || c != 0x10) {
return false; return false;
} }
} }
}
return true; return true;
} }
...@@ -1929,19 +1967,22 @@ public class PNGMetadata extends IIOMetadata implements Cloneable { ...@@ -1929,19 +1967,22 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
while (child != null) { while (child != null) {
String childName = child.getNodeName(); String childName = child.getNodeName();
if (childName.equals("TextEntry")) { if (childName.equals("TextEntry")) {
String keyword = getAttribute(child, "keyword"); String keyword =
getAttribute(child, "keyword", "", false);
String value = getAttribute(child, "value"); String value = getAttribute(child, "value");
String encoding = getAttribute(child, "encoding"); String language =
String language = getAttribute(child, "language"); getAttribute(child, "language", "", false);
String compression = String compression =
getAttribute(child, "compression"); getAttribute(child, "compression", "none", false);
if (isISOLatin(value)) { if (!isValidKeyword(keyword)) {
// Just ignore this node, PNG requires keywords
} else if (isISOLatin(value, true)) {
if (compression.equals("zip")) { if (compression.equals("zip")) {
// Use a zTXt node // Use a zTXt node
zTXt_keyword.add(keyword); zTXt_keyword.add(keyword);
zTXt_text.add(value); zTXt_text.add(value);
zTXt_compressionMethod.add(new Integer(0)); zTXt_compressionMethod.add(Integer.valueOf(0));
} else { } else {
// Use a tEXt node // Use a tEXt node
tEXt_keyword.add(keyword); tEXt_keyword.add(keyword);
......
/*
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @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);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册