/*
 * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.awt.image;

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

/**
 * The {@code IndexColorModel} class is a {@code ColorModel}
 * class that works with pixel values consisting of a
 * single sample that is an index into a fixed colormap in the default
 * sRGB color space.  The colormap specifies red, green, blue, and
 * optional alpha components corresponding to each index.  All components
 * are represented in the colormap as 8-bit unsigned integral values.
 * Some constructors allow the caller to specify "holes" in the colormap
 * by indicating which colormap entries are valid and which represent
 * unusable colors via the bits set in a {@code BigInteger} object.
 * This color model is similar to an X11 PseudoColor visual.
 * <p>
 * Some constructors provide a means to specify an alpha component
 * for each pixel in the colormap, while others either provide no
 * such means or, in some cases, a flag to indicate whether the
 * colormap data contains alpha values.  If no alpha is supplied to
 * the constructor, an opaque alpha component (alpha = 1.0) is
 * assumed for each entry.
 * An optional transparent pixel value can be supplied that indicates a
 * pixel to be made completely transparent, regardless of any alpha
 * component supplied or assumed for that pixel value.
 * Note that the color components in the colormap of an
 * {@code IndexColorModel} objects are never pre-multiplied with
 * the alpha components.
 * <p>
 * <a name="transparency">
 * The transparency of an {@code IndexColorModel} object is
 * determined by examining the alpha components of the colors in the
 * colormap and choosing the most specific value after considering
 * the optional alpha values and any transparent index specified.
 * The transparency value is {@code Transparency.OPAQUE}
 * only if all valid colors in
 * the colormap are opaque and there is no valid transparent pixel.
 * If all valid colors
 * in the colormap are either completely opaque (alpha = 1.0) or
 * completely transparent (alpha = 0.0), which typically occurs when
 * a valid transparent pixel is specified,
 * the value is {@code Transparency.BITMASK}.
 * Otherwise, the value is {@code Transparency.TRANSLUCENT}, indicating
 * that some valid color has an alpha component that is
 * neither completely transparent nor completely opaque
 * (0.0 &lt; alpha &lt; 1.0).
 * </a>
 *
 * <p>
 * If an {@code IndexColorModel} object has
 * a transparency value of {@code Transparency.OPAQUE},
 * then the {@code hasAlpha}
 * and {@code getNumComponents} methods
 * (both inherited from {@code ColorModel})
 * return false and 3, respectively.
 * For any other transparency value,
 * {@code hasAlpha} returns true
 * and {@code getNumComponents} returns 4.
 *
 * <p>
 * <a name="index_values">
 * The values used to index into the colormap are taken from the least
 * significant <em>n</em> bits of pixel representations where
 * <em>n</em> is based on the pixel size specified in the constructor.
 * For pixel sizes smaller than 8 bits, <em>n</em> is rounded up to a
 * power of two (3 becomes 4 and 5,6,7 become 8).
 * For pixel sizes between 8 and 16 bits, <em>n</em> is equal to the
 * pixel size.
 * Pixel sizes larger than 16 bits are not supported by this class.
 * Higher order bits beyond <em>n</em> are ignored in pixel representations.
 * Index values greater than or equal to the map size, but less than
 * 2<sup><em>n</em></sup>, are undefined and return 0 for all color and
 * alpha components.
 * </a>
 * <p>
 * For those methods that use a primitive array pixel representation of
 * type {@code transferType}, the array length is always one.
 * The transfer types supported are {@code DataBuffer.TYPE_BYTE} and
 * {@code DataBuffer.TYPE_USHORT}.  A single int pixel
 * representation is valid for all objects of this class, since it is
 * always possible to represent pixel values used with this class in a
 * single int.  Therefore, methods that use this representation do
 * not throw an {@code IllegalArgumentException} due to an invalid
 * pixel value.
 * <p>
 * Many of the methods in this class are final.  The reason for
 * this is that the underlying native graphics code makes assumptions
 * about the layout and operation of this class and those assumptions
 * are reflected in the implementations of the methods here that are
 * marked final.  You can subclass this class for other reasons, but
 * you cannot override or modify the behaviour of those methods.
 *
 * @see ColorModel
 * @see ColorSpace
 * @see DataBuffer
 *
 */
public class IndexColorModel extends ColorModel {
    private int rgb[];
    private int map_size;
    private int pixel_mask;
    private int transparent_index = -1;
    private boolean allgrayopaque;
    private BigInteger validBits;

    private sun.awt.image.BufImgSurfaceData.ICMColorData colorData = null;

    private static int[] opaqueBits = {8, 8, 8};
    private static int[] alphaBits = {8, 8, 8, 8};

    private static native void initIDs();
    static {
        ColorModel.loadLibraries();
        initIDs();
    }
    /**
     * Constructs an {@code IndexColorModel} from the specified
     * arrays of red, green, and blue components.  Pixels described
     * by this color model all have alpha components of 255
     * unnormalized (1.0&nbsp;normalized), which means they
     * are fully opaque.  All of the arrays specifying the color
     * components must have at least the specified number of entries.
     * The {@code ColorSpace} is the default sRGB space.
     * Since there is no alpha information in any of the arguments
     * to this constructor, the transparency value is always
     * {@code Transparency.OPAQUE}.
     * The transfer type is the smallest of {@code DataBuffer.TYPE_BYTE}
     * or {@code DataBuffer.TYPE_USHORT} that can hold a single pixel.
     * @param bits      the number of bits each pixel occupies
     * @param size      the size of the color component arrays
     * @param r         the array of red color components
     * @param g         the array of green color components
     * @param b         the array of blue color components
     * @throws IllegalArgumentException if {@code bits} is less
     *         than 1 or greater than 16
     * @throws IllegalArgumentException if {@code size} is less
     *         than 1
     */
    public IndexColorModel(int bits, int size,
                           byte r[], byte g[], byte b[]) {
        super(bits, opaqueBits,
              ColorSpace.getInstance(ColorSpace.CS_sRGB),
              false, false, OPAQUE,
              ColorModel.getDefaultTransferType(bits));
        if (bits < 1 || bits > 16) {
            throw new IllegalArgumentException("Number of bits must be between"
                                               +" 1 and 16.");
        }
        setRGBs(size, r, g, b, null);
        calculatePixelMask();
    }

    /**
     * Constructs an {@code IndexColorModel} from the given arrays
     * of red, green, and blue components.  Pixels described by this color
     * model all have alpha components of 255 unnormalized
     * (1.0&nbsp;normalized), which means they are fully opaque, except
     * for the indicated pixel to be made transparent.  All of the arrays
     * specifying the color components must have at least the specified
     * number of entries.
     * The {@code ColorSpace} is the default sRGB space.
     * The transparency value may be {@code Transparency.OPAQUE} or
     * {@code Transparency.BITMASK} depending on the arguments, as
     * specified in the <a href="#transparency">class description</a> above.
     * The transfer type is the smallest of {@code DataBuffer.TYPE_BYTE}
     * or {@code DataBuffer.TYPE_USHORT} that can hold a
     * single pixel.
     * @param bits      the number of bits each pixel occupies
     * @param size      the size of the color component arrays
     * @param r         the array of red color components
     * @param g         the array of green color components
     * @param b         the array of blue color components
     * @param trans     the index of the transparent pixel
     * @throws IllegalArgumentException if {@code bits} is less than
     *          1 or greater than 16
     * @throws IllegalArgumentException if {@code size} is less than
     *          1
     */
    public IndexColorModel(int bits, int size,
                           byte r[], byte g[], byte b[], int trans) {
        super(bits, opaqueBits,
              ColorSpace.getInstance(ColorSpace.CS_sRGB),
              false, false, OPAQUE,
              ColorModel.getDefaultTransferType(bits));
        if (bits < 1 || bits > 16) {
            throw new IllegalArgumentException("Number of bits must be between"
                                               +" 1 and 16.");
        }
        setRGBs(size, r, g, b, null);
        setTransparentPixel(trans);
        calculatePixelMask();
    }

    /**
     * Constructs an {@code IndexColorModel} from the given
     * arrays of red, green, blue and alpha components.  All of the
     * arrays specifying the components must have at least the specified
     * number of entries.
     * The {@code ColorSpace} is the default sRGB space.
     * The transparency value may be any of {@code Transparency.OPAQUE},
     * {@code Transparency.BITMASK},
     * or {@code Transparency.TRANSLUCENT}
     * depending on the arguments, as specified
     * in the <a href="#transparency">class description</a> above.
     * The transfer type is the smallest of {@code DataBuffer.TYPE_BYTE}
     * or {@code DataBuffer.TYPE_USHORT} that can hold a single pixel.
     * @param bits      the number of bits each pixel occupies
     * @param size      the size of the color component arrays
     * @param r         the array of red color components
     * @param g         the array of green color components
     * @param b         the array of blue color components
     * @param a         the array of alpha value components
     * @throws IllegalArgumentException if {@code bits} is less
     *           than 1 or greater than 16
     * @throws IllegalArgumentException if {@code size} is less
     *           than 1
     */
    public IndexColorModel(int bits, int size,
                           byte r[], byte g[], byte b[], byte a[]) {
        super (bits, alphaBits,
               ColorSpace.getInstance(ColorSpace.CS_sRGB),
               true, false, TRANSLUCENT,
               ColorModel.getDefaultTransferType(bits));
        if (bits < 1 || bits > 16) {
            throw new IllegalArgumentException("Number of bits must be between"
                                               +" 1 and 16.");
        }
        setRGBs (size, r, g, b, a);
        calculatePixelMask();
    }

    /**
     * Constructs an {@code IndexColorModel} from a single
     * array of interleaved red, green, blue and optional alpha
     * components.  The array must have enough values in it to
     * fill all of the needed component arrays of the specified
     * size.  The {@code ColorSpace} is the default sRGB space.
     * The transparency value may be any of {@code Transparency.OPAQUE},
     * {@code Transparency.BITMASK},
     * or {@code Transparency.TRANSLUCENT}
     * depending on the arguments, as specified
     * in the <a href="#transparency">class description</a> above.
     * The transfer type is the smallest of
     * {@code DataBuffer.TYPE_BYTE} or {@code DataBuffer.TYPE_USHORT}
     * that can hold a single pixel.
     *
     * @param bits      the number of bits each pixel occupies
     * @param size      the size of the color component arrays
     * @param cmap      the array of color components
     * @param start     the starting offset of the first color component
     * @param hasalpha  indicates whether alpha values are contained in
     *                  the {@code cmap} array
     * @throws IllegalArgumentException if {@code bits} is less
     *           than 1 or greater than 16
     * @throws IllegalArgumentException if {@code size} is less
     *           than 1
     */
    public IndexColorModel(int bits, int size, byte cmap[], int start,
                           boolean hasalpha) {
        this(bits, size, cmap, start, hasalpha, -1);
        if (bits < 1 || bits > 16) {
            throw new IllegalArgumentException("Number of bits must be between"
                                               +" 1 and 16.");
        }
    }

    /**
     * Constructs an {@code IndexColorModel} from a single array of
     * interleaved red, green, blue and optional alpha components.  The
     * specified transparent index represents a pixel that is made
     * entirely transparent regardless of any alpha value specified
     * for it.  The array must have enough values in it to fill all
     * of the needed component arrays of the specified size.
     * The {@code ColorSpace} is the default sRGB space.
     * The transparency value may be any of {@code Transparency.OPAQUE},
     * {@code Transparency.BITMASK},
     * or {@code Transparency.TRANSLUCENT}
     * depending on the arguments, as specified
     * in the <a href="#transparency">class description</a> above.
     * The transfer type is the smallest of
     * {@code DataBuffer.TYPE_BYTE} or {@code DataBuffer.TYPE_USHORT}
     * that can hold a single pixel.
     * @param bits      the number of bits each pixel occupies
     * @param size      the size of the color component arrays
     * @param cmap      the array of color components
     * @param start     the starting offset of the first color component
     * @param hasalpha  indicates whether alpha values are contained in
     *                  the {@code cmap} array
     * @param trans     the index of the fully transparent pixel
     * @throws IllegalArgumentException if {@code bits} is less than
     *               1 or greater than 16
     * @throws IllegalArgumentException if {@code size} is less than
     *               1
     */
    public IndexColorModel(int bits, int size, byte cmap[], int start,
                           boolean hasalpha, int trans) {
        // REMIND: This assumes the ordering: RGB[A]
        super(bits, opaqueBits,
              ColorSpace.getInstance(ColorSpace.CS_sRGB),
              false, false, OPAQUE,
              ColorModel.getDefaultTransferType(bits));

        if (bits < 1 || bits > 16) {
            throw new IllegalArgumentException("Number of bits must be between"
                                               +" 1 and 16.");
        }
        if (size < 1) {
            throw new IllegalArgumentException("Map size ("+size+
                                               ") must be >= 1");
        }
        map_size = size;
        rgb = new int[calcRealMapSize(bits, size)];
        int j = start;
        int alpha = 0xff;
        boolean allgray = true;
        int transparency = OPAQUE;
        for (int i = 0; i < size; i++) {
            int r = cmap[j++] & 0xff;
            int g = cmap[j++] & 0xff;
            int b = cmap[j++] & 0xff;
            allgray = allgray && (r == g) && (g == b);
            if (hasalpha) {
                alpha = cmap[j++] & 0xff;
                if (alpha != 0xff) {
                    if (alpha == 0x00) {
                        if (transparency == OPAQUE) {
                            transparency = BITMASK;
                        }
                        if (transparent_index < 0) {
                            transparent_index = i;
                        }
                    } else {
                        transparency = TRANSLUCENT;
                    }
                    allgray = false;
                }
            }
            rgb[i] = (alpha << 24) | (r << 16) | (g << 8) | b;
        }
        this.allgrayopaque = allgray;
        setTransparency(transparency);
        setTransparentPixel(trans);
        calculatePixelMask();
    }

    /**
     * Constructs an {@code IndexColorModel} from an array of
     * ints where each int is comprised of red, green, blue, and
     * optional alpha components in the default RGB color model format.
     * The specified transparent index represents a pixel that is made
     * entirely transparent regardless of any alpha value specified
     * for it.  The array must have enough values in it to fill all
     * of the needed component arrays of the specified size.
     * The {@code ColorSpace} is the default sRGB space.
     * The transparency value may be any of {@code Transparency.OPAQUE},
     * {@code Transparency.BITMASK},
     * or {@code Transparency.TRANSLUCENT}
     * depending on the arguments, as specified
     * in the <a href="#transparency">class description</a> above.
     * @param bits      the number of bits each pixel occupies
     * @param size      the size of the color component arrays
     * @param cmap      the array of color components
     * @param start     the starting offset of the first color component
     * @param hasalpha  indicates whether alpha values are contained in
     *                  the {@code cmap} array
     * @param trans     the index of the fully transparent pixel
     * @param transferType the data type of the array used to represent
     *           pixel values.  The data type must be either
     *           {@code DataBuffer.TYPE_BYTE} or
     *           {@code DataBuffer.TYPE_USHORT}.
     * @throws IllegalArgumentException if {@code bits} is less
     *           than 1 or greater than 16
     * @throws IllegalArgumentException if {@code size} is less
     *           than 1
     * @throws IllegalArgumentException if {@code transferType} is not
     *           one of {@code DataBuffer.TYPE_BYTE} or
     *           {@code DataBuffer.TYPE_USHORT}
     */
    public IndexColorModel(int bits, int size,
                           int cmap[], int start,
                           boolean hasalpha, int trans, int transferType) {
        // REMIND: This assumes the ordering: RGB[A]
        super(bits, opaqueBits,
              ColorSpace.getInstance(ColorSpace.CS_sRGB),
              false, false, OPAQUE,
              transferType);

        if (bits < 1 || bits > 16) {
            throw new IllegalArgumentException("Number of bits must be between"
                                               +" 1 and 16.");
        }
        if (size < 1) {
            throw new IllegalArgumentException("Map size ("+size+
                                               ") must be >= 1");
        }
        if ((transferType != DataBuffer.TYPE_BYTE) &&
            (transferType != DataBuffer.TYPE_USHORT)) {
            throw new IllegalArgumentException("transferType must be either" +
                "DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT");
        }

        setRGBs(size, cmap, start, hasalpha);
        setTransparentPixel(trans);
        calculatePixelMask();
    }

    /**
     * Constructs an {@code IndexColorModel} from an
     * {@code int} array where each {@code int} is
     * comprised of red, green, blue, and alpha
     * components in the default RGB color model format.
     * The array must have enough values in it to fill all
     * of the needed component arrays of the specified size.
     * The {@code ColorSpace} is the default sRGB space.
     * The transparency value may be any of {@code Transparency.OPAQUE},
     * {@code Transparency.BITMASK},
     * or {@code Transparency.TRANSLUCENT}
     * depending on the arguments, as specified
     * in the <a href="#transparency">class description</a> above.
     * The transfer type must be one of {@code DataBuffer.TYPE_BYTE}
     * {@code DataBuffer.TYPE_USHORT}.
     * The {@code BigInteger} object specifies the valid/invalid pixels
     * in the {@code cmap} array.  A pixel is valid if the
     * {@code BigInteger} value at that index is set, and is invalid
     * if the {@code BigInteger} bit  at that index is not set.
     * @param bits the number of bits each pixel occupies
     * @param size the size of the color component array
     * @param cmap the array of color components
     * @param start the starting offset of the first color component
     * @param transferType the specified data type
     * @param validBits a {@code BigInteger} object.  If a bit is
     *    set in the BigInteger, the pixel at that index is valid.
     *    If a bit is not set, the pixel at that index
     *    is considered invalid.  If null, all pixels are valid.
     *    Only bits from 0 to the map size are considered.
     * @throws IllegalArgumentException if {@code bits} is less
     *           than 1 or greater than 16
     * @throws IllegalArgumentException if {@code size} is less
     *           than 1
     * @throws IllegalArgumentException if {@code transferType} is not
     *           one of {@code DataBuffer.TYPE_BYTE} or
     *           {@code DataBuffer.TYPE_USHORT}
     *
     * @since 1.3
     */
    public IndexColorModel(int bits, int size, int cmap[], int start,
                           int transferType, BigInteger validBits) {
        super (bits, alphaBits,
               ColorSpace.getInstance(ColorSpace.CS_sRGB),
               true, false, TRANSLUCENT,
               transferType);

        if (bits < 1 || bits > 16) {
            throw new IllegalArgumentException("Number of bits must be between"
                                               +" 1 and 16.");
        }
        if (size < 1) {
            throw new IllegalArgumentException("Map size ("+size+
                                               ") must be >= 1");
        }
        if ((transferType != DataBuffer.TYPE_BYTE) &&
            (transferType != DataBuffer.TYPE_USHORT)) {
            throw new IllegalArgumentException("transferType must be either" +
                "DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT");
        }

        if (validBits != null) {
            // Check to see if it is all valid
            for (int i=0; i < size; i++) {
                if (!validBits.testBit(i)) {
                    this.validBits = validBits;
                    break;
                }
            }
        }

        setRGBs(size, cmap, start, true);
        calculatePixelMask();
    }

    private void setRGBs(int size, byte r[], byte g[], byte b[], byte a[]) {
        if (size < 1) {
            throw new IllegalArgumentException("Map size ("+size+
                                               ") must be >= 1");
        }
        map_size = size;
        rgb = new int[calcRealMapSize(pixel_bits, size)];
        int alpha = 0xff;
        int transparency = OPAQUE;
        boolean allgray = true;
        for (int i = 0; i < size; i++) {
            int rc = r[i] & 0xff;
            int gc = g[i] & 0xff;
            int bc = b[i] & 0xff;
            allgray = allgray && (rc == gc) && (gc == bc);
            if (a != null) {
                alpha = a[i] & 0xff;
                if (alpha != 0xff) {
                    if (alpha == 0x00) {
                        if (transparency == OPAQUE) {
                            transparency = BITMASK;
                        }
                        if (transparent_index < 0) {
                            transparent_index = i;
                        }
                    } else {
                        transparency = TRANSLUCENT;
                    }
                    allgray = false;
                }
            }
            rgb[i] = (alpha << 24) | (rc << 16) | (gc << 8) | bc;
        }
        this.allgrayopaque = allgray;
        setTransparency(transparency);
    }

    private void setRGBs(int size, int cmap[], int start, boolean hasalpha) {
        map_size = size;
        rgb = new int[calcRealMapSize(pixel_bits, size)];
        int j = start;
        int transparency = OPAQUE;
        boolean allgray = true;
        BigInteger validBits = this.validBits;
        for (int i = 0; i < size; i++, j++) {
            if (validBits != null && !validBits.testBit(i)) {
                continue;
            }
            int cmaprgb = cmap[j];
            int r = (cmaprgb >> 16) & 0xff;
            int g = (cmaprgb >>  8) & 0xff;
            int b = (cmaprgb      ) & 0xff;
            allgray = allgray && (r == g) && (g == b);
            if (hasalpha) {
                int alpha = cmaprgb >>> 24;
                if (alpha != 0xff) {
                    if (alpha == 0x00) {
                        if (transparency == OPAQUE) {
                            transparency = BITMASK;
                        }
                        if (transparent_index < 0) {
                            transparent_index = i;
                        }
                    } else {
                        transparency = TRANSLUCENT;
                    }
                    allgray = false;
                }
            } else {
                cmaprgb |= 0xff000000;
            }
            rgb[i] = cmaprgb;
        }
        this.allgrayopaque = allgray;
        setTransparency(transparency);
    }

    private int calcRealMapSize(int bits, int size) {
        int newSize = Math.max(1 << bits, size);
        return Math.max(newSize, 256);
    }

    private BigInteger getAllValid() {
        int numbytes = (map_size+7)/8;
        byte[] valid = new byte[numbytes];
        java.util.Arrays.fill(valid, (byte)0xff);
        valid[0] = (byte)(0xff >>> (numbytes*8 - map_size));

        return new BigInteger(1, valid);
    }

    /**
     * Returns the transparency.  Returns either OPAQUE, BITMASK,
     * or TRANSLUCENT
     * @return the transparency of this {@code IndexColorModel}
     * @see Transparency#OPAQUE
     * @see Transparency#BITMASK
     * @see Transparency#TRANSLUCENT
     */
    public int getTransparency() {
        return transparency;
    }

    /**
     * Returns an array of the number of bits for each color/alpha component.
     * The array contains the color components in the order red, green,
     * blue, followed by the alpha component, if present.
     * @return an array containing the number of bits of each color
     *         and alpha component of this {@code IndexColorModel}
     */
    public int[] getComponentSize() {
        if (nBits == null) {
            if (supportsAlpha) {
                nBits = new int[4];
                nBits[3] = 8;
            }
            else {
                nBits = new int[3];
            }
            nBits[0] = nBits[1] = nBits[2] = 8;
        }
        return nBits.clone();
    }

    /**
     * Returns the size of the color/alpha component arrays in this
     * {@code IndexColorModel}.
     * @return the size of the color and alpha component arrays.
     */
    public final int getMapSize() {
        return map_size;
    }

    /**
     * Returns the index of a transparent pixel in this
     * {@code IndexColorModel} or -1 if there is no pixel
     * with an alpha value of 0.  If a transparent pixel was
     * explicitly specified in one of the constructors by its
     * index, then that index will be preferred, otherwise,
     * the index of any pixel which happens to be fully transparent
     * may be returned.
     * @return the index of a transparent pixel in this
     *         {@code IndexColorModel} object, or -1 if there
     *         is no such pixel
     */
    public final int getTransparentPixel() {
        return transparent_index;
    }

    /**
     * Copies the array of red color components into the specified array.
     * Only the initial entries of the array as specified by
     * {@link #getMapSize() getMapSize} are written.
     * @param r the specified array into which the elements of the
     *      array of red color components are copied
     */
    public final void getReds(byte r[]) {
        for (int i = 0; i < map_size; i++) {
            r[i] = (byte) (rgb[i] >> 16);
        }
    }

    /**
     * Copies the array of green color components into the specified array.
     * Only the initial entries of the array as specified by
     * {@code getMapSize} are written.
     * @param g the specified array into which the elements of the
     *      array of green color components are copied
     */
    public final void getGreens(byte g[]) {
        for (int i = 0; i < map_size; i++) {
            g[i] = (byte) (rgb[i] >> 8);
        }
    }

    /**
     * Copies the array of blue color components into the specified array.
     * Only the initial entries of the array as specified by
     * {@code getMapSize} are written.
     * @param b the specified array into which the elements of the
     *      array of blue color components are copied
     */
    public final void getBlues(byte b[]) {
        for (int i = 0; i < map_size; i++) {
            b[i] = (byte) rgb[i];
        }
    }

    /**
     * Copies the array of alpha transparency components into the
     * specified array.  Only the initial entries of the array as specified
     * by {@code getMapSize} are written.
     * @param a the specified array into which the elements of the
     *      array of alpha components are copied
     */
    public final void getAlphas(byte a[]) {
        for (int i = 0; i < map_size; i++) {
            a[i] = (byte) (rgb[i] >> 24);
        }
    }

    /**
     * Converts data for each index from the color and alpha component
     * arrays to an int in the default RGB ColorModel format and copies
     * the resulting 32-bit ARGB values into the specified array.  Only
     * the initial entries of the array as specified by
     * {@code getMapSize} are
     * written.
     * @param rgb the specified array into which the converted ARGB
     *        values from this array of color and alpha components
     *        are copied.
     */
    public final void getRGBs(int rgb[]) {
        System.arraycopy(this.rgb, 0, rgb, 0, map_size);
    }

    private void setTransparentPixel(int trans) {
        if (trans >= 0 && trans < map_size) {
            rgb[trans] &= 0x00ffffff;
            transparent_index = trans;
            allgrayopaque = false;
            if (this.transparency == OPAQUE) {
                setTransparency(BITMASK);
            }
        }
    }

    private void setTransparency(int transparency) {
        if (this.transparency != transparency) {
            this.transparency = transparency;
            if (transparency == OPAQUE) {
                supportsAlpha = false;
                numComponents = 3;
                nBits = opaqueBits;
            } else {
                supportsAlpha = true;
                numComponents = 4;
                nBits = alphaBits;
            }
        }
    }

    /**
     * This method is called from the constructors to set the pixel_mask
     * value, which is based on the value of pixel_bits.  The pixel_mask
     * value is used to mask off the pixel parameters for methods such
     * as getRed(), getGreen(), getBlue(), getAlpha(), and getRGB().
     */
    private final void calculatePixelMask() {
        // Note that we adjust the mask so that our masking behavior here
        // is consistent with that of our native rendering loops.
        int maskbits = pixel_bits;
        if (maskbits == 3) {
            maskbits = 4;
        } else if (maskbits > 4 && maskbits < 8) {
            maskbits = 8;
        }
        pixel_mask = (1 << maskbits) - 1;
    }

    /**
     * Returns the red color component for the specified pixel, scaled
     * from 0 to 255 in the default RGB ColorSpace, sRGB.  The pixel value
     * is specified as an int.
     * Only the lower <em>n</em> bits of the pixel value, as specified in the
     * <a href="#index_values">class description</a> above, are used to
     * calculate the returned value.
     * The returned value is a non pre-multiplied value.
     * @param pixel the specified pixel
     * @return the value of the red color component for the specified pixel
     */
    public final int getRed(int pixel) {
        return (rgb[pixel & pixel_mask] >> 16) & 0xff;
    }

    /**
     * Returns the green color component for the specified pixel, scaled
     * from 0 to 255 in the default RGB ColorSpace, sRGB.  The pixel value
     * is specified as an int.
     * Only the lower <em>n</em> bits of the pixel value, as specified in the
     * <a href="#index_values">class description</a> above, are used to
     * calculate the returned value.
     * The returned value is a non pre-multiplied value.
     * @param pixel the specified pixel
     * @return the value of the green color component for the specified pixel
     */
    public final int getGreen(int pixel) {
        return (rgb[pixel & pixel_mask] >> 8) & 0xff;
    }

    /**
     * Returns the blue color component for the specified pixel, scaled
     * from 0 to 255 in the default RGB ColorSpace, sRGB.  The pixel value
     * is specified as an int.
     * Only the lower <em>n</em> bits of the pixel value, as specified in the
     * <a href="#index_values">class description</a> above, are used to
     * calculate the returned value.
     * The returned value is a non pre-multiplied value.
     * @param pixel the specified pixel
     * @return the value of the blue color component for the specified pixel
     */
    public final int getBlue(int pixel) {
        return rgb[pixel & pixel_mask] & 0xff;
    }

    /**
     * Returns the alpha component for the specified pixel, scaled
     * from 0 to 255.  The pixel value is specified as an int.
     * Only the lower <em>n</em> bits of the pixel value, as specified in the
     * <a href="#index_values">class description</a> above, are used to
     * calculate the returned value.
     * @param pixel the specified pixel
     * @return the value of the alpha component for the specified pixel
     */
    public final int getAlpha(int pixel) {
        return (rgb[pixel & pixel_mask] >> 24) & 0xff;
    }

    /**
     * Returns the color/alpha components of the pixel in the default
     * RGB color model format.  The pixel value is specified as an int.
     * Only the lower <em>n</em> bits of the pixel value, as specified in the
     * <a href="#index_values">class description</a> above, are used to
     * calculate the returned value.
     * The returned value is in a non pre-multiplied format.
     * @param pixel the specified pixel
     * @return the color and alpha components of the specified pixel
     * @see ColorModel#getRGBdefault
     */
    public final int getRGB(int pixel) {
        return rgb[pixel & pixel_mask];
    }

    private static final int CACHESIZE = 40;
    private int lookupcache[] = new int[CACHESIZE];

    /**
     * Returns a data element array representation of a pixel in this
     * ColorModel, given an integer pixel representation in the
     * default RGB color model.  This array can then be passed to the
     * {@link WritableRaster#setDataElements(int, int, java.lang.Object) setDataElements}
     * method of a {@link WritableRaster} object.  If the pixel variable is
     * {@code null}, a new array is allocated.  If {@code pixel}
     * is not {@code null}, it must be
     * a primitive array of type {@code transferType}; otherwise, a
     * {@code ClassCastException} is thrown.  An
     * {@code ArrayIndexOutOfBoundsException} is
     * thrown if {@code pixel} is not large enough to hold a pixel
     * value for this {@code ColorModel}.  The pixel array is returned.
     * <p>
     * Since {@code IndexColorModel} can be subclassed, subclasses
     * inherit the implementation of this method and if they don't
     * override it then they throw an exception if they use an
     * unsupported {@code transferType}.
     *
     * @param rgb the integer pixel representation in the default RGB
     * color model
     * @param pixel the specified pixel
     * @return an array representation of the specified pixel in this
     *  {@code IndexColorModel}.
     * @throws ClassCastException if {@code pixel}
     *  is not a primitive array of type {@code transferType}
     * @throws ArrayIndexOutOfBoundsException if
     *  {@code pixel} is not large enough to hold a pixel value
     *  for this {@code ColorModel}
     * @throws UnsupportedOperationException if {@code transferType}
     *         is invalid
     * @see WritableRaster#setDataElements
     * @see SampleModel#setDataElements
     */
    public synchronized Object getDataElements(int rgb, Object pixel) {
        int red = (rgb>>16) & 0xff;
        int green = (rgb>>8) & 0xff;
        int blue  = rgb & 0xff;
        int alpha = (rgb>>>24);
        int pix = 0;

        // Note that pixels are stored at lookupcache[2*i]
        // and the rgb that was searched is stored at
        // lookupcache[2*i+1].  Also, the pixel is first
        // inverted using the unary complement operator
        // before storing in the cache so it can never be 0.
        for (int i = CACHESIZE - 2; i >= 0; i -= 2) {
            if ((pix = lookupcache[i]) == 0) {
                break;
            }
            if (rgb == lookupcache[i+1]) {
                return installpixel(pixel, ~pix);
            }
        }

        if (allgrayopaque) {
            // IndexColorModel objects are all tagged as
            // non-premultiplied so ignore the alpha value
            // of the incoming color, convert the
            // non-premultiplied color components to a
            // grayscale value and search for the closest
            // gray value in the palette.  Since all colors
            // in the palette are gray, we only need compare
            // to one of the color components for a match
            // using a simple linear distance formula.

            int minDist = 256;
            int d;
            int gray = (red*77 + green*150 + blue*29 + 128)/256;

            for (int i = 0; i < map_size; i++) {
                if (this.rgb[i] == 0x0) {
                    // For allgrayopaque colormaps, entries are 0
                    // iff they are an invalid color and should be
                    // ignored during color searches.
                    continue;
                }
                d = (this.rgb[i] & 0xff) - gray;
                if (d < 0) d = -d;
                if (d < minDist) {
                    pix = i;
                    if (d == 0) {
                        break;
                    }
                    minDist = d;
                }
            }
        } else if (transparency == OPAQUE) {
            // IndexColorModel objects are all tagged as
            // non-premultiplied so ignore the alpha value
            // of the incoming color and search for closest
            // color match independently using a 3 component
            // Euclidean distance formula.
            // For opaque colormaps, palette entries are 0
            // iff they are an invalid color and should be
            // ignored during color searches.
            // As an optimization, exact color searches are
            // likely to be fairly common in opaque colormaps
            // so first we will do a quick search for an
            // exact match.

            int smallestError = Integer.MAX_VALUE;
            int lut[] = this.rgb;
            int lutrgb;
            for (int i=0; i < map_size; i++) {
                lutrgb = lut[i];
                if (lutrgb == rgb && lutrgb != 0) {
                    pix = i;
                    smallestError = 0;
                    break;
                }
            }

            if (smallestError != 0) {
                for (int i=0; i < map_size; i++) {
                    lutrgb = lut[i];
                    if (lutrgb == 0) {
                        continue;
                    }

                    int tmp = ((lutrgb >> 16) & 0xff) - red;
                    int currentError = tmp*tmp;
                    if (currentError < smallestError) {
                        tmp = ((lutrgb >> 8) & 0xff) - green;
                        currentError += tmp * tmp;
                        if (currentError < smallestError) {
                            tmp = (lutrgb & 0xff) - blue;
                            currentError += tmp * tmp;
                            if (currentError < smallestError) {
                                pix = i;
                                smallestError = currentError;
                            }
                        }
                    }
                }
            }
        } else if (alpha == 0 && transparent_index >= 0) {
            // Special case - transparent color maps to the
            // specified transparent pixel, if there is one

            pix = transparent_index;
        } else {
            // IndexColorModel objects are all tagged as
            // non-premultiplied so use non-premultiplied
            // color components in the distance calculations.
            // Look for closest match using a 4 component
            // Euclidean distance formula.

            int smallestError = Integer.MAX_VALUE;
            int lut[] = this.rgb;
            for (int i=0; i < map_size; i++) {
                int lutrgb = lut[i];
                if (lutrgb == rgb) {
                    if (validBits != null && !validBits.testBit(i)) {
                        continue;
                    }
                    pix = i;
                    break;
                }

                int tmp = ((lutrgb >> 16) & 0xff) - red;
                int currentError = tmp*tmp;
                if (currentError < smallestError) {
                    tmp = ((lutrgb >> 8) & 0xff) - green;
                    currentError += tmp * tmp;
                    if (currentError < smallestError) {
                        tmp = (lutrgb & 0xff) - blue;
                        currentError += tmp * tmp;
                        if (currentError < smallestError) {
                            tmp = (lutrgb >>> 24) - alpha;
                            currentError += tmp * tmp;
                            if (currentError < smallestError &&
                                (validBits == null || validBits.testBit(i)))
                            {
                                pix = i;
                                smallestError = currentError;
                            }
                        }
                    }
                }
            }
        }
        System.arraycopy(lookupcache, 2, lookupcache, 0, CACHESIZE - 2);
        lookupcache[CACHESIZE - 1] = rgb;
        lookupcache[CACHESIZE - 2] = ~pix;
        return installpixel(pixel, pix);
    }

    private Object installpixel(Object pixel, int pix) {
        switch (transferType) {
        case DataBuffer.TYPE_INT:
            int[] intObj;
            if (pixel == null) {
                pixel = intObj = new int[1];
            } else {
                intObj = (int[]) pixel;
            }
            intObj[0] = pix;
            break;
        case DataBuffer.TYPE_BYTE:
            byte[] byteObj;
            if (pixel == null) {
                pixel = byteObj = new byte[1];
            } else {
                byteObj = (byte[]) pixel;
            }
            byteObj[0] = (byte) pix;
            break;
        case DataBuffer.TYPE_USHORT:
            short[] shortObj;
            if (pixel == null) {
                pixel = shortObj = new short[1];
            } else {
                shortObj = (short[]) pixel;
            }
            shortObj[0] = (short) pix;
            break;
        default:
            throw new UnsupportedOperationException("This method has not been "+
                             "implemented for transferType " + transferType);
        }
        return pixel;
    }

    /**
     * Returns an array of unnormalized color/alpha components for a
     * specified pixel in this {@code ColorModel}.  The pixel value
     * is specified as an int.  If the {@code components} array is {@code null},
     * a new array is allocated that contains
     * {@code offset + getNumComponents()} elements.
     * The {@code components} array is returned,
     * with the alpha component included
     * only if {@code hasAlpha} returns true.
     * Color/alpha components are stored in the {@code components} array starting
     * at {@code offset} even if the array is allocated by this method.
     * An {@code ArrayIndexOutOfBoundsException}
     * is thrown if  the {@code components} array is not {@code null} and is
     * not large enough to hold all the color and alpha components
     * starting at {@code offset}.
     * @param pixel the specified pixel
     * @param components the array to receive the color and alpha
     * components of the specified pixel
     * @param offset the offset into the {@code components} array at
     * which to start storing the color and alpha components
     * @return an array containing the color and alpha components of the
     * specified pixel starting at the specified offset.
     * @see ColorModel#hasAlpha
     * @see ColorModel#getNumComponents
     */
    public int[] getComponents(int pixel, int[] components, int offset) {
        if (components == null) {
            components = new int[offset+numComponents];
        }

        // REMIND: Needs to change if different color space
        components[offset+0] = getRed(pixel);
        components[offset+1] = getGreen(pixel);
        components[offset+2] = getBlue(pixel);
        if (supportsAlpha && (components.length-offset) > 3) {
            components[offset+3] = getAlpha(pixel);
        }

        return components;
    }

    /**
     * Returns an array of unnormalized color/alpha components for
     * a specified pixel in this {@code ColorModel}.  The pixel
     * value is specified by an array of data elements of type
     * {@code transferType} passed in as an object reference.
     * If {@code pixel} is not a primitive array of type
     * {@code transferType}, a {@code ClassCastException}
     * is thrown.  An {@code ArrayIndexOutOfBoundsException}
     * is thrown if {@code pixel} is not large enough to hold
     * a pixel value for this {@code ColorModel}.  If the
     * {@code components} array is {@code null}, a new array
     * is allocated that contains
     * {@code offset + getNumComponents()} elements.
     * The {@code components} array is returned,
     * with the alpha component included
     * only if {@code hasAlpha} returns true.
     * Color/alpha components are stored in the {@code components}
     * array starting at {@code offset} even if the array is
     * allocated by this method.  An
     * {@code ArrayIndexOutOfBoundsException} is also
     * thrown if  the {@code components} array is not
     * {@code null} and is not large enough to hold all the color
     * and alpha components starting at {@code offset}.
     * <p>
     * Since {@code IndexColorModel} can be subclassed, subclasses
     * inherit the implementation of this method and if they don't
     * override it then they throw an exception if they use an
     * unsupported {@code transferType}.
     *
     * @param pixel the specified pixel
     * @param components an array that receives the color and alpha
     * components of the specified pixel
     * @param offset the index into the {@code components} array at
     * which to begin storing the color and alpha components of the
     * specified pixel
     * @return an array containing the color and alpha components of the
     * specified pixel starting at the specified offset.
     * @throws ArrayIndexOutOfBoundsException if {@code pixel}
     *            is not large enough to hold a pixel value for this
     *            {@code ColorModel} or if the
     *            {@code components} array is not {@code null}
     *            and is not large enough to hold all the color
     *            and alpha components starting at {@code offset}
     * @throws ClassCastException if {@code pixel} is not a
     *            primitive array of type {@code transferType}
     * @throws UnsupportedOperationException if {@code transferType}
     *         is not one of the supported transfer types
     * @see ColorModel#hasAlpha
     * @see ColorModel#getNumComponents
     */
    public int[] getComponents(Object pixel, int[] components, int offset) {
        int intpixel;
        switch (transferType) {
            case DataBuffer.TYPE_BYTE:
               byte bdata[] = (byte[])pixel;
               intpixel = bdata[0] & 0xff;
            break;
            case DataBuffer.TYPE_USHORT:
               short sdata[] = (short[])pixel;
               intpixel = sdata[0] & 0xffff;
            break;
            case DataBuffer.TYPE_INT:
               int idata[] = (int[])pixel;
               intpixel = idata[0];
            break;
            default:
               throw new UnsupportedOperationException("This method has not been "+
                   "implemented for transferType " + transferType);
        }
        return getComponents(intpixel, components, offset);
    }

    /**
     * Returns a pixel value represented as an int in this
     * {@code ColorModel} given an array of unnormalized
     * color/alpha components.  An
     * {@code ArrayIndexOutOfBoundsException}
     * is thrown if the {@code components} array is not large
     * enough to hold all of the color and alpha components starting
     * at {@code offset}.  Since
     * {@code ColorModel} can be subclassed, subclasses inherit the
     * implementation of this method and if they don't override it then
     * they throw an exception if they use an unsupported transferType.
     * @param components an array of unnormalized color and alpha
     * components
     * @param offset the index into {@code components} at which to
     * begin retrieving the color and alpha components
     * @return an {@code int} pixel value in this
     * {@code ColorModel} corresponding to the specified components.
     * @throws ArrayIndexOutOfBoundsException if
     *  the {@code components} array is not large enough to
     *  hold all of the color and alpha components starting at
     *  {@code offset}
     * @throws UnsupportedOperationException if {@code transferType}
     *         is invalid
     */
    public int getDataElement(int[] components, int offset) {
        int rgb = (components[offset+0]<<16)
            | (components[offset+1]<<8) | (components[offset+2]);
        if (supportsAlpha) {
            rgb |= (components[offset+3]<<24);
        }
        else {
            rgb |= 0xff000000;
        }
        Object inData = getDataElements(rgb, null);
        int pixel;
        switch (transferType) {
            case DataBuffer.TYPE_BYTE:
               byte bdata[] = (byte[])inData;
               pixel = bdata[0] & 0xff;
            break;
            case DataBuffer.TYPE_USHORT:
               short sdata[] = (short[])inData;
               pixel = sdata[0];
            break;
            case DataBuffer.TYPE_INT:
               int idata[] = (int[])inData;
               pixel = idata[0];
            break;
            default:
               throw new UnsupportedOperationException("This method has not been "+
                   "implemented for transferType " + transferType);
        }
        return pixel;
    }

    /**
     * Returns a data element array representation of a pixel in this
     * {@code ColorModel} given an array of unnormalized color/alpha
     * components.  This array can then be passed to the
     * {@code setDataElements} method of a {@code WritableRaster}
     * object.  An {@code ArrayIndexOutOfBoundsException} is
     * thrown if the
     * {@code components} array is not large enough to hold all of the
     * color and alpha components starting at {@code offset}.
     * If the pixel variable is {@code null}, a new array
     * is allocated.  If {@code pixel} is not {@code null},
     * it must be a primitive array of type {@code transferType};
     * otherwise, a {@code ClassCastException} is thrown.
     * An {@code ArrayIndexOutOfBoundsException} is thrown if pixel
     * is not large enough to hold a pixel value for this
     * {@code ColorModel}.
     * <p>
     * Since {@code IndexColorModel} can be subclassed, subclasses
     * inherit the implementation of this method and if they don't
     * override it then they throw an exception if they use an
     * unsupported {@code transferType}
     *
     * @param components an array of unnormalized color and alpha
     * components
     * @param offset the index into {@code components} at which to
     * begin retrieving color and alpha components
     * @param pixel the {@code Object} representing an array of color
     * and alpha components
     * @return an {@code Object} representing an array of color and
     * alpha components.
     * @throws ClassCastException if {@code pixel}
     *  is not a primitive array of type {@code transferType}
     * @throws ArrayIndexOutOfBoundsException if
     *  {@code pixel} is not large enough to hold a pixel value
     *  for this {@code ColorModel} or the {@code components}
     *  array is not large enough to hold all of the color and alpha
     *  components starting at {@code offset}
     * @throws UnsupportedOperationException if {@code transferType}
     *         is not one of the supported transfer types
     * @see WritableRaster#setDataElements
     * @see SampleModel#setDataElements
     */
    public Object getDataElements(int[] components, int offset, Object pixel) {
        int rgb = (components[offset+0]<<16) | (components[offset+1]<<8)
            | (components[offset+2]);
        if (supportsAlpha) {
            rgb |= (components[offset+3]<<24);
        }
        else {
            rgb &= 0xff000000;
        }
        return getDataElements(rgb, pixel);
    }

    /**
     * Creates a {@code WritableRaster} with the specified width
     * and height that has a data layout ({@code SampleModel})
     * compatible with this {@code ColorModel}.  This method
     * only works for color models with 16 or fewer bits per pixel.
     * <p>
     * Since {@code IndexColorModel} can be subclassed, any
     * subclass that supports greater than 16 bits per pixel must
     * override this method.
     *
     * @param w the width to apply to the new {@code WritableRaster}
     * @param h the height to apply to the new {@code WritableRaster}
     * @return a {@code WritableRaster} object with the specified
     * width and height.
     * @throws UnsupportedOperationException if the number of bits in a
     *         pixel is greater than 16
     * @see WritableRaster
     * @see SampleModel
     */
    public WritableRaster createCompatibleWritableRaster(int w, int h) {
        WritableRaster raster;

        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
            // TYPE_BINARY
            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE,
                                               w, h, 1, pixel_bits, null);
        }
        else if (pixel_bits <= 8) {
            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
                                                  w,h,1,null);
        }
        else if (pixel_bits <= 16) {
            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT,
                                                  w,h,1,null);
        }
        else {
            throw new
                UnsupportedOperationException("This method is not supported "+
                                              " for pixel bits > 16.");
        }
        return raster;
    }

    /**
      * Returns {@code true} if {@code raster} is compatible
      * with this {@code ColorModel} or {@code false} if it
      * is not compatible with this {@code ColorModel}.
      * @param raster the {@link Raster} object to test for compatibility
      * @return {@code true} if {@code raster} is compatible
      * with this {@code ColorModel}; {@code false} otherwise.
      *
      */
    public boolean isCompatibleRaster(Raster raster) {

        int size = raster.getSampleModel().getSampleSize(0);
        return ((raster.getTransferType() == transferType) &&
                (raster.getNumBands() == 1) && ((1 << size) >= map_size));
    }

    /**
     * Creates a {@code SampleModel} with the specified
     * width and height that has a data layout compatible with
     * this {@code ColorModel}.
     * @param w the width to apply to the new {@code SampleModel}
     * @param h the height to apply to the new {@code SampleModel}
     * @return a {@code SampleModel} object with the specified
     * width and height.
     * @throws IllegalArgumentException if {@code w} or
     *         {@code h} is not greater than 0
     * @see SampleModel
     */
    public SampleModel createCompatibleSampleModel(int w, int h) {
        int[] off = new int[1];
        off[0] = 0;
        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
            return new MultiPixelPackedSampleModel(transferType, w, h,
                                                   pixel_bits);
        }
        else {
            return new ComponentSampleModel(transferType, w, h, 1, w,
                                            off);
        }
    }

    /**
     * Checks if the specified {@code SampleModel} is compatible
     * with this {@code ColorModel}.  If {@code sm} is
     * {@code null}, this method returns {@code false}.
     * @param sm the specified {@code SampleModel},
     *           or {@code null}
     * @return {@code true} if the specified {@code SampleModel}
     * is compatible with this {@code ColorModel}; {@code false}
     * otherwise.
     * @see SampleModel
     */
    public boolean isCompatibleSampleModel(SampleModel sm) {
        // fix 4238629
        if (! (sm instanceof ComponentSampleModel) &&
            ! (sm instanceof MultiPixelPackedSampleModel)   ) {
            return false;
        }

        // Transfer type must be the same
        if (sm.getTransferType() != transferType) {
            return false;
        }

        if (sm.getNumBands() != 1) {
            return false;
        }

        return true;
    }

    /**
     * Returns a new {@code BufferedImage} of TYPE_INT_ARGB or
     * TYPE_INT_RGB that has a {@code Raster} with pixel data
     * computed by expanding the indices in the source {@code Raster}
     * using the color/alpha component arrays of this {@code ColorModel}.
     * Only the lower <em>n</em> bits of each index value in the source
     * {@code Raster}, as specified in the
     * <a href="#index_values">class description</a> above, are used to
     * compute the color/alpha values in the returned image.
     * If {@code forceARGB} is {@code true}, a TYPE_INT_ARGB image is
     * returned regardless of whether or not this {@code ColorModel}
     * has an alpha component array or a transparent pixel.
     * @param raster the specified {@code Raster}
     * @param forceARGB if {@code true}, the returned
     *     {@code BufferedImage} is TYPE_INT_ARGB; otherwise it is
     *     TYPE_INT_RGB
     * @return a {@code BufferedImage} created with the specified
     *     {@code Raster}
     * @throws IllegalArgumentException if the raster argument is not
     *           compatible with this IndexColorModel
     */
    public BufferedImage convertToIntDiscrete(Raster raster,
                                              boolean forceARGB) {
        ColorModel cm;

        if (!isCompatibleRaster(raster)) {
            throw new IllegalArgumentException("This raster is not compatible" +
                 "with this IndexColorModel.");
        }
        if (forceARGB || transparency == TRANSLUCENT) {
            cm = ColorModel.getRGBdefault();
        }
        else if (transparency == BITMASK) {
            cm = new DirectColorModel(25, 0xff0000, 0x00ff00, 0x0000ff,
                                      0x1000000);
        }
        else {
            cm = new DirectColorModel(24, 0xff0000, 0x00ff00, 0x0000ff);
        }

        int w = raster.getWidth();
        int h = raster.getHeight();
        WritableRaster discreteRaster =
                  cm.createCompatibleWritableRaster(w, h);
        Object obj = null;
        int[] data = null;

        int rX = raster.getMinX();
        int rY = raster.getMinY();

        for (int y=0; y < h; y++, rY++) {
            obj = raster.getDataElements(rX, rY, w, 1, obj);
            if (obj instanceof int[]) {
                data = (int[])obj;
            } else {
                data = DataBuffer.toIntArray(obj);
            }
            for (int x=0; x < w; x++) {
                data[x] = rgb[data[x] & pixel_mask];
            }
            discreteRaster.setDataElements(0, y, w, 1, data);
        }

        return new BufferedImage(cm, discreteRaster, false, null);
    }

    /**
     * Returns whether or not the pixel is valid.
     * @param pixel the specified pixel value
     * @return {@code true} if {@code pixel}
     * is valid; {@code false} otherwise.
     * @since 1.3
     */
    public boolean isValid(int pixel) {
        return ((pixel >= 0 && pixel < map_size) &&
                (validBits == null || validBits.testBit(pixel)));
    }

    /**
     * Returns whether or not all of the pixels are valid.
     * @return {@code true} if all pixels are valid;
     * {@code false} otherwise.
     * @since 1.3
     */
    public boolean isValid() {
        return (validBits == null);
    }

    /**
     * Returns a {@code BigInteger} that indicates the valid/invalid
     * pixels in the colormap.  A bit is valid if the
     * {@code BigInteger} value at that index is set, and is invalid
     * if the {@code BigInteger} value at that index is not set.
     * The only valid ranges to query in the {@code BigInteger} are
     * between 0 and the map size.
     * @return a {@code BigInteger} indicating the valid/invalid pixels.
     * @since 1.3
     */
    public BigInteger getValidPixels() {
        if (validBits == null) {
            return getAllValid();
        }
        else {
            return validBits;
        }
    }

    /**
     * Disposes of system resources associated with this
     * {@code ColorModel} once this {@code ColorModel} is no
     * longer referenced.
     */
    public void finalize() {
    }

    /**
     * Returns the {@code String} representation of the contents of
     * this {@code ColorModel} object.
     * @return a {@code String} representing the contents of this
     * {@code ColorModel} object.
     */
    public String toString() {
       return new String("IndexColorModel: #pixelBits = "+pixel_bits
                         + " numComponents = "+numComponents
                         + " color space = "+colorSpace
                         + " transparency = "+transparency
                         + " transIndex   = "+transparent_index
                         + " has alpha = "+supportsAlpha
                         + " isAlphaPre = "+isAlphaPremultiplied
                         );
    }
}
