Home » openjdk-7 » java » awt » image » [javadoc | source]

    1   /*
    2    * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package java.awt.image;
   27   
   28   import java.awt.Transparency;
   29   import java.awt.color.ColorSpace;
   30   import java.awt.color.ICC_ColorSpace;
   31   import sun.java2d.cmm.CMSManager;
   32   import sun.java2d.cmm.ColorTransform;
   33   import sun.java2d.cmm.PCMM;
   34   import java.awt.Toolkit;
   35   import java.util.Collections;
   36   import java.util.Map;
   37   import java.util.WeakHashMap;
   38   
   39   /**
   40    * The <code>ColorModel</code> abstract class encapsulates the
   41    * methods for translating a pixel value to color components
   42    * (for example, red, green, and blue) and an alpha component.
   43    * In order to render an image to the screen, a printer, or another
   44    * image, pixel values must be converted to color and alpha components.
   45    * As arguments to or return values from methods of this class,
   46    * pixels are represented as 32-bit ints or as arrays of primitive types.
   47    * The number, order, and interpretation of color components for a
   48    * <code>ColorModel</code> is specified by its <code>ColorSpace</code>.
   49    * A <code>ColorModel</code> used with pixel data that does not include
   50    * alpha information treats all pixels as opaque, which is an alpha
   51    * value of 1.0.
   52    * <p>
   53    * This <code>ColorModel</code> class supports two representations of
   54    * pixel values.  A pixel value can be a single 32-bit int or an
   55    * array of primitive types.  The Java(tm) Platform 1.0 and 1.1 APIs
   56    * represented pixels as single <code>byte</code> or single
   57    * <code>int</code> values.  For purposes of the <code>ColorModel</code>
   58    * class, pixel value arguments were passed as ints.  The Java(tm) 2
   59    * Platform API introduced additional classes for representing images.
   60    * With {@link BufferedImage} or {@link RenderedImage}
   61    * objects, based on {@link Raster} and {@link SampleModel} classes, pixel
   62    * values might not be conveniently representable as a single int.
   63    * Consequently, <code>ColorModel</code> now has methods that accept
   64    * pixel values represented as arrays of primitive types.  The primitive
   65    * type used by a particular <code>ColorModel</code> object is called its
   66    * transfer type.
   67    * <p>
   68    * <code>ColorModel</code> objects used with images for which pixel values
   69    * are not conveniently representable as a single int throw an
   70    * {@link IllegalArgumentException} when methods taking a single int pixel
   71    * argument are called.  Subclasses of <code>ColorModel</code> must
   72    * specify the conditions under which this occurs.  This does not
   73    * occur with {@link DirectColorModel} or {@link IndexColorModel} objects.
   74    * <p>
   75    * Currently, the transfer types supported by the Java 2D(tm) API are
   76    * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
   77    * DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, and DataBuffer.TYPE_DOUBLE.
   78    * Most rendering operations will perform much faster when using ColorModels
   79    * and images based on the first three of these types.  In addition, some
   80    * image filtering operations are not supported for ColorModels and
   81    * images based on the latter three types.
   82    * The transfer type for a particular <code>ColorModel</code> object is
   83    * specified when the object is created, either explicitly or by default.
   84    * All subclasses of <code>ColorModel</code> must specify what the
   85    * possible transfer types are and how the number of elements in the
   86    * primitive arrays representing pixels is determined.
   87    * <p>
   88    * For <code>BufferedImages</code>, the transfer type of its
   89    * <code>Raster</code> and of the <code>Raster</code> object's
   90    * <code>SampleModel</code> (available from the
   91    * <code>getTransferType</code> methods of these classes) must match that
   92    * of the <code>ColorModel</code>.  The number of elements in an array
   93    * representing a pixel for the <code>Raster</code> and
   94    * <code>SampleModel</code> (available from the
   95    * <code>getNumDataElements</code> methods of these classes) must match
   96    * that of the <code>ColorModel</code>.
   97    * <p>
   98    * The algorithm used to convert from pixel values to color and alpha
   99    * components varies by subclass.  For example, there is not necessarily
  100    * a one-to-one correspondence between samples obtained from the
  101    * <code>SampleModel</code> of a <code>BufferedImage</code> object's
  102    * <code>Raster</code> and color/alpha components.  Even when
  103    * there is such a correspondence, the number of bits in a sample is not
  104    * necessarily the same as the number of bits in the corresponding color/alpha
  105    * component.  Each subclass must specify how the translation from
  106    * pixel values to color/alpha components is done.
  107    * <p>
  108    * Methods in the <code>ColorModel</code> class use two different
  109    * representations of color and alpha components - a normalized form
  110    * and an unnormalized form.  In the normalized form, each component is a
  111    * <code>float</code> value between some minimum and maximum values.  For
  112    * the alpha component, the minimum is 0.0 and the maximum is 1.0.  For
  113    * color components the minimum and maximum values for each component can
  114    * be obtained from the <code>ColorSpace</code> object.  These values
  115    * will often be 0.0 and 1.0 (e.g. normalized component values for the
  116    * default sRGB color space range from 0.0 to 1.0), but some color spaces
  117    * have component values with different upper and lower limits.  These
  118    * limits can be obtained using the <code>getMinValue</code> and
  119    * <code>getMaxValue</code> methods of the <code>ColorSpace</code>
  120    * class.  Normalized color component values are not premultiplied.
  121    * All <code>ColorModels</code> must support the normalized form.
  122    * <p>
  123    * In the unnormalized
  124    * form, each component is an unsigned integral value between 0 and
  125    * 2<sup>n</sup> - 1, where n is the number of significant bits for a
  126    * particular component.  If pixel values for a particular
  127    * <code>ColorModel</code> represent color samples premultiplied by
  128    * the alpha sample, unnormalized color component values are
  129    * also premultiplied.  The unnormalized form is used only with instances
  130    * of <code>ColorModel</code> whose <code>ColorSpace</code> has minimum
  131    * component values of 0.0 for all components and maximum values of
  132    * 1.0 for all components.
  133    * The unnormalized form for color and alpha components can be a convenient
  134    * representation for <code>ColorModels</code> whose normalized component
  135    * values all lie
  136    * between 0.0 and 1.0.  In such cases the integral value 0 maps to 0.0 and
  137    * the value 2<sup>n</sup> - 1 maps to 1.0.  In other cases, such as
  138    * when the normalized component values can be either negative or positive,
  139    * the unnormalized form is not convenient.  Such <code>ColorModel</code>
  140    * objects throw an {@link IllegalArgumentException} when methods involving
  141    * an unnormalized argument are called.  Subclasses of <code>ColorModel</code>
  142    * must specify the conditions under which this occurs.
  143    *
  144    * @see IndexColorModel
  145    * @see ComponentColorModel
  146    * @see PackedColorModel
  147    * @see DirectColorModel
  148    * @see java.awt.Image
  149    * @see BufferedImage
  150    * @see RenderedImage
  151    * @see java.awt.color.ColorSpace
  152    * @see SampleModel
  153    * @see Raster
  154    * @see DataBuffer
  155    */
  156   public abstract class ColorModel implements Transparency{
  157       private long pData;         // Placeholder for data for native functions
  158   
  159       /**
  160        * The total number of bits in the pixel.
  161        */
  162       protected int pixel_bits;
  163       int nBits[];
  164       int transparency = Transparency.TRANSLUCENT;
  165       boolean supportsAlpha = true;
  166       boolean isAlphaPremultiplied = false;
  167       int numComponents = -1;
  168       int numColorComponents = -1;
  169       ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
  170       int colorSpaceType = ColorSpace.TYPE_RGB;
  171       int maxBits;
  172       boolean is_sRGB = true;
  173   
  174       /**
  175        * Data type of the array used to represent pixel values.
  176        */
  177       protected int transferType;
  178   
  179       /**
  180        * This is copied from java.awt.Toolkit since we need the library
  181        * loaded in java.awt.image also:
  182        *
  183        * WARNING: This is a temporary workaround for a problem in the
  184        * way the AWT loads native libraries. A number of classes in the
  185        * AWT package have a native method, initIDs(), which initializes
  186        * the JNI field and method ids used in the native portion of
  187        * their implementation.
  188        *
  189        * Since the use and storage of these ids is done by the
  190        * implementation libraries, the implementation of these method is
  191        * provided by the particular AWT implementations (for example,
  192        * "Toolkit"s/Peer), such as Motif, Microsoft Windows, or Tiny. The
  193        * problem is that this means that the native libraries must be
  194        * loaded by the java.* classes, which do not necessarily know the
  195        * names of the libraries to load. A better way of doing this
  196        * would be to provide a separate library which defines java.awt.*
  197        * initIDs, and exports the relevant symbols out to the
  198        * implementation libraries.
  199        *
  200        * For now, we know it's done by the implementation, and we assume
  201        * that the name of the library is "awt".  -br.
  202        */
  203       private static boolean loaded = false;
  204       static void loadLibraries() {
  205           if (!loaded) {
  206               java.security.AccessController.doPrivileged(
  207                     new sun.security.action.LoadLibraryAction("awt"));
  208               loaded = true;
  209           }
  210       }
  211       private static native void initIDs();
  212       static {
  213           /* ensure that the proper libraries are loaded */
  214           loadLibraries();
  215           initIDs();
  216       }
  217       private static ColorModel RGBdefault;
  218   
  219       /**
  220        * Returns a <code>DirectColorModel</code> that describes the default
  221        * format for integer RGB values used in many of the methods in the
  222        * AWT image interfaces for the convenience of the programmer.
  223        * The color space is the default {@link ColorSpace}, sRGB.
  224        * The format for the RGB values is an integer with 8 bits
  225        * each of alpha, red, green, and blue color components ordered
  226        * correspondingly from the most significant byte to the least
  227        * significant byte, as in:  0xAARRGGBB.  Color components are
  228        * not premultiplied by the alpha component.  This format does not
  229        * necessarily represent the native or the most efficient
  230        * <code>ColorModel</code> for a particular device or for all images.
  231        * It is merely used as a common color model format.
  232        * @return a <code>DirectColorModel</code>object describing default
  233        *          RGB values.
  234        */
  235       public static ColorModel getRGBdefault() {
  236           if (RGBdefault == null) {
  237               RGBdefault = new DirectColorModel(32,
  238                                                 0x00ff0000,       // Red
  239                                                 0x0000ff00,       // Green
  240                                                 0x000000ff,       // Blue
  241                                                 0xff000000        // Alpha
  242                                                 );
  243           }
  244           return RGBdefault;
  245       }
  246   
  247       /**
  248        * Constructs a <code>ColorModel</code> that translates pixels of the
  249        * specified number of bits to color/alpha components.  The color
  250        * space is the default RGB <code>ColorSpace</code>, which is sRGB.
  251        * Pixel values are assumed to include alpha information.  If color
  252        * and alpha information are represented in the pixel value as
  253        * separate spatial bands, the color bands are assumed not to be
  254        * premultiplied with the alpha value. The transparency type is
  255        * java.awt.Transparency.TRANSLUCENT.  The transfer type will be the
  256        * smallest of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
  257        * or DataBuffer.TYPE_INT that can hold a single pixel
  258        * (or DataBuffer.TYPE_UNDEFINED if bits is greater
  259        * than 32).  Since this constructor has no information about the
  260        * number of bits per color and alpha component, any subclass calling
  261        * this constructor should override any method that requires this
  262        * information.
  263        * @param bits the number of bits of a pixel
  264        * @throws IllegalArgumentException if the number
  265        *          of bits in <code>bits</code> is less than 1
  266        */
  267       public ColorModel(int bits) {
  268           pixel_bits = bits;
  269           if (bits < 1) {
  270               throw new IllegalArgumentException("Number of bits must be > 0");
  271           }
  272           numComponents = 4;
  273           numColorComponents = 3;
  274           maxBits = bits;
  275           // REMIND: make sure transferType is set correctly
  276           transferType = ColorModel.getDefaultTransferType(bits);
  277       }
  278   
  279       /**
  280        * Constructs a <code>ColorModel</code> that translates pixel values
  281        * to color/alpha components.  Color components will be in the
  282        * specified <code>ColorSpace</code>. <code>pixel_bits</code> is the
  283        * number of bits in the pixel values.  The bits array
  284        * specifies the number of significant bits per color and alpha component.
  285        * Its length should be the number of components in the
  286        * <code>ColorSpace</code> if there is no alpha information in the
  287        * pixel values, or one more than this number if there is alpha
  288        * information.  <code>hasAlpha</code> indicates whether or not alpha
  289        * information is present.  The <code>boolean</code>
  290        * <code>isAlphaPremultiplied</code> specifies how to interpret pixel
  291        * values in which color and alpha information are represented as
  292        * separate spatial bands.  If the <code>boolean</code>
  293        * is <code>true</code>, color samples are assumed to have been
  294        * multiplied by the alpha sample.  The <code>transparency</code>
  295        * specifies what alpha values can be represented by this color model.
  296        * The transfer type is the type of primitive array used to represent
  297        * pixel values.  Note that the bits array contains the number of
  298        * significant bits per color/alpha component after the translation
  299        * from pixel values.  For example, for an
  300        * <code>IndexColorModel</code> with <code>pixel_bits</code> equal to
  301        * 16, the bits array might have four elements with each element set
  302        * to 8.
  303        * @param pixel_bits the number of bits in the pixel values
  304        * @param bits array that specifies the number of significant bits
  305        *          per color and alpha component
  306        * @param cspace the specified <code>ColorSpace</code>
  307        * @param hasAlpha <code>true</code> if alpha information is present;
  308        *          <code>false</code> otherwise
  309        * @param isAlphaPremultiplied <code>true</code> if color samples are
  310        *          assumed to be premultiplied by the alpha samples;
  311        *          <code>false</code> otherwise
  312        * @param transparency what alpha values can be represented by this
  313        *          color model
  314        * @param transferType the type of the array used to represent pixel
  315        *          values
  316        * @throws IllegalArgumentException if the length of
  317        *          the bit array is less than the number of color or alpha
  318        *          components in this <code>ColorModel</code>, or if the
  319        *          transparency is not a valid value.
  320        * @throws IllegalArgumentException if the sum of the number
  321        *          of bits in <code>bits</code> is less than 1 or if
  322        *          any of the elements in <code>bits</code> is less than 0.
  323        * @see java.awt.Transparency
  324        */
  325       protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace,
  326                            boolean hasAlpha,
  327                            boolean isAlphaPremultiplied,
  328                            int transparency,
  329                            int transferType) {
  330           colorSpace                = cspace;
  331           colorSpaceType            = cspace.getType();
  332           numColorComponents        = cspace.getNumComponents();
  333           numComponents             = numColorComponents + (hasAlpha ? 1 : 0);
  334           supportsAlpha             = hasAlpha;
  335           if (bits.length < numComponents) {
  336               throw new IllegalArgumentException("Number of color/alpha "+
  337                                                  "components should be "+
  338                                                  numComponents+
  339                                                  " but length of bits array is "+
  340                                                  bits.length);
  341           }
  342   
  343           // 4186669
  344           if (transparency < Transparency.OPAQUE ||
  345               transparency > Transparency.TRANSLUCENT)
  346           {
  347               throw new IllegalArgumentException("Unknown transparency: "+
  348                                                  transparency);
  349           }
  350   
  351           if (supportsAlpha == false) {
  352               this.isAlphaPremultiplied = false;
  353               this.transparency = Transparency.OPAQUE;
  354           }
  355           else {
  356               this.isAlphaPremultiplied = isAlphaPremultiplied;
  357               this.transparency         = transparency;
  358           }
  359   
  360           nBits = (int[]) bits.clone();
  361           this.pixel_bits = pixel_bits;
  362           if (pixel_bits <= 0) {
  363               throw new IllegalArgumentException("Number of pixel bits must "+
  364                                                  "be > 0");
  365           }
  366           // Check for bits < 0
  367           maxBits = 0;
  368           for (int i=0; i < bits.length; i++) {
  369               // bug 4304697
  370               if (bits[i] < 0) {
  371                   throw new
  372                       IllegalArgumentException("Number of bits must be >= 0");
  373               }
  374               if (maxBits < bits[i]) {
  375                   maxBits = bits[i];
  376               }
  377           }
  378   
  379           // Make sure that we don't have all 0-bit components
  380           if (maxBits == 0) {
  381               throw new IllegalArgumentException("There must be at least "+
  382                                                  "one component with > 0 "+
  383                                                 "pixel bits.");
  384           }
  385   
  386           // Save this since we always need to check if it is the default CS
  387           if (cspace != ColorSpace.getInstance(ColorSpace.CS_sRGB)) {
  388               is_sRGB = false;
  389           }
  390   
  391           // Save the transfer type
  392           this.transferType = transferType;
  393       }
  394   
  395       /**
  396        * Returns whether or not alpha is supported in this
  397        * <code>ColorModel</code>.
  398        * @return <code>true</code> if alpha is supported in this
  399        * <code>ColorModel</code>; <code>false</code> otherwise.
  400        */
  401       final public boolean hasAlpha() {
  402           return supportsAlpha;
  403       }
  404   
  405       /**
  406        * Returns whether or not the alpha has been premultiplied in the
  407        * pixel values to be translated by this <code>ColorModel</code>.
  408        * If the boolean is <code>true</code>, this <code>ColorModel</code>
  409        * is to be used to interpret pixel values in which color and alpha
  410        * information are represented as separate spatial bands, and color
  411        * samples are assumed to have been multiplied by the
  412        * alpha sample.
  413        * @return <code>true</code> if the alpha values are premultiplied
  414        *          in the pixel values to be translated by this
  415        *          <code>ColorModel</code>; <code>false</code> otherwise.
  416        */
  417       final public boolean isAlphaPremultiplied() {
  418           return isAlphaPremultiplied;
  419       }
  420   
  421       /**
  422        * Returns the transfer type of this <code>ColorModel</code>.
  423        * The transfer type is the type of primitive array used to represent
  424        * pixel values as arrays.
  425        * @return the transfer type.
  426        * @since 1.3
  427        */
  428       final public int getTransferType() {
  429           return transferType;
  430       }
  431   
  432       /**
  433        * Returns the number of bits per pixel described by this
  434        * <code>ColorModel</code>.
  435        * @return the number of bits per pixel.
  436        */
  437       public int getPixelSize() {
  438           return pixel_bits;
  439       }
  440   
  441       /**
  442        * Returns the number of bits for the specified color/alpha component.
  443        * Color components are indexed in the order specified by the
  444        * <code>ColorSpace</code>.  Typically, this order reflects the name
  445        * of the color space type. For example, for TYPE_RGB, index 0
  446        * corresponds to red, index 1 to green, and index 2
  447        * to blue.  If this <code>ColorModel</code> supports alpha, the alpha
  448        * component corresponds to the index following the last color
  449        * component.
  450        * @param componentIdx the index of the color/alpha component
  451        * @return the number of bits for the color/alpha component at the
  452        *          specified index.
  453        * @throws ArrayIndexOutOfBoundsException if <code>componentIdx</code>
  454        *         is greater than the number of components or
  455        *         less than zero
  456        * @throws NullPointerException if the number of bits array is
  457        *         <code>null</code>
  458        */
  459       public int getComponentSize(int componentIdx) {
  460           // REMIND:
  461           if (nBits == null) {
  462               throw new NullPointerException("Number of bits array is null.");
  463           }
  464   
  465           return nBits[componentIdx];
  466       }
  467   
  468       /**
  469        * Returns an array of the number of bits per color/alpha component.
  470        * The array contains the color components in the order specified by the
  471        * <code>ColorSpace</code>, followed by the alpha component, if
  472        * present.
  473        * @return an array of the number of bits per color/alpha component
  474        */
  475       public int[] getComponentSize() {
  476           if (nBits != null) {
  477               return (int[]) nBits.clone();
  478           }
  479   
  480           return null;
  481       }
  482   
  483       /**
  484        * Returns the transparency.  Returns either OPAQUE, BITMASK,
  485        * or TRANSLUCENT.
  486        * @return the transparency of this <code>ColorModel</code>.
  487        * @see Transparency#OPAQUE
  488        * @see Transparency#BITMASK
  489        * @see Transparency#TRANSLUCENT
  490        */
  491       public int getTransparency() {
  492           return transparency;
  493       }
  494   
  495       /**
  496        * Returns the number of components, including alpha, in this
  497        * <code>ColorModel</code>.  This is equal to the number of color
  498        * components, optionally plus one, if there is an alpha component.
  499        * @return the number of components in this <code>ColorModel</code>
  500        */
  501       public int getNumComponents() {
  502           return numComponents;
  503       }
  504   
  505       /**
  506        * Returns the number of color components in this
  507        * <code>ColorModel</code>.
  508        * This is the number of components returned by
  509        * {@link ColorSpace#getNumComponents}.
  510        * @return the number of color components in this
  511        * <code>ColorModel</code>.
  512        * @see ColorSpace#getNumComponents
  513        */
  514       public int getNumColorComponents() {
  515           return numColorComponents;
  516       }
  517   
  518       /**
  519        * Returns the red color component for the specified pixel, scaled
  520        * from 0 to 255 in the default RGB ColorSpace, sRGB.  A color conversion
  521        * is done if necessary.  The pixel value is specified as an int.
  522        * An <code>IllegalArgumentException</code> is thrown if pixel
  523        * values for this <code>ColorModel</code> are not conveniently
  524        * representable as a single int.  The returned value is not a
  525        * pre-multiplied value.  For example, if the
  526        * alpha is premultiplied, this method divides it out before returning
  527        * the value.  If the alpha value is 0, the red value is 0.
  528        * @param pixel a specified pixel
  529        * @return the value of the red component of the specified pixel.
  530        */
  531       public abstract int getRed(int pixel);
  532   
  533       /**
  534        * Returns the green color component for the specified pixel, scaled
  535        * from 0 to 255 in the default RGB ColorSpace, sRGB.  A color conversion
  536        * is done if necessary.  The pixel value is specified as an int.
  537        * An <code>IllegalArgumentException</code> is thrown if pixel
  538        * values for this <code>ColorModel</code> are not conveniently
  539        * representable as a single int.  The returned value is a non
  540        * pre-multiplied value.  For example, if the alpha is premultiplied,
  541        * this method divides it out before returning
  542        * the value.  If the alpha value is 0, the green value is 0.
  543        * @param pixel the specified pixel
  544        * @return the value of the green component of the specified pixel.
  545        */
  546       public abstract int getGreen(int pixel);
  547   
  548       /**
  549        * Returns the blue color component for the specified pixel, scaled
  550        * from 0 to 255 in the default RGB ColorSpace, sRGB.  A color conversion
  551        * is done if necessary.  The pixel value is specified as an int.
  552        * An <code>IllegalArgumentException</code> is thrown if pixel values
  553        * for this <code>ColorModel</code> are not conveniently representable
  554        * as a single int.  The returned value is a non pre-multiplied
  555        * value, for example, if the alpha is premultiplied, this method
  556        * divides it out before returning the value.  If the alpha value is
  557        * 0, the blue value is 0.
  558        * @param pixel the specified pixel
  559        * @return the value of the blue component of the specified pixel.
  560        */
  561       public abstract int getBlue(int pixel);
  562   
  563       /**
  564        * Returns the alpha component for the specified pixel, scaled
  565        * from 0 to 255.  The pixel value is specified as an int.
  566        * An <code>IllegalArgumentException</code> is thrown if pixel
  567        * values for this <code>ColorModel</code> are not conveniently
  568        * representable as a single int.
  569        * @param pixel the specified pixel
  570        * @return the value of alpha component of the specified pixel.
  571        */
  572       public abstract int getAlpha(int pixel);
  573   
  574       /**
  575        * Returns the color/alpha components of the pixel in the default
  576        * RGB color model format.  A color conversion is done if necessary.
  577        * The pixel value is specified as an int.
  578        * An <code>IllegalArgumentException</code> thrown if pixel values
  579        * for this <code>ColorModel</code> are not conveniently representable
  580        * as a single int.  The returned value is in a non
  581        * pre-multiplied format. For example, if the alpha is premultiplied,
  582        * this method divides it out of the color components.  If the alpha
  583        * value is 0, the color values are 0.
  584        * @param pixel the specified pixel
  585        * @return the RGB value of the color/alpha components of the
  586        *          specified pixel.
  587        * @see ColorModel#getRGBdefault
  588        */
  589       public int getRGB(int pixel) {
  590           return (getAlpha(pixel) << 24)
  591               | (getRed(pixel) << 16)
  592               | (getGreen(pixel) << 8)
  593               | (getBlue(pixel) << 0);
  594       }
  595   
  596       /**
  597        * Returns the red color component for the specified pixel, scaled
  598        * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB.  A
  599        * color conversion is done if necessary.  The pixel value is
  600        * specified by an array of data elements of type transferType passed
  601        * in as an object reference.  The returned value is a non
  602        * pre-multiplied value.  For example, if alpha is premultiplied,
  603        * this method divides it out before returning
  604        * the value.  If the alpha value is 0, the red value is 0.
  605        * If <code>inData</code> is not a primitive array of type
  606        * transferType, a <code>ClassCastException</code> is thrown.  An
  607        * <code>ArrayIndexOutOfBoundsException</code> is thrown if
  608        * <code>inData</code> is not large enough to hold a pixel value for
  609        * this <code>ColorModel</code>.
  610        * If this <code>transferType</code> is not supported, a
  611        * <code>UnsupportedOperationException</code> will be
  612        * thrown.  Since
  613        * <code>ColorModel</code> is an abstract class, any instance
  614        * must be an instance of a subclass.  Subclasses inherit the
  615        * implementation of this method and if they don't override it, this
  616        * method throws an exception if the subclass uses a
  617        * <code>transferType</code> other than
  618        * <code>DataBuffer.TYPE_BYTE</code>,
  619        * <code>DataBuffer.TYPE_USHORT</code>, or
  620        * <code>DataBuffer.TYPE_INT</code>.
  621        * @param inData an array of pixel values
  622        * @return the value of the red component of the specified pixel.
  623        * @throws ClassCastException if <code>inData</code>
  624        *  is not a primitive array of type <code>transferType</code>
  625        * @throws ArrayIndexOutOfBoundsException if
  626        *  <code>inData</code> is not large enough to hold a pixel value
  627        *  for this <code>ColorModel</code>
  628        * @throws UnsupportedOperationException if this
  629        *  <code>tranferType</code> is not supported by this
  630        *  <code>ColorModel</code>
  631        */
  632       public int getRed(Object inData) {
  633           int pixel=0,length=0;
  634           switch (transferType) {
  635               case DataBuffer.TYPE_BYTE:
  636                  byte bdata[] = (byte[])inData;
  637                  pixel = bdata[0] & 0xff;
  638                  length = bdata.length;
  639               break;
  640               case DataBuffer.TYPE_USHORT:
  641                  short sdata[] = (short[])inData;
  642                  pixel = sdata[0] & 0xffff;
  643                  length = sdata.length;
  644               break;
  645               case DataBuffer.TYPE_INT:
  646                  int idata[] = (int[])inData;
  647                  pixel = idata[0];
  648                  length = idata.length;
  649               break;
  650               default:
  651                  throw new UnsupportedOperationException("This method has not been "+
  652                      "implemented for transferType " + transferType);
  653           }
  654           if (length == 1) {
  655               return getRed(pixel);
  656           }
  657           else {
  658               throw new UnsupportedOperationException
  659                   ("This method is not supported by this color model");
  660           }
  661       }
  662   
  663       /**
  664        * Returns the green color component for the specified pixel, scaled
  665        * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB.  A
  666        * color conversion is done if necessary.  The pixel value is
  667        * specified by an array of data elements of type transferType passed
  668        * in as an object reference.  The returned value will be a non
  669        * pre-multiplied value.  For example, if the alpha is premultiplied,
  670        * this method divides it out before returning the value.  If the
  671        * alpha value is 0, the green value is 0.  If <code>inData</code> is
  672        * not a primitive array of type transferType, a
  673        * <code>ClassCastException</code> is thrown.  An
  674        * <code>ArrayIndexOutOfBoundsException</code> is thrown if
  675        * <code>inData</code> is not large enough to hold a pixel value for
  676        * this <code>ColorModel</code>.
  677        * If this <code>transferType</code> is not supported, a
  678        * <code>UnsupportedOperationException</code> will be
  679        * thrown.  Since
  680        * <code>ColorModel</code> is an abstract class, any instance
  681        * must be an instance of a subclass.  Subclasses inherit the
  682        * implementation of this method and if they don't override it, this
  683        * method throws an exception if the subclass uses a
  684        * <code>transferType</code> other than
  685        * <code>DataBuffer.TYPE_BYTE</code>,
  686        * <code>DataBuffer.TYPE_USHORT</code>, or
  687        * <code>DataBuffer.TYPE_INT</code>.
  688        * @param inData an array of pixel values
  689        * @return the value of the green component of the specified pixel.
  690        * @throws <code>ClassCastException</code> if <code>inData</code>
  691        *  is not a primitive array of type <code>transferType</code>
  692        * @throws <code>ArrayIndexOutOfBoundsException</code> if
  693        *  <code>inData</code> is not large enough to hold a pixel value
  694        *  for this <code>ColorModel</code>
  695        * @throws <code>UnsupportedOperationException</code> if this
  696        *  <code>tranferType</code> is not supported by this
  697        *  <code>ColorModel</code>
  698        */
  699       public int getGreen(Object inData) {
  700           int pixel=0,length=0;
  701           switch (transferType) {
  702               case DataBuffer.TYPE_BYTE:
  703                  byte bdata[] = (byte[])inData;
  704                  pixel = bdata[0] & 0xff;
  705                  length = bdata.length;
  706               break;
  707               case DataBuffer.TYPE_USHORT:
  708                  short sdata[] = (short[])inData;
  709                  pixel = sdata[0] & 0xffff;
  710                  length = sdata.length;
  711               break;
  712               case DataBuffer.TYPE_INT:
  713                  int idata[] = (int[])inData;
  714                  pixel = idata[0];
  715                  length = idata.length;
  716               break;
  717               default:
  718                  throw new UnsupportedOperationException("This method has not been "+
  719                      "implemented for transferType " + transferType);
  720           }
  721           if (length == 1) {
  722               return getGreen(pixel);
  723           }
  724           else {
  725               throw new UnsupportedOperationException
  726                   ("This method is not supported by this color model");
  727           }
  728       }
  729   
  730       /**
  731        * Returns the blue color component for the specified pixel, scaled
  732        * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB.  A
  733        * color conversion is done if necessary.  The pixel value is
  734        * specified by an array of data elements of type transferType passed
  735        * in as an object reference.  The returned value is a non
  736        * pre-multiplied value.  For example, if the alpha is premultiplied,
  737        * this method divides it out before returning the value.  If the
  738        * alpha value is 0, the blue value will be 0.  If
  739        * <code>inData</code> is not a primitive array of type transferType,
  740        * a <code>ClassCastException</code> is thrown.  An
  741        * <code>ArrayIndexOutOfBoundsException</code> is
  742        * thrown if <code>inData</code> is not large enough to hold a pixel
  743        * value for this <code>ColorModel</code>.
  744        * If this <code>transferType</code> is not supported, a
  745        * <code>UnsupportedOperationException</code> will be
  746        * thrown.  Since
  747        * <code>ColorModel</code> is an abstract class, any instance
  748        * must be an instance of a subclass.  Subclasses inherit the
  749        * implementation of this method and if they don't override it, this
  750        * method throws an exception if the subclass uses a
  751        * <code>transferType</code> other than
  752        * <code>DataBuffer.TYPE_BYTE</code>,
  753        * <code>DataBuffer.TYPE_USHORT</code>, or
  754        * <code>DataBuffer.TYPE_INT</code>.
  755        * @param inData an array of pixel values
  756        * @return the value of the blue component of the specified pixel.
  757        * @throws ClassCastException if <code>inData</code>
  758        *  is not a primitive array of type <code>transferType</code>
  759        * @throws ArrayIndexOutOfBoundsException if
  760        *  <code>inData</code> is not large enough to hold a pixel value
  761        *  for this <code>ColorModel</code>
  762        * @throws UnsupportedOperationException if this
  763        *  <code>tranferType</code> is not supported by this
  764        *  <code>ColorModel</code>
  765        */
  766       public int getBlue(Object inData) {
  767           int pixel=0,length=0;
  768           switch (transferType) {
  769               case DataBuffer.TYPE_BYTE:
  770                  byte bdata[] = (byte[])inData;
  771                  pixel = bdata[0] & 0xff;
  772                  length = bdata.length;
  773               break;
  774               case DataBuffer.TYPE_USHORT:
  775                  short sdata[] = (short[])inData;
  776                  pixel = sdata[0] & 0xffff;
  777                  length = sdata.length;
  778               break;
  779               case DataBuffer.TYPE_INT:
  780                  int idata[] = (int[])inData;
  781                  pixel = idata[0];
  782                  length = idata.length;
  783               break;
  784               default:
  785                  throw new UnsupportedOperationException("This method has not been "+
  786                      "implemented for transferType " + transferType);
  787           }
  788           if (length == 1) {
  789               return getBlue(pixel);
  790           }
  791           else {
  792               throw new UnsupportedOperationException
  793                   ("This method is not supported by this color model");
  794           }
  795       }
  796   
  797       /**
  798        * Returns the alpha component for the specified pixel, scaled
  799        * from 0 to 255.  The pixel value is specified by an array of data
  800        * elements of type transferType passed in as an object reference.
  801        * If inData is not a primitive array of type transferType, a
  802        * <code>ClassCastException</code> is thrown.  An
  803        * <code>ArrayIndexOutOfBoundsException</code> is thrown if
  804        * <code>inData</code> is not large enough to hold a pixel value for
  805        * this <code>ColorModel</code>.
  806        * If this <code>transferType</code> is not supported, a
  807        * <code>UnsupportedOperationException</code> will be
  808        * thrown.  Since
  809        * <code>ColorModel</code> is an abstract class, any instance
  810        * must be an instance of a subclass.  Subclasses inherit the
  811        * implementation of this method and if they don't override it, this
  812        * method throws an exception if the subclass uses a
  813        * <code>transferType</code> other than
  814        * <code>DataBuffer.TYPE_BYTE</code>,
  815        * <code>DataBuffer.TYPE_USHORT</code>, or
  816        * <code>DataBuffer.TYPE_INT</code>.
  817        * @param inData the specified pixel
  818        * @return the alpha component of the specified pixel, scaled from
  819        * 0 to 255.
  820        * @throws ClassCastException if <code>inData</code>
  821        *  is not a primitive array of type <code>transferType</code>
  822        * @throws ArrayIndexOutOfBoundsException if
  823        *  <code>inData</code> is not large enough to hold a pixel value
  824        *  for this <code>ColorModel</code>
  825        * @throws UnsupportedOperationException if this
  826        *  <code>tranferType</code> is not supported by this
  827        *  <code>ColorModel</code>
  828        */
  829       public int getAlpha(Object inData) {
  830           int pixel=0,length=0;
  831           switch (transferType) {
  832               case DataBuffer.TYPE_BYTE:
  833                  byte bdata[] = (byte[])inData;
  834                  pixel = bdata[0] & 0xff;
  835                  length = bdata.length;
  836               break;
  837               case DataBuffer.TYPE_USHORT:
  838                  short sdata[] = (short[])inData;
  839                  pixel = sdata[0] & 0xffff;
  840                  length = sdata.length;
  841               break;
  842               case DataBuffer.TYPE_INT:
  843                  int idata[] = (int[])inData;
  844                  pixel = idata[0];
  845                  length = idata.length;
  846               break;
  847               default:
  848                  throw new UnsupportedOperationException("This method has not been "+
  849                      "implemented for transferType " + transferType);
  850           }
  851           if (length == 1) {
  852               return getAlpha(pixel);
  853           }
  854           else {
  855               throw new UnsupportedOperationException
  856                   ("This method is not supported by this color model");
  857           }
  858       }
  859   
  860       /**
  861        * Returns the color/alpha components for the specified pixel in the
  862        * default RGB color model format.  A color conversion is done if
  863        * necessary.  The pixel value is specified by an array of data
  864        * elements of type transferType passed in as an object reference.
  865        * If inData is not a primitive array of type transferType, a
  866        * <code>ClassCastException</code> is thrown.  An
  867        * <code>ArrayIndexOutOfBoundsException</code> is
  868        * thrown if <code>inData</code> is not large enough to hold a pixel
  869        * value for this <code>ColorModel</code>.
  870        * The returned value will be in a non pre-multiplied format, i.e. if
  871        * the alpha is premultiplied, this method will divide it out of the
  872        * color components (if the alpha value is 0, the color values will be 0).
  873        * @param inData the specified pixel
  874        * @return the color and alpha components of the specified pixel.
  875        * @see ColorModel#getRGBdefault
  876        */
  877       public int getRGB(Object inData) {
  878           return (getAlpha(inData) << 24)
  879               | (getRed(inData) << 16)
  880               | (getGreen(inData) << 8)
  881               | (getBlue(inData) << 0);
  882       }
  883   
  884       /**
  885        * Returns a data element array representation of a pixel in this
  886        * <code>ColorModel</code>, given an integer pixel representation in
  887        * the default RGB color model.
  888        * This array can then be passed to the
  889        * {@link WritableRaster#setDataElements} method of
  890        * a {@link WritableRaster} object.  If the pixel variable is
  891        * <code>null</code>, a new array will be allocated.  If
  892        * <code>pixel</code> is not
  893        * <code>null</code>, it must be a primitive array of type
  894        * <code>transferType</code>; otherwise, a
  895        * <code>ClassCastException</code> is thrown.  An
  896        * <code>ArrayIndexOutOfBoundsException</code> is thrown if
  897        * <code>pixel</code> is
  898        * not large enough to hold a pixel value for this
  899        * <code>ColorModel</code>. The pixel array is returned.
  900        * If this <code>transferType</code> is not supported, a
  901        * <code>UnsupportedOperationException</code> will be
  902        * thrown.  Since <code>ColorModel</code> is an abstract class,
  903        * any instance is an instance of a subclass.  Subclasses must
  904        * override this method since the implementation in this abstract
  905        * class throws an <code>UnsupportedOperationException</code>.
  906        * @param rgb the integer pixel representation in the default RGB
  907        * color model
  908        * @param pixel the specified pixel
  909        * @return an array representation of the specified pixel in this
  910        *  <code>ColorModel</code>.
  911        * @throws ClassCastException if <code>pixel</code>
  912        *  is not a primitive array of type <code>transferType</code>
  913        * @throws ArrayIndexOutOfBoundsException if
  914        *  <code>pixel</code> is not large enough to hold a pixel value
  915        *  for this <code>ColorModel</code>
  916        * @throws UnsupportedOperationException if this
  917        *  method is not supported by this <code>ColorModel</code>
  918        * @see WritableRaster#setDataElements
  919        * @see SampleModel#setDataElements
  920        */
  921       public Object getDataElements(int rgb, Object pixel) {
  922           throw new UnsupportedOperationException
  923               ("This method is not supported by this color model.");
  924       }
  925   
  926       /**
  927        * Returns an array of unnormalized color/alpha components given a pixel
  928        * in this <code>ColorModel</code>.  The pixel value is specified as
  929        * an <code>int</code>.  An <code>IllegalArgumentException</code>
  930        * will be thrown if pixel values for this <code>ColorModel</code> are
  931        * not conveniently representable as a single <code>int</code> or if
  932        * color component values for this <code>ColorModel</code> are not
  933        * conveniently representable in the unnormalized form.
  934        * For example, this method can be used to retrieve the
  935        * components for a specific pixel value in a
  936        * <code>DirectColorModel</code>.  If the components array is
  937        * <code>null</code>, a new array will be allocated.  The
  938        * components array will be returned.  Color/alpha components are
  939        * stored in the components array starting at <code>offset</code>
  940        * (even if the array is allocated by this method).  An
  941        * <code>ArrayIndexOutOfBoundsException</code> is thrown if  the
  942        * components array is not <code>null</code> and is not large
  943        * enough to hold all the color and alpha components (starting at offset).
  944        * Since <code>ColorModel</code> is an abstract class,
  945        * any instance is an instance of a subclass.  Subclasses must
  946        * override this method since the implementation in this abstract
  947        * class throws an <code>UnsupportedOperationException</code>.
  948        * @param pixel the specified pixel
  949        * @param components the array to receive the color and alpha
  950        * components of the specified pixel
  951        * @param offset the offset into the <code>components</code> array at
  952        * which to start storing the color and alpha components
  953        * @return an array containing the color and alpha components of the
  954        * specified pixel starting at the specified offset.
  955        * @throws UnsupportedOperationException if this
  956        *          method is not supported by this <code>ColorModel</code>
  957        */
  958       public int[] getComponents(int pixel, int[] components, int offset) {
  959           throw new UnsupportedOperationException
  960               ("This method is not supported by this color model.");
  961       }
  962   
  963       /**
  964        * Returns an array of unnormalized color/alpha components given a pixel
  965        * in this <code>ColorModel</code>.  The pixel value is specified by
  966        * an array of data elements of type transferType passed in as an
  967        * object reference.  If <code>pixel</code> is not a primitive array
  968        * of type transferType, a <code>ClassCastException</code> is thrown.
  969        * An <code>IllegalArgumentException</code> will be thrown if color
  970        * component values for this <code>ColorModel</code> are not
  971        * conveniently representable in the unnormalized form.
  972        * An <code>ArrayIndexOutOfBoundsException</code> is
  973        * thrown if <code>pixel</code> is not large enough to hold a pixel
  974        * value for this <code>ColorModel</code>.
  975        * This method can be used to retrieve the components for a specific
  976        * pixel value in any <code>ColorModel</code>.  If the components
  977        * array is <code>null</code>, a new array will be allocated.  The
  978        * components array will be returned.  Color/alpha components are
  979        * stored in the <code>components</code> array starting at
  980        * <code>offset</code> (even if the array is allocated by this
  981        * method).  An <code>ArrayIndexOutOfBoundsException</code>
  982        * is thrown if  the components array is not <code>null</code> and is
  983        * not large enough to hold all the color and alpha components
  984        * (starting at <code>offset</code>).
  985        * Since <code>ColorModel</code> is an abstract class,
  986        * any instance is an instance of a subclass.  Subclasses must
  987        * override this method since the implementation in this abstract
  988        * class throws an <code>UnsupportedOperationException</code>.
  989        * @param pixel the specified pixel
  990        * @param components an array that receives the color and alpha
  991        * components of the specified pixel
  992        * @param offset the index into the <code>components</code> array at
  993        * which to begin storing the color and alpha components of the
  994        * specified pixel
  995        * @return an array containing the color and alpha components of the
  996        * specified pixel starting at the specified offset.
  997        * @throws UnsupportedOperationException if this
  998        *          method is not supported by this <code>ColorModel</code>
  999        */
 1000       public int[] getComponents(Object pixel, int[] components, int offset) {
 1001           throw new UnsupportedOperationException
 1002               ("This method is not supported by this color model.");
 1003       }
 1004   
 1005       /**
 1006        * Returns an array of all of the color/alpha components in unnormalized
 1007        * form, given a normalized component array.  Unnormalized components
 1008        * are unsigned integral values between 0 and 2<sup>n</sup> - 1, where
 1009        * n is the number of bits for a particular component.  Normalized
 1010        * components are float values between a per component minimum and
 1011        * maximum specified by the <code>ColorSpace</code> object for this
 1012        * <code>ColorModel</code>.  An <code>IllegalArgumentException</code>
 1013        * will be thrown if color component values for this
 1014        * <code>ColorModel</code> are not conveniently representable in the
 1015        * unnormalized form.  If the
 1016        * <code>components</code> array is <code>null</code>, a new array
 1017        * will be allocated.  The <code>components</code> array will
 1018        * be returned.  Color/alpha components are stored in the
 1019        * <code>components</code> array starting at <code>offset</code> (even
 1020        * if the array is allocated by this method). An
 1021        * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
 1022        * <code>components</code> array is not <code>null</code> and is not
 1023        * large enough to hold all the color and alpha
 1024        * components (starting at <code>offset</code>).  An
 1025        * <code>IllegalArgumentException</code> is thrown if the
 1026        * <code>normComponents</code> array is not large enough to hold
 1027        * all the color and alpha components starting at
 1028        * <code>normOffset</code>.
 1029        * @param normComponents an array containing normalized components
 1030        * @param normOffset the offset into the <code>normComponents</code>
 1031        * array at which to start retrieving normalized components
 1032        * @param components an array that receives the components from
 1033        * <code>normComponents</code>
 1034        * @param offset the index into <code>components</code> at which to
 1035        * begin storing normalized components from
 1036        * <code>normComponents</code>
 1037        * @return an array containing unnormalized color and alpha
 1038        * components.
 1039        * @throws IllegalArgumentException If the component values for this
 1040        * <CODE>ColorModel</CODE> are not conveniently representable in the
 1041        * unnormalized form.
 1042        * @throws IllegalArgumentException if the length of
 1043        *          <code>normComponents</code> minus <code>normOffset</code>
 1044        *          is less than <code>numComponents</code>
 1045        * @throws UnsupportedOperationException if the
 1046        *          constructor of this <code>ColorModel</code> called the
 1047        *          <code>super(bits)</code> constructor, but did not
 1048        *          override this method.  See the constructor,
 1049        *          {@link #ColorModel(int)}.
 1050        */
 1051       public int[] getUnnormalizedComponents(float[] normComponents,
 1052                                              int normOffset,
 1053                                              int[] components, int offset) {
 1054           // Make sure that someone isn't using a custom color model
 1055           // that called the super(bits) constructor.
 1056           if (colorSpace == null) {
 1057               throw new UnsupportedOperationException("This method is not supported "+
 1058                                           "by this color model.");
 1059           }
 1060   
 1061           if (nBits == null) {
 1062               throw new UnsupportedOperationException ("This method is not supported.  "+
 1063                                            "Unable to determine #bits per "+
 1064                                            "component.");
 1065           }
 1066           if ((normComponents.length - normOffset) < numComponents) {
 1067               throw new
 1068                   IllegalArgumentException(
 1069                           "Incorrect number of components.  Expecting "+
 1070                           numComponents);
 1071           }
 1072   
 1073           if (components == null) {
 1074               components = new int[offset+numComponents];
 1075           }
 1076   
 1077           if (supportsAlpha && isAlphaPremultiplied) {
 1078               float normAlpha = normComponents[normOffset+numColorComponents];
 1079               for (int i=0; i < numColorComponents; i++) {
 1080                   components[offset+i] = (int) (normComponents[normOffset+i]
 1081                                                 * ((1<<nBits[i]) - 1)
 1082                                                 * normAlpha + 0.5f);
 1083               }
 1084               components[offset+numColorComponents] = (int)
 1085                   (normAlpha * ((1<<nBits[numColorComponents]) - 1) + 0.5f);
 1086           }
 1087           else {
 1088               for (int i=0; i < numComponents; i++) {
 1089                   components[offset+i] = (int) (normComponents[normOffset+i]
 1090                                                 * ((1<<nBits[i]) - 1) + 0.5f);
 1091               }
 1092           }
 1093   
 1094           return components;
 1095       }
 1096   
 1097       /**
 1098        * Returns an array of all of the color/alpha components in normalized
 1099        * form, given an unnormalized component array.  Unnormalized components
 1100        * are unsigned integral values between 0 and 2<sup>n</sup> - 1, where
 1101        * n is the number of bits for a particular component.  Normalized
 1102        * components are float values between a per component minimum and
 1103        * maximum specified by the <code>ColorSpace</code> object for this
 1104        * <code>ColorModel</code>.  An <code>IllegalArgumentException</code>
 1105        * will be thrown if color component values for this
 1106        * <code>ColorModel</code> are not conveniently representable in the
 1107        * unnormalized form.  If the
 1108        * <code>normComponents</code> array is <code>null</code>, a new array
 1109        * will be allocated.  The <code>normComponents</code> array
 1110        * will be returned.  Color/alpha components are stored in the
 1111        * <code>normComponents</code> array starting at
 1112        * <code>normOffset</code> (even if the array is allocated by this
 1113        * method).  An <code>ArrayIndexOutOfBoundsException</code> is thrown
 1114        * if the <code>normComponents</code> array is not <code>null</code>
 1115        * and is not large enough to hold all the color and alpha components
 1116        * (starting at <code>normOffset</code>).  An
 1117        * <code>IllegalArgumentException</code> is thrown if the
 1118        * <code>components</code> array is not large enough to hold all the
 1119        * color and alpha components starting at <code>offset</code>.
 1120        * <p>
 1121        * Since <code>ColorModel</code> is an abstract class,
 1122        * any instance is an instance of a subclass.  The default implementation
 1123        * of this method in this abstract class assumes that component values
 1124        * for this class are conveniently representable in the unnormalized
 1125        * form.  Therefore, subclasses which may
 1126        * have instances which do not support the unnormalized form must
 1127        * override this method.
 1128        * @param components an array containing unnormalized components
 1129        * @param offset the offset into the <code>components</code> array at
 1130        * which to start retrieving unnormalized components
 1131        * @param normComponents an array that receives the normalized components
 1132        * @param normOffset the index into <code>normComponents</code> at
 1133        * which to begin storing normalized components
 1134        * @return an array containing normalized color and alpha
 1135        * components.
 1136        * @throws IllegalArgumentException If the component values for this
 1137        * <CODE>ColorModel</CODE> are not conveniently representable in the
 1138        * unnormalized form.
 1139        * @throws UnsupportedOperationException if the
 1140        *          constructor of this <code>ColorModel</code> called the
 1141        *          <code>super(bits)</code> constructor, but did not
 1142        *          override this method.  See the constructor,
 1143        *          {@link #ColorModel(int)}.
 1144        * @throws UnsupportedOperationException if this method is unable
 1145        *          to determine the number of bits per component
 1146        */
 1147       public float[] getNormalizedComponents(int[] components, int offset,
 1148                                              float[] normComponents,
 1149                                              int normOffset) {
 1150           // Make sure that someone isn't using a custom color model
 1151           // that called the super(bits) constructor.
 1152           if (colorSpace == null) {
 1153               throw new UnsupportedOperationException("This method is not supported by "+
 1154                                           "this color model.");
 1155           }
 1156           if (nBits == null) {
 1157               throw new UnsupportedOperationException ("This method is not supported.  "+
 1158                                            "Unable to determine #bits per "+
 1159                                            "component.");
 1160           }
 1161   
 1162           if ((components.length - offset) < numComponents) {
 1163               throw new
 1164                   IllegalArgumentException(
 1165                           "Incorrect number of components.  Expecting "+
 1166                           numComponents);
 1167           }
 1168   
 1169           if (normComponents == null) {
 1170               normComponents = new float[numComponents+normOffset];
 1171           }
 1172   
 1173           if (supportsAlpha && isAlphaPremultiplied) {
 1174               // Normalized coordinates are non premultiplied
 1175               float normAlpha = (float)components[offset+numColorComponents];
 1176               normAlpha /= (float) ((1<<nBits[numColorComponents]) - 1);
 1177               if (normAlpha != 0.0f) {
 1178                   for (int i=0; i < numColorComponents; i++) {
 1179                       normComponents[normOffset+i] =
 1180                           ((float) components[offset+i]) /
 1181                           (normAlpha * ((float) ((1<<nBits[i]) - 1)));
 1182                   }
 1183               } else {
 1184                   for (int i=0; i < numColorComponents; i++) {
 1185                       normComponents[normOffset+i] = 0.0f;
 1186                   }
 1187               }
 1188               normComponents[normOffset+numColorComponents] = normAlpha;
 1189           }
 1190           else {
 1191               for (int i=0; i < numComponents; i++) {
 1192                   normComponents[normOffset+i] = ((float) components[offset+i]) /
 1193                                                  ((float) ((1<<nBits[i]) - 1));
 1194               }
 1195           }
 1196   
 1197           return normComponents;
 1198       }
 1199   
 1200       /**
 1201        * Returns a pixel value represented as an <code>int</code> in this
 1202        * <code>ColorModel</code>, given an array of unnormalized color/alpha
 1203        * components.  This method will throw an
 1204        * <code>IllegalArgumentException</code> if component values for this
 1205        * <code>ColorModel</code> are not conveniently representable as a
 1206        * single <code>int</code> or if color component values for this
 1207        * <code>ColorModel</code> are not conveniently representable in the
 1208        * unnormalized form.  An
 1209        * <code>ArrayIndexOutOfBoundsException</code> is thrown if  the
 1210        * <code>components</code> array is not large enough to hold all the
 1211        * color and alpha components (starting at <code>offset</code>).
 1212        * Since <code>ColorModel</code> is an abstract class,
 1213        * any instance is an instance of a subclass.  Subclasses must
 1214        * override this method since the implementation in this abstract
 1215        * class throws an <code>UnsupportedOperationException</code>.
 1216        * @param components an array of unnormalized color and alpha
 1217        * components
 1218        * @param offset the index into <code>components</code> at which to
 1219        * begin retrieving the color and alpha components
 1220        * @return an <code>int</code> pixel value in this
 1221        * <code>ColorModel</code> corresponding to the specified components.
 1222        * @throws IllegalArgumentException if
 1223        *  pixel values for this <code>ColorModel</code> are not
 1224        *  conveniently representable as a single <code>int</code>
 1225        * @throws IllegalArgumentException if
 1226        *  component values for this <code>ColorModel</code> are not
 1227        *  conveniently representable in the unnormalized form
 1228        * @throws ArrayIndexOutOfBoundsException if
 1229        *  the <code>components</code> array is not large enough to
 1230        *  hold all of the color and alpha components starting at
 1231        *  <code>offset</code>
 1232        * @throws UnsupportedOperationException if this
 1233        *  method is not supported by this <code>ColorModel</code>
 1234        */
 1235       public int getDataElement(int[] components, int offset) {
 1236           throw new UnsupportedOperationException("This method is not supported "+
 1237                                       "by this color model.");
 1238       }
 1239   
 1240       /**
 1241        * Returns a data element array representation of a pixel in this
 1242        * <code>ColorModel</code>, given an array of unnormalized color/alpha
 1243        * components.  This array can then be passed to the
 1244        * <code>setDataElements</code> method of a <code>WritableRaster</code>
 1245        * object.  This method will throw an <code>IllegalArgumentException</code>
 1246        * if color component values for this <code>ColorModel</code> are not
 1247        * conveniently representable in the unnormalized form.
 1248        * An <code>ArrayIndexOutOfBoundsException</code> is thrown
 1249        * if the <code>components</code> array is not large enough to hold
 1250        * all the color and alpha components (starting at
 1251        * <code>offset</code>).  If the <code>obj</code> variable is
 1252        * <code>null</code>, a new array will be allocated.  If
 1253        * <code>obj</code> is not <code>null</code>, it must be a primitive
 1254        * array of type transferType; otherwise, a
 1255        * <code>ClassCastException</code> is thrown.  An
 1256        * <code>ArrayIndexOutOfBoundsException</code> is thrown if
 1257        * <code>obj</code> is not large enough to hold a pixel value for this
 1258        * <code>ColorModel</code>.
 1259        * Since <code>ColorModel</code> is an abstract class,
 1260        * any instance is an instance of a subclass.  Subclasses must
 1261        * override this method since the implementation in this abstract
 1262        * class throws an <code>UnsupportedOperationException</code>.
 1263        * @param components an array of unnormalized color and alpha
 1264        * components
 1265        * @param offset the index into <code>components</code> at which to
 1266        * begin retrieving color and alpha components
 1267        * @param obj the <code>Object</code> representing an array of color
 1268        * and alpha components
 1269        * @return an <code>Object</code> representing an array of color and
 1270        * alpha components.
 1271        * @throws ClassCastException if <code>obj</code>
 1272        *  is not a primitive array of type <code>transferType</code>
 1273        * @throws ArrayIndexOutOfBoundsException if
 1274        *  <code>obj</code> is not large enough to hold a pixel value
 1275        *  for this <code>ColorModel</code> or the <code>components</code>
 1276        *  array is not large enough to hold all of the color and alpha
 1277        *  components starting at <code>offset</code>
 1278        * @throws IllegalArgumentException if
 1279        *  component values for this <code>ColorModel</code> are not
 1280        *  conveniently representable in the unnormalized form
 1281        * @throws UnsupportedOperationException if this
 1282        *  method is not supported by this <code>ColorModel</code>
 1283        * @see WritableRaster#setDataElements
 1284        * @see SampleModel#setDataElements
 1285        */
 1286       public Object getDataElements(int[] components, int offset, Object obj) {
 1287           throw new UnsupportedOperationException("This method has not been implemented "+
 1288                                       "for this color model.");
 1289       }
 1290   
 1291       /**
 1292        * Returns a pixel value represented as an <code>int</code> in this
 1293        * <code>ColorModel</code>, given an array of normalized color/alpha
 1294        * components.  This method will throw an
 1295        * <code>IllegalArgumentException</code> if pixel values for this
 1296        * <code>ColorModel</code> are not conveniently representable as a
 1297        * single <code>int</code>.  An
 1298        * <code>ArrayIndexOutOfBoundsException</code> is thrown if  the
 1299        * <code>normComponents</code> array is not large enough to hold all the
 1300        * color and alpha components (starting at <code>normOffset</code>).
 1301        * Since <code>ColorModel</code> is an abstract class,
 1302        * any instance is an instance of a subclass.  The default implementation
 1303        * of this method in this abstract class first converts from the
 1304        * normalized form to the unnormalized form and then calls
 1305        * <code>getDataElement(int[], int)</code>.  Subclasses which may
 1306        * have instances which do not support the unnormalized form must
 1307        * override this method.
 1308        * @param normComponents an array of normalized color and alpha
 1309        * components
 1310        * @param normOffset the index into <code>normComponents</code> at which to
 1311        * begin retrieving the color and alpha components
 1312        * @return an <code>int</code> pixel value in this
 1313        * <code>ColorModel</code> corresponding to the specified components.
 1314        * @throws IllegalArgumentException if
 1315        *  pixel values for this <code>ColorModel</code> are not
 1316        *  conveniently representable as a single <code>int</code>
 1317        * @throws ArrayIndexOutOfBoundsException if
 1318        *  the <code>normComponents</code> array is not large enough to
 1319        *  hold all of the color and alpha components starting at
 1320        *  <code>normOffset</code>
 1321        * @since 1.4
 1322        */
 1323       public int getDataElement(float[] normComponents, int normOffset) {
 1324           int components[] = getUnnormalizedComponents(normComponents,
 1325                                                        normOffset, null, 0);
 1326           return getDataElement(components, 0);
 1327       }
 1328   
 1329       /**
 1330        * Returns a data element array representation of a pixel in this
 1331        * <code>ColorModel</code>, given an array of normalized color/alpha
 1332        * components.  This array can then be passed to the
 1333        * <code>setDataElements</code> method of a <code>WritableRaster</code>
 1334        * object.  An <code>ArrayIndexOutOfBoundsException</code> is thrown
 1335        * if the <code>normComponents</code> array is not large enough to hold
 1336        * all the color and alpha components (starting at
 1337        * <code>normOffset</code>).  If the <code>obj</code> variable is
 1338        * <code>null</code>, a new array will be allocated.  If
 1339        * <code>obj</code> is not <code>null</code>, it must be a primitive
 1340        * array of type transferType; otherwise, a
 1341        * <code>ClassCastException</code> is thrown.  An
 1342        * <code>ArrayIndexOutOfBoundsException</code> is thrown if
 1343        * <code>obj</code> is not large enough to hold a pixel value for this
 1344        * <code>ColorModel</code>.
 1345        * Since <code>ColorModel</code> is an abstract class,
 1346        * any instance is an instance of a subclass.  The default implementation
 1347        * of this method in this abstract class first converts from the
 1348        * normalized form to the unnormalized form and then calls
 1349        * <code>getDataElement(int[], int, Object)</code>.  Subclasses which may
 1350        * have instances which do not support the unnormalized form must
 1351        * override this method.
 1352        * @param normComponents an array of normalized color and alpha
 1353        * components
 1354        * @param normOffset the index into <code>normComponents</code> at which to
 1355        * begin retrieving color and alpha components
 1356        * @param obj a primitive data array to hold the returned pixel
 1357        * @return an <code>Object</code> which is a primitive data array
 1358        * representation of a pixel
 1359        * @throws ClassCastException if <code>obj</code>
 1360        *  is not a primitive array of type <code>transferType</code>
 1361        * @throws ArrayIndexOutOfBoundsException if
 1362        *  <code>obj</code> is not large enough to hold a pixel value
 1363        *  for this <code>ColorModel</code> or the <code>normComponents</code>
 1364        *  array is not large enough to hold all of the color and alpha
 1365        *  components starting at <code>normOffset</code>
 1366        * @see WritableRaster#setDataElements
 1367        * @see SampleModel#setDataElements
 1368        * @since 1.4
 1369        */
 1370       public Object getDataElements(float[] normComponents, int normOffset,
 1371                                     Object obj) {
 1372           int components[] = getUnnormalizedComponents(normComponents,
 1373                                                        normOffset, null, 0);
 1374           return getDataElements(components, 0, obj);
 1375       }
 1376   
 1377       /**
 1378        * Returns an array of all of the color/alpha components in normalized
 1379        * form, given a pixel in this <code>ColorModel</code>.  The pixel
 1380        * value is specified by an array of data elements of type transferType
 1381        * passed in as an object reference.  If pixel is not a primitive array
 1382        * of type transferType, a <code>ClassCastException</code> is thrown.
 1383        * An <code>ArrayIndexOutOfBoundsException</code> is thrown if
 1384        * <code>pixel</code> is not large enough to hold a pixel value for this
 1385        * <code>ColorModel</code>.
 1386        * Normalized components are float values between a per component minimum
 1387        * and maximum specified by the <code>ColorSpace</code> object for this
 1388        * <code>ColorModel</code>.  If the
 1389        * <code>normComponents</code> array is <code>null</code>, a new array
 1390        * will be allocated.  The <code>normComponents</code> array
 1391        * will be returned.  Color/alpha components are stored in the
 1392        * <code>normComponents</code> array starting at
 1393        * <code>normOffset</code> (even if the array is allocated by this
 1394        * method).  An <code>ArrayIndexOutOfBoundsException</code> is thrown
 1395        * if the <code>normComponents</code> array is not <code>null</code>
 1396        * and is not large enough to hold all the color and alpha components
 1397        * (starting at <code>normOffset</code>).
 1398        * Since <code>ColorModel</code> is an abstract class,
 1399        * any instance is an instance of a subclass.  The default implementation
 1400        * of this method in this abstract class first retrieves color and alpha
 1401        * components in the unnormalized form using
 1402        * <code>getComponents(Object, int[], int)</code> and then calls
 1403        * <code>getNormalizedComponents(int[], int, float[], int)</code>.
 1404        * Subclasses which may
 1405        * have instances which do not support the unnormalized form must
 1406        * override this method.
 1407        * @param pixel the specified pixel
 1408        * @param normComponents an array to receive the normalized components
 1409        * @param normOffset the offset into the <code>normComponents</code>
 1410        * array at which to start storing normalized components
 1411        * @return an array containing normalized color and alpha
 1412        * components.
 1413        * @throws ClassCastException if <code>pixel</code> is not a primitive
 1414        *          array of type transferType
 1415        * @throws ArrayIndexOutOfBoundsException if
 1416        *          <code>normComponents</code> is not large enough to hold all
 1417        *          color and alpha components starting at <code>normOffset</code>
 1418        * @throws ArrayIndexOutOfBoundsException if
 1419        *          <code>pixel</code> is not large enough to hold a pixel
 1420        *          value for this <code>ColorModel</code>.
 1421        * @throws UnsupportedOperationException if the
 1422        *          constructor of this <code>ColorModel</code> called the
 1423        *          <code>super(bits)</code> constructor, but did not
 1424        *          override this method.  See the constructor,
 1425        *          {@link #ColorModel(int)}.
 1426        * @throws UnsupportedOperationException if this method is unable
 1427        *          to determine the number of bits per component
 1428        * @since 1.4
 1429        */
 1430       public float[] getNormalizedComponents(Object pixel,
 1431                                              float[] normComponents,
 1432                                              int normOffset) {
 1433           int components[] = getComponents(pixel, null, 0);
 1434           return getNormalizedComponents(components, 0,
 1435                                          normComponents, normOffset);
 1436       }
 1437   
 1438       /**
 1439        * Tests if the specified <code>Object</code> is an instance of
 1440        * <code>ColorModel</code> and if it equals this
 1441        * <code>ColorModel</code>.
 1442        * @param obj the <code>Object</code> to test for equality
 1443        * @return <code>true</code> if the specified <code>Object</code>
 1444        * is an instance of <code>ColorModel</code> and equals this
 1445        * <code>ColorModel</code>; <code>false</code> otherwise.
 1446        */
 1447       public boolean equals(Object obj) {
 1448           if (!(obj instanceof ColorModel)) {
 1449               return false;
 1450           }
 1451           ColorModel cm = (ColorModel) obj;
 1452   
 1453           if (this == cm) {
 1454               return true;
 1455           }
 1456           if (supportsAlpha != cm.hasAlpha() ||
 1457               isAlphaPremultiplied != cm.isAlphaPremultiplied() ||
 1458               pixel_bits != cm.getPixelSize() ||
 1459               transparency != cm.getTransparency() ||
 1460               numComponents != cm.getNumComponents())
 1461           {
 1462               return false;
 1463           }
 1464   
 1465           int[] nb = cm.getComponentSize();
 1466   
 1467           if ((nBits != null) && (nb != null)) {
 1468               for (int i = 0; i < numComponents; i++) {
 1469                   if (nBits[i] != nb[i]) {
 1470                       return false;
 1471                   }
 1472               }
 1473           } else {
 1474               return ((nBits == null) && (nb == null));
 1475           }
 1476   
 1477           return true;
 1478       }
 1479   
 1480       /**
 1481        * Returns the hash code for this ColorModel.
 1482        *
 1483        * @return    a hash code for this ColorModel.
 1484        */
 1485       public int hashCode() {
 1486   
 1487           int result = 0;
 1488   
 1489           result = (supportsAlpha ? 2 : 3) +
 1490                    (isAlphaPremultiplied ? 4 : 5) +
 1491                    pixel_bits * 6 +
 1492                    transparency * 7 +
 1493                    numComponents * 8;
 1494   
 1495           if (nBits != null) {
 1496               for (int i = 0; i < numComponents; i++) {
 1497                   result = result + nBits[i] * (i + 9);
 1498               }
 1499           }
 1500   
 1501           return result;
 1502       }
 1503   
 1504       /**
 1505        * Returns the <code>ColorSpace</code> associated with this
 1506        * <code>ColorModel</code>.
 1507        * @return the <code>ColorSpace</code> of this
 1508        * <code>ColorModel</code>.
 1509        */
 1510       final public ColorSpace getColorSpace() {
 1511           return colorSpace;
 1512       }
 1513   
 1514       /**
 1515        * Forces the raster data to match the state specified in the
 1516        * <code>isAlphaPremultiplied</code> variable, assuming the data is
 1517        * currently correctly described by this <code>ColorModel</code>.  It
 1518        * may multiply or divide the color raster data by alpha, or do
 1519        * nothing if the data is in the correct state.  If the data needs to
 1520        * be coerced, this method will also return an instance of this
 1521        * <code>ColorModel</code> with the <code>isAlphaPremultiplied</code>
 1522        * flag set appropriately.  This method will throw a
 1523        * <code>UnsupportedOperationException</code> if it is not supported
 1524        * by this <code>ColorModel</code>.
 1525        * Since <code>ColorModel</code> is an abstract class,
 1526        * any instance is an instance of a subclass.  Subclasses must
 1527        * override this method since the implementation in this abstract
 1528        * class throws an <code>UnsupportedOperationException</code>.
 1529        * @param raster the <code>WritableRaster</code> data
 1530        * @param isAlphaPremultiplied <code>true</code> if the alpha is
 1531        * premultiplied; <code>false</code> otherwise
 1532        * @return a <code>ColorModel</code> object that represents the
 1533        * coerced data.
 1534        */
 1535       public ColorModel coerceData (WritableRaster raster,
 1536                                     boolean isAlphaPremultiplied) {
 1537           throw new UnsupportedOperationException
 1538               ("This method is not supported by this color model");
 1539       }
 1540   
 1541       /**
 1542         * Returns <code>true</code> if <code>raster</code> is compatible
 1543         * with this <code>ColorModel</code> and <code>false</code> if it is
 1544         * not.
 1545         * Since <code>ColorModel</code> is an abstract class,
 1546         * any instance is an instance of a subclass.  Subclasses must
 1547         * override this method since the implementation in this abstract
 1548         * class throws an <code>UnsupportedOperationException</code>.
 1549         * @param raster the {@link Raster} object to test for compatibility
 1550         * @return <code>true</code> if <code>raster</code> is compatible
 1551         * with this <code>ColorModel</code>.
 1552         * @throws UnsupportedOperationException if this
 1553         *         method has not been implemented for this
 1554         *         <code>ColorModel</code>
 1555         */
 1556       public boolean isCompatibleRaster(Raster raster) {
 1557           throw new UnsupportedOperationException(
 1558               "This method has not been implemented for this ColorModel.");
 1559       }
 1560   
 1561       /**
 1562        * Creates a <code>WritableRaster</code> with the specified width and
 1563        * height that has a data layout (<code>SampleModel</code>) compatible
 1564        * with this <code>ColorModel</code>.
 1565        * Since <code>ColorModel</code> is an abstract class,
 1566        * any instance is an instance of a subclass.  Subclasses must
 1567        * override this method since the implementation in this abstract
 1568        * class throws an <code>UnsupportedOperationException</code>.
 1569        * @param w the width to apply to the new <code>WritableRaster</code>
 1570        * @param h the height to apply to the new <code>WritableRaster</code>
 1571        * @return a <code>WritableRaster</code> object with the specified
 1572        * width and height.
 1573        * @throws UnsupportedOperationException if this
 1574        *          method is not supported by this <code>ColorModel</code>
 1575        * @see WritableRaster
 1576        * @see SampleModel
 1577        */
 1578       public WritableRaster createCompatibleWritableRaster(int w, int h) {
 1579           throw new UnsupportedOperationException
 1580               ("This method is not supported by this color model");
 1581       }
 1582   
 1583       /**
 1584        * Creates a <code>SampleModel</code> with the specified width and
 1585        * height that has a data layout compatible with this
 1586        * <code>ColorModel</code>.
 1587        * Since <code>ColorModel</code> is an abstract class,
 1588        * any instance is an instance of a subclass.  Subclasses must
 1589        * override this method since the implementation in this abstract
 1590        * class throws an <code>UnsupportedOperationException</code>.
 1591        * @param w the width to apply to the new <code>SampleModel</code>
 1592        * @param h the height to apply to the new <code>SampleModel</code>
 1593        * @return a <code>SampleModel</code> object with the specified
 1594        * width and height.
 1595        * @throws UnsupportedOperationException if this
 1596        *          method is not supported by this <code>ColorModel</code>
 1597        * @see SampleModel
 1598        */
 1599       public SampleModel createCompatibleSampleModel(int w, int h) {
 1600           throw new UnsupportedOperationException
 1601               ("This method is not supported by this color model");
 1602       }
 1603   
 1604       /** Checks if the <code>SampleModel</code> is compatible with this
 1605        * <code>ColorModel</code>.
 1606        * Since <code>ColorModel</code> is an abstract class,
 1607        * any instance is an instance of a subclass.  Subclasses must
 1608        * override this method since the implementation in this abstract
 1609        * class throws an <code>UnsupportedOperationException</code>.
 1610        * @param sm the specified <code>SampleModel</code>
 1611        * @return <code>true</code> if the specified <code>SampleModel</code>
 1612        * is compatible with this <code>ColorModel</code>; <code>false</code>
 1613        * otherwise.
 1614        * @throws UnsupportedOperationException if this
 1615        *          method is not supported by this <code>ColorModel</code>
 1616        * @see SampleModel
 1617        */
 1618       public boolean isCompatibleSampleModel(SampleModel sm) {
 1619           throw new UnsupportedOperationException
 1620               ("This method is not supported by this color model");
 1621       }
 1622   
 1623       /**
 1624        * Disposes of system resources associated with this
 1625        * <code>ColorModel</code> once this <code>ColorModel</code> is no
 1626        * longer referenced.
 1627        */
 1628       public void finalize() {
 1629       }
 1630   
 1631   
 1632       /**
 1633        * Returns a <code>Raster</code> representing the alpha channel of an
 1634        * image, extracted from the input <code>Raster</code>, provided that
 1635        * pixel values of this <code>ColorModel</code> represent color and
 1636        * alpha information as separate spatial bands (e.g.
 1637        * {@link ComponentColorModel} and <code>DirectColorModel</code>).
 1638        * This method assumes that <code>Raster</code> objects associated
 1639        * with such a <code>ColorModel</code> store the alpha band, if
 1640        * present, as the last band of image data.  Returns <code>null</code>
 1641        * if there is no separate spatial alpha channel associated with this
 1642        * <code>ColorModel</code>.  If this is an
 1643        * <code>IndexColorModel</code> which has alpha in the lookup table,
 1644        * this method will return <code>null</code> since
 1645        * there is no spatially discrete alpha channel.
 1646        * This method will create a new <code>Raster</code> (but will share
 1647        * the data array).
 1648        * Since <code>ColorModel</code> is an abstract class, any instance
 1649        * is an instance of a subclass.  Subclasses must override this
 1650        * method to get any behavior other than returning <code>null</code>
 1651        * because the implementation in this abstract class returns
 1652        * <code>null</code>.
 1653        * @param raster the specified <code>Raster</code>
 1654        * @return a <code>Raster</code> representing the alpha channel of
 1655        * an image, obtained from the specified <code>Raster</code>.
 1656        */
 1657       public WritableRaster getAlphaRaster(WritableRaster raster) {
 1658           return null;
 1659       }
 1660   
 1661       /**
 1662        * Returns the <code>String</code> representation of the contents of
 1663        * this <code>ColorModel</code>object.
 1664        * @return a <code>String</code> representing the contents of this
 1665        * <code>ColorModel</code> object.
 1666        */
 1667       public String toString() {
 1668          return new String("ColorModel: #pixelBits = "+pixel_bits
 1669                            + " numComponents = "+numComponents
 1670                            + " color space = "+colorSpace
 1671                            + " transparency = "+transparency
 1672                            + " has alpha = "+supportsAlpha
 1673                            + " isAlphaPre = "+isAlphaPremultiplied
 1674                            );
 1675       }
 1676   
 1677       static int getDefaultTransferType(int pixel_bits) {
 1678           if (pixel_bits <= 8) {
 1679               return DataBuffer.TYPE_BYTE;
 1680           } else if (pixel_bits <= 16) {
 1681               return DataBuffer.TYPE_USHORT;
 1682           } else if (pixel_bits <= 32) {
 1683               return DataBuffer.TYPE_INT;
 1684           } else {
 1685               return DataBuffer.TYPE_UNDEFINED;
 1686           }
 1687       }
 1688   
 1689       static byte[] l8Tos8 = null;   // 8-bit linear to 8-bit non-linear sRGB LUT
 1690       static byte[] s8Tol8 = null;   // 8-bit non-linear sRGB to 8-bit linear LUT
 1691       static byte[] l16Tos8 = null;  // 16-bit linear to 8-bit non-linear sRGB LUT
 1692       static short[] s8Tol16 = null; // 8-bit non-linear sRGB to 16-bit linear LUT
 1693   
 1694                                   // Maps to hold LUTs for grayscale conversions
 1695       static Map g8Tos8Map = null;     // 8-bit gray values to 8-bit sRGB values
 1696       static Map lg16Toog8Map = null;  // 16-bit linear to 8-bit "other" gray
 1697       static Map g16Tos8Map = null;    // 16-bit gray values to 8-bit sRGB values
 1698       static Map lg16Toog16Map = null; // 16-bit linear to 16-bit "other" gray
 1699   
 1700       static boolean isLinearRGBspace(ColorSpace cs) {
 1701           // Note: CMM.LINEAR_RGBspace will be null if the linear
 1702           // RGB space has not been created yet.
 1703           return (cs == CMSManager.LINEAR_RGBspace);
 1704       }
 1705   
 1706       static boolean isLinearGRAYspace(ColorSpace cs) {
 1707           // Note: CMM.GRAYspace will be null if the linear
 1708           // gray space has not been created yet.
 1709           return (cs == CMSManager.GRAYspace);
 1710       }
 1711   
 1712       static byte[] getLinearRGB8TosRGB8LUT() {
 1713           if (l8Tos8 == null) {
 1714               l8Tos8 = new byte[256];
 1715               float input, output;
 1716               // algorithm for linear RGB to nonlinear sRGB conversion
 1717               // is from the IEC 61966-2-1 International Standard,
 1718               // Colour Management - Default RGB colour space - sRGB,
 1719               // First Edition, 1999-10,
 1720               // avaiable for order at http://www.iec.ch
 1721               for (int i = 0; i <= 255; i++) {
 1722                   input = ((float) i) / 255.0f;
 1723                   if (input <= 0.0031308f) {
 1724                       output = input * 12.92f;
 1725                   } else {
 1726                       output = 1.055f * ((float) Math.pow(input, (1.0 / 2.4)))
 1727                                - 0.055f;
 1728                   }
 1729                   l8Tos8[i] = (byte) Math.round(output * 255.0f);
 1730               }
 1731           }
 1732           return l8Tos8;
 1733       }
 1734   
 1735       static byte[] getsRGB8ToLinearRGB8LUT() {
 1736           if (s8Tol8 == null) {
 1737               s8Tol8 = new byte[256];
 1738               float input, output;
 1739               // algorithm from IEC 61966-2-1 International Standard
 1740               for (int i = 0; i <= 255; i++) {
 1741                   input = ((float) i) / 255.0f;
 1742                   if (input <= 0.04045f) {
 1743                       output = input / 12.92f;
 1744                   } else {
 1745                       output = (float) Math.pow((input + 0.055f) / 1.055f, 2.4);
 1746                   }
 1747                   s8Tol8[i] = (byte) Math.round(output * 255.0f);
 1748               }
 1749           }
 1750           return s8Tol8;
 1751       }
 1752   
 1753       static byte[] getLinearRGB16TosRGB8LUT() {
 1754           if (l16Tos8 == null) {
 1755               l16Tos8 = new byte[65536];
 1756               float input, output;
 1757               // algorithm from IEC 61966-2-1 International Standard
 1758               for (int i = 0; i <= 65535; i++) {
 1759                   input = ((float) i) / 65535.0f;
 1760                   if (input <= 0.0031308f) {
 1761                       output = input * 12.92f;
 1762                   } else {
 1763                       output = 1.055f * ((float) Math.pow(input, (1.0 / 2.4)))
 1764                                - 0.055f;
 1765                   }
 1766                   l16Tos8[i] = (byte) Math.round(output * 255.0f);
 1767               }
 1768           }
 1769           return l16Tos8;
 1770       }
 1771   
 1772       static short[] getsRGB8ToLinearRGB16LUT() {
 1773           if (s8Tol16 == null) {
 1774               s8Tol16 = new short[256];
 1775               float input, output;
 1776               // algorithm from IEC 61966-2-1 International Standard
 1777               for (int i = 0; i <= 255; i++) {
 1778                   input = ((float) i) / 255.0f;
 1779                   if (input <= 0.04045f) {
 1780                       output = input / 12.92f;
 1781                   } else {
 1782                       output = (float) Math.pow((input + 0.055f) / 1.055f, 2.4);
 1783                   }
 1784                   s8Tol16[i] = (short) Math.round(output * 65535.0f);
 1785               }
 1786           }
 1787           return s8Tol16;
 1788       }
 1789   
 1790       /*
 1791        * Return a byte LUT that converts 8-bit gray values in the grayCS
 1792        * ColorSpace to the appropriate 8-bit sRGB value.  I.e., if lut
 1793        * is the byte array returned by this method and sval = lut[gval],
 1794        * then the sRGB triple (sval,sval,sval) is the best match to gval.
 1795        * Cache references to any computed LUT in a Map.
 1796        */
 1797       static byte[] getGray8TosRGB8LUT(ICC_ColorSpace grayCS) {
 1798           if (isLinearGRAYspace(grayCS)) {
 1799               return getLinearRGB8TosRGB8LUT();
 1800           }
 1801           if (g8Tos8Map != null) {
 1802               byte[] g8Tos8LUT = (byte []) g8Tos8Map.get(grayCS);
 1803               if (g8Tos8LUT != null) {
 1804                   return g8Tos8LUT;
 1805               }
 1806           }
 1807           byte[] g8Tos8LUT = new byte[256];
 1808           for (int i = 0; i <= 255; i++) {
 1809               g8Tos8LUT[i] = (byte) i;
 1810           }
 1811           ColorTransform[] transformList = new ColorTransform[2];
 1812           PCMM mdl = CMSManager.getModule();
 1813           ICC_ColorSpace srgbCS =
 1814               (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_sRGB);
 1815           transformList[0] = mdl.createTransform(
 1816               grayCS.getProfile(), ColorTransform.Any, ColorTransform.In);
 1817           transformList[1] = mdl.createTransform(
 1818               srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
 1819           ColorTransform t = mdl.createTransform(transformList);
 1820           byte[] tmp = t.colorConvert(g8Tos8LUT, null);
 1821           for (int i = 0, j= 2; i <= 255; i++, j += 3) {
 1822               // All three components of tmp should be equal, since
 1823               // the input color space to colorConvert is a gray scale
 1824               // space.  However, there are slight anomalies in the results.
 1825               // Copy tmp starting at index 2, since colorConvert seems
 1826               // to be slightly more accurate for the third component!
 1827               g8Tos8LUT[i] = tmp[j];
 1828           }
 1829           if (g8Tos8Map == null) {
 1830               g8Tos8Map = Collections.synchronizedMap(new WeakHashMap(2));
 1831           }
 1832           g8Tos8Map.put(grayCS, g8Tos8LUT);
 1833           return g8Tos8LUT;
 1834       }
 1835   
 1836       /*
 1837        * Return a byte LUT that converts 16-bit gray values in the CS_GRAY
 1838        * linear gray ColorSpace to the appropriate 8-bit value in the
 1839        * grayCS ColorSpace.  Cache references to any computed LUT in a Map.
 1840        */
 1841       static byte[] getLinearGray16ToOtherGray8LUT(ICC_ColorSpace grayCS) {
 1842           if (lg16Toog8Map != null) {
 1843               byte[] lg16Toog8LUT = (byte []) lg16Toog8Map.get(grayCS);
 1844               if (lg16Toog8LUT != null) {
 1845                   return lg16Toog8LUT;
 1846               }
 1847           }
 1848           short[] tmp = new short[65536];
 1849           for (int i = 0; i <= 65535; i++) {
 1850               tmp[i] = (short) i;
 1851           }
 1852           ColorTransform[] transformList = new ColorTransform[2];
 1853           PCMM mdl = CMSManager.getModule();
 1854           ICC_ColorSpace lgCS =
 1855               (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_GRAY);
 1856           transformList[0] = mdl.createTransform (
 1857               lgCS.getProfile(), ColorTransform.Any, ColorTransform.In);
 1858           transformList[1] = mdl.createTransform (
 1859               grayCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
 1860           ColorTransform t = mdl.createTransform(transformList);
 1861           tmp = t.colorConvert(tmp, null);
 1862           byte[] lg16Toog8LUT = new byte[65536];
 1863           for (int i = 0; i <= 65535; i++) {
 1864               // scale unsigned short (0 - 65535) to unsigned byte (0 - 255)
 1865               lg16Toog8LUT[i] =
 1866                   (byte) (((float) (tmp[i] & 0xffff)) * (1.0f /257.0f) + 0.5f);
 1867           }
 1868           if (lg16Toog8Map == null) {
 1869               lg16Toog8Map = Collections.synchronizedMap(new WeakHashMap(2));
 1870           }
 1871           lg16Toog8Map.put(grayCS, lg16Toog8LUT);
 1872           return lg16Toog8LUT;
 1873       }
 1874   
 1875       /*
 1876        * Return a byte LUT that converts 16-bit gray values in the grayCS
 1877        * ColorSpace to the appropriate 8-bit sRGB value.  I.e., if lut
 1878        * is the byte array returned by this method and sval = lut[gval],
 1879        * then the sRGB triple (sval,sval,sval) is the best match to gval.
 1880        * Cache references to any computed LUT in a Map.
 1881        */
 1882       static byte[] getGray16TosRGB8LUT(ICC_ColorSpace grayCS) {
 1883           if (isLinearGRAYspace(grayCS)) {
 1884               return getLinearRGB16TosRGB8LUT();
 1885           }
 1886           if (g16Tos8Map != null) {
 1887               byte[] g16Tos8LUT = (byte []) g16Tos8Map.get(grayCS);
 1888               if (g16Tos8LUT != null) {
 1889                   return g16Tos8LUT;
 1890               }
 1891           }
 1892           short[] tmp = new short[65536];
 1893           for (int i = 0; i <= 65535; i++) {
 1894               tmp[i] = (short) i;
 1895           }
 1896           ColorTransform[] transformList = new ColorTransform[2];
 1897           PCMM mdl = CMSManager.getModule();
 1898           ICC_ColorSpace srgbCS =
 1899               (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_sRGB);
 1900           transformList[0] = mdl.createTransform (
 1901               grayCS.getProfile(), ColorTransform.Any, ColorTransform.In);
 1902           transformList[1] = mdl.createTransform (
 1903               srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
 1904           ColorTransform t = mdl.createTransform(transformList);
 1905           tmp = t.colorConvert(tmp, null);
 1906           byte[] g16Tos8LUT = new byte[65536];
 1907           for (int i = 0, j= 2; i <= 65535; i++, j += 3) {
 1908               // All three components of tmp should be equal, since
 1909               // the input color space to colorConvert is a gray scale
 1910               // space.  However, there are slight anomalies in the results.
 1911               // Copy tmp starting at index 2, since colorConvert seems
 1912               // to be slightly more accurate for the third component!
 1913   
 1914               // scale unsigned short (0 - 65535) to unsigned byte (0 - 255)
 1915               g16Tos8LUT[i] =
 1916                   (byte) (((float) (tmp[j] & 0xffff)) * (1.0f /257.0f) + 0.5f);
 1917           }
 1918           if (g16Tos8Map == null) {
 1919               g16Tos8Map = Collections.synchronizedMap(new WeakHashMap(2));
 1920           }
 1921           g16Tos8Map.put(grayCS, g16Tos8LUT);
 1922           return g16Tos8LUT;
 1923       }
 1924   
 1925       /*
 1926        * Return a short LUT that converts 16-bit gray values in the CS_GRAY
 1927        * linear gray ColorSpace to the appropriate 16-bit value in the
 1928        * grayCS ColorSpace.  Cache references to any computed LUT in a Map.
 1929        */
 1930       static short[] getLinearGray16ToOtherGray16LUT(ICC_ColorSpace grayCS) {
 1931           if (lg16Toog16Map != null) {
 1932               short[] lg16Toog16LUT = (short []) lg16Toog16Map.get(grayCS);
 1933               if (lg16Toog16LUT != null) {
 1934                   return lg16Toog16LUT;
 1935               }
 1936           }
 1937           short[] tmp = new short[65536];
 1938           for (int i = 0; i <= 65535; i++) {
 1939               tmp[i] = (short) i;
 1940           }
 1941           ColorTransform[] transformList = new ColorTransform[2];
 1942           PCMM mdl = CMSManager.getModule();
 1943           ICC_ColorSpace lgCS =
 1944               (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_GRAY);
 1945           transformList[0] = mdl.createTransform (
 1946               lgCS.getProfile(), ColorTransform.Any, ColorTransform.In);
 1947           transformList[1] = mdl.createTransform(
 1948               grayCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
 1949           ColorTransform t = mdl.createTransform(
 1950               transformList);
 1951           short[] lg16Toog16LUT = t.colorConvert(tmp, null);
 1952           if (lg16Toog16Map == null) {
 1953               lg16Toog16Map = Collections.synchronizedMap(new WeakHashMap(2));
 1954           }
 1955           lg16Toog16Map.put(grayCS, lg16Toog16LUT);
 1956           return lg16Toog16LUT;
 1957       }
 1958   
 1959   }

Home » openjdk-7 » java » awt » image » [javadoc | source]