1 /* 2 * Copyright (c) 2003, 2017, 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 4892194 8014427 27 * @summary Test checks that we able to encode TYPE_3BYTE_BGR images to bmp 28 * format. Test failed if ArrayIndexOutOfBoundsException will be thrown 29 * or pixel colors will be changed by the writing/reading. 30 */ 31 32 import java.awt.Color; 33 import java.awt.Dimension; 34 import java.awt.Graphics; 35 import java.awt.Graphics2D; 36 import java.awt.color.ColorSpace; 37 import java.awt.image.BufferedImage; 38 import java.awt.image.ColorModel; 39 import java.awt.image.ComponentColorModel; 40 import java.awt.image.DataBuffer; 41 import java.awt.image.Raster; 42 import java.awt.image.WritableRaster; 43 import java.io.ByteArrayInputStream; 44 import java.io.ByteArrayOutputStream; 45 import java.io.File; 46 import java.io.FileOutputStream; 47 import java.io.IOException; 48 49 import javax.imageio.IIOImage; 50 import javax.imageio.ImageIO; 51 import javax.imageio.ImageWriter; 52 import javax.imageio.stream.ImageOutputStream; 53 import javax.swing.JComponent; 54 import javax.swing.JFrame; 55 56 public class Write3ByteBgrTest { 57 private static int width = 100; 58 private static int height = 100; 59 private static Color color = new Color(0x10, 0x20, 0x30); 60 61 static int bufferedImageType[] = { 62 BufferedImage.TYPE_CUSTOM, 63 BufferedImage.TYPE_BYTE_BINARY, 64 BufferedImage.TYPE_3BYTE_BGR 65 }; 66 67 static String bufferedImageStringType[] = { 68 "BufferedImage.TYPE_CUSTOM: test for BandedSampleModel", 69 "BufferedImage.TYPE_BYTE_BINARY", 70 "BufferedImage.TYPE_3BYTE_BGR" 71 }; 72 73 private static String writingFormat = "BMP"; 74 private static ImageWriter writer = (ImageWriter)ImageIO.getImageWritersByFormatName(writingFormat).next(); 75 private int type; 76 main(String[] args)77 public static void main(String[] args) { 78 79 //int i = 0; 80 for(int i=0; i<bufferedImageType.length; i++) { 81 Write3ByteBgrTest t1 = new Write3ByteBgrTest(bufferedImageType[i]); 82 83 System.out.println("\n\nImage test for type " + bufferedImageStringType[i]); 84 t1.doImageTest(); 85 } 86 } 87 Write3ByteBgrTest(int type)88 private Write3ByteBgrTest(int type) { 89 this.type = type; 90 } 91 doImageTest()92 private void doImageTest() { 93 try { 94 BufferedImage src = createTestImage(type); 95 BufferedImage dst = writeImage(src); 96 97 compareImages(src, dst); 98 } catch (ArrayIndexOutOfBoundsException e) { 99 throw new RuntimeException("Test failed: index out of array bounds!"); 100 } 101 } 102 103 compareImages(BufferedImage src, BufferedImage dst)104 private void compareImages(BufferedImage src, BufferedImage dst) { 105 Object dstPixel = dst.getRaster().getDataElements(width/2, height/2, null); 106 Object srcPixel = src.getRaster().getDataElements(width/2, height/2, null); 107 108 if ( (src.getColorModel().getRed(srcPixel) != dst.getColorModel().getRed(dstPixel)) || 109 (src.getColorModel().getGreen(srcPixel) != dst.getColorModel().getGreen(dstPixel)) || 110 (src.getColorModel().getBlue(srcPixel) != dst.getColorModel().getBlue(dstPixel)) || 111 (src.getColorModel().getAlpha(srcPixel) != dst.getColorModel().getAlpha(dstPixel)) ) { 112 113 showPixel(src, width/2, height/2); 114 showPixel(dst, width/2, height/2); 115 116 showRes(dst, src); 117 throw new RuntimeException( 118 "Colors are different: " + 119 Integer.toHexString(src.getColorModel().getRGB(srcPixel)) + " and " + 120 Integer.toHexString(dst.getColorModel().getRGB(dstPixel))); 121 } 122 } 123 writeImage(BufferedImage src)124 private BufferedImage writeImage(BufferedImage src) { 125 try { 126 BufferedImage dst = null; 127 if (!writer.getOriginatingProvider().canEncodeImage(src)) { 128 throw new RuntimeException(writingFormat+" writer does not support the image type "+type); 129 } 130 System.out.println(writingFormat+" writer claims it can encode the image "+type); 131 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 132 ImageOutputStream ios = ImageIO.createImageOutputStream(baos); 133 writer.setOutput(ios); 134 IIOImage img = new IIOImage(src.getRaster(), null, null); 135 writer.write(img); 136 ios.close(); 137 baos.close(); 138 139 // save to file 140 File f = new File("test"+src.getType()+".bmp"); 141 FileOutputStream fos = new FileOutputStream(f); 142 fos.write(baos.toByteArray()); 143 fos.close(); 144 145 146 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 147 dst = ImageIO.read(bais); 148 return dst; 149 } catch (IOException e) { 150 e.printStackTrace(); 151 throw new RuntimeException(e); 152 } 153 } 154 showPixel(BufferedImage src, int x, int y)155 private static void showPixel(BufferedImage src, int x, int y) { 156 System.out.println("Img is " + src); 157 Object p = src.getRaster().getDataElements(x, y, null); 158 System.out.println("RGB: " + 159 Integer.toHexString(src.getColorModel().getRGB(p))); 160 System.out.println("Red: " + 161 Integer.toHexString(src.getColorModel().getRed(p))); 162 System.out.println("Green: " + 163 Integer.toHexString(src.getColorModel().getGreen(p))); 164 System.out.println("Blue: " + 165 Integer.toHexString(src.getColorModel().getBlue(p))); 166 System.out.println("Alpha: " + 167 Integer.toHexString(src.getColorModel().getAlpha(p))); 168 } 169 createTestImage(int type)170 private static BufferedImage createTestImage(int type) { 171 return createTestImage(type, color); 172 } 173 createTestImage(int type, Color c)174 private static BufferedImage createTestImage(int type, Color c) { 175 BufferedImage i = null; 176 if (type == BufferedImage.TYPE_CUSTOM) { 177 WritableRaster wr = Raster.createBandedRaster( 178 DataBuffer.TYPE_BYTE, 179 width, height, 180 width, // scanlineStride 181 new int[] { 0, 1, 2},// bankIndices[], 182 new int[] { 1, 2, 0},// bankOffsets[], 183 null); 184 185 ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); 186 187 ColorModel cm = new ComponentColorModel(cs, 188 new int[] { 8, 8, 8}, 189 false, 190 false, 191 ColorModel.OPAQUE, 192 DataBuffer.TYPE_BYTE); 193 i = new BufferedImage(cm, wr, false, null); 194 } else { 195 i = new BufferedImage(width, height, type); 196 } 197 198 Graphics2D g = i.createGraphics(); 199 200 g.setColor(c); 201 g.fillRect(0, 0, width, height); 202 g.setColor(Color.white); 203 g.drawRect(10,10, width-20, height-20); 204 205 return i; 206 } 207 showRes(final BufferedImage src, final BufferedImage dst)208 private static void showRes(final BufferedImage src, 209 final BufferedImage dst) 210 { 211 final int w = src.getWidth()+ dst.getWidth(); 212 final int h = Math.max(src.getHeight(), dst.getHeight()); 213 214 JFrame f = new JFrame("Test results"); 215 f.getContentPane().add( new JComponent() { 216 public Dimension getPreferredSize() { 217 return new Dimension(w,h); 218 } 219 220 public void paintComponent(Graphics g) { 221 g.drawImage(src,0,0, null); 222 g.drawImage(dst, src.getWidth(),0, null); 223 } 224 }); 225 f.pack(); 226 f.setVisible(true); 227 } 228 } 229