1/* 2 * Copyright (c) 2005, 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 6332480 27 * @summary Test verifies that images encoded as BMP with RLE4 or RLE8 28 * compression type are read correctly 29 */ 30 31import java.awt.Color; 32import java.awt.Graphics2D; 33import java.awt.image.BufferedImage; 34import java.awt.image.IndexColorModel; 35import java.io.ByteArrayInputStream; 36import java.io.ByteArrayOutputStream; 37import java.io.IOException; 38 39import javax.imageio.IIOImage; 40import javax.imageio.ImageIO; 41import javax.imageio.ImageWriteParam; 42import javax.imageio.ImageWriter; 43import javax.imageio.stream.ImageOutputStream; 44 45public class RLECompressionTest { 46 public static final int TEST_RLE8 = 0x01; 47 public static final int TEST_RLE4 = 0x02; 48 49 private static Color[] usedColors = new Color[] { 50 Color.black, Color.white, Color.red, 51 Color.green, Color.blue, Color.yellow }; 52 53 int w = 100; 54 // NB: problem occurs when image height > width 55 // The problem manifestation is that only first w 56 // lines of image are filled by decoded data, 57 // rest of image (all lines below (w-1)-th line) 58 // is leaved uninitialized (black). 59 // In order to verify that this problem is solved, 60 // we use image with height > width. 61 int h = 2 * w; 62 63 private IndexColorModel getTestColorModel(int type) { 64 IndexColorModel icm = null; 65 int bpp = 8; 66 int size = 256; 67 68 switch(type) { 69 case TEST_RLE8: 70 bpp = 8; 71 size = 256; 72 break; 73 case TEST_RLE4: 74 bpp = 4; 75 size = 16; 76 break; 77 default: 78 throw new IllegalArgumentException("Wrong test type: " + type); 79 } 80 81 byte[] palette = new byte[size * 3]; 82 for (int i = 0; i < usedColors.length; i++) { 83 palette[3 * i] = (byte)(0xff & usedColors[i].getRed()); 84 palette[3 * i + 1] = (byte)(0xff & usedColors[i].getGreen()); 85 palette[3 * i + 2] = (byte)(0xff & usedColors[i].getBlue()); 86 } 87 // rest of palette is black 88 89 icm = new IndexColorModel(bpp, size, palette, 0, false); 90 return icm; 91 } 92 93 private BufferedImage getTestImage(int type) { 94 BufferedImage src = null; 95 IndexColorModel icm = getTestColorModel(type); 96 src = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED, icm); 97 Graphics2D g = src.createGraphics(); 98 g.setColor(Color.white); 99 g.fillRect(0, 0, w, h); 100 g.dispose(); 101 102 return src; 103 } 104 105 public void doTest(int type) throws IOException { 106 BufferedImage src = getTestImage(type); 107 108 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 109 ImageOutputStream ios = ImageIO.createImageOutputStream(baos); 110 111 ImageWriter writer = ImageIO.getImageWritersByFormatName("BMP").next(); 112 writer.setOutput(ios); 113 114 ImageWriteParam wparam = writer.getDefaultWriteParam(); 115 wparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 116 switch(type) { 117 case TEST_RLE8: 118 wparam.setCompressionType("BI_RLE8"); 119 break; 120 case TEST_RLE4: 121 wparam.setCompressionType("BI_RLE4"); 122 break; 123 default: 124 throw new IllegalArgumentException("Wrong test type: " + type); 125 } 126 127 writer.write(null, new IIOImage(src, null, null), wparam); 128 129 ios.close(); 130 baos.close(); 131 132 // read result 133 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 134 135 BufferedImage dst = ImageIO.read(bais); 136 137 checkResult(src, dst); 138 } 139 140 private void checkResult(BufferedImage src, BufferedImage dst) { 141 int x = w / 2; 142 for (int y = 0; y < h; y++) { 143 int srcRgb = src.getRGB(x, y); 144 int dstRgb = dst.getRGB(x, y); 145 146 if (srcRgb != dstRgb) { 147 throw new RuntimeException("Test failed due to color difference: " + 148 Integer.toHexString(dstRgb) + " instead of " + Integer.toHexString(srcRgb) + 149 " at [" + x + ", " + y + "]"); 150 } 151 } 152 } 153 154 public static void main(String[] args) throws IOException { 155 RLECompressionTest test = new RLECompressionTest(); 156 test.doTest(TEST_RLE8); 157 test.doTest(TEST_RLE4); 158 } 159} 160