/* ShortLookupTable.java -- Java class for a pixel translation table.
   Copyright (C) 2004, 2005, 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 java.awt.image;

/**
 * ShortLookupTable represents translation arrays for pixel values.  It wraps
 * one or more data arrays for each layer (or component) in an image, such as
 * Alpha, R, G, and B.  When doing translation, the offset is subtracted from
 * the pixel values to allow a subset of an array to be used.
 *
 * @author Jerry Quinn (jlquinn@optonline.net)
 * @version 1.0
 */
public class ShortLookupTable extends LookupTable
{
  // Array of translation tables.
  private short data[][];

  /**
   * Creates a new <code>ShortLookupTable</code> instance.
   *
   * Offset is subtracted from pixel values when looking up in the translation
   * tables.  If data.length is one, the same table is applied to all pixel
   * components.
   * 
   * @param offset Offset to be subtracted.
   * @param data Array of lookup tables.
   * @exception IllegalArgumentException if offset &lt; 0 or data.length &lt; 1.
   */
  public ShortLookupTable(int offset, short[][] data)
    throws IllegalArgumentException
  {
    super(offset, data.length);
    
    // tests show that Sun's implementation creates a new array to store the
    // references from the incoming 'data' array - not sure why, but we'll 
    // match that behaviour just in case it matters...
    this.data = new short[data.length][];
    for (int i = 0; i < data.length; i++)
      this.data[i] = data[i];
  }

  /**
   * Creates a new <code>ShortLookupTable</code> instance.
   *
   * Offset is subtracted from pixel values when looking up in the translation
   * table.  The same table is applied to all pixel components.
   * 
   * @param offset Offset to be subtracted.
   * @param data Lookup table for all components (<code>null</code> not 
   *     permitted).
   * @exception IllegalArgumentException if offset &lt; 0.
   */
  public ShortLookupTable(int offset, short[] data)
    throws IllegalArgumentException
  {
    super(offset, 1);
    if (data == null)
      throw new NullPointerException("Null 'data' argument.");
    this.data = new short[][] {data};
  }

  /** 
   * Return the lookup tables.  This is a reference to the actual table, so
   * modifying the contents of the returned array will modify the lookup table. 
   * 
   * @return The lookup table.
   */
  public final short[][] getTable()
  {
    return data;
  }

  /**
   * Return translated values for a pixel.
   *
   * For each value in the pixel src, use the value minus offset as an index
   * in the component array and copy the value there to the output for the
   * component.  If dest is null, the output is a new array, otherwise the
   * translated values are written to dest.  Dest can be the same array as
   * src.
   *
   * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
   * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
   * translation arrays.
   *
   * @param src Component values of a pixel.
   * @param dst Destination array for values, or null.
   * @return Translated values for the pixel.
   */
  public int[] lookupPixel(int[] src, int[] dst)
    throws ArrayIndexOutOfBoundsException
  {
    if (dst == null)
      dst = new int[src.length];

    if (data.length == 1)
      for (int i = 0; i < src.length; i++)
        dst[i] = data[0][src[i] - offset];
    else
      for (int i = 0; i < src.length; i++)
        dst[i] = data[i][src[i] - offset];
      
    return dst;
  }

  /**
   * Return translated values for a pixel.
   *
   * For each value in the pixel src, use the value minus offset as an index
   * in the component array and copy the value there to the output for the
   * component.  If dest is null, the output is a new array, otherwise the
   * translated values are written to dest.  Dest can be the same array as
   * src.
   *
   * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
   * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
   * translation arrays.
   *
   * @param src Component values of a pixel.
   * @param dst Destination array for values, or null.
   * @return Translated values for the pixel.
   *
   */
  public short[] lookupPixel(short[] src, short[] dst)
    throws ArrayIndexOutOfBoundsException
  {
    if (dst == null)
      dst = new short[src.length];

    if (data.length == 1)
      for (int i = 0; i < src.length; i++)
        dst[i] = data[0][((int) src[i]) - offset];
    else
      for (int i = 0; i < src.length; i++)
        dst[i] = data[i][((int) src[i]) - offset];
      
    return dst;

  }
}
