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
30import java.awt.Color;
31import java.awt.Graphics2D;
32import java.awt.Rectangle;
33import java.awt.image.BufferedImage;
34import java.awt.image.ColorModel;
35import java.awt.image.Raster;
36import java.io.ByteArrayInputStream;
37import java.io.ByteArrayOutputStream;
38import java.io.IOException;
39import java.util.Iterator;
40
41import javax.imageio.IIOImage;
42import javax.imageio.ImageIO;
43import javax.imageio.ImageReader;
44import javax.imageio.ImageTypeSpecifier;
45import javax.imageio.ImageWriteParam;
46import javax.imageio.ImageWriter;
47import javax.imageio.metadata.IIOMetadata;
48import javax.imageio.stream.ImageOutputStream;
49
50public 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}
176