/* PNGChunk.java -- Generic PNG chunk
   Copyright (C) 2006 Free Software Foundation

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.png;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
 * Class to load and validate a generic PNG chunk.
 */
public class PNGChunk
{

  /**
   * CRC table and initialization code.
   */
  private static long[] crcTable;

  static 
   {
     long c;
     crcTable = new long[256];
   
     for(int i = 0; i < 256; i++)
       {
	 c = i;
	 for(int j = 0; j < 8; j++) 
	   if( (c & 1) == 1 )
	     c = 0xEDB88320L ^ (c >> 1);
	   else
	     c = c >> 1;
	 crcTable[i] = c;
       }
   }

  /**
   * (recognized) PNG chunk types.
   */
  public static final int TYPE_HEADER = 0x49484452; // 'IHDR'
  public static final int TYPE_PALETTE = 0x504c5445;// 'PLTE'
  public static final int TYPE_DATA = 0x49444154;   // 'IDAT'
  public static final int TYPE_TIME = 0x74494d45;   // 'tIME'
  public static final int TYPE_END = 0x49454e44;    // 'IEND'
  public static final int TYPE_PHYS = 0x70485973;   // 'pHYS'
  public static final int TYPE_GAMMA = 0x67414d41;  // 'gAMA'
  public static final int TYPE_PROFILE = 0x69434350;  // 'iCCP'

  /**
   * The chunk type - Represented in the file as 4 ASCII bytes,
   */
  private int type;

  /**
   * The chunk data
   */
  protected byte[] data;
  
  /**
   * The chunk's crc
   */
  private int crc;

  /**
   * Constructor for reading a generic chunk.
   */
  protected PNGChunk( int type, byte[] data, int crc )
  {
    this.type = type;
    this.data = data;
    this.crc = crc;
  }

  /**
   * Constructor for creating new chunks. 
   * (only used by subclasses - creating a generic chunk is rather useless)
   */
  protected PNGChunk( int type )
  {
    this.type = type;
  }

  /**
   * Loads a chunk from an InputStream. Does not perform validation,
   * but will throw an IOException if the read fails.
   * @param in - th einputstream to read from
   * @param strict - if true, a PNGException is thrown on all invalid chunks,
   * if false, only critical chunks will throw PNGExceptions.
   */
  public static PNGChunk readChunk(InputStream in, boolean strict) 
    throws IOException, PNGException
  {
    byte data[] = new byte[4];
    if( in.read( data ) != 4 )
      throw new IOException("Could not read chunk length.");
    int length = ((data[0] & 0xFF) << 24) | ((data[1] & 0xFF) << 16 ) | 
      ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);

    if( in.read( data ) != 4 )
      throw new IOException("Could not read chunk type.");
    int type = ((data[0] & 0xFF) << 24) | ((data[1] & 0xFF) << 16 ) | 
      ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);

    byte[] chkdata = new byte[ length ];
    if( in.read( chkdata ) != length )
      throw new IOException("Could not read chunk data.");
    
    if( in.read( data ) != 4 )
      throw new IOException("Could not read chunk CRC.");
    
    int crc = ((data[0] & 0xFF) << 24) | ( (data[1] & 0xFF) << 16 ) | 
      ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);

    if( strict )
      return getChunk( type, chkdata, crc );
    else
      {
	try
	  {
	    return getChunk( type, chkdata, crc );
	  }
	catch(PNGException pnge)
	  {
	    if( isEssentialChunk( type ) )
	      throw pnge;
	    return null;
	  }
      }
  }

  /**
   * Returns a specialied object for a chunk, if we have one.
   */
  private static PNGChunk getChunk( int type, byte[] data, int crc )
    throws PNGException
  {
    switch( type )
      {
      case TYPE_HEADER:
	return new PNGHeader( type, data, crc );
      case TYPE_DATA:
	return new PNGData( type, data, crc );
      case TYPE_PALETTE:
	return new PNGPalette( type, data, crc );
      case TYPE_TIME:
	return new PNGTime( type, data, crc );
      case TYPE_PHYS:
	return new PNGPhys( type, data, crc );
      case TYPE_GAMMA:
	return new PNGGamma( type, data, crc );
      case TYPE_PROFILE:
	return new PNGICCProfile( type, data, crc );
      default:
	return new PNGChunk( type, data, crc );
      }
  }

  /**
   * Returns whether the chunk is essential or not
   */
  private static boolean isEssentialChunk( int type )
  {
    switch( type )
      {
      case TYPE_HEADER:
      case TYPE_DATA:
      case TYPE_PALETTE:
      case TYPE_END:
	return true;
      default:
	return false;
      }
  }

  /**
   * Validates the chunk
   */
  public boolean isValidChunk()
  {
    return (crc == calcCRC());
  }

  /**
   * Returns the chunk type.
   */
  public int getType()
  {
    return type;
  }

  /**
   * Writes a PNG chunk to an output stream, 
   * performing the CRC calculation as well.
   */
  public void writeChunk(OutputStream out) throws IOException
  {
    out.write( getInt(data.length) );
    out.write( getInt(type) );
    out.write( data );
    out.write( getInt(calcCRC()) );
  }

  /**
   * Return whether the chunk contains any data.
   */
  public boolean isEmpty()
  {
    return ( data.length == 0 );
  }

  /**
   * Convenience method. Cast an int to four bytes (big endian).
   * (Now why doesn't java have a simple way of doing this?)
   */
  public static byte[] getInt(int intValue)
  {
    long i = (intValue & 0xFFFFFFFFL);
    byte[] b = new byte[4];
    b[0] = (byte)((i & 0xFF000000L) >> 24);
    b[1] = (byte)((i & 0x00FF0000L) >> 16);
    b[2] = (byte)((i & 0x0000FF00L) >> 8);
    b[3] = (byte)(i & 0x000000FFL);
    return b;
  }

  /**
   * Calculates this chunk's CRC value.
   */
  private int calcCRC()
  {
    long c = 0xFFFFFFFFL;
    byte[] t = getInt( type );
    for(int i = 0; i < 4; i++)
      c = crcTable[ (int)((c ^ t[i]) & 0xFF) ] ^ (c >> 8);
      
    for(int i = 0; i < data.length; i++)
      c = crcTable[ (int)((c ^ data[i]) & 0xFF) ] ^ (c >> 8);

    return (int)(c ^ 0xFFFFFFFFL);
  }

  public String toString()
  {
    return "PNG Chunk. Type: " + new String( getInt(type) ) + " , CRC: " + 
      crc + " , calculated CRC: "+calcCRC();
  }
   
}
