1 /*
   2  * Copyright (c) 2016, 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  *
  27  * @bug     8144991 8150154
  28  * @ignore  8150154
  29  * @author  a.stepanov
  30  * @summary Check if repeating image writing doesn't fail
  31  *          (particularly, no AIOOB occurs)
  32  *
  33  * @run     main RepeatingWriteTest
  34  */
  35 
  36 
  37 import java.awt.*;
  38 import java.awt.image.BufferedImage;
  39 import java.io.*;
  40 import javax.imageio.*;
  41 import javax.imageio.stream.*;
  42 import java.util.Iterator;
  43 import java.util.Locale;
  44 import javax.imageio.plugins.bmp.BMPImageWriteParam;
  45 import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
  46 
  47 public class RepeatingWriteTest {
  48 
  49     private static final int TYPES[] = new int[]{
  50        BufferedImage.TYPE_INT_RGB,        BufferedImage.TYPE_INT_ARGB,
  51        BufferedImage.TYPE_INT_ARGB_PRE,   BufferedImage.TYPE_INT_BGR,
  52        BufferedImage.TYPE_3BYTE_BGR,      BufferedImage.TYPE_4BYTE_ABGR,
  53        BufferedImage.TYPE_4BYTE_ABGR_PRE, BufferedImage.TYPE_BYTE_GRAY,
  54        BufferedImage.TYPE_USHORT_GRAY,    BufferedImage.TYPE_BYTE_BINARY,
  55        BufferedImage.TYPE_BYTE_INDEXED,   BufferedImage.TYPE_USHORT_565_RGB,
  56        BufferedImage.TYPE_USHORT_555_RGB};
  57 
  58     private static final String NAMES[] = new String[]{
  59        "TYPE_INT_RGB",        "TYPE_INT_ARGB",
  60        "TYPE_INT_ARGB_PRE",   "TYPE_INT_BGR",
  61        "TYPE_3BYTE_BGR",      "TYPE_4BYTE_ABGR",
  62        "TYPE_4BYTE_ABGR_PRE", "TYPE_BYTE_GRAY",
  63        "TYPE_USHORT_GRAY",    "TYPE_BYTE_BINARY",
  64        "TYPE_BYTE_INDEXED",   "TYPE_USHORT_565_RGB",
  65        "TYPE_USHORT_555_RGB"};
  66 
  67     private static final int SZ1 = 200, SZ2 = 100;
  68     private static final Color C1 = Color.BLACK, C2 = Color.WHITE;
  69 
  70     private static ImageWriter getWriter(String format) {
  71         Iterator<ImageWriter> writers =
  72             ImageIO.getImageWritersByFormatName(format);
  73         if (!writers.hasNext()) {
  74             throw new RuntimeException("no writers available for " + format);
  75         }
  76         return writers.next();
  77     }
  78 
  79     private static ImageReader getReader(String format) {
  80         Iterator<ImageReader> readers =
  81             ImageIO.getImageReadersByFormatName(format);
  82         if (!readers.hasNext()) {
  83             throw new RuntimeException("no readers available for " + format);
  84         }
  85         return readers.next();
  86     }
  87 
  88     private static class ImageCheckException extends Exception {
  89         public ImageCheckException(String msg) { super(msg); }
  90     }
  91 
  92     private final String format;
  93 
  94     public RepeatingWriteTest(String format) { this.format = format; }
  95 
  96     private void checkImage(String fileName, boolean is1st) throws Exception {
  97 
  98         Color cRef = is1st ? C1  : C2;
  99         int  szRef = is1st ? SZ1 : SZ2;
 100 
 101         ImageReader reader = getReader(format);
 102         ImageInputStream iis = ImageIO.createImageInputStream(new File(fileName));
 103         reader.setInput(iis);
 104         BufferedImage img = reader.read(0);
 105         Color c = new Color(img.getRGB(szRef / 2, szRef / 2));
 106 
 107         int w = img.getWidth(), h = img.getHeight();
 108 
 109         if (w != szRef || h != szRef) {
 110             throw new ImageCheckException(fileName +
 111                 ": invalid image size " + w + " x " + h);
 112         }
 113 
 114         if (!c.equals(cRef)) {
 115             throw new ImageCheckException(fileName +
 116                 ": invalid image color " + c);
 117         }
 118     }
 119 
 120     private void doTest(int i, int j) throws Exception {
 121 
 122         String pair = NAMES[i] + " " + NAMES[j];
 123 
 124         // some type checks: avoid IO exceptions
 125         if ((format.equals("jpeg") || format.equals("bmp")) &&
 126             (pair.contains("USHORT_GRAY") ||
 127              pair.contains("ARGB") || pair.contains("ABGR"))) {
 128             return;
 129         }
 130 
 131 
 132         String f1 = "test-1-" + NAMES[i] + "." + format;
 133         String f2 = "test-2-" + NAMES[j] + "." + format;
 134 
 135         ImageWriter writer = getWriter(format);
 136 
 137         // --- write 1st image ---
 138         OutputStream s = new BufferedOutputStream(new FileOutputStream(f1));
 139         ImageOutputStream ios = ImageIO.createImageOutputStream(s);
 140         writer.setOutput(ios);
 141 
 142         BufferedImage img = new BufferedImage(SZ1, SZ1, TYPES[i]);
 143         Graphics g = img.getGraphics();
 144         g.setColor(C1);
 145         g.fillRect(0, 0, SZ1, SZ1);
 146         g.dispose();
 147 
 148         if (format.equals("jpeg")) {
 149             writer.write(null, new IIOImage(img, null, null),
 150                 new JPEGImageWriteParam(Locale.getDefault()));
 151         } if (format.equals("bmp")) {
 152             writer.write(null, new IIOImage(img, null, null),
 153                 new BMPImageWriteParam());
 154         } else {
 155             writer.write(img);
 156         }
 157         ios.flush();
 158         s.close();
 159 
 160         // --- write 2nd image ---
 161         s = new BufferedOutputStream(new FileOutputStream(f2));
 162         ios = ImageIO.createImageOutputStream(s);
 163         writer.setOutput(ios);
 164 
 165         img = new BufferedImage(SZ2, SZ2, TYPES[j]);
 166         g = img.getGraphics();
 167         g.setColor(C2);
 168         g.fillRect(0, 0, SZ2, SZ2);
 169         g.dispose();
 170 
 171         if (format.equals("jpeg")) {
 172             writer.write(null, new IIOImage(img, null, null),
 173                 new JPEGImageWriteParam(Locale.getDefault()));
 174         } if (format.equals("bmp")) {
 175             writer.write(null, new IIOImage(img, null, null),
 176                 new BMPImageWriteParam());
 177         } else {
 178             writer.write(img);
 179         }
 180         ios.flush();
 181         s.close();
 182 
 183         // --- check files ---
 184         checkImage(f1, true);
 185         checkImage(f2, false);
 186     }
 187 
 188     public static void main(String args[]) throws Exception {
 189 
 190 
 191         int n = TYPES.length;
 192         int nAIOOB = 0, nChecksFailed = 0;
 193 
 194         String formats[] = {"bmp", "jpeg", "gif", "png", "tiff"};
 195 
 196         for (String f: formats) {
 197             System.out.println("\nformat: " + f);
 198             RepeatingWriteTest test = new RepeatingWriteTest(f);
 199             for (int i = 0; i < n; ++i) {
 200                 for (int j = 0; j < n; ++j) {
 201                     try {
 202                         test.doTest(i, j);
 203                     } catch (ArrayIndexOutOfBoundsException e) {
 204                         System.err.println(f + ": AIOOB for pair " +
 205                             NAMES[i] + ", " + NAMES[j] + ": " + e.getMessage());
 206                         nAIOOB++;
 207                     } catch (ImageCheckException e) {
 208                         System.err.println(f +
 209                             ": image check failed for " + e.getMessage());
 210                         nChecksFailed++;
 211                     }
 212                 }
 213             }
 214         }
 215 
 216         if (nAIOOB > 0 || nChecksFailed > 0) {
 217             throw new RuntimeException("test failed: " + nAIOOB + " AIOOBs, " +
 218                 nChecksFailed + " image check failures");
 219         }
 220     }
 221 }