1 /*
   2  * Copyright (c) 2005, 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 6275211 6276621
  27  * @summary Tests that GIF writer plugin is able to write indexed images if
  28  *          palette size is not a power of two
  29  */
  30 
  31 import java.awt.Color;
  32 import java.awt.Graphics2D;
  33 import java.awt.image.BufferedImage;
  34 import java.awt.image.IndexColorModel;
  35 import java.io.ByteArrayOutputStream;
  36 import java.io.IOException;
  37 
  38 import javax.imageio.ImageIO;
  39 import javax.imageio.ImageWriter;
  40 import javax.imageio.stream.ImageOutputStream;
  41 
  42 public class OddPaletteTest {
  43 
  44     private static int w = 100;
  45     private static int h = 100;
  46 
  47     public static void main(String[] args) {
  48         BufferedImage[] srcs = new BufferedImage[2];
  49         srcs[0] = createTestImage(7); // bug 6275211
  50         srcs[1] = createTestImage(1); // bug 6276621
  51 
  52         for (int i = 0; i < srcs.length; i++) {
  53             doTest(srcs[i]);
  54         }
  55     }
  56 
  57     private static void doTest(BufferedImage src) {
  58         ImageWriter w = ImageIO.getImageWritersByFormatName("GIF").next();
  59         if (w == null) {
  60             throw new RuntimeException("No writer available!");
  61         }
  62 
  63         try {
  64             ByteArrayOutputStream baos = new ByteArrayOutputStream();
  65             ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
  66             w.setOutput(ios);
  67             w.write(src);
  68         } catch (IOException e) {
  69             throw new RuntimeException("Test failed.", e);
  70         } catch (IllegalArgumentException e) {
  71             throw new RuntimeException("Test failed.", e);
  72         }
  73     }
  74 
  75     private static BufferedImage createTestImage(int paletteSize) {
  76         byte[] r = new byte[paletteSize];
  77         byte[] g = new byte[paletteSize];
  78         byte[] b = new byte[paletteSize];
  79 
  80         int shift = 256 / paletteSize;
  81         for (int i = 0; i < paletteSize; i++) {
  82             r[i] = g[i] = b[i] = (byte)(shift * i);
  83         }
  84 
  85         int numBits = getNumBits(paletteSize);
  86 
  87         System.out.println("num of bits " + numBits);
  88 
  89         IndexColorModel icm =
  90             new IndexColorModel(numBits, paletteSize,  r, g, b);
  91 
  92         BufferedImage img = new BufferedImage(w, h,
  93                                               BufferedImage.TYPE_BYTE_INDEXED,
  94                                               icm);
  95         Graphics2D  g2d = img.createGraphics();
  96         g2d.setColor(Color.white);
  97         g2d.fillRect(0, 0, w, h);
  98         g2d.setColor(Color.black);
  99         g2d.drawLine(0, 0, w, h);
 100         g2d.drawLine(0, h, w, 0);
 101 
 102         return img;
 103     }
 104 
 105     private static int getNumBits(int paletteSize) {
 106         if (paletteSize < 0) {
 107             throw new IllegalArgumentException("negative palette size: " +
 108                                                paletteSize);
 109         }
 110         if (paletteSize < 2) {
 111             return 1;
 112         }
 113         int numBits = 0;
 114 
 115         paletteSize--;
 116 
 117         while (paletteSize > 0) {
 118             numBits++;
 119             paletteSize = paletteSize >> 1;
 120         }
 121         return numBits;
 122     }
 123 }