--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/jpeg/MagentaEXIFTest.java Wed Feb 04 10:28:40 2015 -0800
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8071707 6243376
+ * @summary Test verifies that EXIF images with differing sampling factors
+ * are written correctly
+ *
+ * @run main MagentaEXIFTest
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOInvalidTreeException;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataNode;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+public class MagentaEXIFTest {
+
+ public static void main(final String[] argv) throws Exception {
+
+ IIOMetadata jpegmetadata = null;
+ ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next();
+ try {
+ jpegmetadata = createJPEGMetadata(jpgWriter);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ImageOutputStream output = ImageIO.createImageOutputStream(baos);
+ jpgWriter.setOutput(output);
+ int w=100, h=100;
+ BufferedImage bi = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g2d = bi.createGraphics();
+ g2d.setColor(Color.white);
+ g2d.fillRect(0, 0, w, h);
+ IIOImage image = new IIOImage(bi, null, jpegmetadata);
+ jpgWriter.write(null, image, null);
+ jpgWriter.dispose();
+
+ baos.flush();
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ImageInputStream iis = ImageIO.createImageInputStream(bais);
+ bi = ImageIO.read(iis);
+ for (int i=0; i<bi.getWidth(); i++) {
+ for(int j=0; j<bi.getHeight(); j++) {
+ if (bi.getRGB(i, j) != Color.white.getRGB()) {
+ throw new RuntimeException("Wrong color : " + Integer.toHexString(bi.getRGB(i, j)));
+ }
+ }
+ }
+
+ }
+
+
+ static void displayMetadata(Node node, int level) {
+ for (int i = 0; i < level; i++) System.out.print(" ");
+ System.out.print("<" + node.getNodeName());
+ NamedNodeMap map = node.getAttributes();
+ if (map != null) { // print attribute values
+ int length = map.getLength();
+ for (int i = 0; i < length; i++) {
+ Node attr = map.item(i);
+ System.out.print(" " + attr.getNodeName() +
+ "=\"" + attr.getNodeValue() + "\"");
+ }
+ }
+
+ Node child = node.getFirstChild();
+ if (child != null) {
+ System.out.println(">"); // close current tag
+ while (child != null) { // emit child tags recursively
+ displayMetadata(child, level + 1);
+ child = child.getNextSibling();
+ }
+ for (int i = 0; i < level; i++) System.out.print(" ");
+ System.out.println("</" + node.getNodeName() + ">");
+ } else {
+ System.out.println("/>");
+ }
+ }
+
+ /*
+ * Construct a JPEG IIOMetadata that has had the JFIF marker removed and
+ * an APP1 EXIF marker added, and further massaged so that we have differing
+ * horizontal and vertical sampling factors for one channel.
+ */
+ static IIOMetadata createJPEGMetadata(ImageWriter iw) throws IIOInvalidTreeException {
+ String jpegMDName = "javax_imageio_jpeg_image_1.0";
+ ImageWriter imgWriter = ImageIO.getImageWritersByFormatName("jpg").next();
+ BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+ ImageTypeSpecifier ist = new ImageTypeSpecifier(bi);
+ IIOMetadata metadata = imgWriter.getDefaultImageMetadata(ist, null);
+
+ IIOMetadataNode root = new IIOMetadataNode(jpegMDName);
+ IIOMetadataNode header = new IIOMetadataNode("JPEGvariety");
+ IIOMetadataNode sequence = new IIOMetadataNode("markerSequence");
+
+ root.appendChild(header);
+ root.appendChild(sequence);
+
+ IIOMetadataNode app1 = new IIOMetadataNode("unknown");
+ app1.setUserObject(new byte[255]);
+ app1.setAttribute("MarkerTag", "255");
+ sequence.appendChild(app1);
+
+ IIOMetadataNode sof = new IIOMetadataNode("sof");
+ sof.setAttribute("process", "0");
+ sof.setAttribute("samplePrecision", "8");
+ sof.setAttribute("numLines", "100");
+ sof.setAttribute("samplesPerLine", "100");
+ sof.setAttribute("numFrameComponents", "3");
+ IIOMetadataNode c1 = new IIOMetadataNode("componentSpec");
+ c1.setAttribute("componentId", "1");
+ c1.setAttribute("HsamplingFactor", "1");
+ c1.setAttribute("VsamplingFactor", "2");
+ c1.setAttribute("QtableSelector", "1");
+ sof.appendChild(c1);
+ IIOMetadataNode c2 = new IIOMetadataNode("componentSpec");
+ c2.setAttribute("componentId", "2");
+ c2.setAttribute("HsamplingFactor", "1");
+ c2.setAttribute("VsamplingFactor", "1");
+ c2.setAttribute("QtableSelector", "1");
+ sof.appendChild(c2);
+ IIOMetadataNode c3 = new IIOMetadataNode("componentSpec");
+ c3.setAttribute("componentId", "3");
+ c3.setAttribute("HsamplingFactor", "1");
+ c3.setAttribute("VsamplingFactor", "1");
+ c3.setAttribute("QtableSelector", "1");
+ sof.appendChild(c3);
+ sequence.appendChild(sof);
+ metadata.setFromTree(jpegMDName, root);
+ IIOMetadata def = imgWriter.getDefaultImageMetadata(ist, null);
+ metadata.mergeTree(jpegMDName, def.getAsTree(jpegMDName));
+ Node tree = metadata.getAsTree(jpegMDName);
+ Node variety = tree.getFirstChild();
+ Node jfif = variety.getFirstChild();
+ variety.removeChild(jfif);
+ sequence = (IIOMetadataNode)tree.getLastChild();
+ NodeList markers = sequence.getChildNodes();
+ IIOMetadataNode n, sofNode=null;
+ for (int i=0;i<markers.getLength();i++) {
+ n = (IIOMetadataNode)markers.item(i);
+ if (n.getNodeName().equals("sof")) {
+ sofNode = n;
+ break;
+ }
+ }
+ IIOMetadataNode componentSpec = (IIOMetadataNode)sofNode.getFirstChild();
+ Attr attr = componentSpec.getAttributeNode("HsamplingFactor");
+ attr.setValue("1");
+ attr = componentSpec.getAttributeNode("VsamplingFactor");
+ attr.setValue("2");
+ metadata.setFromTree(jpegMDName, tree);
+ String[] names = metadata.getMetadataFormatNames();
+ int length = names.length;
+ for (int i = 0; i < length; i++) {
+ System.out.println( "Format name: " + names[ i ] );
+ displayMetadata(metadata.getAsTree(names[i]), 0);
+ }
+
+ return metadata;
+ }
+}