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