/* GIFFile.java -- GIF decoder
   Copyright (C) 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.javax.imageio.gif;

import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;

/**
 * GIFFile - reads a GIF file.
 * 
 * This class only does the bare minimum work, and returns the data in raw
 * formats (described below). The class is J2ME compatible, and hopefully
 * we can keep it that way without any significant overhead.
 *
 * @author Sven de Marothy. 
 */
public class GIFFile 
{
  // "NETSCAPE2.0" - identifier
  private final static byte[] nsBlock = new byte[]
  {0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e, 0x30 };

  /**
   * Block identifiers
   */
  private final static int EXTENSION = 0x21;
  private final static int LOCAL = 0x2C;
  private final static int TERMINATOR = 0x3B;

  /**
   * Extension block types
   */
  private final static int EXTENSION_COMMENT = 254;
  private final static int EXTENSION_GCONTROL = 249; 
  private final static int EXTENSION_APPLICATION = 255;

  /**
   * Undraw commands for animation.
   */
  private final static int UNDRAW_OVERWRITE = 1;
  private final static int UNDRAW_RESTORE_BACKGROUND = 2;
  private final static int UNDRAW_RESTORE_PREVIOUS = 3; 

  /**
   * Image position and dimensions (images may be partial)
   */
  private int x, y, width, height;

  /**
   * Global dimensions
   */
  private int globalWidth, globalHeight;

  /**
   * Background color index.
   */
  private byte bgIndex;

  /**
   * Number of colors
   */
  private int nColors;

  /**
   * Global palette, if any
   */
  private byte[] globalPalette;

  /**
   * Any
   */
  private boolean hasGlobalColorMap;

  /**
   * Local palette, if any (used if available)
   */
  private byte[] localPalette;

  /**
   * Interlaced GIF or not?
   */
  private boolean interlaced;

  /**
   * Has transparency?
   */
  private boolean hasTransparency;
  
  /**
   * Undraw mode (animations)
   */
  private int undraw;

  /**
   * Transparent index;
   */
  private int transparentIndex;

  /**
   * The uncompressed raster
   */
  private byte[] raster;

  /**
   * The compressed data (freed after uncompressing)
   */
  private byte[] compressedData;

  /**
   * Frame delay in 100ths of a second ( centiseconds, metrically )
   */
  private int duration;

  /**
   * Indices used during decompression
   */
  private int dataBlockIndex;

  /**
   * The file comment , if a comment block exists.
   */
  private String comment;

  /**
   * Fields used by getBits()
   */
  private int remainingBits = 0;
  private int currentBits = 0;

  /**
   * Netscape animation extension
   */
  private boolean isLooped = false;

  /** Number of loops, 0 = infinite */
  private int loops;

  /**
   * Additional frames if it's an animated GIF.
   */
  private Vector animationFrames;

  /**
   * Loads the file from an input stream, which is not closed.
   * @throws IOException if an I/O error occured.
   * @throws GIFException if some file parsing error occured
   */
  public GIFFile(InputStream in) throws IOException, GIFException 
  {
    // Validate the signature
    if( !readSignature( in ) )
      throw new GIFException("Invalid GIF signature.");

    {
      byte[] data = new byte[7];
      if (in.read(data) != 7)
	throw new IOException("Couldn't read global descriptor.");

      globalWidth = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
      globalHeight = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
      byte flags = data[4];
      bgIndex = data[5];
      nColors = (1 << (( flags & 0x07) + 1));
      hasGlobalColorMap = ((flags & 0x80) != 0);
    }

    if( hasGlobalColorMap )
      {
	globalPalette = new byte[ nColors * 3 ];
	if( in.read( globalPalette ) != nColors * 3 )
	  throw new IOException("Couldn't read color map.");
      }
    
    int c = in.read();
    while( c == EXTENSION )
      {
	readExtension( in );
	c = in.read();
      }
      
    if( c != LOCAL )
      throw new GIFException("Extension blocks not followed by a local descriptor ("+c+")");

    loadImage( in );
    c = in.read(); 

    if( c == TERMINATOR ) // Not an animated GIF.
      return;

    // Load animation frames. Just quit if an error occurs instead 
    // of throwing an exception.
    animationFrames = new Vector();
    try 
      {
	while( c != TERMINATOR )
	  {
	    animationFrames.add( new GIFFile( this, in, c ) );
	    c = in.read(); 
	  }
      }
    catch(IOException ioe)
      {
      }
    catch(GIFException gife)
      {
      }
  }

  /**
   * Constructor for additional animation frames.
   */
  private GIFFile(GIFFile parent, InputStream in, int c) 
    throws IOException, GIFException 
  {
    // Copy global properties.
    globalWidth = parent.globalWidth;
    globalHeight = parent.globalHeight;
    nColors = parent.nColors;
    globalPalette = parent.globalPalette;
    hasGlobalColorMap = parent.hasGlobalColorMap;
    interlaced = parent.interlaced;
    comment = parent.comment;
    isLooped = parent.isLooped;
    loops = parent.loops;

    while( c == EXTENSION )
    {
      readExtension( in );      
      c = in.read();
    }
      
    if( c != LOCAL )
      throw new GIFException("Extension blocks not followed by a local descriptor ("+c+")");

    loadImage( in );
  }

  /**
   * Reads a GIF file signature from an inputstream and checks it.
   *
   * @param in - the stream (reads 6 bytes, does not close or reset).
   * @return true if the signature is a valid GIF signature.
   * @throws an IOException if the signature could not be read.
   */
  public static boolean readSignature( InputStream in ) throws IOException
  { 
    byte[] data = new byte[6];
    if (in.read(data) != 6)
      throw new IOException("Couldn't read signature.");

    if( data[0] != 0x47 || data[1] != 0x49 || data[2] != 0x46 ||
	data[3] != 0x38 ) // GIF8
      return false;

    if( (data[4] != 0x39 && data[4] != 0x37) || // 7 | 9
	(data[5] != 0x61 && data[5] != 0x62) ) // 'a' or 'b'
      return false;
    return true;
  }
  

  /**
   * Loads the image local descriptor and then loads/decodes the image raster,
   * and then performs any necessary postprocessing like deinterlacing.
   */
  private void loadImage(InputStream in)
    throws IOException, GIFException
  {
    readLocal( in );

    try
      {
	decodeRaster( in );
      }
    catch(ArrayIndexOutOfBoundsException aioobe)
      {
	throw new GIFException("Error decompressing image.");
      }
    
    if( interlaced )  // Clean up
      deinterlace();
    packPixels();
  }

  /**
   * Pack the pixels if it's a 2, 4 or 16 color image.
   * While GIF may support any number of colors from 2-256, we won't bother
   * trying to pack pixels not resulting in even byte boundaries.
   * (AWT doesn't support that anyway, and most apps do the same.)
   */
  private void packPixels()
  {
    if( nColors != 2 && nColors != 4 && nColors != 16 )
      return;

    int nbits = 1;
    int ppbyte = 8; 
    if( nColors == 4 )
      {
	nbits = 2;
	ppbyte = 4;
      }
    else if( nColors == 16 )
      {
	nbits = 4;
	ppbyte = 2;
      }

    int rem = (width & (ppbyte - 1));
    int w = ( rem == 0 ) ? (width / ppbyte) : 
      ((width + ppbyte - rem) / ppbyte); 
    byte[] nr = new byte[ w * height ];
    for(int j = 0; j < height; j++)
      {
	for(int i = 0; i < width - ppbyte; i += ppbyte)
	  for(int k = 0; k < ppbyte; k++)
	    nr[ j * w + (i / ppbyte) ] |= (byte)((raster[ width * j + i + k ]
						  << (8 - nbits * (1 + k))));
 	for(int i = 0; i < rem; i++)
 	  nr[ j * w + w - 1 ] |= (byte)((raster[ width * j + width - rem + i ]
					 << (nbits * (rem - i))));
      }
    raster = nr;
  }

  /**
   * Returns the (global) width
   */
  public int getWidth()
  {
    return width;
  }

  /**
   * Returns the image height
   */
  public int getHeight()
  {
    return height;
  }

  /**
   * Returns the # of colors.
   */
  public int getNColors()
  {
    return nColors;
  }

  /**
   * Returns whether the GIF has transparency.
   */
  public boolean hasTransparency()
  {
    return hasTransparency;
  }

  /**
   * Returns the index of the transparent color.
   */
  public int getTransparentIndex()
  {
    return transparentIndex;
  }

  /**
   * Retuns the GIF file comment, or null if none exists.
   */
  public String getComment()
  {
    return comment;
  }

  /**
   * Get duration of the frame for animations.
   */
  public int getDuration()
  {
    return duration;
  }

  /**
   * Deinterlaces the image.
   */
  private void deinterlace()
  {
    byte[] nr = new byte[ width * height ];
    int n = 0;
    for(int i = 0; i < ((height + 7) >> 3); i++)
      {
	System.arraycopy( raster, n, nr, width * i * 8, width );
	n += width;
      }
    for(int i = 0; i < ((height + 3) >> 3); i++)
      {
	System.arraycopy( raster, n, nr, width * ( 8 * i + 4 ), width );
	n += width;
      }
    for(int i = 0; i < (height >> 2); i++)
      {
	System.arraycopy( raster, n, nr, width * (4 * i + 2), width );
	n += width;
      }
    for(int i = 0; i < (height >> 1); i++)
      {
	System.arraycopy( raster, n, nr, width * (2 * i + 1), width );
	n += width;
      }
    raster = nr;
  }

  /**
   * Reads the local descriptor
   */
  private void readLocal(InputStream in) throws IOException
  {
    byte[] data = new byte[9];
    if (in.read(data) != 9)
      throw new IOException("Couldn't read local descriptor.");
    x = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
    y = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
    width = ((data[5] & 0xFF) << 8) | (data[4] & 0xFF);
    height = ((data[7] & 0xFF) << 8) | (data[6] & 0xFF);
    byte flags = data[8];
    interlaced = (( flags & 0x40 ) != 0);
    if( (flags & 0x80) != 0 )
      { // has a local color map
	int nLocalColors = (1 << (( flags & 0x07) + 1));
	if( !hasGlobalColorMap )
	  nColors = nLocalColors;
	localPalette = new byte[ nLocalColors * 3 ];
	if( in.read( localPalette ) != nLocalColors * 3 )
	  throw new IOException("Couldn't read color map.");
      }
  }   

  /**
   * Returns the image's palette in raw format 
   * (r0,g0,b0,r1,g1,b2..r(Ncolors-1),g(Ncolors-1),b(Ncolors-1))
   */
  public byte[] getRawPalette()
  {
    return hasGlobalColorMap ? globalPalette : localPalette;
  }

  /**
   * Returns the image file for animated gifs.
   */
  public GIFFile getImage( int index )
  {
    if( index == 0 )
      return this;
    if( animationFrames == null )
      throw new ArrayIndexOutOfBoundsException("Only one image in file");
    return (GIFFile)animationFrames.elementAt( index - 1 );
  }

  /**
   * Return the image's raw image data.
   * If the color depth is 1,2 or 4 bits per pixel the pixels are packed
   * and the scanlines padded up to the nearest byte if needed.
   */
  public byte[] getRawImage()
  {
    return raster;
  }

  /**
   * Return the number of images in the GIF file
   */
  public int nImages()
  {
    if( animationFrames != null )
      return 1 + animationFrames.size();
    return 1;
  }

  /**
   * Handles extension blocks.
   */
  private void readExtension(InputStream in) throws IOException, GIFException 
  {
    int functionCode = in.read();
    byte[] data = readData(in);
    switch( functionCode )
      {
      case EXTENSION_COMMENT: // comment block
	comment = new String(data, "8859_1");
	break;

      case EXTENSION_GCONTROL: // Graphics control extension
	undraw = (data[0] & 0x1C) >> 2;
	// allegedly there can be bad values of this.
	if( undraw < 1 && undraw > 3 ) undraw = 1; 
	hasTransparency = ((data[0] & 0x01) == 1);
	transparentIndex = (data[3] & 0xFF);
	duration = ((data[2] & 0xFF) << 8) | (data[1] & 0xFF);
	break;

	// Application extension. We only parse the Netscape animation
	// extension here. Which is the only one most use anyway.
      case EXTENSION_APPLICATION:
	boolean isNS = true;
	for(int i = 0; i < nsBlock.length; i++ )
	  if( nsBlock[i] != data[i] )
	    isNS = false;
	if( isNS )
	  {
	    isLooped = true;
	    loops = ((data[12] & 0xFF) << 8) | (data[13] & 0xFF);
	  }
	break;

      default:
	break;
      }
  }

  /**
   * Reads a series of data blocks and merges them into a single one.
   */
  private byte[] readData(InputStream in) throws IOException
  {
    Vector v = new Vector();
    int totalBytes = 0;

    int n = in.read();
    do
      {
	totalBytes += n;
	byte[] block = new byte[ n ];
	in.read(block);
	v.add(block);
	n = in.read();
      }
    while( n > 0 );

    n = 0;
    byte[] bigBuffer = new byte[ totalBytes ];
    for( int i = 0; i < v.size(); i++ )
      {
	byte[] block = (byte[])v.elementAt(i);
	System.arraycopy(block, 0, bigBuffer, n, block.length);
	n += block.length;
      }
    return bigBuffer;
  }

  /**
   * Loads a compressed image block and decompresses it.
   */
  private void decodeRaster(InputStream in) throws IOException
  {
    int initialCodeSize = in.read();
    compressedData = readData( in );
    dataBlockIndex = 0;

    int rasterIndex = 0; // Index into the raster
    int clearCode = (1 << initialCodeSize); // 256 usually
    int endCode = clearCode + 1; // The stop code.

    raster = new byte[ width * height ];

    int codeSize = initialCodeSize + 1;
    int code = getBits( codeSize ); // = clear
    int nextCode = endCode + 1;

    /*
     * Initialize LZW dictionary
     *
     * First index - code #
     * Second index:
     * 0 = color index
     * 1 = parent (-1 - no parent)
     * 2 = first value
     * 3 - depth
     * The latter two aren't strictly necessary but make things faster, since
     * copying the values forward is faster than going back and looking.
     */
    short[][] dictionary = new short[ 4096 ][ 4 ];

    for(short i = 0; i < nColors; i ++ )
      {
	dictionary[i][0] = i;  // color index	
	dictionary[i][1] = -1; // parent
	dictionary[i][2] = i;  // first	
	dictionary[i][3] = 1;  // depth
      }

    code = getBits( codeSize ); // get second code
    raster[ rasterIndex++ ] = (byte)dictionary[code][0];
    int old = code;    
    code = getBits( codeSize ); // start at the third code
    int c;

    do
      {
	if( code == clearCode )
	  {
	    codeSize = initialCodeSize + 1;
 	    nextCode = endCode + 1; 
	    // get and output second code
	    code = getBits( codeSize ); 
	    raster[ rasterIndex++ ] = (byte)dictionary[code][0];
	    old = code;
	  }
	else
	  {
	    dictionary[nextCode][1] = (short)old; // parent = old
	    dictionary[nextCode][2] = dictionary[old][2]; // first pixel
	    dictionary[nextCode][3] = (short)(dictionary[old][3] + 1); // depth
	
	    // appended pixel  = first pixel of c
	    if( code < nextCode )
	      {
		dictionary[nextCode][0] = dictionary[code][2]; 
		old = code;
	      }
	    else // first of old
	      {
		dictionary[nextCode][0] = dictionary[old][2]; 
		old = nextCode;
	      }

	    c = old;
	    // output the code c
	    int depth = dictionary[c][3];
	    for( int i = depth - 1; i >= 0; i-- )
	      {
		raster[ rasterIndex + i ] = (byte)dictionary[c][0];
		c = dictionary[c][1]; // go to parent.
	      }
	    rasterIndex += depth;
	    nextCode ++;

	    if( codeSize < 12 && nextCode >= (1 << codeSize) )
	      codeSize++;
	  }
	code = getBits( codeSize );
      }
    while( code != endCode && dataBlockIndex < compressedData.length );
    
    compressedData = null; // throw away compressed data.
  }

  /**
   * Returns nbits number of bits (in the LSBs) from compressedData
   */
  private int getBits( int nbits )
  {
    while( nbits > remainingBits )
      {
	int c = (compressedData[ dataBlockIndex++ ] & 0xFF) << remainingBits;
	currentBits |= c;
	remainingBits += 8;
      }
    int rval = (currentBits & ((1 << nbits) - 1));
    currentBits = (currentBits >> nbits);
    remainingBits -= nbits;
    return rval;
  }

  /**
   * Generic exception used by GIFFile to report decoding errors.
   */
  public static class GIFException extends Exception 
  {
    public GIFException(String message)
    {
      super(message);
    }
  }
}
