/* * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package test.com.sun.javafx.iio; import com.sun.javafx.iio.ImageFrame; import com.sun.javafx.iio.ImageLoader; import com.sun.javafx.iio.ImageStorage; import com.sun.javafx.iio.gif.GIFImageLoader2; import java.awt.image.*; import java.io.*; import static org.junit.Assert.*; import org.junit.Test; class TestStream extends InputStream { byte data[]; int p = 0; public TestStream(byte data[]) { this.data = data; } @Override public int read() throws IOException { return p < data.length ? (int)data[p++] & 0xff : -1; } } public class GIFLoaderTest { @Test public void testCtorNPE() { try { new GIFImageLoader2(null); } catch (NullPointerException ex) { return; // PASSED } catch (IOException ioEx) { fail("unexpected IOException:" + ioEx.toString()); } fail("expected NPE after constructor invocation with null"); } @Test public void testCtorReadBadHeader1() { final byte tooShortHeaderData[] = { 0,1,2,3,4 }; try { new GIFImageLoader2(new TestStream(tooShortHeaderData)); } catch (EOFException ex) { return; // PASSED } catch (IOException ioEx) { fail("unexpected IOException:" + ioEx.toString()); } fail("expected EOF exception for streams lesser then 13 bytes"); } @Test public void testCtorReadBadHeader2() { final byte tooShortHeaderData[] = { 'G', 'I', 'F', '8', '9', 'a', 0, 0, 0, 0, 0, 0 }; try { new GIFImageLoader2(new TestStream(tooShortHeaderData)); } catch (EOFException ex) { return; // PASSED } catch (IOException ioEx) { fail("unexpected IOException:" + ioEx.toString()); } fail("expected EOF exception for streams lesser then 13 bytes"); } @Test public void testCtorReadGoodHeader() { final byte _87HeaderData[] = { 'G', 'I', 'F', '8', '7', 'a', 1, 0, 1, 0, 0, 0, 0 }; final byte _89HeaderData[] = { 'G', 'I', 'F', '8', '9', 'a', 1, 0, 1, 0, 0, 0, 0 }; try { new GIFImageLoader2(new TestStream(_87HeaderData)); new GIFImageLoader2(new TestStream(_89HeaderData)); } catch (IOException ioEx) { ioEx.printStackTrace(System.out); fail("unexpected IOException:" + ioEx.toString()); } } @Test (timeout=2000) public void testCtorReadBadExtension() { final byte badGifData[] = { 'G', 'I', 'F', '8', '9', 'a', 1, 0, 1, 0, -112, 0, 0, -18, 51, 34, 0, 0, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 4, 1, 43, 48 }; // Create a loader using the data containing a bad GIF extension GIFImageLoader2 loader = null; try { loader = new GIFImageLoader2(new TestStream(badGifData)); } catch (IOException ioEx) { fail("unexpected IOException:" + ioEx.toString()); } assertNotNull(loader); // Now try to load the image; it should get an EOFException try { loader.load(0, 1, 1, true, true); } catch (EOFException ex) { return; // PASSED } catch (IOException ioEx) { fail("unexpected IOException:" + ioEx.toString()); } fail("expected EOF exception for streams with bad extension"); } private void compareBGRaAndIndexed(byte dataRGBA[], byte dataIndexed[], int paletteBGRA[]) { assertEquals(dataIndexed.length*4, dataRGBA.length); for (int i = 0, j = 0, e = dataIndexed.length; i < e; j += 4, ++i) { int r = dataRGBA[j+0] & 0xFF, g = dataRGBA[j+1] & 0xFF, b = dataRGBA[j+2] & 0xFF, a = dataRGBA[j+3] & 0xFF; int x = b + (g<<8) + (r<<16) + (a<<24); int y = paletteBGRA[dataIndexed[i] & 0xFF]; if ((x != y) && (((x & 0xFF000000) != 0) || ((y & 0xFF000000) != 0))) { fail("colors are different : JDK: " + Integer.toHexString(y) + ", JavaFX: " + Integer.toHexString(x)); } } } private void compareBGRaAndIndexed(byte dataRGBA[], int dataIndexed[], int paletteBGRA[]) { assertEquals(dataIndexed.length*4, dataRGBA.length); for (int i = 0, j = 0, e = dataIndexed.length; i < e; j += 4, ++i) { int r = dataRGBA[j+0] & 0xFF, g = dataRGBA[j+1] & 0xFF, b = dataRGBA[j+2] & 0xFF, a = dataRGBA[j+3] & 0xFF; int x = b + (g<<8) + (r<<16) + (a<<24); int y = paletteBGRA[dataIndexed[i] & 0xFF]; if ((x != y) && (((x & 0xFF000000) != 0) || ((y & 0xFF000000) != 0))) { fail("colors are different : JDK: " + Integer.toHexString(y) + ", JavaFX: " + Integer.toHexString(x)); } } } private void compareImageFrameAndBImage(ImageFrame f, BufferedImage bimg) { byte dataRGBA[] = (byte[])f.getImageData().array(); assertEquals(dataRGBA.length, f.getHeight() * f.getWidth() * 4); assertEquals(f.getImageType(), ImageStorage.ImageType.RGBA); assertEquals(f.getHeight(), bimg.getHeight()); assertEquals(f.getWidth(), bimg.getWidth()); if (bimg.getColorModel() instanceof IndexColorModel) { IndexColorModel idx = (IndexColorModel)bimg.getColorModel(); int rgb[] = new int [256]; idx.getRGBs(rgb); Raster r = bimg.getData(); DataBuffer db = r.getDataBuffer(); assertTrue( db instanceof DataBufferByte); DataBufferByte bdb = (DataBufferByte)db; assertEquals(bdb.getNumBanks(), 1); byte dataIndexed[] = bdb.getData(0); int bitsPerPixel = idx.getPixelSize(); if (bitsPerPixel == 8) { assertEquals(dataIndexed.length, f.getHeight()*f.getWidth()); compareBGRaAndIndexed(dataRGBA, dataIndexed, rgb); } else { int rgbData[] = new int[bimg.getWidth() * bimg.getHeight()]; r.getPixels(0, 0, bimg.getWidth(), bimg.getHeight(), rgbData); compareBGRaAndIndexed(dataRGBA, rgbData, rgb); } } else { Raster r = bimg.getData(); // System.out.println("" + r.getWidth() + "," + r.getHeight() + "," + r.getNumBands() // + "," + r.getDataBuffer() + "," + r.getSampleModel()); fail("Unexpected image form AWT"); } } private void testReadGIFFile(String fname) throws IOException { InputStream i = this.getClass().getResourceAsStream(fname); InputStream testStream = ImageTestHelper.createStutteringInputStream(i); ImageLoader l = new GIFImageLoader2(testStream); ImageFrame f = l.load(0, 0, 0, true, false); InputStream i2 = this.getClass().getResourceAsStream(fname); BufferedImage bimg = javax.imageio.ImageIO.read(i2); compareImageFrameAndBImage(f, bimg); } @Test public void testReadGIFFile() throws Exception { for (String s : fileList) { try { testReadGIFFile(s); } catch (Exception ex) { System.err.println("Failure in test file " + s); throw ex; } } } // public static void main(String[] args) throws IOException { // new GIFLoaderTest().testReadGIFFile(); // } final static String fileList[] = { "gif/adam_7_interlacing/basi0g01.gif", "gif/adam_7_interlacing/basi0g02.gif", "gif/adam_7_interlacing/basi0g04.gif", "gif/adam_7_interlacing/basi0g08.gif", "gif/adam_7_interlacing/basi0g16.gif", "gif/adam_7_interlacing/basi2c08.gif", "gif/adam_7_interlacing/basi2c16.gif", "gif/adam_7_interlacing/basi3p01.gif", "gif/adam_7_interlacing/basi3p02.gif", "gif/adam_7_interlacing/basi3p04.gif", "gif/adam_7_interlacing/basi3p08.gif", "gif/adam_7_interlacing/basi4a08.gif", "gif/adam_7_interlacing/basi4a16.gif", "gif/adam_7_interlacing/basi6a08.gif", "gif/adam_7_interlacing/basi6a16.gif", "gif/base/basn0g01.gif", "gif/base/basn0g02.gif", "gif/base/basn0g04.gif", "gif/base/basn0g08.gif", "gif/base/basn0g16.gif", "gif/base/basn2c08.gif", "gif/base/basn2c16.gif", "gif/base/basn3p01.gif", "gif/base/basn3p02.gif", "gif/base/basn3p04.gif", "gif/base/basn3p08.gif", "gif/base/basn4a08.gif", "gif/base/basn4a16.gif", "gif/base/basn6a08.gif", "gif/base/basn6a16.gif", "gif/background/bgai4a08.gif", "gif/background/bgai4a16.gif", "gif/background/bgan6a08.gif", "gif/background/bgan6a16.gif", "gif/background/bgbn4a08.gif", "gif/background/bggn4a16.gif", "gif/background/bgwn6a08.gif", "gif/background/bgyn6a16.gif", "gif/ancillary_chunks/ccwn2c08.gif", "gif/ancillary_chunks/ccwn3p08.gif", "gif/ancillary_chunks/cdfn2c08.gif", "gif/ancillary_chunks/cdhn2c08.gif", "gif/ancillary_chunks/cdsn2c08.gif", "gif/ancillary_chunks/cdun2c08.gif", "gif/ancillary_chunks/ch1n3p04.gif", "gif/ancillary_chunks/ch2n3p08.gif", "gif/ancillary_chunks/cm0n0g04.gif", "gif/ancillary_chunks/cm7n0g04.gif", "gif/ancillary_chunks/cm9n0g04.gif", "gif/ancillary_chunks/cs3n2c16.gif", "gif/ancillary_chunks/cs3n3p08.gif", "gif/ancillary_chunks/cs5n2c08.gif", "gif/ancillary_chunks/cs5n3p08.gif", "gif/ancillary_chunks/cs8n2c08.gif", "gif/ancillary_chunks/cs8n3p08.gif", "gif/ancillary_chunks/ct0n0g04.gif", "gif/ancillary_chunks/ct1n0g04.gif", "gif/ancillary_chunks/cten0g04.gif", "gif/ancillary_chunks/ctfn0g04.gif", "gif/ancillary_chunks/ctgn0g04.gif", "gif/ancillary_chunks/cthn0g04.gif", "gif/ancillary_chunks/ctjn0g04.gif", "gif/filtering/f00n0g08.gif", "gif/filtering/f00n2c08.gif", "gif/filtering/f01n0g08.gif", "gif/filtering/f01n2c08.gif", "gif/filtering/f02n0g08.gif", "gif/filtering/f02n2c08.gif", "gif/filtering/f03n0g08.gif", "gif/filtering/f03n2c08.gif", "gif/filtering/f04n0g08.gif", "gif/filtering/f04n2c08.gif", "gif/filtering/f99n0g04.gif", "gif/gamma/g03n0g16.gif", "gif/gamma/g03n2c08.gif", "gif/gamma/g03n3p04.gif", "gif/gamma/g04n0g16.gif", "gif/gamma/g04n2c08.gif", "gif/gamma/g04n3p04.gif", "gif/gamma/g05n0g16.gif", "gif/gamma/g05n2c08.gif", "gif/gamma/g05n3p04.gif", "gif/gamma/g07n0g16.gif", "gif/gamma/g07n2c08.gif", "gif/gamma/g07n3p04.gif", "gif/gamma/g10n0g16.gif", "gif/gamma/g10n2c08.gif", "gif/gamma/g10n3p04.gif", "gif/gamma/g25n0g16.gif", "gif/gamma/g25n2c08.gif", "gif/gamma/g25n3p04.gif", "gif/chunk_ordering/oi1n0g16.gif", "gif/chunk_ordering/oi1n2c16.gif", "gif/chunk_ordering/oi2n0g16.gif", "gif/chunk_ordering/oi2n2c16.gif", "gif/chunk_ordering/oi4n0g16.gif", "gif/chunk_ordering/oi4n2c16.gif", "gif/chunk_ordering/oi9n0g16.gif", "gif/chunk_ordering/oi9n2c16.gif", "gif/add_palets/pp0n2c16.gif", "gif/add_palets/pp0n6a08.gif", "gif/add_palets/ps1n0g08.gif", "gif/add_palets/ps1n2c16.gif", "gif/add_palets/ps2n0g08.gif", "gif/add_palets/ps2n2c16.gif", "gif/odd_sizes/s01i3p01.gif", "gif/odd_sizes/s01n3p01.gif", "gif/odd_sizes/s02i3p01.gif", "gif/odd_sizes/s02n3p01.gif", "gif/odd_sizes/s03i3p01.gif", "gif/odd_sizes/s03n3p01.gif", "gif/odd_sizes/s04i3p01.gif", "gif/odd_sizes/s04n3p01.gif", "gif/odd_sizes/s05i3p02.gif", "gif/odd_sizes/s05n3p02.gif", "gif/odd_sizes/s06i3p02.gif", "gif/odd_sizes/s06n3p02.gif", "gif/odd_sizes/s07i3p02.gif", "gif/odd_sizes/s07n3p02.gif", "gif/odd_sizes/s08i3p02.gif", "gif/odd_sizes/s08n3p02.gif", "gif/odd_sizes/s09i3p02.gif", "gif/odd_sizes/s09n3p02.gif", "gif/odd_sizes/s32i3p04.gif", "gif/odd_sizes/s32n3p04.gif", "gif/odd_sizes/s33i3p04.gif", "gif/odd_sizes/s33n3p04.gif", "gif/odd_sizes/s34i3p04.gif", "gif/odd_sizes/s34n3p04.gif", "gif/odd_sizes/s35i3p04.gif", "gif/odd_sizes/s35n3p04.gif", "gif/odd_sizes/s36i3p04.gif", "gif/odd_sizes/s36n3p04.gif", "gif/odd_sizes/s37i3p04.gif", "gif/odd_sizes/s37n3p04.gif", "gif/odd_sizes/s38i3p04.gif", "gif/odd_sizes/s38n3p04.gif", "gif/odd_sizes/s39i3p04.gif", "gif/odd_sizes/s39n3p04.gif", "gif/odd_sizes/s40i3p04.gif", "gif/odd_sizes/s40n3p04.gif", "gif/transparency/tbbn0g04.gif", "gif/transparency/tbbn2c16.gif", "gif/transparency/tbbn3p08.gif", "gif/transparency/tbgn2c16.gif", "gif/transparency/tbgn3p08.gif", "gif/transparency/tbrn2c08.gif", "gif/transparency/tbwn0g16.gif", "gif/transparency/tbwn3p08.gif", "gif/transparency/tbyn3p08.gif", "gif/transparency/tp0n0g08.gif", "gif/transparency/tp0n2c08.gif", "gif/transparency/tp0n3p08.gif", "gif/transparency/tp1n3p08.gif", "gif/corrupted/xc1n0g08.gif", "gif/corrupted/xc9n2c08.gif", "gif/corrupted/xcrn0g04.gif", "gif/corrupted/xcsn0g01.gif", "gif/corrupted/xd0n2c08.gif", "gif/corrupted/xd3n2c08.gif", "gif/corrupted/xd9n2c08.gif", "gif/corrupted/xdtn0g01.gif", "gif/corrupted/xhdn0g08.gif", "gif/corrupted/xlfn0g04.gif", "gif/corrupted/xs1n0g01.gif", "gif/corrupted/xs2n0g01.gif", "gif/corrupted/xs4n0g01.gif", "gif/corrupted/xs7n0g01.gif", "gif/zlib_compression_level/z00n2c08.gif", "gif/zlib_compression_level/z03n2c08.gif", "gif/zlib_compression_level/z06n2c08.gif", "gif/zlib_compression_level/z09n2c08.gif" }; }