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 
  49 import org.w3c.dom.Node;
  50 
  51 public class ITXtTest {
  52     static public void main(String args[]) {
  53         ITXtTest t_en = new ITXtTest();
  54         t_en.description = "xml - en";
  55         t_en.keyword = "XML:com.adobe.xmp";
  56         t_en.isCompressed = false;
  57         t_en.compression = 0;
  58         t_en.language = "en";
  59         t_en.trasKeyword = "XML:com.adobe.xmp";
  60         t_en.text = "<xml>Something</xml>";
  61 
  62         doTest(t_en);
  63 
  64         // check compression case
  65         t_en.isCompressed = true;
  66         t_en.description = "xml - en - compressed";
  67 
  68         doTest(t_en);
  69 
  70         ITXtTest t_ru = new ITXtTest();
  71         t_ru.description = "xml - ru";
  72         t_ru.keyword = "XML:com.adobe.xmp";
  73         t_ru.isCompressed = false;
  74         t_ru.compression = 0;
  75         t_ru.language = "ru";
  76         t_ru.trasKeyword = "\u0410\u0410\u0410\u0410\u0410 XML";
  77         t_ru.text = "<xml>\u042A\u042F\u042F\u042F\u042F\u042F\u042F</xml>";
  78 
  79         doTest(t_ru);
  80 
  81         t_ru.isCompressed = true;
  82         t_ru.description = "xml - ru - compressed";
  83 
  84         doTest(t_ru);
  85     }
  86 
  87 
  88     String description;
  89 
  90     String keyword;
  91     boolean isCompressed;
  92     int compression;
  93     String language;
  94     String trasKeyword;
  95     String text;
  96 
  97 
  98     public IIOMetadataNode getNode() {
  99         IIOMetadataNode iTXt = new IIOMetadataNode("iTXt");
 100         IIOMetadataNode iTXtEntry = new IIOMetadataNode("iTXtEntry");
 101         iTXtEntry.setAttribute("keyword", keyword);
 102         iTXtEntry.setAttribute("compressionFlag",
 103                                isCompressed ? "true" : "false");
 104         iTXtEntry.setAttribute("compressionMethod",
 105                                Integer.toString(compression));
 106         iTXtEntry.setAttribute("languageTag", language);
 107         iTXtEntry.setAttribute("translatedKeyword",
 108                                trasKeyword);
 109         iTXtEntry.setAttribute("text", text);
 110         iTXt.appendChild(iTXtEntry);
 111         return iTXt;
 112     }
 113 
 114     public static ITXtTest getFromNode(IIOMetadataNode n) {
 115         ITXtTest t = new ITXtTest();
 116 
 117         if (!"iTXt".equals(n.getNodeName())) {
 118             throw new RuntimeException("Invalid node");
 119         }
 120         IIOMetadataNode e = (IIOMetadataNode)n.getFirstChild();
 121         if (!"iTXtEntry".equals(e.getNodeName())) {
 122             throw new RuntimeException("Invalid entry node");
 123         }
 124         t.keyword = e.getAttribute("keyword");
 125         t.isCompressed =
 126             Boolean.valueOf(e.getAttribute("compressionFlag")).booleanValue();
 127         t.compression =
 128             Integer.valueOf(e.getAttribute("compressionMethod")).intValue();
 129         t.language = e.getAttribute("languageTag");
 130         t.trasKeyword = e.getAttribute("translatedKeyword");
 131         t.text = e.getAttribute("text");
 132 
 133         return t;
 134     }
 135 
 136     @Override
 137     public boolean equals(Object o) {
 138         if (! (o instanceof ITXtTest)) {
 139             return false;
 140         }
 141         ITXtTest t = (ITXtTest)o;
 142         if (!keyword.equals(t.keyword)) { return false; }
 143         if (isCompressed != t.isCompressed) { return false; }
 144         if (compression != t.compression) { return false; }
 145         if (!language.equals(t.language)) { return false; }
 146         if (!trasKeyword.equals(t.trasKeyword)) { return false; }
 147         if (!text.equals(t.text)) { return false; }
 148 
 149         return true;
 150     }
 151 
 152 
 153 
 154     private static void doTest(ITXtTest src) {
 155 
 156         System.out.println("Test: " + src.description);
 157 
 158         File file = new File("test.png");
 159 
 160         writeTo(file, src);
 161         ITXtTest dst = readFrom(file);
 162 
 163         if (dst == null || !dst.equals(src)) {
 164             throw new RuntimeException("Test failed.");
 165         }
 166 
 167         System.out.println("Test passed.");
 168     }
 169 
 170     private static void writeTo(File f, ITXtTest t) {
 171         BufferedImage src = createBufferedImage();
 172         try {
 173             ImageOutputStream imageOutputStream =
 174                 ImageIO.createImageOutputStream(f);
 175 
 176             ImageTypeSpecifier imageTypeSpecifier =
 177                 new ImageTypeSpecifier(src);
 178             ImageWriter imageWriter =
 179                 ImageIO.getImageWritersByFormatName("PNG").next();
 180 
 181             imageWriter.setOutput(imageOutputStream);
 182 
 183             IIOMetadata m =
 184                 imageWriter.getDefaultImageMetadata(imageTypeSpecifier, null);
 185 
 186             String format = m.getNativeMetadataFormatName();
 187             Node root = m.getAsTree(format);
 188 
 189             IIOMetadataNode iTXt = t.getNode();
 190             root.appendChild(iTXt);
 191             m.setFromTree(format, root);
 192 
 193             imageWriter.write(new IIOImage(src, null, m));
 194             imageOutputStream.close();
 195             System.out.println("Writing done.");
 196         } catch (Throwable e) {
 197             throw new RuntimeException("Writing test failed.", e);
 198         }
 199     }
 200 
 201     private static ITXtTest readFrom(File f) {
 202         try {
 203             ImageInputStream iis = ImageIO.createImageInputStream(f);
 204             ImageReader r = ImageIO.getImageReaders(iis).next();
 205             r.setInput(iis);
 206 
 207             IIOImage dst = r.readAll(0, null);
 208 
 209             // look for iTXt node
 210             IIOMetadata m = dst.getMetadata();
 211             Node root = m.getAsTree(m.getNativeMetadataFormatName());
 212             Node n = root.getFirstChild();
 213             while (n != null && !"iTXt".equals(n.getNodeName())) {
 214                 n = n.getNextSibling();
 215             }
 216             if (n == null) {
 217                 throw new RuntimeException("No iTXt node!");
 218             }
 219             ITXtTest t = ITXtTest.getFromNode((IIOMetadataNode)n);
 220             return t;
 221         } catch (Throwable e) {
 222             throw new RuntimeException("Reading test failed.", e);
 223         }
 224     }
 225 
 226     private static BufferedImage createBufferedImage() {
 227         BufferedImage image = new BufferedImage(128, 128,
 228                       BufferedImage.TYPE_4BYTE_ABGR_PRE);
 229         Graphics2D graph = image.createGraphics();
 230         graph.setPaintMode();
 231         graph.setColor(Color.orange);
 232         graph.fillRect(32, 32, 64, 64);
 233         graph.dispose();
 234         return image;
 235     }
 236 }