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 4641872 4892194
  27  * @summary Tests writing and reading abilities of BMP plugin
  28  */
  29 
  30 import java.awt.Color;
  31 import java.awt.Graphics2D;
  32 import java.awt.image.BufferedImage;
  33 import java.awt.image.ColorModel;
  34 import java.awt.image.Raster;
  35 import java.io.ByteArrayInputStream;
  36 import java.io.ByteArrayOutputStream;
  37 import java.io.File;
  38 import java.io.FileInputStream;
  39 import java.io.FileOutputStream;
  40 import java.io.IOException;
  41 import java.util.Iterator;
  42 
  43 import javax.imageio.IIOException;
  44 import javax.imageio.IIOImage;
  45 import javax.imageio.ImageIO;
  46 import javax.imageio.ImageReader;
  47 import javax.imageio.ImageTypeSpecifier;
  48 import javax.imageio.ImageWriteParam;
  49 import javax.imageio.ImageWriter;
  50 import javax.imageio.metadata.IIOMetadata;
  51 import javax.imageio.spi.ImageWriterSpi;
  52 
  53 public class BMPPluginTest {
  54 
  55     private static final int[] types = {
  56         BufferedImage.TYPE_INT_RGB, // = 1;
  57         BufferedImage.TYPE_INT_ARGB, // = 2;
  58         BufferedImage.TYPE_INT_ARGB_PRE, // = 3;
  59         BufferedImage.TYPE_INT_BGR, // = 4;
  60         BufferedImage.TYPE_3BYTE_BGR, // = 5;
  61         BufferedImage.TYPE_4BYTE_ABGR, // = 6;
  62         BufferedImage.TYPE_4BYTE_ABGR_PRE, // 7
  63         BufferedImage.TYPE_USHORT_565_RGB, // 8
  64         BufferedImage.TYPE_USHORT_555_RGB, // 9
  65         BufferedImage.TYPE_BYTE_GRAY, // 10
  66         BufferedImage.TYPE_USHORT_GRAY, //11
  67         BufferedImage.TYPE_BYTE_BINARY, //12
  68         BufferedImage.TYPE_BYTE_INDEXED //13
  69     };
  70 
  71     private static String format = "BMP";
  72 
  73     private static ImageReader ir = null;
  74     private static ImageWriter iw = null;
  75     private BufferedImage img;
  76     private ImageWriteParam param;
  77     private ByteArrayOutputStream baos;
  78 
  79     private static void init() {
  80 
  81         Iterator i = ImageIO.getImageWritersByFormatName(format);
  82         if (!i.hasNext()) {
  83             throw new RuntimeException("No available ImageWrites for "+format+" format!");
  84         }
  85         iw = (ImageWriter)i.next();
  86 
  87         i = ImageIO.getImageReadersByFormatName(format);
  88         if (!i.hasNext()) {
  89             throw new RuntimeException("No available ImageReaders for " +format+" format!");
  90         }
  91 
  92         ir = (ImageReader)i.next();
  93     }
  94 
  95     public static void main(String[] args) {
  96         if (args.length > 0) {
  97             format = args[0];
  98             System.out.println("Test format " + format);
  99         }
 100 
 101         init();
 102         System.out.println("IR="+ir);
 103         System.out.println("IW="+iw);
 104         ImageIO.setUseCache(false);
 105 
 106         for (int i=0; i<types.length; i++) {
 107             boolean bPassed = true;
 108             Object reason = null;
 109 
 110             try {
 111 
 112                 BufferedImage image = createTestImage(types[i]);
 113 
 114                 ImageWriteParam param = iw.getDefaultWriteParam();
 115 
 116                 BMPPluginTest t = new BMPPluginTest(image, param);
 117                 boolean res = false;
 118                 res = t.test();
 119                 if (!res) {
 120                     bPassed = false;
 121                     reason = new String("Null result");
 122                 }
 123             } catch (IllegalArgumentException ex) {
 124                 System.out.println("Expected exception type was caught: " + ex);
 125 
 126             } catch (Throwable ex ) {
 127                 System.out.println("FAILED");
 128                 ex.printStackTrace();
 129                 bPassed = false;
 130                 reason = ex;
 131                 throw new RuntimeException("Test for type " + types[i] + " FAILED due to exception");
 132             }
 133 /*
 134             System.out.println("Type " + types[i] + " result: " +
 135                                (bPassed ? "PASSED" : "FAILED") +
 136                                ((reason != null) ? (" Reason: " + reason) : ""));
 137 */
 138             System.out.println("Test for type " + types[i] + " PASSED");
 139         }
 140 
 141         System.out.println("END OF TEST");
 142     }
 143 
 144     public BMPPluginTest(BufferedImage img, ImageWriteParam param) {
 145 
 146         this.img = img;
 147         this.param = param;
 148         baos = new ByteArrayOutputStream();
 149     }
 150 
 151     public boolean test() throws IIOException, IOException {
 152 
 153         ir.reset();
 154         iw.reset();
 155 
 156         String[] suffixes = iw.getOriginatingProvider().getFileSuffixes();
 157 
 158         IIOMetadata md = iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), param);
 159 
 160         System.out.println("Image type " + img.getType());
 161 
 162         ImageWriterSpi spi = iw.getOriginatingProvider();
 163         boolean bCanEncode = spi.canEncodeImage(img);
 164 
 165         System.out.println("Can encode image? " + (bCanEncode ? "YES" : "NO"));
 166         if (!bCanEncode) {
 167             return true;
 168         }
 169         IIOImage iio_img = new IIOImage(img, null, md);
 170 
 171         String fname = "test"+img.getType()+"."+suffixes[0];
 172 
 173         iw.setOutput(ImageIO.createImageOutputStream(new FileOutputStream(new File(fname))));
 174         System.out.print("write image ... ");
 175         iw.write(iio_img);
 176         System.out.println("OK");
 177         System.out.print("read image ... ");
 178 
 179         byte[] ba_image = baos.toByteArray();
 180 
 181         ByteArrayInputStream bais = new ByteArrayInputStream(ba_image);
 182 
 183         ir.setInput(ImageIO.createImageInputStream(new FileInputStream(new File(fname))));
 184 
 185         BufferedImage res = ir.read(0);
 186         System.out.println("OK");
 187 
 188         System.out.print("compare images ... ");
 189         boolean r = compare(img,res);
 190         System.out.println(r?"OK":"FAILED");
 191         return r;
 192     }
 193 
 194     private boolean compare(BufferedImage in, BufferedImage out) {
 195         int width = in.getWidth();
 196         int height = in.getHeight();
 197         if (out.getWidth() != width || out.getHeight() != height) {
 198             throw new RuntimeException("Dimensions changed!");
 199         }
 200 
 201         Raster oldras = in.getRaster();
 202         ColorModel oldcm = in.getColorModel();
 203         Raster newras = out.getRaster();
 204         ColorModel newcm = out.getColorModel();
 205 
 206         for (int j = 0; j < height; j++) {
 207             for (int i = 0; i < width; i++) {
 208                 Object oldpixel = oldras.getDataElements(i, j, null);
 209                 int oldrgb = oldcm.getRGB(oldpixel);
 210                 int oldalpha = oldcm.getAlpha(oldpixel);
 211 
 212                 Object newpixel = newras.getDataElements(i, j, null);
 213                 int newrgb = newcm.getRGB(newpixel);
 214                 int newalpha = newcm.getAlpha(newpixel);
 215 
 216                 if (newrgb != oldrgb ||
 217                     newalpha != oldalpha) {
 218                     throw new RuntimeException("Pixels differ at " + i +
 219                                                ", " + j);
 220                 }
 221             }
 222         }
 223         return true;
 224     }
 225 
 226 
 227     private static BufferedImage createTestImage(int type) throws IOException {
 228 
 229         int w = 200;
 230         int h = 200;
 231         BufferedImage b = new BufferedImage(w, h, type);
 232         Graphics2D g = b.createGraphics();
 233         g.setColor(Color.white);
 234         g.fillRect(0,0, w, h);
 235         g.setColor(Color.black);
 236         g.fillOval(10, 10, w -20, h-20);
 237 
 238         return b;
 239     }
 240 
 241 }