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