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

import gnu.java.awt.Buffers;
import gnu.java.lang.CPStringBuilder;

/**
 * MultiPixelPackedSampleModel provides a single band model that supports
 * multiple pixels in a single unit.  Pixels have 2^n bits and 2^k pixels fit
 * per data element.
 *
 * @author Jerry Quinn (jlquinn@optonline.net)
 */
public class MultiPixelPackedSampleModel extends SampleModel
{
  private int scanlineStride;
  private int[] bitMasks;
  private int[] bitOffsets;
  private int[] sampleSize;
  private int dataBitOffset;
  private int elemBits;
  private int numberOfBits;
  private int numElems;

  /**
   * Creates a new <code>MultiPixelPackedSampleModel</code> with the specified
   * data type, which should be one of:
   * <ul>
   *   <li>{@link DataBuffer#TYPE_BYTE};</li>
   *   <li>{@link DataBuffer#TYPE_USHORT};</li>
   *   <li>{@link DataBuffer#TYPE_INT};</li>
   * </ul>
   * 
   * @param dataType  the data type.
   * @param w  the width (in pixels).
   * @param h  the height (in pixels).
   * @param numberOfBits  the number of bits per pixel (must be a power of 2).
   */
  public MultiPixelPackedSampleModel(int dataType, int w, int h,
				     int numberOfBits)
  {
    this(dataType, w, h, numberOfBits, 0, 0);
  }

  /**
   * Creates a new <code>MultiPixelPackedSampleModel</code> with the specified
   * data type, which should be one of:
   * <ul>
   *   <li>{@link DataBuffer#TYPE_BYTE};</li>
   *   <li>{@link DataBuffer#TYPE_USHORT};</li>
   *   <li>{@link DataBuffer#TYPE_INT};</li>
   * </ul>
   * 
   * @param dataType  the data type.
   * @param w  the width (in pixels).
   * @param h  the height (in pixels).
   * @param numberOfBits  the number of bits per pixel (must be a power of 2).
   * @param scanlineStride  the number of data elements from a pixel on one 
   *     row to the corresponding pixel in the next row.
   * @param dataBitOffset  the offset to the first data bit.
   */
  public MultiPixelPackedSampleModel(int dataType, int w, int h,
				     int numberOfBits, int scanlineStride,
				     int dataBitOffset)
  {
    super(dataType, w, h, 1);

    switch (dataType)
      {
      case DataBuffer.TYPE_BYTE:
	elemBits = 8;
	break;
      case DataBuffer.TYPE_USHORT:
	elemBits = 16;
	break;
      case DataBuffer.TYPE_INT:
	elemBits = 32;
	break;
      default:
	throw new IllegalArgumentException("MultiPixelPackedSampleModel"
					   + " unsupported dataType");
      }

    this.dataBitOffset = dataBitOffset;

    this.numberOfBits = numberOfBits;
    if (numberOfBits > elemBits)
      throw new RasterFormatException("MultiPixelPackedSampleModel pixel size"
				      + " larger than dataType");
    switch (numberOfBits)
      {
      case 1: case 2: case 4: case 8: case 16: case 32: break;
      default:
	throw new RasterFormatException("MultiPixelPackedSampleModel pixel"
					+ " size not 2^n bits");
      }
    numElems = elemBits / numberOfBits;

    // Compute scan line large enough for w pixels.
    if (scanlineStride == 0)
      scanlineStride = ((dataBitOffset + w * numberOfBits) - 1) / elemBits + 1;
    this.scanlineStride = scanlineStride;

    
    sampleSize = new int[1];
    sampleSize[0] = numberOfBits;

    bitMasks = new int[numElems];
    bitOffsets = new int[numElems];
    for (int i=0; i < numElems; i++)
      {
	bitOffsets[numElems - i- 1] = numberOfBits * i;
	bitMasks[numElems - i - 1] = ((1 << numberOfBits) - 1) << 
	    bitOffsets[numElems - i - 1];
      }
  }

  /**
   * Creates a new <code>MultiPixelPackedSample</code> model with the same
   * data type and bits per pixel as this model, but with the specified
   * dimensions.
   * 
   * @param w  the width (in pixels).
   * @param h  the height (in pixels).
   * 
   * @return The new sample model.
   */
  public SampleModel createCompatibleSampleModel(int w, int h)
  {
    /* FIXME: We can avoid recalculation of bit offsets and sample
       sizes here by passing these from the current instance to a
       special private constructor. */
    return new MultiPixelPackedSampleModel(dataType, w, h, numberOfBits);
  }

  /**
   * Creates a DataBuffer for holding pixel data in the format and
   * layout described by this SampleModel. The returned buffer will
   * consist of one single bank.
   * 
   * @return A new data buffer.
   */
  public DataBuffer createDataBuffer()
  {
    int size = scanlineStride * height;
    if (dataBitOffset > 0)
      size += (dataBitOffset - 1) / elemBits + 1;
    return Buffers.createBuffer(getDataType(), size);
  }

  /**
   * Returns the number of data elements required to transfer a pixel in the
   * get/setDataElements() methods.
   * 
   * @return <code>1</code>.
   */
  public int getNumDataElements()
  {
    return 1;
  }

  /**
   * Returns an array containing the size (in bits) of the samples in each 
   * band.  The <code>MultiPixelPackedSampleModel</code> class supports only
   * one band, so this method returns an array with length <code>1</code>. 
   * 
   * @return An array containing the size (in bits) of the samples in band zero. 
   *     
   * @see #getSampleSize(int)
   */
  public int[] getSampleSize()
  {
    return (int[]) sampleSize.clone();
  }
  
  /**
   * Returns the size of the samples in the specified band.  Note that the
   * <code>MultiPixelPackedSampleModel</code> supports only one band -- this
   * method ignored the <code>band</code> argument, and always returns the size
   * of band zero.
   * 
   * @param band  the band (this parameter is ignored).
   * 
   * @return The size of the samples in band zero.
   * 
   * @see #getSampleSize()
   */
  public int getSampleSize(int band)
  {
    return sampleSize[0];
  }

  /**
   * Returns the index in the data buffer that stores the pixel at (x, y).
   * 
   * @param x  the x-coordinate.
   * @param y  the y-coordinate.
   * 
   * @return The index in the data buffer that stores the pixel at (x, y).
   * 
   * @see #getBitOffset(int)
   */
  public int getOffset(int x, int y)
  {
    return scanlineStride * y + ((dataBitOffset + x * numberOfBits) / elemBits);
  }

  /**
   * The bit offset (within an element in the data buffer) of the pixels with 
   * the specified x-coordinate.
   * 
   * @param x  the x-coordinate.
   * 
   * @return The bit offset.
   */
  public int getBitOffset(int x)
  {
    return (dataBitOffset + x * numberOfBits) % elemBits;
  }

  /**
   * Returns the offset to the first data bit.
   * 
   * @return The offset to the first data bit.
   */
  public int getDataBitOffset()
  {
    return dataBitOffset;
  }

  /**
   * Returns the number of data elements from a pixel in one row to the
   * corresponding pixel in the next row.
   * 
   * @return The scanline stride.
   */
  public int getScanlineStride()
  {
    return scanlineStride;
  }

  /**
   * Returns the number of bits per pixel.
   * 
   * @return The number of bits per pixel.
   */
  public int getPixelBitStride()
  {
    return numberOfBits;
  }
  
  /**
   * Returns the transfer type, which is one of the following (depending on
   * the number of bits per sample for this model):
   * <ul>
   *   <li>{@link DataBuffer#TYPE_BYTE};</li>
   *   <li>{@link DataBuffer#TYPE_USHORT};</li>
   *   <li>{@link DataBuffer#TYPE_INT};</li>
   * </ul>
   * 
   * @return The transfer type.
   */
  public int getTransferType()
  {
    if (numberOfBits <= DataBuffer.getDataTypeSize(DataBuffer.TYPE_BYTE))
      return DataBuffer.TYPE_BYTE;
    else if (numberOfBits <= DataBuffer.getDataTypeSize(DataBuffer.TYPE_USHORT))
      return DataBuffer.TYPE_USHORT;
    return DataBuffer.TYPE_INT;
  }

  /**
   * Normally this method returns a sample model for accessing a subset of
   * bands of image data, but since <code>MultiPixelPackedSampleModel</code>
   * only supports a single band, this overridden implementation just returns
   * a new instance of <code>MultiPixelPackedSampleModel</code>, with the same
   * attributes as this instance.
   * 
   * @param bands  the bands to include in the subset (this is ignored, except
   *     that if it is non-<code>null</code> a check is made to ensure that the
   *     array length is equal to <code>1</code>).
   *     
   * @throws RasterFormatException if <code>bands</code> is not 
   *     <code>null</code> and <code>bands.length != 1</code>.
   */
  public SampleModel createSubsetSampleModel(int[] bands)
  {
    if (bands != null && bands.length != 1)
      throw new RasterFormatException("MultiPixelPackedSampleModel only"
          + " supports one band");
    return new MultiPixelPackedSampleModel(dataType, width, height, 
        numberOfBits, scanlineStride, dataBitOffset);
  }

  /**
   * Extract one pixel and return in an array of transfer type.
   *
   * Extracts the pixel at x, y from data and stores into the 0th index of the
   * array obj, since there is only one band.  If obj is null, a new array of
   * getTransferType() is created.
   *
   * @param x The x-coordinate of the pixel rectangle to store in 
   *     <code>obj</code>.
   * @param y The y-coordinate of the pixel rectangle to store in 
   *     <code>obj</code>.
   * @param obj The primitive array to store the pixels into or null to force 
   *     creation.
   * @param data The DataBuffer that is the source of the pixel data.
   * @return The primitive array containing the pixel data.
   * @see java.awt.image.SampleModel#getDataElements(int, int, Object, 
   *     DataBuffer)
   */
  public Object getDataElements(int x, int y, Object obj, DataBuffer data)
  {
    int pixel = getSample(x, y, 0, data);
    switch (getTransferType())
      {
        case DataBuffer.TYPE_BYTE:
          if (obj == null) 
            obj = new byte[1];
          ((byte[]) obj)[0] = (byte) pixel;
          return obj;
        case DataBuffer.TYPE_USHORT:
          if (obj == null) 
            obj = new short[1];
          ((short[]) obj)[0] = (short) pixel;
          return obj;
        case DataBuffer.TYPE_INT:
          if (obj == null) 
            obj = new int[1];
          ((int[]) obj)[0] = pixel;
          return obj;
        default:
          // Seems like the only sensible thing to do.
          throw new ClassCastException();
      }
  }

  /**
   * Returns an array (of length 1) containing the sample for the pixel at 
   * (x, y) in the specified data buffer.  If <code>iArray</code> is not 
   * <code>null</code>, it will be populated with the sample value and 
   * returned as the result of this function (this avoids allocating a new 
   * array instance).
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param iArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * @param data  the data buffer (<code>null</code> not permitted).
   * 
   * @return An array containing the pixel sample value.
   * 
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
   */
  public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
  {
    if (iArray == null) 
      iArray = new int[1];
    iArray[0] = getSample(x, y, 0, data);
    return iArray;
  }

  /**
   * Returns the sample value for the pixel at (x, y) in the specified data 
   * buffer.
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param b  the band (in the range <code>0</code> to 
   *     <code>getNumBands() - 1</code>).
   * @param data  the data buffer (<code>null</code> not permitted).
   * 
   * @return The sample value.
   * 
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
   */
  public int getSample(int x, int y, int b, DataBuffer data)
  {
    int pos =
      ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
    int offset = getOffset(x, y);
    int samples = data.getElem(offset);
    return (samples & bitMasks[pos]) >>> bitOffsets[pos];
  }
  
  /**
   * Set the pixel at x, y to the value in the first element of the primitive
   * array obj.
   *
   * @param x The x-coordinate of the data elements in <code>obj</code>.
   * @param y The y-coordinate of the data elements in <code>obj</code>.
   * @param obj The primitive array containing the data elements to set.
   * @param data The DataBuffer to store the data elements into.
   */
  public void setDataElements(int x, int y, Object obj, DataBuffer data)
  {
    int transferType = getTransferType();
    try
      {
        switch (transferType)
          {
            case DataBuffer.TYPE_BYTE:
              {
                byte[] in = (byte[]) obj;
                setSample(x, y, 0, in[0] & 0xFF, data);
                return;
              }
            case DataBuffer.TYPE_USHORT:
              {
                short[] in = (short[]) obj;
                setSample(x, y, 0, in[0] & 0xFFFF, data);
                return;
              }
            case DataBuffer.TYPE_INT:
              {
                int[] in = (int[]) obj;
                setSample(x, y, 0, in[0], data);
                return;
              }
            default:
              throw new ClassCastException("Unsupported data type");
          }
      }
    catch (ArrayIndexOutOfBoundsException aioobe)
      {
        String msg = "While writing data elements" +
          ", x=" + x + ", y=" + y +
          ", width=" + width + ", height=" + height +
          ", scanlineStride=" + scanlineStride +
          ", offset=" + getOffset(x, y) +
          ", data.getSize()=" + data.getSize() +
          ", data.getOffset()=" + data.getOffset() +
          ": " + aioobe;
        throw new ArrayIndexOutOfBoundsException(msg);
      }
  }

  /**
   * Sets the sample value for the pixel at (x, y) in the specified data 
   * buffer to the specified value. 
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param iArray  the sample value (<code>null</code> not permitted).
   * @param data  the data buffer (<code>null</code> not permitted).
   * 
   * @throws NullPointerException if either <code>iArray</code> or 
   *     <code>data</code> is <code>null</code>.
   *     
   * @see #setSample(int, int, int, int, DataBuffer)
   */
  public void setPixel(int x, int y, int[] iArray, DataBuffer data)
  {
    setSample(x, y, 0, iArray[0], data);
  }

  /**
   * Sets the sample value for a band for the pixel at (x, y) in the 
   * specified data buffer. 
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param b  the band (in the range <code>0</code> to 
   *     <code>getNumBands() - 1</code>).
   * @param s  the sample value.
   * @param data  the data buffer (<code>null</code> not permitted).
   * 
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
   */
  public void setSample(int x, int y, int b, int s, DataBuffer data)
  {
    int bitpos =
      ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
    int offset = getOffset(x, y);

    s = s << bitOffsets[bitpos];
    s = s & bitMasks[bitpos];

    int sample = data.getElem(offset);
    sample |= s;
    data.setElem(offset, sample);
  }
  
  /**
   * Tests this sample model for equality with an arbitrary object.  This 
   * method returns <code>true</code> if and only if:
   * <ul>
   *   <li><code>obj</code> is not <code>null</code>;
   *   <li><code>obj</code> is an instance of 
   *       <code>MultiPixelPackedSampleModel</code>;
   *   <li>both models have the same:
   *     <ul>
   *       <li><code>dataType</code>;
   *       <li><code>width</code>;
   *       <li><code>height</code>;
   *       <li><code>numberOfBits</code>;
   *       <li><code>scanlineStride</code>;
   *       <li><code>dataBitOffsets</code>.
   *     </ul>
   *   </li>
   * </ul>
   * 
   * @param obj  the object (<code>null</code> permitted)
   * 
   * @return <code>true</code> if this model is equal to <code>obj</code>, and
   *     <code>false</code> otherwise.
   */
  public boolean equals(Object obj) 
  {
    if (this == obj) 
      return true;
    if (! (obj instanceof MultiPixelPackedSampleModel)) 
      return false;
    MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel) obj;
    if (this.dataType != that.dataType)
      return false;
    if (this.width != that.width)
      return false;
    if (this.height != that.height)
      return false;
    if (this.numberOfBits != that.numberOfBits)
      return false;
    if (this.scanlineStride != that.scanlineStride)
      return false;
    if (this.dataBitOffset != that.dataBitOffset)
      return false;
    return true;
  }
  
  /**
   * Returns a hash code for this <code>MultiPixelPackedSampleModel</code>.
   * 
   * @return A hash code.
   */
  public int hashCode()
  {
    // this hash code won't match Sun's, but that shouldn't matter...
    int result = 193;
    result = 37 * result + dataType;
    result = 37 * result + width;
    result = 37 * result + height;
    result = 37 * result + numberOfBits;
    result = 37 * result + scanlineStride;
    result = 37 * result + dataBitOffset;
    return result;
  }
  
  /**
   * Creates a String with some information about this SampleModel.
   * @return A String describing this SampleModel.
   * @see java.lang.Object#toString()
   */
  public String toString()
  {
    CPStringBuilder result = new CPStringBuilder();
    result.append(getClass().getName());
    result.append("[");
    result.append("scanlineStride=").append(scanlineStride);
    for(int i=0; i < bitMasks.length; i+=1)
    {
      result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
    }
    
    result.append("]");
    return result.toString();
  }
}
