1 /* 2 * Copyright (c) 2018, 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 6574555 5109146 27 * @summary Test verifies that PNGImageWriter encodes the R, G, B 28 * values of bKGD chunk properly. 29 * @run main VerifyRGBValuesFromBKGDChunk 30 */ 31 32 import java.awt.image.BufferedImage; 33 import java.io.IOException; 34 import java.util.Iterator; 35 import javax.imageio.ImageTypeSpecifier; 36 import javax.imageio.ImageWriter; 37 import javax.imageio.ImageReader; 38 import javax.imageio.ImageIO; 39 import javax.imageio.ImageWriteParam; 40 import javax.imageio.metadata.IIOInvalidTreeException; 41 import javax.imageio.metadata.IIOMetadata; 42 import javax.imageio.metadata.IIOMetadataNode; 43 import javax.imageio.IIOImage; 44 import javax.imageio.stream.ImageInputStream; 45 import javax.imageio.stream.ImageOutputStream; 46 import java.io.ByteArrayInputStream; 47 import java.io.ByteArrayOutputStream; 48 import java.io.InputStream; 49 50 public class VerifyRGBValuesFromBKGDChunk { 51 52 private static IIOMetadata encodeMetadata; 53 private static ImageWriter writer; 54 private static ImageReader reader; 55 private static BufferedImage img; 56 private static ImageWriteParam param; 57 private static boolean nativeBKGDFail, standardBKGDFail; 58 private static IIOMetadataNode bKGD_RGBNode; 59 private static final String BKGDRED = "100"; 60 private static final String BKGDGREEN = "150"; 61 private static final String BKGDBLUE = "200"; 62 63 private static void mergeStandardMetadata() throws IIOInvalidTreeException { 64 IIOMetadataNode background_rgb = new IIOMetadataNode("BackgroundColor"); 65 66 background_rgb.setAttribute("red", BKGDRED); 67 background_rgb.setAttribute("green", BKGDGREEN); 68 background_rgb.setAttribute("blue", BKGDBLUE); 69 70 IIOMetadataNode chroma = new IIOMetadataNode("Chroma"); 71 chroma.appendChild(background_rgb); 72 IIOMetadataNode encodeRoot = new IIOMetadataNode("javax_imageio_1.0"); 73 encodeRoot.appendChild(chroma); 74 75 ImageTypeSpecifier specifier = 76 ImageTypeSpecifier. 77 createFromBufferedImageType(BufferedImage.TYPE_INT_BGR); 78 encodeMetadata = writer.getDefaultImageMetadata(specifier, param); 79 encodeMetadata.mergeTree("javax_imageio_1.0", encodeRoot); 80 } 81 82 private static void mergeNativeMetadata() throws IIOInvalidTreeException { 83 IIOMetadataNode bKGD_rgb = new IIOMetadataNode("bKGD_RGB"); 84 85 bKGD_rgb.setAttribute("red", BKGDRED); 86 bKGD_rgb.setAttribute("green", BKGDGREEN); 87 bKGD_rgb.setAttribute("blue", BKGDBLUE); 88 89 IIOMetadataNode bKGD = new IIOMetadataNode("bKGD"); 90 bKGD.appendChild(bKGD_rgb); 91 IIOMetadataNode encodeRoot = 92 new IIOMetadataNode("javax_imageio_png_1.0"); 93 encodeRoot.appendChild(bKGD); 94 95 ImageTypeSpecifier specifier = 96 ImageTypeSpecifier. 97 createFromBufferedImageType(BufferedImage.TYPE_INT_BGR); 98 encodeMetadata = writer.getDefaultImageMetadata(specifier, param); 99 encodeMetadata.mergeTree("javax_imageio_png_1.0", encodeRoot); 100 } 101 102 private static void writeAndReadMetadata() throws IOException { 103 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 104 ImageOutputStream ios = ImageIO.createImageOutputStream(baos); 105 writer.setOutput(ios); 106 107 writer.write(encodeMetadata, 108 new IIOImage(img, null, encodeMetadata), param); 109 110 baos.flush(); 111 byte[] imageByteArray = baos.toByteArray(); 112 baos.close(); 113 114 // Get bKGD chunk from image and verify the values 115 InputStream input= new ByteArrayInputStream(imageByteArray); 116 ImageInputStream iis = ImageIO.createImageInputStream(input); 117 reader.setInput(iis, false, false); 118 119 IIOMetadata decodeMetadata = reader.getImageMetadata(0); 120 IIOMetadataNode decodeRoot = 121 (IIOMetadataNode) decodeMetadata. 122 getAsTree("javax_imageio_png_1.0"); 123 bKGD_RGBNode = (IIOMetadataNode) 124 decodeRoot.getElementsByTagName("bKGD_RGB").item(0); 125 } 126 127 private static boolean verifyRGBValues() { 128 return (!(BKGDRED.equals(bKGD_RGBNode.getAttribute("red")) && 129 BKGDGREEN.equals(bKGD_RGBNode.getAttribute("green")) && 130 BKGDBLUE.equals(bKGD_RGBNode.getAttribute("blue")))); 131 } 132 133 private static void VerifyNativeRGBValuesFromBKGDChunk() 134 throws IOException { 135 136 mergeNativeMetadata(); 137 writeAndReadMetadata(); 138 nativeBKGDFail = verifyRGBValues(); 139 } 140 141 private static void VerifyStandardRGBValuesFromBKGDChunk() 142 throws IOException { 143 144 mergeStandardMetadata(); 145 writeAndReadMetadata(); 146 standardBKGDFail = verifyRGBValues(); 147 } 148 149 public static void main(String[] args) throws IOException { 150 int width = 1; 151 int height = 1; 152 img = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); 153 Iterator<ImageWriter> iterWriter = 154 ImageIO.getImageWritersBySuffix("png"); 155 writer = iterWriter.next(); 156 157 param = writer.getDefaultWriteParam(); 158 159 Iterator<ImageReader> iterReader = 160 ImageIO.getImageReadersBySuffix("png"); 161 reader = iterReader.next(); 162 // Verify bKGD RGB values after merging metadata using native tree 163 VerifyNativeRGBValuesFromBKGDChunk(); 164 165 // Verify bKGD RGB values after merging metadata using standard tree 166 VerifyStandardRGBValuesFromBKGDChunk(); 167 168 writer.dispose(); 169 reader.dispose(); 170 171 if (nativeBKGDFail || standardBKGDFail) { 172 throw new RuntimeException("bKGD RGB values are not stored" + 173 " properly"); 174 } 175 } 176 } 177