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 = 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 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<ICC_ColorSpace, byte[]> g8Tos8Map = null;     // 8-bit gray values to 8-bit sRGB values
1696     static Map<ICC_ColorSpace, byte[]> lg16Toog8Map = null;  // 16-bit linear to 8-bit "other" gray
1697     static Map<ICC_ColorSpace, byte[]> g16Tos8Map = null;    // 16-bit gray values to 8-bit sRGB values
1698     static Map<ICC_ColorSpace, short[]> 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 = 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<ICC_ColorSpace, byte[]>(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 = 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<ICC_ColorSpace, byte[]>(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 = 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<ICC_ColorSpace, byte[]>(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 = 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<ICC_ColorSpace, short[]>(2));
1954         }
1955         lg16Toog16Map.put(grayCS, lg16Toog16LUT);
1956         return lg16Toog16LUT;
1957     }
1958 
1959 }