Hiya, 
I reviewed and commited these patches from David.

(David: I moved GradientPaintContext to gnu.java.awt instead of having
it package-private in java.awt.)

2005-06-01  David Gilbert  <[EMAIL PROTECTED]>

        * gnu/java/awt/GradientPaintContext.java: New file.
        * java/awt/GradientPaint.java: Implemented.
        * java/awt/image/IndexColorModel.java: Reimplemented.


? java/awt/GradientPaintContext.java
Index: java/awt/GradientPaint.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/GradientPaint.java,v
retrieving revision 1.1
diff -u -r1.1 GradientPaint.java
--- java/awt/GradientPaint.java	6 May 2002 02:43:17 -0000	1.1
+++ java/awt/GradientPaint.java	18 May 2005 16:36:55 -0000
@@ -1,5 +1,5 @@
 /* GradientPaint.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2005, Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -44,7 +44,8 @@
 import java.awt.image.ColorModel;
 
 /**
- * STUB CLASS ONLY
+ * A paint object that can be used to color a region by blending two colors. 
+ * Instances of this class are immutable.
  */
 public class GradientPaint implements Paint
 {
@@ -56,18 +57,48 @@
   private final Color c2;
   private final boolean cyclic;
 
+  /**
+   * Creates a new acyclic <code>GradientPaint</code>.
+   * 
+   * @param x1  the x-coordinate of the anchor point for color 1.
+   * @param y1  the y-coordinate of the anchor point for color 1.
+   * @param c1  color 1 (<code>null</code> not permitted).
+   * @param x2  the x-coordinate of the anchor point for color 2.
+   * @param y2  the y-coordinate of the anchor point for color 2.
+   * @param c2  the second color (<code>null</code> not permitted).
+   */
   public GradientPaint(float x1, float y1, Color c1,
                        float x2, float y2, Color c2)
   {
     this(x1, y1, c1, x2, y2, c2, false);
   }
 
+  /**
+   * Creates a new acyclic <code>GradientPaint</code>.
+   * 
+   * @param p1  anchor point 1 (<code>null</code> not permitted).
+   * @param c1  color 1 (<code>null</code> not permitted).
+   * @param p2  anchor point 2 (<code>null</code> not permitted).
+   * @param c2  color 2 (<code>null</code> not permitted).
+   */
   public GradientPaint(Point2D p1, Color c1, Point2D p2, Color c2)
   {
     this((float) p1.getX(), (float) p1.getY(), c1,
          (float) p2.getX(), (float) p2.getY(), c2, false);
   }
 
+  /**
+   * Creates a new cyclic or acyclic <code>GradientPaint</code>.
+   * 
+   * @param x1  the x-coordinate of the anchor point for color 1.
+   * @param y1  the y-coordinate of the anchor point for color 1.
+   * @param c1  color 1 (<code>null</code> not permitted).
+   * @param x2  the x-coordinate of the anchor point for color 2.
+   * @param y2  the y-coordinate of the anchor point for color 2.
+   * @param c2  the second color (<code>null</code> not permitted).
+   * @param cyclic  a flag that controls whether the gradient is cyclic or
+   *                acyclic.
+   */
   public GradientPaint(float x1, float y1, Color c1,
                        float x2, float y2, Color c2, boolean cyclic)
   {
@@ -82,6 +113,16 @@
     this.cyclic = cyclic;
   }
 
+  /**
+   * Creates a new cyclic or acyclic <code>GradientPaint</code>.
+   * 
+   * @param p1  anchor point 1 (<code>null</code> not permitted).
+   * @param c1  color 1 (<code>null</code> not permitted).
+   * @param p2  anchor point 2 (<code>null</code> not permitted).
+   * @param c2  color 2 (<code>null</code> not permitted).
+   * @param cyclic  a flag that controls whether the gradient is cyclic or
+   *                acyclic.
+   */
   public GradientPaint(Point2D p1, Color c1, Point2D p2, Color c2,
                        boolean cyclic)
   {
@@ -89,41 +130,99 @@
          (float) p2.getX(), (float) p2.getY(), c2, cyclic);
   }
 
+  /**
+   * Returns a point with the same coordinates as the anchor point for color 1.
+   * Note that if you modify this point, the <code>GradientPaint</code> remains
+   * unchanged.
+   * 
+   * @return A point with the same coordinates as the anchor point for color 1.
+   */
   public Point2D getPoint1()
   {
     return new Point2D.Float(x1, y1);
   }
 
+  /**
+   * Returns the first color.
+   * 
+   * @return The color (never <code>null</code>).
+   */
   public Color getColor1()
   {
     return c1;
   }
 
+  /**
+   * Returns a point with the same coordinates as the anchor point for color 2.
+   * Note that if you modify this point, the <code>GradientPaint</code> remains
+   * unchanged.
+   * 
+   * @return A point with the same coordinates as the anchor point for color 2.
+   */
   public Point2D getPoint2()
   {
     return new Point2D.Float(x2, y2);
   }
 
+  /**
+   * Returns the second color.
+   * 
+   * @return The color (never <code>null</code>).
+   */
   public Color getColor2()
   {
     return c2;
   }
 
+  /**
+   * Returns <code>true</code> if this <code>GradientPaint</code> instance is
+   * cyclic, and <code>false</code> otherwise.
+   * 
+   * @return A boolean.
+   */
   public boolean isCyclic()
   {
     return cyclic;
   }
 
+  /**
+   * Returns the [EMAIL PROTECTED] PaintContext} used to generate the color pattern.
+   * 
+   * @param cm  the color model, used as a hint (ignored in this 
+   *            implementation).
+   * @param deviceBounds  the device space bounding box of the painted area.
+   * @param userBounds  the user space bounding box of the painted area.
+   * @param xform  the transformation from user space to device space.
+   * @param hints  any hints for choosing between rendering alternatives.
+   * 
+   * @return The context for performing the paint
+   */
   public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
                                     Rectangle2D userBounds,
                                     AffineTransform xform,
                                     RenderingHints hints)
   {
-    throw new Error("not implemented");
+    Point2D xp1 = xform.transform(getPoint1(), null);
+    Point2D xp2 = xform.transform(getPoint2(), null);
+    return new GradientPaintContext((float) xp1.getX(), (float) xp1.getY(), c1, 
+            (float) xp2.getX(), (float) xp2.getY(), c2, cyclic);
   }
 
+  /**
+   * Returns the transparency code for this <code>GradientPaint</code> instance.
+   * This is derived from the two [EMAIL PROTECTED] Color} objects used in creating this
+   * object:  if both colors are opaque, this method returns 
+   * [EMAIL PROTECTED] Transparency#OPAQUE}, otherwise it returns 
+   * [EMAIL PROTECTED] Transparency#TRANSLUCENT}.
+   * 
+   * @return [EMAIL PROTECTED] Transparency#OPAQUE} or [EMAIL PROTECTED] Transparency#TRANSLUCENT}.
+   */
   public int getTransparency()
   {
-    throw new Error("not implemented");
+    if (c1.getAlpha() == 255 && c2.getAlpha() == 255)
+      return Transparency.OPAQUE;
+    else
+      return Transparency.TRANSLUCENT;   
   }
+  
 } // class GradientPaint
/* GradientPaintContext.java -- 
   Copyright (C) 2005, 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 gnu.java.awt;

import java.awt.geom.Point2D;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.PaintContext;
import java.awt.Color;

/**
 * A [EMAIL PROTECTED] PaintContext} used by the [EMAIL PROTECTED] GradientPaint} class.
 */
public class GradientPaintContext implements PaintContext 
{

  // This implementation follows the technique described in 
  // "Java(tm) 2D Graphics" by Jonathan Knudsen (O'Reilly 1999).
    
  /** The x-coordinate of the anchor point for color 1. */
  private final float x1;
    
  /** The y-coordinate of the anchor point for color 1. */
  private final float y1;
    
  /** Color 1. */
  private final Color c1;
    
  /** The x-coordinate of the anchor point for color 2. */
  private final float x2;
    
  /** The y-coordinate of the anchor point for color 2. */
  private final float y2;
    
  /** Color 2. */
  private final Color c2;
    
  /** A flag indicating whether the gradient is cyclic or acyclic. */
  private final boolean cyclic;
    
  /** The length of the gradient line - computed from the two anchor points. */
  private final double length; 

  /**
   * Creates a new instance.
   * 
   * @param x1  the x-coordinate for the anchor point for color 1.
   * @param y1  the y-coordinate for the anchor point for color 1.
   * @param c1  color 1.
   * @param x2  the x-coordinate for the anchor point for color 2.
   * @param y2  the y-coordinate for the anchor point for color 2.
   * @param c2  color 2.
   * @param cyclic  a flag that determines whether the gradient is cyclic
   *                or acyclic.
   */
  public GradientPaintContext(float x1, float y1, Color c1, 
                              float x2, float y2, Color c2, boolean cyclic) 
  {     
    this.x1 = x1;
    this.y1 = y1;
    this.c1 = c1;
    this.x2 = x2;
    this.y2 = y2;
    this.c2 = c2;
    this.cyclic = cyclic;
    length = Point2D.distance(x1, y1, x2, y2);
  }
    
  /**
   * Return the color model of this context. It may be different from the
   * hint specified during createContext, as not all contexts can generate
   * color patterns in an arbitrary model.
   *
   * @return the context color model
   */
  public ColorModel getColorModel() 
  {
    return ColorModel.getRGBdefault();   
  }

  /**
   * Return a raster containing the colors for the graphics operation.
   *
   * @param x the x-coordinate, in device space
   * @param y the y-coordinate, in device space
   * @param w the width, in device space
   * @param h the height, in device space
   * @return a raster for the given area and color
   */
  public Raster getRaster(int x, int y, int w, int h) {
    ColorModel cm = getColorModel();
    WritableRaster raster = cm.createCompatibleWritableRaster(w, h);
    int[] data = new int[w * h * 4];
    double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
    for (int r = 0; r < h; r++) {
      for (int c = 0; c < w; c++) {
        double u = 0.0;
        if (pd2 != 0) 
          u = (((x + c) - x1) * (x2 - x1) + ((y + r) - y1) * (y2 - y1)) 
                  / Math.sqrt(pd2);
        double ratio = u / length;
        if (cyclic)
          ratio = Math.abs(ratio - Math.floor((ratio + 1.0) / 2.0) * 2.0);
        else 
          ratio = Math.max(0.0, Math.min(1.0, ratio));
        int base = (r * w + c) * 4;
        data[base] = (int) (c1.getRed() + ratio * (c2.getRed() - c1.getRed()));
        data[base + 1] 
          = (int) (c1.getGreen() + ratio * (c2.getGreen() - c1.getGreen()));
        data[base + 2] 
          = (int) (c1.getBlue() + ratio * (c2.getBlue() - c1.getBlue()));
        data[base + 3] 
          = (int) (c1.getAlpha() + ratio * (c2.getAlpha() - c1.getAlpha()));
      }
    }
    raster.setPixels(0, 0, w, h, data);
    return raster;
  }

  /**
   * Release the resources allocated for the paint (none in this 
   * implementation).
   */
  public void dispose() {
    // nothing to do    
  }
    
}
Index: java/awt/image/IndexColorModel.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/image/IndexColorModel.java,v
retrieving revision 1.13
diff -u -r1.13 IndexColorModel.java
--- java/awt/image/IndexColorModel.java	1 Apr 2005 16:29:30 -0000	1.13
+++ java/awt/image/IndexColorModel.java	14 Apr 2005 20:57:12 -0000
@@ -1,5 +1,5 @@
 /* IndexColorModel.java -- Java class for interpreting Pixel objects
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,99 +35,156 @@
 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.color.ColorSpace;
 import java.math.BigInteger;
 
 /**
  * Color model similar to pseudo visual in X11.
- *
+ * <br><br>
  * 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.
- * 
+ * <br><br>
+ * The <code>IndexColorModel</code> supports a map of valid pixels, allowing 
+ * the representation of holes in the the color map.  The valid map is 
+ * represented as a [EMAIL PROTECTED] BigInteger} where each bit indicates the validity 
+ * of the map entry with the same index.
+ * <br><br>
  * 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.
+ * <br><br>
+ * <code>IndexColorModel</code> supports anywhere from 1 to 16 bit index 
+ * values.  The allowed transfer types are [EMAIL PROTECTED] DataBuffer#TYPE_BYTE} and 
+ * [EMAIL PROTECTED] DataBuffer#TYPE_USHORT}.
  *
  * @author C. Brian Jones ([EMAIL PROTECTED]) 
  */
 public class IndexColorModel extends ColorModel
 {
   private int map_size;
-  private boolean opaque;
+  private boolean opaque;  // no alpha, but doesn't account for trans
   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. 
+   * Creates a new indexed color model for <code>size</code> color elements 
+   * with no alpha component.  Each array must contain at least 
+   * <code>size</code> elements.  For each array, the i-th color is described 
+   * by reds[i], greens[i] and blues[i]. 
    *
-   * @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 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.
+   *
+   * @throws IllegalArgumentException if <code>bits</code> &lt; 1 or 
+   *         <code>bits</code> &gt; 16.
+   * @throws NullPointerException if any of the arrays is <code>null</code>.
+   * @throws ArrayIndexOutOfBoundsException if <code>size</code> is greater 
+   *         than the length of the component arrays.
    */
   public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
                          byte[] blues)
   {
-    this (bits, size, reds, greens, blues, (byte[]) null);
+    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. 
+   * Creates a new indexed color model for <code>size</code> color elements.
+   * Each array must contain at least <code>size</code> elements.  For each 
+   * array, the i-th color is described by reds[i], greens[i] and blues[i]. 
+   * All the colors are opaque except for the transparent color. 
    *
-   * @param bits the number of bits needed to represent <code>size</code> colors
+   * @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
+   * @param trans the index of the transparent color (use -1 for no 
+   *              transparent color).
+   * 
+   * @throws IllegalArgumentException if <code>bits</code> &lt; 1 or 
+   *         <code>bits</code> &gt; 16.
+   * @throws NullPointerException if any of the arrays is <code>null</code>.
+   * @throws ArrayIndexOutOfBoundsException if <code>size</code> is greater 
+   *         than the length of the component arrays.
    */
   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;
+    super(bits, nArray(8, (0 <= trans && trans < size) ? 4 : 3), 
+        ColorSpace.getInstance(ColorSpace.CS_sRGB), 
+        (0 <= trans && trans < size),  // hasAlpha 
+        false, OPAQUE, 
+        Buffers.smallestAppropriateTransferType(bits)); 
+    if (bits < 1) 
+      throw new IllegalArgumentException("bits < 1");
+    if (bits > 16)
+      throw new IllegalArgumentException("bits > 16");
+    if (size < 1)
+      throw new IllegalArgumentException("size < 1");
+    map_size = size;
+    if (0 <= trans && trans < size) {
+      this.trans = trans;
+      transparency = BITMASK;
+    }
+    rgb = new int[size];
+    for (int i = 0; i < size; i++)
+      {
+        rgb[i] = (0xff000000
+                  | ((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. 
+   * Creates a new indexed color model for <code>size</code> color elements 
+   * including alpha.  Each array must contain at least <code>size</code> 
+   * elements.  For each array, the i-th color is described 
+   * by reds[i], greens[i], blues[i] and alphas[i]. 
    *
-   * @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
+   * @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 (<code>null</code> 
+   *               permitted).
+   *
+   * @throws IllegalArgumentException if <code>bits</code> &lt; 1 or 
+   *           <code>bits</code> &gt; 16.
+   * @throws NullPointerException if <code>reds</code>, <code>greens</code> or
+   *         <code>blues</code> is <code>null</code>.
+   * @throws ArrayIndexOutOfBoundsException if <code>size</code> is greater 
+   *         than the length of the component arrays.
    */
   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); 
+    super(bits, nArray(8, (alphas == null ? 3 : 4)), 
+        ColorSpace.getInstance(ColorSpace.CS_sRGB), 
+        (alphas != null), false, TRANSLUCENT, 
+        Buffers.smallestAppropriateTransferType(bits)); 
+    if (bits < 1) 
+      throw new IllegalArgumentException("bits < 1");
+    if (bits > 16)
+      throw new IllegalArgumentException("bits > 16");
+    if (size < 1)
+      throw new IllegalArgumentException("size < 1");
     map_size = size;
     opaque = (alphas == null);
 
@@ -141,16 +198,25 @@
                       | ((greens[i] & 0xff) << 8)
                       | (blues[i] & 0xff));
           }
+        transparency = OPAQUE;
       }
     else
       {
+	byte alphaZero = (byte) 0x00;
+        byte alphaOne = (byte) 0xFF;
         for (int i = 0; i < size; i++)
           {
+	    alphaZero = (byte) (alphaZero | alphas[i]);
+            alphaOne = (byte) (alphaOne & alphas[i]);
             rgb[i] = ((alphas[i] & 0xff) << 24
                       | ((reds[i] & 0xff) << 16)
                       | ((greens[i] & 0xff) << 8)
                       | (blues[i] & 0xff));
           }
+        if ((alphaZero == (byte) 0x00) || (alphaOne == (byte) 0xFF))
+	  transparency = BITMASK;
+	else
+	  transparency = TRANSLUCENT;
       }
 
     // Generate a bigint with 1's for every pixel
@@ -158,61 +224,85 @@
   }
 
   /**
-   * 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. 
+   * Creates a new indexed color model using the color components in 
+   * <code>cmap</code>. If <code>hasAlpha</code> is <code>true</code> then
+   * <code>cmap</code> contains an alpha component after each of the red, green
+   * and blue components.
    *
-   * @param bits the number of bits needed to represent <code>size</code> colors
+   * @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.
+   * @throws IllegalArgumentException if bits &lt; 1, bits &gt; 16, or size 
+   *         &lt; 1.
+   * @throws NullPointerException if <code>cmap</code> is <code>null</code>.
    */
-  public IndexColorModel (int bits, int size, byte[] cmap, int start, 
-                          boolean hasAlpha)
+  public IndexColorModel(int bits, int size, byte[] cmap, int start, 
+                         boolean hasAlpha)
   {
-    this (bits, size, cmap, start, hasAlpha, -1);
+    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).
+   * 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 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);
+   * @throws IllegalArgumentException if bits &lt; 1, bits &gt; 16, or size
+   *         &lt; 1.
+   * @throws NullPointerException if <code>cmap</code> is <code>null</code>.
+   */
+  public IndexColorModel(int bits, int size, byte[] cmap, int start, 
+                         boolean hasAlpha, int trans)
+  {
+    super(bits, nArray(8, hasAlpha || (0 <= trans && trans < size) ? 4 : 3), 
+        ColorSpace.getInstance(ColorSpace.CS_sRGB),
+        hasAlpha || (0 <= trans && trans < size), false, OPAQUE, 
+        Buffers.smallestAppropriateTransferType(bits));
+    if (bits < 1)
+      throw new IllegalArgumentException("bits < 1");
     if (bits > 16)
       throw new IllegalArgumentException("bits > 16");
     if (size < 1)
       throw new IllegalArgumentException("size < 1");
     map_size = size;
     opaque = !hasAlpha;
-    this.trans = trans;
+    if (0 <= trans && trans < size)
+      this.trans = trans;
 
     rgb = new int[size];
     if (hasAlpha)
     {
-      for (int i = 0; i < size; i++)
+      int alpha;
+      int alphaZero = 0x00;  // use to detect all zeros
+      int alphaOne = 0xff;   // use to detect all ones
+      for (int i = 0; i < size; i++) {
+	alpha = cmap[4 * i + 3 + start] & 0xff;  
+        alphaZero = alphaZero | alpha;
+        alphaOne = alphaOne & alpha;
         rgb[i] =
-	  // alpha
-	  ((cmap[4 * i + 3 + start] & 0xff) << 24
+	  ( alpha << 24
 	   // red
 	   | ((cmap[4 * i + start] & 0xff) << 16)
 	   // green
 	   | ((cmap[4 * i + 1 + start] & 0xff) << 8)
 	   // blue
 	   | (cmap[4 * i + 2 + start] & 0xff));
+      }
+      if (alphaZero == 0) 
+	transparency = BITMASK;
+      else if (alphaOne == 255) 
+        transparency = (trans != -1 ? BITMASK : OPAQUE);
+      else
+	transparency = TRANSLUCENT;
     }
     else
     {
@@ -224,6 +314,8 @@
 		  | ((cmap[3 * i + 1 + start] & 0xff) << 8)
 		  // blue
 		  | (cmap[3 * i + 2 + start] & 0xff));
+      if (trans != -1)
+	transparency = BITMASK;
     }
 
     // Generate a bigint with 1's for every pixel
@@ -236,22 +328,26 @@
    * 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 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.
+   * @param transferType [EMAIL PROTECTED] DataBuffer#TYPE_BYTE} or 
+            [EMAIL PROTECTED] DataBuffer#TYPE_USHORT}.
+   * @throws IllegalArgumentException if bits &lt; 1, bits &gt; 16, or size
+   *         &lt; 1.
+   * @throws IllegalArgumentException if <code>transferType</code> is something
+   *         other than [EMAIL PROTECTED] DataBuffer#TYPE_BYTE} or 
+   *         [EMAIL PROTECTED] DataBuffer#TYPE_USHORT}.
    */
-  public IndexColorModel (int bits, int size, int[] cmap, int start, 
-                          boolean hasAlpha, int trans, int transferType)
+  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
+    super(bits, 
+	  nArray(8, 4), // bits for each channel
 	  ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
 	  true, // has alpha
 	  false, // not premultiplied
@@ -265,7 +361,8 @@
       throw new IllegalArgumentException("size < 1");
     map_size = size;
     opaque = !hasAlpha;
-    this.trans = trans;
+    if (0 <= trans && trans < size)
+      this.trans = trans;
 
     rgb = new int[size];
     if (!hasAlpha)
@@ -280,30 +377,34 @@
 
   /**
    * Construct an IndexColorModel using a colormap with holes.
-   * 
+   * <br><br>
    * 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.
-   * 
+   * <br><br>
    * 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.
+   * @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 [EMAIL PROTECTED] DataBuffer#TYPE_BYTE} or 
+   *                     [EMAIL PROTECTED] DataBuffer#TYPE_USHORT}.
+   * @param validBits a map of the valid entries in <code>cmap</code>.
+   * @throws IllegalArgumentException if bits &lt; 1, bits &gt; 16, or size
+   *         &lt; 1.
    * @throws IllegalArgumentException if transferType is something other than
-   * TYPE_BYTE or TYPE_USHORT.
+   *         [EMAIL PROTECTED] DataBuffer#TYPE_BYTE} or [EMAIL PROTECTED] DataBuffer#TYPE_USHORT}.
    */
-  public IndexColorModel (int bits, int size, int[] cmap, int start, 
-                          int transferType, BigInteger validBits)
+  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
+    super(bits, // total bits, sRGB, four channels
+	  nArray(8, 4), // bits for each channel
 	  ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
 	  true, // has alpha
 	  false, // not premultiplied
@@ -328,112 +429,181 @@
       System.arraycopy(cmap, start, rgb, 0, size);
   }
 
-  public final int getMapSize ()
+  /**
+   * Returns the size of the color lookup table.
+   *
+   * @return The size of the color lookup table.
+   */
+  public final int getMapSize()
   {
     return map_size;
   }
 
   /**
-   * Get the index of the transparent color in this color model
+   * Get the index of the transparent color in this color model.
+   *
+   * @return The index of the color that is considered transparent, or -1 if 
+   *         there is no transparent color.
    */
-  public final int getTransparentPixel ()
+  public final int getTransparentPixel()
   {
     return trans;
   }
 
   /**
-   * <br>
+   * Fills the supplied array with the red component of each color in the 
+   * lookup table.
+   *
+   * @param r an array that is at least as large as [EMAIL PROTECTED] #getMapSize()}.
+   * @throws NullPointerException if <code>r</code> is <code>null</code>.
+   * @throws ArrayIndexOutOfBoundsException if <code>r</code> has less 
+   *         than [EMAIL PROTECTED] #getMapSize()} elements. 
    */
-  public final void getReds (byte[] r)
+  public final void getReds(byte[] r)
   {
-    getComponents (r, 2);
+    int i;
+    for (i = 0; i < map_size; i++)
+      r[i] = (byte) ((0x00FF0000  & rgb[i]) >> 16);
   }
 
   /**
-   * <br>
+   * Fills the supplied array with the green component of each color in the 
+   * lookup table.
+   *
+   * @param g an array that is at least as large as [EMAIL PROTECTED] #getMapSize()}.
+   * @throws NullPointerException if <code>g</code> is <code>null</code>.
+   * @throws ArrayIndexOutOfBoundsException if <code>g</code> has less 
+   *         than [EMAIL PROTECTED] #getMapSize()} elements. 
    */
-  public final void getGreens (byte[] g)
+  public final void getGreens(byte[] g)
   {
-    getComponents (g, 1);
+    int i;
+    for (i = 0; i < map_size; i++)
+      g[i] = (byte) ((0x0000FF00  & rgb[i]) >> 8);
   }
 
   /**
-   * <br>
+   * Fills the supplied array with the blue component of each color in the 
+   * lookup table.
+   *
+   * @param b an array that is at least as large as [EMAIL PROTECTED] #getMapSize()}.
+   * @throws NullPointerException if <code>b</code> is <code>null</code>.
+   * @throws ArrayIndexOutOfBoundsException if <code>b</code> has less 
+   *         than [EMAIL PROTECTED] #getMapSize()} elements. 
    */
-  public final void getBlues (byte[] b)
+  public final void getBlues(byte[] b)
   {
-    getComponents (b, 0);
+    int i;
+    for (i = 0; i < map_size; i++)
+      b[i] = (byte) (0x000000FF & rgb[i]);
   }
 
   /**
-   * <br>
+   * Fills the supplied array with the alpha component of each color in the 
+   * lookup table.  If the model has a transparent pixel specified, the alpha
+   * for that pixel will be 0.
+   *
+   * @param a an array that is at least as large as [EMAIL PROTECTED] #getMapSize()}.
+   * @throws NullPointerException if <code>a</code> is <code>null</code>.
+   * @throws ArrayIndexOutOfBoundsException if <code>a</code> has less 
+   *         than [EMAIL PROTECTED] #getMapSize()} elements. 
    */
-  public final void getAlphas (byte[] a)
+  public final void getAlphas(byte[] a)
   {
-    getComponents (a, 3);
+    int i;
+    for (i = 0; i < map_size; i++)
+      if (i == trans) 
+	a[i] = (byte) 0;
+      else 
+        a[i] = (byte) ((0xFF000000  & rgb[i]) >> 24);
   }
 
-  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.
+   * Returns the red component of the color in the lookup table for the 
+   * given pixel value.
+   *
+   * @param pixel  the pixel lookup value.
+   *
+   * @return The red component of the color in the lookup table.
+   * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
    */
-  public final int getRed (int pixel)
+  public final int getRed(int pixel)
   {
     if (pixel < map_size)
-	    return (int) ((generateMask (2) & rgb[pixel]) >> (2 * pixel_bits));
+      return (0x00FF0000 & rgb[pixel]) >> 16;
     
     return 0;
   }
 
   /**
-   * Get the green component of the given pixel.
+   * Returns the green component of the color in the lookup table for the 
+   * given pixel value.
+   *
+   * @param pixel  the pixel lookup value.
+   *
+   * @return The green component of the color in the lookup table.
+   * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
    */
-  public final int getGreen (int pixel)
+  public final int getGreen(int pixel)
   {
     if (pixel < map_size)
-	    return (int) ((generateMask (1) & rgb[pixel]) >> (1 * pixel_bits));
+      return (0x0000FF00 & rgb[pixel]) >> 8;
     
     return 0;
   }
 
   /**
-   * Get the blue component of the given pixel.
+   * Returns the blue component of the color in the lookup table for the 
+   * given pixel value.
+   *
+   * @param pixel  the pixel lookup value.
+   *
+   * @return The blue component of the color in the lookup table.
+   * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
    */
-  public final int getBlue (int pixel)
+  public final int getBlue(int pixel)
   {
-    if (pixel < map_size) 
-	    return (int) (generateMask (0) & rgb[pixel]);
+    if (pixel < map_size)
+      return 0x000000FF & rgb[pixel];
     
     return 0;
   }
 
   /**
-   * Get the alpha component of the given pixel.
+   * Returns the alpha component of the color in the lookup table for the 
+   * given pixel value. If no alpha channel was specified when the color model
+   * was created, then 255 is returned for all pixels except the transparent
+   * pixel (if one is defined - see [EMAIL PROTECTED] #getTransparentPixel()}) which
+   * returns an alpha of 0.
+   *
+   * @param pixel  the pixel lookup value.
+   *
+   * @return The alpha component of the color in the lookup table (in the 
+   *         range 0 to 255).
+   * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
    */
-  public final int getAlpha (int pixel)
+  public final int getAlpha(int pixel)
   {
-    if (opaque || pixel >= map_size)
+    if (opaque && pixel != trans) 
       return 255;
+    if ((pixel == trans && trans != -1) || pixel >= map_size)
+      return 0;
 
-    return (int) ((generateMask (3) & rgb[pixel]) >> (3 * pixel_bits));
+    return (0xFF000000 & rgb[pixel]) >> 24;
   }
 
   /**
    * Get the RGB color value of the given pixel using the default
    * RGB color model. 
    *
-   * @param pixel a pixel value
+   * @param pixel the pixel lookup value.
+   * @return The RGB color value.
+   * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
    */
-  public final int getRGB (int pixel)
+  public final int getRGB(int pixel)
   {
     if (pixel >= 0 && pixel < map_size)
-	    return rgb[pixel];
+      return rgb[pixel];
     
     return 0;
   }
@@ -444,36 +614,47 @@
    *
    * @param rgb The destination array.
    */
-  public final void getRGBs (int[] rgb)
+  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. */
+  /** 
+   * Return <code>true</code> if the lookup table contains valid data for 
+   * <code>pixel</code>, and <code>false</code> otherwise.
+   *
+   * @param pixel  the pixel value used to index the color lookup table.
+   * @return <code>true</code> if <code>pixel</code> is valid, 
+   *         <code>false</code> otherwise.
+   */
   public boolean isValid(int pixel)
   {
-    return validBits.testBit(pixel);
+    if (pixel >= 0)
+      return validBits.testBit(pixel);
+    return false;
   }
   
-  /** Return true if all pixels are valid, false otherwise. */
+  /** 
+   * Return <code>true</code> if all pixels are valid, <code>false</code> 
+   * otherwise.
+   *
+   * @return <code>true</code> if all pixels are valid, <code>false</code> 
+   * 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"));
+    allbits = allbits.setBit(map_size);
+    allbits = 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.
+   * Returns a binary value ([EMAIL PROTECTED] BigInteger}) where each bit represents an 
+   * entry in the color lookup table.  If the bit is on, the entry is valid.
+   * 
+   * @return The binary value.
    */
   public BigInteger getValidPixels()
   {
@@ -481,7 +662,8 @@
   }
   
   /**
-   * Construct a BufferedImage with rgb pixel values from a Raster.
+   * Construct a [EMAIL PROTECTED] BufferedImage} with rgb pixel values from a 
+   * [EMAIL PROTECTED] 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
@@ -513,4 +695,3 @@
     return im;
   }
 }
-
_______________________________________________
Classpath-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/classpath-patches

Reply via email to