/* * Copyright (c) 2006, 2017, 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 5076878 * @summary Test verifies that ImageIO creates BMP images with correct bpp */ import java.awt.Color; import java.awt.Graphics; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.DirectColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Hashtable; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.metadata.IIOMetadata; import javax.imageio.stream.ImageInputStream; import org.w3c.dom.Node; public class NoExtraBytesTest { private static Hashtable tests = null; private static Color[] usedColors = new Color[] { Color.red, Color.green, Color.blue, Color.yellow, Color.white, Color.black }; private static final int TYPE_INT_GRB = 0x100; private static final int TYPE_INT_GBR = 0x101; private static final int TYPE_INT_RBG = 0x102; private static final int TYPE_INT_BRG = 0x103; private static final int TYPE_INT_555_GRB = 0x104; private static final int TYPE_3BYTE_RGB = 0x105; private static final int TYPE_3BYTE_GRB = 0x106; private static final int w = 300; private static final int h = 200; private static final int dx = w / usedColors.length; public static void main(String[] args) throws IOException { initTests(); for (Integer type : tests.keySet()) { new NoExtraBytesTest(type.intValue(), tests.get(type).intValue()).doTest(); } System.out.println("Test passed."); } private static void initTests() { tests = new Hashtable(); tests.put(new Integer(BufferedImage.TYPE_INT_RGB), new Integer(24)); tests.put(new Integer(BufferedImage.TYPE_INT_BGR), new Integer(24)); tests.put(new Integer(BufferedImage.TYPE_3BYTE_BGR), new Integer(24)); tests.put(new Integer(TYPE_INT_GRB), new Integer(24)); tests.put(new Integer(TYPE_INT_GBR), new Integer(24)); tests.put(new Integer(TYPE_INT_RBG), new Integer(24)); tests.put(new Integer(TYPE_INT_BRG), new Integer(24)); tests.put(new Integer(BufferedImage.TYPE_USHORT_555_RGB), new Integer(16)); tests.put(new Integer(BufferedImage.TYPE_USHORT_565_RGB), new Integer(16)); tests.put(new Integer(TYPE_INT_555_GRB), new Integer(16)); tests.put(new Integer(TYPE_3BYTE_RGB), new Integer(24)); tests.put(new Integer(TYPE_3BYTE_GRB), new Integer(24)); } private static String getImageTypeName(int t) { switch(t) { case BufferedImage.TYPE_INT_RGB: return "TYPE_INT_RGB"; case BufferedImage.TYPE_INT_BGR: return "TYPE_INT_BGR"; case BufferedImage.TYPE_3BYTE_BGR: return "TYPE_3BYTE_BGR"; case BufferedImage.TYPE_USHORT_555_RGB: return "TYPE_USHORT_555_RGB"; case BufferedImage.TYPE_USHORT_565_RGB: return "TYPE_USHORT_565_RGB"; case TYPE_INT_GRB: return "TYPE_INT_GRB"; case TYPE_INT_GBR: return "TYPE_INT_GBR"; case TYPE_INT_RBG: return "TYPE_INT_RBG"; case TYPE_INT_BRG: return "TYPE_INT_BRG"; case TYPE_INT_555_GRB: return "TYPE_INT_555_GRB"; case TYPE_3BYTE_RGB: return "TYPE_3BYTE_RGB"; case TYPE_3BYTE_GRB: return "TYPE_3BYTE_GRB"; default: throw new IllegalArgumentException("Unknown image type: " + t); } } private static BufferedImage createTestImage(int type) { BufferedImage dst = null; ColorModel colorModel = null; WritableRaster raster = null; ColorSpace cs = null; System.out.println("Create image for " + getImageTypeName(type)); switch(type) { case TYPE_INT_GRB: colorModel = new DirectColorModel(24, 0x0000ff00, 0x00ff0000, 0x000000ff); break; case TYPE_INT_GBR: colorModel = new DirectColorModel(24, 0x000000ff, 0x00ff0000, 0x0000ff00); break; case TYPE_INT_RBG: colorModel = new DirectColorModel(24, 0x00ff0000, 0x000000ff, 0x0000ff00); break; case TYPE_INT_BRG: colorModel = new DirectColorModel(24, 0x0000ff00, 0x000000ff, 0x00ff0000); break; case TYPE_INT_555_GRB: colorModel = new DirectColorModel(24, 0x0000001F, 0x000003e0, 0x00007c00); break; case TYPE_3BYTE_RGB: cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); int[] nBits = {8, 8, 8}; int[] bOffs = {0, 1, 2}; colorModel = new ComponentColorModel(cs, nBits, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h, w*3, 3, bOffs, null); break; case TYPE_3BYTE_GRB: cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); //nBits = {8, 8, 8}; //bOffs = {0, 1, 2}; colorModel = new ComponentColorModel(cs, new int[] { 8, 8, 8 }, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h, w*3, 3, new int[] { 1, 0, 2}, null); break; default: dst = new BufferedImage(w, h, type); //colorModel = ImageTypeSpecifier.createFromBufferedImageType(type).getColorModel(); } if (dst == null) { if (raster == null) { raster = colorModel.createCompatibleWritableRaster(w, h); } dst = new BufferedImage(colorModel, raster, false, null); } Graphics g = dst.createGraphics(); for (int i = 0; i < usedColors.length; i ++) { g.setColor(usedColors[i]); g.fillRect(i * dx, 0, dx, h); } g.dispose(); return dst; } private BufferedImage src; private int expectedColorDepth; private int type; private IIOImage iio_dst; public NoExtraBytesTest(int type, int expectedColorDepth) { this.type = type; this.src = createTestImage(type); this.expectedColorDepth = expectedColorDepth; } public void doTest() throws IOException { // write src as BMP System.out.println("Test for image: " + getImageTypeName(type)); System.out.println("image is " + src); File f = File.createTempFile("sizeTest_", ".bmp", new File(".")); System.out.println("Use file " + f.getCanonicalPath()); ImageIO.write(src, "BMP", f); //read it again read(f); checkColorDepth(); checkImageContent(); } private void read(File f) throws IOException { ImageReader reader = ImageIO.getImageReadersByFormatName("BMP").next(); ImageInputStream iis = ImageIO.createImageInputStream(new FileInputStream(f)); reader.setInput(iis); iio_dst = reader.readAll(0, reader.getDefaultReadParam()); } private void checkColorDepth() { IIOMetadata dst = iio_dst.getMetadata(); Node data = dst.getAsTree("javax_imageio_bmp_1.0"); Node n = data.getFirstChild(); while (n != null && !("BitsPerPixel".equals(n.getNodeName()))) { System.out.println("Node " + n.getNodeName()); n = n.getNextSibling(); } if (n == null) { throw new RuntimeException("No BitsPerSample node!"); } int bpp = 0; String value = n.getNodeValue(); System.out.println("value = " + value); try { bpp = Integer.parseInt(value); } catch (NumberFormatException e) { throw new RuntimeException("Wrong bpp value: " + value, e); } if (bpp != this.expectedColorDepth) { throw new RuntimeException("Wrong color depth: " + bpp + " (should be " + this.expectedColorDepth + ")"); } } private void checkImageContent() { BufferedImage dst = (BufferedImage)iio_dst.getRenderedImage(); int y = h / 2; int x = dx / 2; for (int i = 0; i < usedColors.length; i++, x += dx) { int srcRgb = src.getRGB(x, y); int dstRgb = dst.getRGB(x, y); int rgb = usedColors[i].getRGB(); if (dstRgb != srcRgb || dstRgb != rgb) { throw new RuntimeException("Wrong color at [" + x + ", " + y + "] " + Integer.toHexString(dstRgb) + " (srcRgb=" + Integer.toHexString(srcRgb) + ", original color is " + Integer.toHexString(rgb) + ")"); } } System.out.println("Image colors are OK."); } }