Path: blob/master/test/jdk/javax/imageio/plugins/bmp/BMPCompressionTest.java
41153 views
/*1* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 464187226* @summary Tests writing compression modes of BMP plugin27* @modules java.desktop/com.sun.imageio.plugins.bmp28*/2930import java.awt.Color;31import java.awt.Dimension;32import java.awt.Graphics;33import java.awt.Graphics2D;34import java.awt.Transparency;35import java.awt.color.ColorSpace;36import java.awt.image.BufferedImage;37import java.awt.image.ColorModel;38import java.awt.image.ComponentColorModel;39import java.awt.image.DataBuffer;40import java.awt.image.DirectColorModel;41import java.awt.image.IndexColorModel;42import java.awt.image.PixelInterleavedSampleModel;43import java.awt.image.Raster;44import java.awt.image.SampleModel;45import java.awt.image.SinglePixelPackedSampleModel;46import java.awt.image.WritableRaster;47import java.io.ByteArrayInputStream;48import java.io.ByteArrayOutputStream;49import java.io.File;50import java.io.FileOutputStream;51import java.io.IOException;52import java.util.Arrays;53import java.util.Iterator;54import java.util.LinkedList;55import java.util.List;5657import javax.imageio.IIOImage;58import javax.imageio.ImageIO;59import javax.imageio.ImageReader;60import javax.imageio.ImageTypeSpecifier;61import javax.imageio.ImageWriteParam;62import javax.imageio.ImageWriter;63import javax.imageio.metadata.IIOMetadata;64import javax.imageio.plugins.bmp.BMPImageWriteParam;65import javax.imageio.stream.ImageOutputStream;66import javax.swing.JComponent;67import javax.swing.JFrame;6869import com.sun.imageio.plugins.bmp.BMPMetadata;7071public class BMPCompressionTest {7273static final String format = "BMP";7475public static void main(String[] args) {7677ImageWriter iw = null;78Iterator writers = ImageIO.getImageWritersByFormatName(format);79if (!writers.hasNext()) {80throw new RuntimeException("No available Image writer for "+format);81}82iw = (ImageWriter)writers.next();838485Iterator tests = Test.createTestSet(iw);8687while(tests.hasNext()) {8889Test t = (Test)tests.next();90System.out.println(t.getDescription());91t.doTest();92}9394}959697static class Test {98static ImageWriter iw;99private BufferedImage img;100private String description;101private BMPImageWriteParam param;102private IIOMetadata meta;103104105public static Iterator createTestSet(ImageWriter w) {106List l = new LinkedList();107108Test.iw = w;109110// variate compression types111BMPImageWriteParam param = (BMPImageWriteParam)iw.getDefaultWriteParam();112param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);113param.setCompressionType("BI_RGB");114if (param.canWriteCompressed()) {115String[] cTypes = param.getCompressionTypes();116String[] cDescr = param.getCompressionQualityDescriptions();117float[] cValues = param.getCompressionQualityValues();118119if (cDescr == null) {120System.out.println("There are no compression quality description!");121} else {122for(int i=0; i<cDescr.length; i++) {123System.out.println("Quality[" + i + "]=\""+cDescr[i]+"\"");124}125}126if (cValues == null) {127System.out.println("There are no compression quality values!");128} else {129for(int i=0; i<cValues.length; i++) {130System.out.println("Value["+i+"]=\""+cValues[i]+"\"");131}132}133134for(int i=0; i<cTypes.length; i++) {135String compressionType = cTypes[i];136BufferedImage img = null;137138int type = BufferedImage.TYPE_INT_BGR;139try {140img = createTestImage(type);141if (compressionType.equals("BI_RLE8")) {142img = createTestImage2(8, DataBuffer.TYPE_BYTE);143} else if (compressionType.equals("BI_RLE4")) {144img = createTestImage3(4, DataBuffer.TYPE_BYTE);145} else if (compressionType.equals("BI_BITFIELDS")) {146img = createTestImage4(32);147}148149} catch (IOException ex) {150throw new RuntimeException("Unable to create test image");151}152BMPImageWriteParam p = (BMPImageWriteParam)iw.getDefaultWriteParam();153System.out.println("Current compression type is \""+cTypes[i]+"\"");154p.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);155p.setCompressionType(compressionType);156157IIOMetadata md = iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), p);158159l.add( new Test(p, md, img));160}161}162// }163return l.iterator();164165}166167private Test(BMPImageWriteParam p, IIOMetadata md, BufferedImage i) {168param = p;169meta = md;170img = i;171172173description = "Compression type is " + p.getCompressionType();174}175176public String getDescription() {177return description;178}179180public void doTest() {181try {182System.out.println(this.getDescription());183if (param.getCompressionMode() != ImageWriteParam.MODE_EXPLICIT) {184System.out.println("Warning: compression mode is not MODE_EXPLICIT");185}186// change metadata according to ImageWriteParam187IIOMetadata new_meta = iw.convertImageMetadata(meta, new ImageTypeSpecifier(img), param);188189IIOImage iio_img = new IIOImage(img, null, new_meta);190191ByteArrayOutputStream baos = new ByteArrayOutputStream();192ImageOutputStream ios = ImageIO.createImageOutputStream(baos);193iw.setOutput(ios);194System.out.print("write image...");195System.out.println("Current compression Type is \""+param.getCompressionType()+"\"");196iw.write(new_meta, iio_img, param);197//iw.write(iio_img);198System.out.println("OK");199System.out.print("read image ... ");200ios.flush();201202byte[] ba_image = baos.toByteArray();203204System.out.println("Array length=" + ba_image.length);205FileOutputStream fos = new FileOutputStream(new File(param.getCompressionType()+".bmp"));206fos.write(ba_image);207fos.flush();208fos = null;209ByteArrayInputStream bais = new ByteArrayInputStream(ba_image);210211ImageReader ir = ImageIO.getImageReader(iw);212ir.setInput(ImageIO.createImageInputStream(bais));213214BufferedImage res = ir.read(0);215System.out.println("OK");216217if (!param.getCompressionType().equals("BI_JPEG")) {218System.out.print("compare images ... ");219boolean r = compare(img,res);220System.out.println(r?"OK":"FAILED");221if (!r) {222throw new RuntimeException("Compared images are not equals. Test failed.");223}224}225226227BMPMetadata mdata = (BMPMetadata)ir.getImageMetadata(0);228229if (!param.getCompressionType().equals(param.getCompressionTypes()[mdata.compression])) {230throw new RuntimeException("Different compression value");231}232233} catch (Exception ex) {234ex.printStackTrace();235throw new RuntimeException("Unexpected exception: " + ex);236}237238}239240private boolean compare(final BufferedImage in, final BufferedImage out) {241242final int width = in.getWidth();243int height = in.getHeight();244if (out.getWidth() != width || out.getHeight() != height) {245throw new RuntimeException("Dimensions changed!");246}247248Raster oldras = in.getRaster();249ColorModel oldcm = in.getColorModel();250Raster newras = out.getRaster();251ColorModel newcm = out.getColorModel();252253for (int j = 0; j < height; j++) {254for (int i = 0; i < width; i++) {255Object oldpixel = oldras.getDataElements(i, j, null);256int oldrgb = oldcm.getRGB(oldpixel);257int oldalpha = oldcm.getAlpha(oldpixel);258259Object newpixel = newras.getDataElements(i, j, null);260int newrgb = newcm.getRGB(newpixel);261int newalpha = newcm.getAlpha(newpixel);262263if (newrgb != oldrgb ||264newalpha != oldalpha) {265// showDiff(in, out);266throw new RuntimeException("Pixels differ at " + i +267", " + j + " new = " + Integer.toHexString(newrgb) + " old = " + Integer.toHexString(oldrgb));268}269}270}271return true;272}273274private static BufferedImage createTestImage2(int nbits, int transfertype) {275final int colorShift = 2;276int SIZE = 256;277BufferedImage image = null;278279ColorSpace colorSpace =280ColorSpace.getInstance(ColorSpace.CS_GRAY);281ColorModel colorModel =282new ComponentColorModel(colorSpace,283new int[] {nbits},284false,285false,286Transparency.OPAQUE,287transfertype);288289SampleModel sampleModel =290new PixelInterleavedSampleModel(transfertype,291SIZE,292SIZE,2931,294SIZE,295new int[] {0});296297image =298new BufferedImage(colorModel,299Raster.createWritableRaster(sampleModel, null),300false, null);301WritableRaster raster = image.getWritableTile(0, 0);302int[] samples = raster.getSamples(0, 0, SIZE, SIZE, 0, (int[])null);303int off = 0;304int[] row = new int[SIZE];305for(int i = 0; i < SIZE; i++) {306Arrays.fill(row, i << colorShift);307System.arraycopy(row, 0, samples, off, SIZE);308off += SIZE;309}310raster.setSamples(0, 0, SIZE, SIZE, 0, samples);311312return image;313}314315316private static BufferedImage createTestImage3(int nbits, int transfertype) {317final int colorShift = 2;318int SIZE = 256;319BufferedImage image = null;320321ColorSpace colorSpace =322ColorSpace.getInstance(ColorSpace.CS_sRGB);323ColorModel colorModel =324new IndexColorModel(nbits,3254,326new byte[] { (byte)255, 0, 0, (byte)255},327new byte[] { 0, (byte)255, 0, (byte)255},328new byte[] { 0, 0, (byte)255, (byte)255});329330SampleModel sampleModel =331new PixelInterleavedSampleModel(transfertype,332SIZE,333SIZE,3341,335SIZE,336new int[] {0});337338image =339new BufferedImage(colorModel,340Raster.createWritableRaster(sampleModel, null),341342false, null);343344Graphics2D g = image.createGraphics();345g.setColor(Color.white);346g.fillRect(0,0, SIZE, SIZE);347g.setColor(Color.red);348g.fillOval(10, 10, SIZE -20, SIZE-20);349350return image;351}352353private static BufferedImage createTestImage4(int nbits) {354int SIZE = 10;355356357BufferedImage image = null;358359ColorSpace colorSpace =360ColorSpace.getInstance(ColorSpace.CS_sRGB);361ColorModel colorModel =362new DirectColorModel(colorSpace,363nbits, 0xff0000, 0x00ff00, 0x0000ff, 0x000000, false, DataBuffer.TYPE_INT);364365SampleModel sampleModel =366new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT,367SIZE,368SIZE,369new int[] { 0xff0000, 0x00ff00, 0x0000ff} );370371372image =373new BufferedImage(colorModel,374Raster.createWritableRaster(sampleModel, null),375376false, null);377378Graphics2D g = image.createGraphics();379g.setColor(Color.red);380g.fillRect(0,0, SIZE, SIZE);381g.setColor(Color.green);382//g.fillOval(10, 10, SIZE -20, SIZE-20);383g.drawLine(7, 0, 7, SIZE);384g.setColor(Color.blue);385g.drawLine(1, 0, 1, SIZE);386g.setColor(Color.white);387g.drawLine(3, 0, 3, SIZE);388g.setColor(Color.yellow);389g.drawLine(5, 0, 5, SIZE);390return image;391}392393private static BufferedImage createTestImage(int type)394throws IOException {395396int w = 200;397int h = 200;398BufferedImage b = new BufferedImage(w, h, type);399Graphics2D g = b.createGraphics();400g.setColor(Color.white);401g.fillRect(0,0, w, h);402g.setColor(Color.black);403g.fillOval(10, 10, w -20, h-20);404405return b;406}407408409}410411private static void showDiff(final BufferedImage in,412final BufferedImage out) {413final int width = in.getWidth();414final int height = in.getHeight();415416JFrame f = new JFrame("");417f.getContentPane().add( new JComponent() {418public Dimension getPreferredSize() {419return new Dimension(2*width+2, height);420}421public void paintComponent(Graphics g) {422g.setColor(Color.black);423g.drawImage(in, 0,0, null);424425g.drawImage(out, width+2, 0, null);426}427});428f.pack();429f.setVisible(true);430}431432}433434435