1 /* 2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 6541476 27 * @summary Test verifies that ImageIO PNG plugin correcly handles the 28 * iTxt chunk (International textual data). 29 * 30 * @run main ITXtTest 31 */ 32 33 34 import java.awt.Color; 35 import java.awt.Graphics2D; 36 import java.awt.image.BufferedImage; 37 import java.io.File; 38 39 import javax.imageio.ImageIO; 40 import javax.imageio.ImageReader; 41 import javax.imageio.IIOImage; 42 import javax.imageio.ImageTypeSpecifier; 43 import javax.imageio.ImageWriter; 44 import javax.imageio.metadata.IIOMetadata; 45 import javax.imageio.metadata.IIOMetadataNode; 46 import javax.imageio.stream.ImageOutputStream; 47 import javax.imageio.stream.ImageInputStream; 48 import java.io.IOException; 49 50 import org.w3c.dom.Node; 51 52 public class ITXtTest { 53 static public void main(String args[]) throws IOException { 54 ITXtTest t_en = new ITXtTest(); 55 t_en.description = "xml - en"; 56 t_en.keyword = "XML:com.adobe.xmp"; 57 t_en.isCompressed = false; 58 t_en.compression = 0; 59 t_en.language = "en"; 60 t_en.trasKeyword = "XML:com.adobe.xmp"; 61 t_en.text = "<xml>Something</xml>"; 62 63 doTest(t_en); 64 65 // check compression case 66 t_en.isCompressed = true; 67 t_en.description = "xml - en - compressed"; 68 69 doTest(t_en); 70 71 ITXtTest t_ru = new ITXtTest(); 72 t_ru.description = "xml - ru"; 73 t_ru.keyword = "XML:com.adobe.xmp"; 74 t_ru.isCompressed = false; 75 t_ru.compression = 0; 76 t_ru.language = "ru"; 77 t_ru.trasKeyword = "\u0410\u0410\u0410\u0410\u0410 XML"; 78 t_ru.text = "<xml>\u042A\u042F\u042F\u042F\u042F\u042F\u042F</xml>"; 79 80 doTest(t_ru); 81 82 t_ru.isCompressed = true; 83 t_ru.description = "xml - ru - compressed"; 84 85 doTest(t_ru); 86 } 87 88 89 String description; 90 91 String keyword; 92 boolean isCompressed; 93 int compression; 94 String language; 95 String trasKeyword; 96 String text; 97 98 99 public IIOMetadataNode getNode() { 100 IIOMetadataNode iTXt = new IIOMetadataNode("iTXt"); 101 IIOMetadataNode iTXtEntry = new IIOMetadataNode("iTXtEntry"); 102 iTXtEntry.setAttribute("keyword", keyword); 103 iTXtEntry.setAttribute("compressionFlag", 104 isCompressed ? "true" : "false"); 105 iTXtEntry.setAttribute("compressionMethod", 106 Integer.toString(compression)); 107 iTXtEntry.setAttribute("languageTag", language); 108 iTXtEntry.setAttribute("translatedKeyword", 109 trasKeyword); 110 iTXtEntry.setAttribute("text", text); 111 iTXt.appendChild(iTXtEntry); 112 return iTXt; 113 } 114 115 public static ITXtTest getFromNode(IIOMetadataNode n) { 116 ITXtTest t = new ITXtTest(); 117 118 if (!"iTXt".equals(n.getNodeName())) { 119 throw new RuntimeException("Invalid node"); 120 } 121 IIOMetadataNode e = (IIOMetadataNode)n.getFirstChild(); 122 if (!"iTXtEntry".equals(e.getNodeName())) { 123 throw new RuntimeException("Invalid entry node"); 124 } 125 t.keyword = e.getAttribute("keyword"); 126 t.isCompressed = 127 Boolean.valueOf(e.getAttribute("compressionFlag")).booleanValue(); 128 t.compression = 129 Integer.valueOf(e.getAttribute("compressionMethod")).intValue(); 130 t.language = e.getAttribute("languageTag"); 131 t.trasKeyword = e.getAttribute("translatedKeyword"); 132 t.text = e.getAttribute("text"); 133 134 return t; 135 } 136 137 @Override 138 public boolean equals(Object o) { 139 if (! (o instanceof ITXtTest)) { 140 return false; 141 } 142 ITXtTest t = (ITXtTest)o; 143 if (!keyword.equals(t.keyword)) { return false; } 144 if (isCompressed != t.isCompressed) { return false; } 145 if (compression != t.compression) { return false; } 146 if (!language.equals(t.language)) { return false; } 147 if (!trasKeyword.equals(t.trasKeyword)) { return false; } 148 if (!text.equals(t.text)) { return false; } 149 150 return true; 151 } 152 153 154 155 private static void doTest(ITXtTest src) throws IOException { 156 157 System.out.println("Test: " + src.description); 158 159 File file = new File("test.png"); 160 161 writeTo(file, src); 162 ITXtTest dst = readFrom(file); 163 164 if (dst == null || !dst.equals(src)) { 165 file.delete(); 166 throw new RuntimeException("Test failed."); 167 } else { 168 file.delete(); 169 System.out.println("Test passed."); 170 } 171 } 172 173 private static void writeTo(File f, ITXtTest t) throws IOException { 174 BufferedImage src = createBufferedImage(); 175 ImageOutputStream imageOutputStream = null; 176 try { 177 imageOutputStream = 178 ImageIO.createImageOutputStream(f); 179 180 ImageTypeSpecifier imageTypeSpecifier = 181 new ImageTypeSpecifier(src); 182 ImageWriter imageWriter = 183 ImageIO.getImageWritersByFormatName("PNG").next(); 184 185 imageWriter.setOutput(imageOutputStream); 186 187 IIOMetadata m = 188 imageWriter.getDefaultImageMetadata(imageTypeSpecifier, null); 189 190 String format = m.getNativeMetadataFormatName(); 191 Node root = m.getAsTree(format); 192 193 IIOMetadataNode iTXt = t.getNode(); 194 root.appendChild(iTXt); 195 m.setFromTree(format, root); 196 197 imageWriter.write(new IIOImage(src, null, m)); 198 imageOutputStream.close(); 199 System.out.println("Writing done."); 200 } catch (Throwable e) { 201 if (imageOutputStream != null) { 202 imageOutputStream.close(); 203 } 204 f.delete(); 205 throw new RuntimeException("Writing test failed.", e); 206 } 207 } 208 209 private static ITXtTest readFrom(File f) throws IOException { 210 ImageInputStream iis = null; 211 try { 212 iis = ImageIO.createImageInputStream(f); 213 ImageReader r = ImageIO.getImageReaders(iis).next(); 214 r.setInput(iis); 215 216 IIOImage dst = r.readAll(0, null); 217 218 // look for iTXt node 219 IIOMetadata m = dst.getMetadata(); 220 Node root = m.getAsTree(m.getNativeMetadataFormatName()); 221 Node n = root.getFirstChild(); 222 while (n != null && !"iTXt".equals(n.getNodeName())) { 223 n = n.getNextSibling(); 224 } 225 if (n == null) { 226 throw new RuntimeException("No iTXt node!"); 227 } 228 ITXtTest t = ITXtTest.getFromNode((IIOMetadataNode)n); 229 iis.close(); 230 return t; 231 } catch (Throwable e) { 232 if (iis != null) { 233 iis.close(); 234 } 235 f.delete(); 236 throw new RuntimeException("Reading test failed.", e); 237 } 238 } 239 240 private static BufferedImage createBufferedImage() { 241 BufferedImage image = new BufferedImage(128, 128, 242 BufferedImage.TYPE_4BYTE_ABGR_PRE); 243 Graphics2D graph = image.createGraphics(); 244 graph.setPaintMode(); 245 graph.setColor(Color.orange); 246 graph.fillRect(32, 32, 64, 64); 247 graph.dispose(); 248 return image; 249 } 250 }