/* IndexColorModel.java -- Java class for interpreting Pixel objects
   Copyright (C) 1999 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 java.awt.image;

import java.awt.color.ColorSpace;
import java.math.BigInteger;

/**
 * Color model similar to pseudo visual in X11.
 *
 * This color model maps linear pixel values to actual RGB and alpha colors.
 * Thus, pixel values are indexes into the color map.  Each color component is
 * an 8-bit unsigned value.
 *
 * The IndexColorModel supports a map of valid pixels, allowing the
 * representation of holes in the the color map.  The valid map is represented
 * as a BigInteger where each bit indicates the validity of the map entry with
 * the same index.
 * 
 * Colors can have alpha components for transparency support.  If alpha
 * component values aren't given, color values are opaque.  The model also
 * supports a reserved pixel value to represent completely transparent colors,
 * no matter what the actual color component values are.
 *
 * IndexColorModel supports anywhere from 1 to 16 bit index values.  The
 * allowed transfer types are DataBuffer.TYPE_BYTE and DataBuffer.TYPE_USHORT.
 *
 * @author C. Brian Jones (cbj@gnu.org) 
 */
public class IndexColorModel extends ColorModel
{
  private int map_size;
  private boolean opaque;
  private int trans = -1;
  private int[] rgb;
  private BigInteger validBits = BigInteger.ZERO;

  /**
   * Each array much contain <code>size</code> elements.  For each 
   * array, the i-th color is described by reds[i], greens[i], 
   * blues[i], alphas[i], unless alphas is not specified, then all the 
   * colors are opaque except for the transparent color. 
   *
   * @param bits the number of bits needed to represent <code>size</code> colors
   * @param size the number of colors in the color map
   * @param reds the red component of all colors
   * @param greens the green component of all colors
   * @param blues the blue component of all colors
   */
  public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
                         byte[] blues)
  {
    this (bits, size, reds, greens, blues, (byte[]) null);
  }

  /**
   * Each array much contain <code>size</code> elements.  For each 
   * array, the i-th color is described by reds[i], greens[i], 
   * blues[i], alphas[i], unless alphas is not specified, then all the 
   * colors are opaque except for the transparent color. 
   *
   * @param bits the number of bits needed to represent <code>size</code> colors
   * @param size the number of colors in the color map
   * @param reds the red component of all colors
   * @param greens the green component of all colors
   * @param blues the blue component of all colors
   * @param trans the index of the transparent color
   */
  public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
                         byte[] blues, int trans)
  {
    this (bits, size, reds, greens, blues, (byte[]) null);
    this.trans = trans;
  }

  /**
   * Each array much contain <code>size</code> elements.  For each 
   * array, the i-th color is described by reds[i], greens[i], 
   * blues[i], alphas[i], unless alphas is not specified, then all the 
   * colors are opaque except for the transparent color. 
   *
   * @param bits the number of bits needed to represent <code>size</code> colors
   * @param size the number of colors in the color map
   * @param reds the red component of all colors
   * @param greens the green component of all colors
   * @param blues the blue component of all colors
   * @param alphas the alpha component of all colors
   */
  public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
                         byte[] blues, byte[] alphas)
  {
    // FIXME: This super() constructor should not be used since it can give
    // the wrong value for hasAlpha() which is final and cannot be overloaded
    super(bits); 
    map_size = size;
    opaque = (alphas == null);

    rgb = new int[size];
    if (alphas == null)
      {
        for (int i = 0; i < size; i++)
          {
            rgb[i] = (0xff000000
                      | ((reds[i] & 0xff) << 16)
                      | ((greens[i] & 0xff) << 8)
                      | (blues[i] & 0xff));
          }
      }
    else
      {
        for (int i = 0; i < size; i++)
          {
            rgb[i] = ((alphas[i] & 0xff) << 24
                      | ((reds[i] & 0xff) << 16)
                      | ((greens[i] & 0xff) << 8)
                      | (blues[i] & 0xff));
          }
      }

    // Generate a bigint with 1's for every pixel
    validBits = validBits.setBit(size).subtract(BigInteger.ONE);
  }

  /**
   * Each array much contain <code>size</code> elements.  For each 
   * array, the i-th color is described by reds[i], greens[i], 
   * blues[i], alphas[i], unless alphas is not specified, then all the 
   * colors are opaque except for the transparent color. 
   *
   * @param bits the number of bits needed to represent <code>size</code> colors
   * @param size the number of colors in the color map
   * @param cmap packed color components
   * @param start the offset of the first color component in <code>cmap</code>
   * @param hasAlpha <code>cmap</code> has alpha values
   * @throws IllegalArgumentException if bits < 1, bits > 16, or size < 1.
   */
  public IndexColorModel (int bits, int size, byte[] cmap, int start, 
                          boolean hasAlpha)
  {
    this (bits, size, cmap, start, hasAlpha, -1);
  }

  /**
   * Construct an IndexColorModel from an array of red, green, blue, and
   * optional alpha components.  The component values are interleaved as RGB(A).
   * 
   * @param bits the number of bits needed to represent <code>size</code> colors
   * @param size the number of colors in the color map
   * @param cmap interleaved color components
   * @param start the offset of the first color component in <code>cmap</code>
   * @param hasAlpha <code>cmap</code> has alpha values
   * @param trans the index of the transparent color
   * @throws IllegalArgumentException if bits < 1, bits > 16, or size < 1.
   */
  public IndexColorModel (int bits, int size, byte[] cmap, int start, 
                          boolean hasAlpha, int trans)
  {
    super (bits);
    if (bits > 16)
      throw new IllegalArgumentException("bits > 16");
    if (size < 1)
      throw new IllegalArgumentException("size < 1");
    map_size = size;
    opaque = !hasAlpha;
    this.trans = trans;

    rgb = new int[size];
    if (hasAlpha)
    {
      for (int i = 0; i < size; i++)
        rgb[i] =
	  // alpha
	  ((cmap[4 * i + 3 + start] & 0xff) << 24
	   // red
	   | ((cmap[4 * i + start] & 0xff) << 16)
	   // green
	   | ((cmap[4 * i + 1 + start] & 0xff) << 8)
	   // blue
	   | (cmap[4 * i + 2 + start] & 0xff));
    }
    else
    {
      for (int i = 0; i < size; i++)
	rgb[i] = (0xff000000
		  // red
		  | ((cmap[3 * i + start] & 0xff) << 16)
		  // green
		  | ((cmap[3 * i + 1 + start] & 0xff) << 8)
		  // blue
		  | (cmap[3 * i + 2 + start] & 0xff));
    }

    // Generate a bigint with 1's for every pixel
    validBits = validBits.setBit(size).subtract(BigInteger.ONE);
  }

  /**
   * Construct an IndexColorModel from an array of <code>size</code> packed
   * colors.  Each int element contains 8-bit red, green, blue, and optional
   * alpha values packed in order.  If hasAlpha is false, then all the colors
   * are opaque except for the transparent color.
   *
   * @param bits the number of bits needed to represent <code>size</code> colors
   * @param size the number of colors in the color map
   * @param cmap packed color components
   * @param start the offset of the first color component in <code>cmap</code>
   * @param hasAlpha <code>cmap</code> has alpha values
   * @param trans the index of the transparent color
   * @param transferType DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
   * @throws IllegalArgumentException if bits < 1, bits > 16, or size < 1.
   * @throws IllegalArgumentException if transferType is something other than
   * TYPE_BYTE or TYPE_USHORT.
   */
  public IndexColorModel (int bits, int size, int[] cmap, int start, 
                          boolean hasAlpha, int trans, int transferType)
  {
    super(bits * 4, // total bits, sRGB, four channels
	  nArray(bits, 4), // bits for each channel
	  ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
	  true, // has alpha
	  false, // not premultiplied
	  TRANSLUCENT, transferType);
    if (transferType != DataBuffer.TYPE_BYTE
        && transferType != DataBuffer.TYPE_USHORT)
      throw new IllegalArgumentException();
    if (bits > 16)
      throw new IllegalArgumentException("bits > 16");
    if (size < 1)
      throw new IllegalArgumentException("size < 1");
    map_size = size;
    opaque = !hasAlpha;
    this.trans = trans;

    rgb = new int[size];
    if (!hasAlpha)
      for (int i = 0; i < size; i++)
	rgb[i] = cmap[i + start] | 0xff000000;
    else
      System.arraycopy(cmap, start, rgb, 0, size);

    // Generate a bigint with 1's for every pixel
    validBits = validBits.setBit(size).subtract(BigInteger.ONE);
  }

  /**
   * Construct an IndexColorModel using a colormap with holes.
   * 
   * The IndexColorModel is built from the array of ints defining the
   * colormap.  Each element contains red, green, blue, and alpha
   * components.    The ColorSpace is sRGB.  The transparency value is
   * automatically determined.
   * 
   * This constructor permits indicating which colormap entries are valid,
   * using the validBits argument.  Each entry in cmap is valid if the
   * corresponding bit in validBits is set.  
   * 
   * @param bits the number of bits needed to represent <code>size</code> colors
   * @param size the number of colors in the color map
   * @param cmap packed color components
   * @param start the offset of the first color component in <code>cmap</code>
   * @param transferType DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
   * @throws IllegalArgumentException if bits < 1, bits > 16, or size < 1.
   * @throws IllegalArgumentException if transferType is something other than
   * TYPE_BYTE or TYPE_USHORT.
   */
  public IndexColorModel (int bits, int size, int[] cmap, int start, 
                          int transferType, BigInteger validBits)
  {
    super(bits * 4, // total bits, sRGB, four channels
	  nArray(bits, 4), // bits for each channel
	  ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
	  true, // has alpha
	  false, // not premultiplied
	  TRANSLUCENT, transferType);
    if (transferType != DataBuffer.TYPE_BYTE
        && transferType != DataBuffer.TYPE_USHORT)
      throw new IllegalArgumentException();
    if (bits > 16)
      throw new IllegalArgumentException("bits > 16");
    if (size < 1)
      throw new IllegalArgumentException("size < 1");
    map_size = size;
    opaque = false;
    this.trans = -1;
    this.validBits = validBits;

    rgb = new int[size];
    if (!hasAlpha)
      for (int i = 0; i < size; i++)
	rgb[i] = cmap[i + start] | 0xff000000;
    else
      System.arraycopy(cmap, start, rgb, 0, size);
  }

  public final int getMapSize ()
  {
    return map_size;
  }

  /**
   * Get the index of the transparent color in this color model
   */
  public final int getTransparentPixel ()
  {
    return trans;
  }

  /**
   * <br>
   */
  public final void getReds (byte[] r)
  {
    getComponents (r, 2);
  }

  /**
   * <br>
   */
  public final void getGreens (byte[] g)
  {
    getComponents (g, 1);
  }

  /**
   * <br>
   */
  public final void getBlues (byte[] b)
  {
    getComponents (b, 0);
  }

  /**
   * <br>
   */
  public final void getAlphas (byte[] a)
  {
    getComponents (a, 3);
  }

  private void getComponents (byte[] c, int ci)
  {
    int i, max = (map_size < c.length) ? map_size : c.length;
    for (i = 0; i < max; i++)
	    c[i] = (byte) ((generateMask (ci)  & rgb[i]) >> (ci * pixel_bits));
  } 

  /**
   * Get the red component of the given pixel.
   */
  public final int getRed (int pixel)
  {
    if (pixel < map_size)
	    return (int) ((generateMask (2) & rgb[pixel]) >> (2 * pixel_bits));
    
    return 0;
  }

  /**
   * Get the green component of the given pixel.
   */
  public final int getGreen (int pixel)
  {
    if (pixel < map_size)
	    return (int) ((generateMask (1) & rgb[pixel]) >> (1 * pixel_bits));
    
    return 0;
  }

  /**
   * Get the blue component of the given pixel.
   */
  public final int getBlue (int pixel)
  {
    if (pixel < map_size) 
	    return (int) (generateMask (0) & rgb[pixel]);
    
    return 0;
  }

  /**
   * Get the alpha component of the given pixel.
   */
  public final int getAlpha (int pixel)
  {
    if (opaque || pixel >= map_size)
      return 255;

    return (int) ((generateMask (3) & rgb[pixel]) >> (3 * pixel_bits));
  }

  /**
   * Get the RGB color value of the given pixel using the default
   * RGB color model. 
   *
   * @param pixel a pixel value
   */
  public final int getRGB (int pixel)
  {
    if (pixel < map_size)
	    return rgb[pixel];
    
    return 0;
  }
    
  /**
   * Get the RGB color values of all pixels in the map using the default
   * RGB color model. 
   *
   * @param rgb The destination array.
   */
  public final void getRGBs (int[] rgb)
  {
    System.arraycopy(this.rgb, 0, rgb, 0, map_size);
  }
    
   //pixel_bits is number of bits to be in generated mask
  private int generateMask (int offset)
  {
    return (((2 << pixel_bits ) - 1) << (pixel_bits * offset));
  }

  /** Return true if pixel is valid, false otherwise. */
  public boolean isValid(int pixel)
  {
    return validBits.testBit(pixel);
  }
  
  /** Return true if all pixels are valid, false otherwise. */
  public boolean isValid()
  {
    // Generate a bigint with 1's for every pixel
    BigInteger allbits = new BigInteger("0");
    allbits.setBit(map_size);
    allbits.subtract(new BigInteger("1"));
    return allbits.equals(validBits);
  }
  
  /** 
   * Returns a BigInteger where each bit represents an entry in the color
   * model.  If the bit is on, the entry is valid.
   */
  public BigInteger getValidPixels()
  {
    return validBits;
  }
  
  /**
   * Construct a BufferedImage with rgb pixel values from a Raster.
   * 
   * Constructs a new BufferedImage in which each pixel is an RGBA int from
   * a Raster with index-valued pixels.  If this model has no alpha component
   * or transparent pixel, the type of the new BufferedImage is TYPE_INT_RGB.
   * Otherwise the type is TYPE_INT_ARGB.  If forceARGB is true, the type is
   * forced to be TYPE_INT_ARGB no matter what.
   * 
   * @param raster The source of pixel values.
   * @param forceARGB True if type must be TYPE_INT_ARGB.
   * @return New BufferedImage with RBGA int pixel values.
   */
  public BufferedImage convertToIntDiscrete(Raster raster, boolean forceARGB)
  {
    int type = forceARGB ? BufferedImage.TYPE_INT_ARGB
      : ((opaque && trans == -1) ? BufferedImage.TYPE_INT_RGB :
	 BufferedImage.TYPE_INT_ARGB); 

    // FIXME: assuming that raster has only 1 band since pixels are supposed
    // to be int indexes.
    // FIXME: it would likely be more efficient to fetch a complete array,
    // but it would take much more memory.
    // FIXME: I'm not sure if transparent pixels or alpha values need special
    // handling here.
    BufferedImage im = new BufferedImage(raster.width, raster.height, type);
    for (int x = raster.minX; x < raster.width + raster.minX; x++)
      for (int y = raster.minY; y < raster.height + raster.minY; y++)
        im.setRGB(x, y, rgb[raster.getSample(x, y, 0)]);

    return im;
  }
}

