1/*
2 * Copyright (c) 2001, 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 4415068 4622201
27 * @summary Tests if the JPEG writer responds to the compression quality setting
28 */
29
30import java.awt.Color;
31import java.awt.Graphics;
32import java.awt.image.BufferedImage;
33import java.io.File;
34import java.io.IOException;
35import java.util.Iterator;
36import java.util.Random;
37
38import javax.imageio.IIOImage;
39import javax.imageio.ImageIO;
40import javax.imageio.ImageTypeSpecifier;
41import javax.imageio.ImageWriteParam;
42import javax.imageio.ImageWriter;
43import javax.imageio.stream.ImageOutputStream;
44
45public class CompressionBug {
46
47    public CompressionBug() throws IOException {
48        File fileHighComp = File.createTempFile("CompressionHigh", ".jpg");
49        File fileLowComp = File.createTempFile("CompressionLow", ".jpg");
50
51        fileHighComp.deleteOnExit();
52        fileLowComp.deleteOnExit();
53
54        ImageOutputStream iosHighComp =
55            ImageIO.createImageOutputStream(fileHighComp);
56        ImageOutputStream iosLowComp =
57            ImageIO.createImageOutputStream(fileLowComp);
58
59        int width = 100;
60        int height = 100;
61        BufferedImage bi =
62            new BufferedImage(width, height,
63                              BufferedImage.TYPE_INT_RGB);
64        Graphics g = bi.createGraphics();
65        Random r = new Random();
66        for (int i = 0; i < 100; i++) {
67            Color c = new Color(r.nextInt(256),
68                                r.nextInt(256),
69                                r.nextInt(256));
70            int x = r.nextInt(width);
71            int y = r.nextInt(height);
72            int w = r.nextInt(width - x);
73            int h = r.nextInt(height - y);
74            g.setColor(c);
75            g.fillRect(x, y, w, h);
76        }
77
78        ImageTypeSpecifier typeSpecifier =
79            new ImageTypeSpecifier(bi.getColorModel(),
80                                   bi.getSampleModel());
81
82        ImageWriter writer = null;
83        Iterator iter = ImageIO.getImageWriters(typeSpecifier,"jpeg");
84        while (iter.hasNext()) {
85            writer = (ImageWriter)iter.next();
86            break;
87        }
88
89        IIOImage iioImg = new IIOImage(bi, null, null);
90        ImageWriteParam wParam = writer.getDefaultWriteParam();
91        wParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
92
93        // write the highly compressed image (a compression quality setting of
94        // 0.1f means low visual quality and small file size)
95        wParam.setCompressionQuality(0.1f);
96        writer.setOutput(iosHighComp);
97        writer.write(null, iioImg, wParam);
98
99        // write the somewhat compressed image (a compression quality setting
100        // of 0.9f means high visual quality and large file size)
101        wParam.setCompressionQuality(0.9f);
102        writer.setOutput(iosLowComp);
103        writer.write(null, iioImg, wParam);
104
105        long sizeOfFileLowComp = fileLowComp.length();
106        long sizeOfFileHighComp = fileHighComp.length();
107
108        // the highly compressed image file should have a smaller file size
109        // than the image file with low compression; throw an exception if
110        // this isn't the case
111        if (sizeOfFileLowComp < sizeOfFileHighComp) {
112            throw new RuntimeException("Lower compression quality did not " +
113                                       "reduce file size!");
114        }
115    }
116
117    public static void main(String args[]) throws IOException {
118        new CompressionBug();
119    }
120}
121