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
  27  * @summary Tests writing compression modes of BMP plugin
  28  */
  29 
  30 import java.awt.Color;
  31 import java.awt.Graphics2D;
  32 import java.awt.Rectangle;
  33 import java.awt.image.BufferedImage;
  34 import java.awt.image.ColorModel;
  35 import java.awt.image.Raster;
  36 import java.io.ByteArrayInputStream;
  37 import java.io.ByteArrayOutputStream;
  38 import java.io.IOException;
  39 import java.util.Iterator;
  40 
  41 import javax.imageio.IIOImage;
  42 import javax.imageio.ImageIO;
  43 import javax.imageio.ImageReader;
  44 import javax.imageio.ImageTypeSpecifier;
  45 import javax.imageio.ImageWriteParam;
  46 import javax.imageio.ImageWriter;
  47 import javax.imageio.metadata.IIOMetadata;
  48 import javax.imageio.stream.ImageOutputStream;
  49 
  50 public class BMPWriteParamTest {
  51 
  52     static final String format = "BMP";
  53 
  54     public static void main(String[] args) {
  55 
  56         ImageWriter iw = null;
  57         Iterator writers = ImageIO.getImageWritersByFormatName(format);
  58         if (!writers.hasNext()) {
  59             throw new RuntimeException("No available Image writer for "+format);
  60         }
  61         iw = (ImageWriter)writers.next();
  62 
  63         try {
  64             BufferedImage img = createTestImage();
  65 
  66             BufferedImage bmp_res = getWriteResult(img, "BMP");
  67             BufferedImage png_res = getWriteResult(img, "PNG");
  68 
  69             compare(bmp_res, png_res);
  70         } catch (Exception ex) {
  71             ex.printStackTrace();
  72             throw new RuntimeException("Unexpected exception: " + ex);
  73         }
  74     }
  75 
  76     private static BufferedImage getWriteResult(BufferedImage img,
  77                                                 String format
  78                                                 ) throws IOException {
  79         ImageWriter iw = null;
  80         Iterator writers = ImageIO.getImageWritersByFormatName(format);
  81         while (writers.hasNext()) {
  82             iw = (ImageWriter)writers.next();
  83             System.out.println(format + " -> " + iw.toString());
  84         }
  85         if (iw==null) {
  86             throw new RuntimeException("No available Image writer for "+format);
  87         }
  88         ImageWriteParam param = iw.getDefaultWriteParam();
  89 
  90         param.setSourceRegion(new Rectangle(10, 10, 31, 31));
  91         param.setSourceSubsampling(3, 3, 0, 0);
  92 
  93         IIOMetadata meta = iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), param);
  94 
  95         IIOImage iio_img = new IIOImage(img, null, meta);
  96 
  97         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  98         ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
  99         iw.setOutput(ios);
 100         iw.write(meta, iio_img, param);
 101         ios.flush();
 102 
 103         byte[] ba_image = baos.toByteArray();
 104 
 105         ByteArrayInputStream bais = new ByteArrayInputStream(ba_image);
 106 
 107         ImageReader ir = null;
 108 
 109         Iterator readers = ImageIO.getImageReadersByFormatName(format);
 110         while (readers.hasNext()) {
 111             ir = (ImageReader)readers.next();
 112             System.out.println(format + " -> " + ir.toString());
 113         }
 114         if (ir==null) {
 115             throw new RuntimeException("No available Image reader for "+format);
 116         }
 117 
 118         ir.setInput(ImageIO.createImageInputStream(bais));
 119 
 120         BufferedImage res = ir.read(0);
 121         return res;
 122     }
 123 
 124     private static BufferedImage createTestImage()
 125       throws IOException {
 126 
 127         int w = 50;
 128         int h = 50;
 129         BufferedImage b = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
 130         Graphics2D g = b.createGraphics();
 131         g.setColor(Color.red);
 132         g.fillRect(0,0, w, h);
 133         g.setColor(Color.white);
 134         for (int i=10; i<=10+30; i+= 3) {
 135             g.drawLine(i, 10, i, 40);
 136             g.drawLine(10, i, 40, i);
 137         }
 138         return b;
 139     }
 140 
 141     private static boolean compare(final BufferedImage in,
 142                                    final BufferedImage out)
 143     {
 144         final int width = in.getWidth();
 145         int height = in.getHeight();
 146         if (out.getWidth() != width || out.getHeight() != height) {
 147             throw new RuntimeException("Dimensions changed!");
 148         }
 149 
 150         Raster oldras = in.getRaster();
 151         ColorModel oldcm = in.getColorModel();
 152         Raster newras = out.getRaster();
 153         ColorModel newcm = out.getColorModel();
 154 
 155         for (int j = 0; j < height; j++) {
 156             for (int i = 0; i < width; i++) {
 157                 Object oldpixel = oldras.getDataElements(i, j, null);
 158                 int oldrgb = oldcm.getRGB(oldpixel);
 159                 int oldalpha = oldcm.getAlpha(oldpixel);
 160 
 161                 Object newpixel = newras.getDataElements(i, j, null);
 162                 int newrgb = newcm.getRGB(newpixel);
 163                 int newalpha = newcm.getAlpha(newpixel);
 164 
 165                 if (newrgb != oldrgb ||
 166                     newalpha != oldalpha) {
 167                     // showDiff(in, out);
 168                     throw new RuntimeException("Pixels differ at " + i +
 169                                                ", " + j + " new = " + Integer.toHexString(newrgb) + " old = " + Integer.toHexString(oldrgb));
 170                 }
 171             }
 172         }
 173         return true;
 174     }
 175 }