/* DirectColorModel.java --
   Copyright (C) 1999, 2000, 2002, 2004  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 java.awt.image;

import gnu.java.awt.Buffers;

import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;

/**
 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
 * @author C. Brian Jones (cbj@gnu.org)
 * @author Mark Benvenuto (mcb54@columbia.edu)
 */
public class DirectColorModel extends PackedColorModel
{
  /**
   * For the color model created with this constructor the pixels
   * will have fully opaque alpha components with a value of 255.
   * Each mask should describe a fully contiguous set of bits in the
   * most likely order of alpha, red, green, blue from the most significant
   * byte to the least significant byte.
   * 
   * @param pixelBits the number of bits wide used for bit size of pixel values
   * @param rmask the bits describing the red component of a pixel
   * @param gmask the bits describing the green component of a pixel
   * @param bmask the bits describing the blue component of a pixel 
   */
  public DirectColorModel(int pixelBits, int rmask, int gmask, int bmask)
  {
    this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
	 rmask, gmask, bmask, 0, 
	 false, // not alpha premultiplied
	 Buffers.smallestAppropriateTransferType(pixelBits) // find type
	 );
  }

  /**
   * For the color model created with this constructor the pixels
   * will have fully opaque alpha components with a value of 255.
   * Each mask should describe a fully contiguous set of bits in the
   * most likely order of red, green, blue from the most significant
   * byte to the least significant byte.
   * 
   * @param pixelBits the number of bits wide used for bit size of pixel values
   * @param rmask the bits describing the red component of a pixel
   * @param gmask the bits describing the green component of a pixel
   * @param bmask the bits describing the blue component of a pixel 
   * @param amask the bits describing the alpha component of a pixel 
   */
  public DirectColorModel(int pixelBits,
			  int rmask, int gmask, int bmask, int amask)
  {
    this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
	 rmask, gmask, bmask, amask,
	 false, // not alpha premultiplied
	 Buffers.smallestAppropriateTransferType(pixelBits) // find type
	 );
  }

  public DirectColorModel(ColorSpace cspace, int pixelBits,
			  int rmask, int gmask, int bmask, int amask,
			  boolean isAlphaPremultiplied,
			  int transferType)
  {
    super(cspace, pixelBits,
	  rmask, gmask, bmask, amask, isAlphaPremultiplied,
	  ((amask == 0) ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
	  transferType);
  }
    
  public final int getRedMask()
  {
    return getMask(0);
  }

  public final int getGreenMask()
  {
    return getMask(1);
  }

  public final int getBlueMask()
  {
    return getMask(2);
  }

  public final int getAlphaMask()
  {
    return hasAlpha() ? getMask(3) : 0;
  }

  /**
   * Get the red component of the given pixel.
   * <br>
   */
  public final int getRed(int pixel)
  {
    return extractAndNormalizeSample(pixel, 0);
  }

  /**
   * Get the green component of the given pixel.
   * <br>
   */
  public final int getGreen(int pixel)
  {
    return extractAndNormalizeSample(pixel, 1);
  }
  
  /**
   * Get the blue component of the given pixel.
   * <br>
   */
  public final int getBlue(int pixel)
  {
    return extractAndNormalizeSample(pixel, 2);
  }

  /**
   * Get the alpha component of the given pixel.
   * <br>
   */
  public final int getAlpha(int pixel)
  {
    if (!hasAlpha())
      return 255;
    return extractAndScaleSample(pixel, 3);
  }

  private int extractAndNormalizeSample(int pixel, int component)
  {
    int value = extractAndScaleSample(pixel, component);
    if (hasAlpha() && isAlphaPremultiplied() && getAlpha(pixel) != 0)
      value = value*255/getAlpha(pixel);
    return value;
  }

  private int extractAndScaleSample(int pixel, int component)
  {
    int field = pixel & getMask(component);
    int to8BitShift =
      8 - shifts[component] - getComponentSize(component);
    return (to8BitShift>0) ?
      (field << to8BitShift) :
      (field >>> (-to8BitShift));
  }

  /**
   * Get the RGB color value of the given pixel using the default
   * RGB color model. 
   * <br>
   *
   * @param pixel a pixel value
   */
  public final int getRGB(int pixel) 
  {
    /* FIXME: The Sun docs show that this method is overridden, but I
       don't see any way to improve on the superclass
       implementation. */
    return super.getRGB(pixel);
  }

  public int getRed(Object inData)
  {
    return getRed(getPixelFromArray(inData));
  }

  public int getGreen(Object inData)
  {
    return getGreen(getPixelFromArray(inData));
  }

  public int getBlue(Object inData)
  {
    return getBlue(getPixelFromArray(inData));
  }
    
  public int getAlpha(Object inData)
  {
    return getAlpha(getPixelFromArray(inData));
  }

  public int getRGB(Object inData)
  {
    return getRGB(getPixelFromArray(inData));
  }
    
  /**
   * Converts a normalized pixel int value in the sRGB color
   * space to an array containing a single pixel of the color space
   * of the color model.
   *
   * <p>This method performs the inverse function of
   * <code>getRGB(Object inData)</code>.
   *
   * @param rgb pixel as a normalized sRGB, 0xAARRGGBB value.
   *  
   * @param pixel to avoid needless creation of arrays, an array to
   * use to return the pixel can be given. If null, a suitable array
   * will be created.
   *
   * @return array of transferType containing a single pixel. The
   * pixel should be encoded in the natural way of the color model.
   *
   * @see #getRGB(Object)
   */
  public Object getDataElements(int rgb, Object pixel)
  {
    // FIXME: handle alpha multiply
    
    int pixelValue = 0;
    int a = 0;
    if (hasAlpha()) {
      a = (rgb >>> 24) & 0xff;
      pixelValue = valueToField(a, 3, 8);
    }
	
    if (hasAlpha() && isAlphaPremultiplied())
      {
	int r, g, b;
	/* if r=0xff and a=0xff, then resulting
	   value will be (r*a)>>>8 == 0xfe... This seems wrong.
	   We should divide by 255 rather than shifting >>>8 after
	   multiplying.
	   
	   Too bad, shifting is probably less expensive.
	   r = ((rgb >>> 16) & 0xff)*a;
	   g = ((rgb >>>  8) & 0xff)*a;
	   b = ((rgb >>> 0) & 0xff)*a; */
	/* The r, g, b values we calculate are 16 bit. This allows
	   us to avoid discarding the lower 8 bits obtained if
	   multiplying with the alpha band. */
	
	// using 16 bit values
	r = ((rgb >>> 8) & 0xff00)*a/255;
	g = ((rgb >>> 0) & 0xff00)*a/255;
	b = ((rgb <<  8) & 0xff00)*a/255;
	pixelValue |= 
	  valueToField(r, 0, 16) |  // Red
	  valueToField(g, 1, 16) |  // Green
	  valueToField(b, 2, 16);   // Blue
      }
    else
      {
	int r, g, b;
	// using 8 bit values
	r = (rgb >>> 16) & 0xff;
	g = (rgb >>>  8) & 0xff;
	b = (rgb >>>  0) & 0xff;
	
	pixelValue |= 
	  valueToField(r, 0, 8) |  // Red
	  valueToField(g, 1, 8) |  // Green
	  valueToField(b, 2, 8);   // Blue
      }
    
    /* In this color model, the whole pixel fits in the first element
       of the array. */
    DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1);
    buffer.setElem(0, pixelValue);
    return Buffers.getData(buffer);
  }
    
  /**
   * Converts a value to the correct field bits based on the
   * information derived from the field masks.
   *
   * @param highBit the position of the most significant bit in the
   * val parameter.
   */
  private int valueToField(int val, int component, int highBit)
  {
    int toFieldShift = 
      getComponentSize(component) + shifts[component] - highBit;
    int ret = (toFieldShift>0) ?
      (val << toFieldShift) :
      (val >>> (-toFieldShift));
    return ret & getMask(component);
  }  

  /**
   * Converts a 16 bit value to the correct field bits based on the
   * information derived from the field masks.
   */
  private int value16ToField(int val, int component)
  {
    int toFieldShift = getComponentSize(component) + shifts[component] - 16;
    return (toFieldShift>0) ?
      (val << toFieldShift) :
      (val >>> (-toFieldShift));
  }

  /**
   * Fills an array with the unnormalized component samples from a
   * pixel value. I.e. decompose the pixel, but not perform any
   * color conversion.
   */
  public final int[] getComponents(int pixel, int[] components, int offset)
  {
    int numComponents = getNumComponents();
    if (components == null) components = new int[offset + numComponents];
    
    for (int b=0; b<numComponents; b++)
      components[offset++] = (pixel&getMask(b)) >>> shifts[b];
	
    return components;
  }

  public final int[] getComponents(Object pixel, int[] components,
				   int offset)
  {
    return getComponents(getPixelFromArray(pixel), components, offset);
  }

  /**
   * Creates a <code>WriteableRaster</code> that has a <code>SampleModel</code>
   * that is compatible with this <code>ColorModel</code>.
   *
   * @param w the width of the writeable raster to create
   * @param h the height of the writeable raster to create
   *
   * @throws IllegalArgumentException if <code>w</code> or <code>h</code>
   *         is less than or equal to zero
   */
  public final WritableRaster createCompatibleWritableRaster(int w, int h)
  {
    // Sun also makes this check here.
    if(w <= 0 || h <= 0)
      throw new IllegalArgumentException("width (=" + w + ") and height (="
                                         + h + ") must be > 0");

    SampleModel sm = createCompatibleSampleModel(w, h);
    Point origin = new Point(0, 0);
    return Raster.createWritableRaster(sm, origin);	
  }

  public int getDataElement(int[] components, int offset)
  {
    int numComponents = getNumComponents();
    int pixelValue = 0;
    
    for (int c=0; c<numComponents; c++)
      pixelValue |= (components[offset++] << shifts[c]) & getMask(c);

    return pixelValue;
  }  

  public Object getDataElements(int[] components, int offset, Object obj)
  {
    /* In this color model, the whole pixel fits in the first element
       of the array. */
    int pixelValue = getDataElement(components, offset);

    DataBuffer buffer = Buffers.createBuffer(transferType, obj, 1);
    buffer.setElem(0, pixelValue);
    return Buffers.getData(buffer);
  }
    
  public final ColorModel coerceData (WritableRaster raster,
				      boolean isAlphaPremultiplied)
  {
    if (this.isAlphaPremultiplied == isAlphaPremultiplied)
      return this;
	
    /* TODO: provide better implementation based on the
       assumptions we can make due to the specific type of the
       color model. */
    super.coerceData(raster, isAlphaPremultiplied);
	
    return new ComponentColorModel(cspace, bits, hasAlpha(),
				   isAlphaPremultiplied, // argument
				   transparency, transferType);
  } 

  public boolean isCompatibleRaster(Raster raster)
  {
    /* FIXME: the Sun docs say this method is overridden here, 
       but I don't see any way to improve upon the implementation
       in ColorModel. */
    return super.isCompatibleRaster(raster);
  }

  String stringParam()
  {
    return super.stringParam() +
      ", redMask=" + Integer.toHexString(getRedMask()) +
      ", greenMask=" + Integer.toHexString(getGreenMask()) +
      ", blueMask=" + Integer.toHexString(getBlueMask()) +
      ", alphaMask=" + Integer.toHexString(getAlphaMask());
  }

  public String toString()
  {
    /* FIXME: Again, docs say override, but how do we improve upon the
       superclass implementation? */
    return super.toString();
  }
}

