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 6324581
  27  * @summary Test verifies that RGB images are written to animated GIF image use
  28  *          local color table if image palette is not equals to the global color
  29  *          table
  30  * @modules java.desktop/com.sun.imageio.plugins.gif
  31  */
  32 
  33 import java.awt.Color;
  34 import java.awt.Graphics2D;
  35 import java.awt.image.BufferedImage;
  36 import java.io.ByteArrayInputStream;
  37 import java.io.ByteArrayOutputStream;
  38 import java.io.File;
  39 import java.io.FileOutputStream;
  40 import java.io.IOException;
  41 import java.util.ArrayList;
  42 
  43 import javax.imageio.IIOImage;
  44 import javax.imageio.ImageIO;
  45 import javax.imageio.ImageReader;
  46 import javax.imageio.ImageTypeSpecifier;
  47 import javax.imageio.ImageWriteParam;
  48 import javax.imageio.ImageWriter;
  49 import javax.imageio.metadata.IIOMetadata;
  50 import javax.imageio.stream.ImageOutputStream;
  51 
  52 import com.sun.imageio.plugins.gif.GIFImageMetadata;
  53 
  54 public class RGBAnimationTest {
  55     protected static String format = "GIF";
  56     protected static boolean doSave = true;
  57 
  58     Frame[] frames;
  59     ImageWriter writer;
  60     ImageReader reader;
  61 
  62     public static void main(String[] args) throws IOException  {
  63         RGBAnimationTest test = new RGBAnimationTest();
  64         test.doTest();
  65     }
  66     /** Creates a new instance of RGBAnimationTest */
  67     public RGBAnimationTest() {
  68         frames = new Frame[4];
  69 
  70 
  71         frames[0] = new Frame(new Color[] {Color.red, Color.green});
  72         frames[1] = new Frame(new Color[] {Color.green, Color.cyan});
  73         frames[2] = new Frame(new Color[] {Color.cyan, Color.yellow});
  74         frames[3] = new Frame(new Color[] {Color.yellow, Color.red});
  75 
  76         writer = ImageIO.getImageWritersByFormatName(format).next();
  77         reader = ImageIO.getImageReadersByFormatName(format).next();
  78     }
  79 
  80     public void doTest() throws IOException {
  81         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  82         writer.reset();
  83         ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
  84         writer.setOutput(ios);
  85 
  86         ImageWriteParam wparam = prepareWriteParam();
  87 
  88         IIOMetadata streamMetadata = prepareStreamMetadata(wparam);
  89 
  90         writer.prepareWriteSequence(streamMetadata);
  91 
  92         for (int i = 0; i < frames.length; i++) {
  93             BufferedImage src = frames[i].getImage();
  94             IIOMetadata imageMetadata = prepareImageMetadata(i, src, wparam);
  95             IIOImage img = new IIOImage(src,  null, imageMetadata);
  96 
  97             writer.writeToSequence(img, wparam);
  98         }
  99         writer.endWriteSequence();
 100         ios.flush();
 101         ios.close();
 102 
 103         if (doSave) {
 104             File f = File.createTempFile("wr_test_", "." + format, new File("."));
 105             System.out.println("Save to file: " + f.getCanonicalPath());
 106             FileOutputStream fos = new FileOutputStream(f);
 107             fos.write(baos.toByteArray());
 108             fos.flush();
 109             fos.close();
 110         }
 111         // read result
 112         reader.reset();
 113         ByteArrayInputStream bais =
 114                 new ByteArrayInputStream(baos.toByteArray());
 115         reader.setInput(ImageIO.createImageInputStream(bais));
 116 
 117         int minIndex = reader.getMinIndex();
 118         int numImages = reader.getNumImages(true);
 119 
 120         for (int i = 0; i < numImages; i++) {
 121             BufferedImage dst = reader.read(i + minIndex);
 122             frames[i].checkResult(dst);
 123         }
 124     }
 125 
 126     protected IIOMetadata prepareImageMetadata(int i, BufferedImage img, ImageWriteParam wparam) {
 127         GIFImageMetadata idata = (GIFImageMetadata)
 128         writer.getDefaultImageMetadata(ImageTypeSpecifier.createFromRenderedImage(img), wparam);
 129 
 130         idata.delayTime = 100;
 131         idata.disposalMethod = 0;
 132         idata.transparentColorFlag = false;
 133 
 134         if (i == 0) {
 135             ArrayList<byte[]> appIDs = new ArrayList<byte[]>();
 136             appIDs.add(new String("NETSCAPE").getBytes());
 137             ArrayList<byte[]> authCodes = new ArrayList<byte[]>();
 138             authCodes.add(new String("2.0").getBytes());
 139             ArrayList<byte[]> appData = new ArrayList<byte[]>();
 140             byte[] authData = {1, 0, 0};
 141             appData.add(authData);
 142 
 143             idata.applicationIDs = appIDs;
 144             idata.authenticationCodes = authCodes;
 145             idata.applicationData = appData;
 146         }
 147         return idata;
 148     }
 149 
 150     protected ImageWriteParam prepareWriteParam() {
 151         return writer.getDefaultWriteParam();
 152     }
 153 
 154     protected IIOMetadata prepareStreamMetadata(ImageWriteParam wparam) {
 155         return writer.getDefaultStreamMetadata(wparam);
 156     }
 157 
 158 }
 159 
 160 class Frame {
 161     protected static int type = BufferedImage.TYPE_INT_RGB;
 162     protected static int dx = 100;
 163     protected static int h = 100;
 164 
 165     protected Color[] colors;
 166     protected BufferedImage img;
 167 
 168     public Frame(Color[] colors) {
 169         this.colors = colors;
 170         img = null;
 171     }
 172 
 173     public BufferedImage getImage() {
 174         if (img == null) {
 175             img = new BufferedImage(dx * colors.length, h, type);
 176             Graphics2D g = img.createGraphics();
 177             for (int i = 0; i < colors.length; i++) {
 178                 g.setColor(colors[i]);
 179                 g.fillRect(dx * i, 0, dx, h);
 180             }
 181         }
 182         return img;
 183     }
 184 
 185     public void checkResult(BufferedImage dst) {
 186         int y = h / 2;
 187         int x = dx / 2;
 188         for (int i = 0; i < colors.length; i++) {
 189 
 190             int srcRgb = img.getRGB(i * dx + x, y);
 191             int dstRgb = dst.getRGB(i * dx + x, y);
 192 
 193             if (srcRgb != dstRgb) {
 194                 throw new RuntimeException("Test failed due to color difference: " +
 195                         Integer.toHexString(dstRgb) + " instead of " +
 196                         Integer.toHexString(srcRgb));
 197             }
 198         }
 199     }
 200 }