/*
 * Copyright 1995-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*-
 *      Reads GIF images from an InputStream and reports the
 *      image data to an InputStreamImageSource object.
 *
 * The algorithm is copyright of CompuServe.
 */
package sun.awt.image;

import java.util.Vector;
import java.util.Hashtable;
import java.io.InputStream;
import java.io.IOException;
import java.awt.image.*;

/**
 * Gif Image converter
 *
 * @author Arthur van Hoff
 * @author Jim Graham
 */
public class GifImageDecoder extends ImageDecoder {
    private static final boolean verbose = false;

    private static final int IMAGESEP           = 0x2c;
    private static final int EXBLOCK            = 0x21;
    private static final int EX_GRAPHICS_CONTROL= 0xf9;
    private static final int EX_COMMENT         = 0xfe;
    private static final int EX_APPLICATION     = 0xff;
    private static final int TERMINATOR         = 0x3b;
    private static final int TRANSPARENCYMASK   = 0x01;
    private static final int INTERLACEMASK      = 0x40;
    private static final int COLORMAPMASK       = 0x80;

    int num_global_colors;
    byte[] global_colormap;
    int trans_pixel = -1;
    IndexColorModel global_model;

    Hashtable props = new Hashtable();

    byte[] saved_image;
    IndexColorModel saved_model;

    int global_width;
    int global_height;
    int global_bgpixel;

    GifFrame curframe;

    public GifImageDecoder(InputStreamImageSource src, InputStream is) {
        super(src, is);
    }

    /**
     * An error has occurred. Throw an exception.
     */
    private static void error(String s1) throws ImageFormatException {
        throw new ImageFormatException(s1);
    }

    /**
     * Read a number of bytes into a buffer.
     * @return number of bytes that were not read due to EOF or error
     */
    private int readBytes(byte buf[], int off, int len) {
        while (len > 0) {
            try {
                int n = input.read(buf, off, len);
                if (n < 0) {
                    break;
                }
                off += n;
                len -= n;
            } catch (IOException e) {
                break;
            }
        }
        return len;
    }

    private static final int ExtractByte(byte buf[], int off) {
        return (buf[off] & 0xFF);
    }

    private static final int ExtractWord(byte buf[], int off) {
        return (buf[off] & 0xFF) | ((buf[off + 1] & 0xFF) << 8);
    }

    /**
     * produce an image from the stream.
     */
    public void produceImage() throws IOException, ImageFormatException {
        try {
            readHeader();

            int totalframes = 0;
            int frameno = 0;
            int nloops = -1;
            int disposal_method = 0;
            int delay = -1;
            boolean loopsRead = false;
            boolean isAnimation = false;

            while (!aborted) {
                int code;

                switch (code = input.read()) {
                  case EXBLOCK:
                    switch (code = input.read()) {
                      case EX_GRAPHICS_CONTROL: {
                        byte buf[] = new byte[6];
                        if (readBytes(buf, 0, 6) != 0) {
                            return;//error("corrupt GIF file");
                        }
                        if ((buf[0] != 4) || (buf[5] != 0)) {
                            return;//error("corrupt GIF file (GCE size)");
                        }
                        // Get the index of the transparent color
                        delay = ExtractWord(buf, 2) * 10;
                        if (delay > 0 && !isAnimation) {
                            isAnimation = true;
                            ImageFetcher.startingAnimation();
                        }
                        disposal_method = (buf[1] >> 2) & 7;
                        if ((buf[1] & TRANSPARENCYMASK) != 0) {
                            trans_pixel = ExtractByte(buf, 4);
                        } else {
                            trans_pixel = -1;
                        }
                        break;
                      }

                      case EX_COMMENT:
                      case EX_APPLICATION:
                      default:
                        boolean loop_tag = false;
                        String comment = "";
                        while (true) {
                            int n = input.read();
                            if (n <= 0) {
                                break;
                            }
                            byte buf[] = new byte[n];
                            if (readBytes(buf, 0, n) != 0) {
                                return;//error("corrupt GIF file");
                            }
                            if (code == EX_COMMENT) {
                                comment += new String(buf, 0);
                            } else if (code == EX_APPLICATION) {
                                if (loop_tag) {
                                    if (n == 3 && buf[0] == 1) {
                                        if (loopsRead) {
                                            ExtractWord(buf, 1);
                                        }
                                        else {
                                            nloops = ExtractWord(buf, 1);
                                            loopsRead = true;
                                        }
                                    } else {
                                        loop_tag = false;
                                    }
                                }
                                if ("NETSCAPE2.0".equals(new String(buf, 0))) {
                                    loop_tag = true;
                                }
                            }
                        }
                        if (code == EX_COMMENT) {
                            props.put("comment", comment);
                        }
                        if (loop_tag && !isAnimation) {
                            isAnimation = true;
                            ImageFetcher.startingAnimation();
                        }
                        break;

                      case -1:
                        return; //error("corrupt GIF file");
                    }
                    break;

                  case IMAGESEP:
                    if (!isAnimation) {
                        input.mark(0); // we don't need the mark buffer
                    }
                    try {
                        if (!readImage(totalframes == 0,
                                       disposal_method,
                                       delay)) {
                            return;
                        }
                    } catch (Exception e) {
                        if (verbose) {
                            e.printStackTrace();
                        }
                        return;
                    }
                    frameno++;
                    totalframes++;
                    break;

                  default:
                  case -1:
                    if (verbose) {
                        if (code == -1) {
                            System.err.println("Premature EOF in GIF file," +
                                               " frame " + frameno);
                        } else {
                            System.err.println("corrupt GIF file (parse) ["
                                               + code + "].");
                        }
                    }
                    if (frameno == 0) {
                        return;
                    }
                    // NOBREAK

                  case TERMINATOR:
                    if (nloops == 0 || nloops-- >= 0) {
                        try {
                            if (curframe != null) {
                                curframe.dispose();
                                curframe = null;
                            }
                            input.reset();
                            saved_image = null;
                            saved_model = null;
                            frameno = 0;
                            break;
                        } catch (IOException e) {
                            return; // Unable to reset input buffer
                        }
                    }
                    if (verbose && frameno != 1) {
                        System.out.println("processing GIF terminator,"
                                           + " frames: " + frameno
                                           + " total: " + totalframes);
                    }
                    imageComplete(ImageConsumer.STATICIMAGEDONE, true);
                    return;
                }
            }
        } finally {
            close();
        }
    }

    /**
     * Read Image header
     */
    private void readHeader() throws IOException, ImageFormatException {
        // Create a buffer
        byte buf[] = new byte[13];

        // Read the header
        if (readBytes(buf, 0, 13) != 0) {
            throw new IOException();
        }

        // Check header
        if ((buf[0] != 'G') || (buf[1] != 'I') || (buf[2] != 'F')) {
            error("not a GIF file.");
        }

        // Global width&height
        global_width = ExtractWord(buf, 6);
        global_height = ExtractWord(buf, 8);

        // colormap info
        int ch = ExtractByte(buf, 10);
        if ((ch & COLORMAPMASK) == 0) {
            // no global colormap so make up our own
            // If there is a local colormap, it will override what we
            // have here.  If there is not a local colormap, the rules
            // for GIF89 say that we can use whatever colormap we want.
            // This means that we should probably put in a full 256 colormap
            // at some point.  REMIND!
            num_global_colors = 2;
            global_bgpixel = 0;
            global_colormap = new byte[2*3];
            global_colormap[0] = global_colormap[1] = global_colormap[2] = (byte)0;
            global_colormap[3] = global_colormap[4] = global_colormap[5] = (byte)255;

        }
        else {
            num_global_colors = 1 << ((ch & 0x7) + 1);

            global_bgpixel = ExtractByte(buf, 11);

            if (buf[12] != 0) {
                props.put("aspectratio", ""+((ExtractByte(buf, 12) + 15) / 64.0));
            }

            // Read colors
            global_colormap = new byte[num_global_colors * 3];
            if (readBytes(global_colormap, 0, num_global_colors * 3) != 0) {
                throw new IOException();
            }
        }
        input.mark(Integer.MAX_VALUE); // set this mark in case this is an animated GIF
    }

    /**
     * The ImageConsumer hints flag for a non-interlaced GIF image.
     */
    private static final int normalflags =
        ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
        ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME;

    /**
     * The ImageConsumer hints flag for an interlaced GIF image.
     */
    private static final int interlaceflags =
        ImageConsumer.RANDOMPIXELORDER | ImageConsumer.COMPLETESCANLINES |
        ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME;

    private short prefix[]  = new short[4096];
    private byte  suffix[]  = new byte[4096];
    private byte  outCode[] = new byte[4097];

    private static native void initIDs();

    static {
        /* ensure that the necessary native libraries are loaded */
        NativeLibLoader.loadLibraries();
        initIDs();
    }

    private native boolean parseImage(int x, int y, int width, int height,
                                      boolean interlace, int initCodeSize,
                                      byte block[], byte rasline[],
                                      IndexColorModel model);

    private int sendPixels(int x, int y, int width, int height,
                           byte rasline[], ColorModel model) {
        int rasbeg, rasend, x2;
        if (y < 0) {
            height += y;
            y = 0;
        }
        if (y + height > global_height) {
            height = global_height - y;
        }
        if (height <= 0) {
            return 1;
        }
        // rasline[0]     == pixel at coordinate (x,y)
        // rasline[width] == pixel at coordinate (x+width, y)
        if (x < 0) {
            rasbeg = -x;
            width += x;         // same as (width -= rasbeg)
            x2 = 0;             // same as (x2     = x + rasbeg)
        } else {
            rasbeg = 0;
            // width -= 0;      // same as (width -= rasbeg)
            x2 = x;             // same as (x2     = x + rasbeg)
        }
        // rasline[rasbeg]          == pixel at coordinate (x2,y)
        // rasline[width]           == pixel at coordinate (x+width, y)
        // rasline[rasbeg + width]  == pixel at coordinate (x2+width, y)
        if (x2 + width > global_width) {
            width = global_width - x2;
        }
        if (width <= 0) {
            return 1;
        }
        rasend = rasbeg + width;
        // rasline[rasbeg] == pixel at coordinate (x2,y)
        // rasline[rasend] == pixel at coordinate (x2+width, y)
        int off = y * global_width + x2;
        boolean save = (curframe.disposal_method == GifFrame.DISPOSAL_SAVE);
        if (trans_pixel >= 0 && !curframe.initialframe) {
            if (saved_image != null && model.equals(saved_model)) {
                for (int i = rasbeg; i < rasend; i++, off++) {
                    byte pixel = rasline[i];
                    if ((pixel & 0xff) == trans_pixel) {
                        rasline[i] = saved_image[off];
                    } else if (save) {
                        saved_image[off] = pixel;
                    }
                }
            } else {
                // We have to do this the hard way - only transmit
                // the non-transparent sections of the line...
                // Fix for 6301050: the interlacing is ignored in this case
                // in order to avoid artefacts in case of animated images.
                int runstart = -1;
                int count = 1;
                for (int i = rasbeg; i < rasend; i++, off++) {
                    byte pixel = rasline[i];
                    if ((pixel & 0xff) == trans_pixel) {
                        if (runstart >= 0) {
                            count = setPixels(x + runstart, y,
                                              i - runstart, 1,
                                              model, rasline,
                                              runstart, 0);
                            if (count == 0) {
                                break;
                            }
                        }
                        runstart = -1;
                    } else {
                        if (runstart < 0) {
                            runstart = i;
                        }
                        if (save) {
                            saved_image[off] = pixel;
                        }
                    }
                }
                if (runstart >= 0) {
                    count = setPixels(x + runstart, y,
                                      rasend - runstart, 1,
                                      model, rasline,
                                      runstart, 0);
                }
                return count;
            }
        } else if (save) {
            System.arraycopy(rasline, rasbeg, saved_image, off, width);
        }
        int count = setPixels(x2, y, width, height, model,
                              rasline, rasbeg, 0);
        return count;
    }

    /**
     * Read Image data
     */
    private boolean readImage(boolean first, int disposal_method, int delay)
        throws IOException
    {
        if (curframe != null && !curframe.dispose()) {
            abort();
            return false;
        }

        long tm = 0;

        if (verbose) {
            tm = System.currentTimeMillis();
        }

        // Allocate the buffer
        byte block[] = new byte[256 + 3];

        // Read the image descriptor
        if (readBytes(block, 0, 10) != 0) {
            throw new IOException();
        }
        int x = ExtractWord(block, 0);
        int y = ExtractWord(block, 2);
        int width = ExtractWord(block, 4);
        int height = ExtractWord(block, 6);

        /*
         * Majority of gif images have
         * same logical screen and frame dimensions.
         * Also, Photoshop and Mozilla seem to use the logical
         * screen dimension (from the global stream header)
         * if frame dimension is invalid.
         *
         * We use similar heuristic and trying to recover
         * frame width from logical screen dimension and
         * frame offset.
         */
        if (width == 0 && global_width != 0) {
            width = global_width - x;
        }
        if (height == 0 && global_height != 0) {
            height = global_height - y;
        }

        boolean interlace = (block[8] & INTERLACEMASK) != 0;

        IndexColorModel model = global_model;

        if ((block[8] & COLORMAPMASK) != 0) {
            // We read one extra byte above so now when we must
            // transfer that byte as the first colormap byte
            // and manually read the code size when we are done
            int num_local_colors = 1 << ((block[8] & 0x7) + 1);

            // Read local colors
            byte[] local_colormap = new byte[num_local_colors * 3];
            local_colormap[0] = block[9];
            if (readBytes(local_colormap, 1, num_local_colors * 3 - 1) != 0) {
                throw new IOException();
            }

            // Now read the "real" code size byte which follows
            // the local color table
            if (readBytes(block, 9, 1) != 0) {
                throw new IOException();
            }
            if (trans_pixel >= num_local_colors) {
                // Fix for 4233748: extend colormap to contain transparent pixel
                num_local_colors = trans_pixel + 1;
                local_colormap = grow_colormap(local_colormap, num_local_colors);
            }
            model = new IndexColorModel(8, num_local_colors, local_colormap,
                                        0, false, trans_pixel);
        } else if (model == null
                   || trans_pixel != model.getTransparentPixel()) {
            if (trans_pixel >= num_global_colors) {
                // Fix for 4233748: extend colormap to contain transparent pixel
                num_global_colors = trans_pixel + 1;
                global_colormap = grow_colormap(global_colormap, num_global_colors);
            }
            model = new IndexColorModel(8, num_global_colors, global_colormap,
                                        0, false, trans_pixel);
            global_model = model;
        }

        // Notify the consumers
        if (first) {
            if (global_width == 0) global_width = width;
            if (global_height == 0) global_height = height;

            setDimensions(global_width, global_height);
            setProperties(props);
            setColorModel(model);
            headerComplete();
        }

        if (disposal_method == GifFrame.DISPOSAL_SAVE && saved_image == null) {
            saved_image = new byte[global_width * global_height];
            /*
             * If height of current image is smaller than the global height,
             * fill the gap with transparent pixels.
             */
            if ((height < global_height) && (model != null)) {
                byte tpix = (byte)model.getTransparentPixel();
                if (tpix >= 0) {
                    byte trans_rasline[] = new byte[global_width];
                    for (int i=0; i<global_width;i++) {
                        trans_rasline[i] = tpix;
                    }

                    setPixels(0, 0, global_width, y,
                              model, trans_rasline, 0, 0);
                    setPixels(0, y+height, global_width,
                              global_height-height-y, model, trans_rasline,
                              0, 0);
                }
            }
        }

        int hints = (interlace ? interlaceflags : normalflags);
        setHints(hints);

        curframe = new GifFrame(this, disposal_method, delay,
                                (curframe == null), model,
                                x, y, width, height);

        // allocate the raster data
        byte rasline[] = new byte[width];

        if (verbose) {
            System.out.print("Reading a " + width + " by " + height + " " +
                      (interlace ? "" : "non-") + "interlaced image...");
        }

        boolean ret = parseImage(x, y, width, height,
                                 interlace, ExtractByte(block, 9),
                                 block, rasline, model);

        if (!ret) {
            abort();
        }

        if (verbose) {
            System.out.println("done in "
                               + (System.currentTimeMillis() - tm)
                               + "ms");
        }

        return ret;
    }

    public static byte[] grow_colormap(byte[] colormap, int newlen) {
        byte[] newcm = new byte[newlen * 3];
        System.arraycopy(colormap, 0, newcm, 0, colormap.length);
        return newcm;
    }
}

class GifFrame {
    private static final boolean verbose = false;
    private static IndexColorModel trans_model;

    static final int DISPOSAL_NONE      = 0x00;
    static final int DISPOSAL_SAVE      = 0x01;
    static final int DISPOSAL_BGCOLOR   = 0x02;
    static final int DISPOSAL_PREVIOUS  = 0x03;

    GifImageDecoder decoder;

    int disposal_method;
    int delay;

    IndexColorModel model;

    int x;
    int y;
    int width;
    int height;

    boolean initialframe;

    public GifFrame(GifImageDecoder id, int dm, int dl, boolean init,
                    IndexColorModel cm, int x, int y, int w, int h) {
        this.decoder = id;
        this.disposal_method = dm;
        this.delay = dl;
        this.model = cm;
        this.initialframe = init;
        this.x = x;
        this.y = y;
        this.width = w;
        this.height = h;
    }

    private void setPixels(int x, int y, int w, int h,
                           ColorModel cm, byte[] pix, int off, int scan) {
        decoder.setPixels(x, y, w, h, cm, pix, off, scan);
    }

    public boolean dispose() {
        if (decoder.imageComplete(ImageConsumer.SINGLEFRAMEDONE, false) == 0) {
            return false;
        } else {
            if (delay > 0) {
                try {
                    if (verbose) {
                        System.out.println("sleeping: "+delay);
                    }
                    Thread.sleep(delay);
                } catch (InterruptedException e) {
                    return false;
                }
            } else {
                Thread.yield();
            }

            if (verbose && disposal_method != 0) {
                System.out.println("disposal method: "+disposal_method);
            }

            int global_width = decoder.global_width;
            int global_height = decoder.global_height;

            if (x < 0) {
                width += x;
                x = 0;
            }
            if (x + width > global_width) {
                width = global_width - x;
            }
            if (width <= 0) {
                disposal_method = DISPOSAL_NONE;
            } else {
                if (y < 0) {
                    height += y;
                    y = 0;
                }
                if (y + height > global_height) {
                    height = global_height - y;
                }
                if (height <= 0) {
                    disposal_method = DISPOSAL_NONE;
                }
            }

            switch (disposal_method) {
            case DISPOSAL_PREVIOUS:
                byte[] saved_image = decoder.saved_image;
                IndexColorModel saved_model = decoder.saved_model;
                if (saved_image != null) {
                    setPixels(x, y, width, height,
                              saved_model, saved_image,
                              y * global_width + x, global_width);
                }
                break;
            case DISPOSAL_BGCOLOR:
                byte tpix;
                if (model.getTransparentPixel() < 0) {
                    model = trans_model;
                    if (model == null) {
                        model = new IndexColorModel(8, 1,
                                                    new byte[4], 0, true);
                        trans_model = model;
                    }
                    tpix = 0;
                } else {
                    tpix = (byte) model.getTransparentPixel();
                }
                byte[] rasline = new byte[width];
                if (tpix != 0) {
                    for (int i = 0; i < width; i++) {
                        rasline[i] = tpix;
                    }
                }

                // clear saved_image using transparent pixels
                // this will be used as the background in the next display
                if( decoder.saved_image != null ) {
                    for( int i = 0; i < global_width * global_height; i ++ )
                        decoder.saved_image[i] = tpix;
                }

                setPixels(x, y, width, height, model, rasline, 0, 0);
                break;
            case DISPOSAL_SAVE:
                decoder.saved_model = model;
                break;
            }
        }
        return true;
    }
}
