1 /*
   2  * Copyright (c) 1995, 2019, 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.Collections;
  35 import java.util.Map;
  36 import java.util.WeakHashMap;
  37 import java.util.Arrays;
  38 
  39 /**
  40  * The {@code ColorModel} abstract class encapsulates the
  41  * methods for translating a pixel value to color components
  42  * (for example, red, green, and blue) and an alpha component.
  43  * In order to render an image to the screen, a printer, or another
  44  * image, pixel values must be converted to color and alpha components.
  45  * As arguments to or return values from methods of this class,
  46  * pixels are represented as 32-bit ints or as arrays of primitive types.
  47  * The number, order, and interpretation of color components for a
  48  * {@code ColorModel} is specified by its {@code ColorSpace}.
  49  * A {@code ColorModel} used with pixel data that does not include
  50  * alpha information treats all pixels as opaque, which is an alpha
  51  * value of 1.0.
  52  * <p>
  53  * This {@code ColorModel} class supports two representations of
  54  * pixel values.  A pixel value can be a single 32-bit int or an
  55  * array of primitive types.  The Java(tm) Platform 1.0 and 1.1 APIs
  56  * represented pixels as single {@code byte} or single
  57  * {@code int} values.  For purposes of the {@code ColorModel}
  58  * class, pixel value arguments were passed as ints.  The Java(tm) 2
  59  * Platform API introduced additional classes for representing images.
  60  * With {@link BufferedImage} or {@link RenderedImage}
  61  * objects, based on {@link Raster} and {@link SampleModel} classes, pixel
  62  * values might not be conveniently representable as a single int.
  63  * Consequently, {@code ColorModel} now has methods that accept
  64  * pixel values represented as arrays of primitive types.  The primitive
  65  * type used by a particular {@code ColorModel} object is called its
  66  * transfer type.
  67  * <p>
  68  * {@code ColorModel} objects used with images for which pixel values
  69  * are not conveniently representable as a single int throw an
  70  * {@link IllegalArgumentException} when methods taking a single int pixel
  71  * argument are called.  Subclasses of {@code ColorModel} must
  72  * specify the conditions under which this occurs.  This does not
  73  * occur with {@link DirectColorModel} or {@link IndexColorModel} objects.
  74  * <p>
  75  * Currently, the transfer types supported by the Java 2D(tm) API are
  76  * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
  77  * DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, and DataBuffer.TYPE_DOUBLE.
  78  * Most rendering operations will perform much faster when using ColorModels
  79  * and images based on the first three of these types.  In addition, some
  80  * image filtering operations are not supported for ColorModels and
  81  * images based on the latter three types.
  82  * The transfer type for a particular {@code ColorModel} object is
  83  * specified when the object is created, either explicitly or by default.
  84  * All subclasses of {@code ColorModel} must specify what the
  85  * possible transfer types are and how the number of elements in the
  86  * primitive arrays representing pixels is determined.
  87  * <p>
  88  * For {@code BufferedImages}, the transfer type of its
  89  * {@code Raster} and of the {@code Raster} object's
  90  * {@code SampleModel} (available from the
  91  * {@code getTransferType} methods of these classes) must match that
  92  * of the {@code ColorModel}.  The number of elements in an array
  93  * representing a pixel for the {@code Raster} and
  94  * {@code SampleModel} (available from the
  95  * {@code getNumDataElements} methods of these classes) must match
  96  * that of the {@code ColorModel}.
  97  * <p>
  98  * The algorithm used to convert from pixel values to color and alpha
  99  * components varies by subclass.  For example, there is not necessarily
 100  * a one-to-one correspondence between samples obtained from the
 101  * {@code SampleModel} of a {@code BufferedImage} object's
 102  * {@code Raster} and color/alpha components.  Even when
 103  * there is such a correspondence, the number of bits in a sample is not
 104  * necessarily the same as the number of bits in the corresponding color/alpha
 105  * component.  Each subclass must specify how the translation from
 106  * pixel values to color/alpha components is done.
 107  * <p>
 108  * Methods in the {@code ColorModel} class use two different
 109  * representations of color and alpha components - a normalized form
 110  * and an unnormalized form.  In the normalized form, each component is a
 111  * {@code float} value between some minimum and maximum values.  For
 112  * the alpha component, the minimum is 0.0 and the maximum is 1.0.  For
 113  * color components the minimum and maximum values for each component can
 114  * be obtained from the {@code ColorSpace} object.  These values
 115  * will often be 0.0 and 1.0 (e.g. normalized component values for the
 116  * default sRGB color space range from 0.0 to 1.0), but some color spaces
 117  * have component values with different upper and lower limits.  These
 118  * limits can be obtained using the {@code getMinValue} and
 119  * {@code getMaxValue} methods of the {@code ColorSpace}
 120  * class.  Normalized color component values are not premultiplied.
 121  * All {@code ColorModels} must support the normalized form.
 122  * <p>
 123  * In the unnormalized
 124  * form, each component is an unsigned integral value between 0 and
 125  * 2<sup>n</sup> - 1, where n is the number of significant bits for a
 126  * particular component.  If pixel values for a particular
 127  * {@code ColorModel} represent color samples premultiplied by
 128  * the alpha sample, unnormalized color component values are
 129  * also premultiplied.  The unnormalized form is used only with instances
 130  * of {@code ColorModel} whose {@code ColorSpace} has minimum
 131  * component values of 0.0 for all components and maximum values of
 132  * 1.0 for all components.
 133  * The unnormalized form for color and alpha components can be a convenient
 134  * representation for {@code ColorModels} whose normalized component
 135  * values all lie
 136  * between 0.0 and 1.0.  In such cases the integral value 0 maps to 0.0 and
 137  * the value 2<sup>n</sup> - 1 maps to 1.0.  In other cases, such as
 138  * when the normalized component values can be either negative or positive,
 139  * the unnormalized form is not convenient.  Such {@code ColorModel}
 140  * objects throw an {@link IllegalArgumentException} when methods involving
 141  * an unnormalized argument are called.  Subclasses of {@code ColorModel}
 142  * must specify the conditions under which this occurs.
 143  *
 144  * @see IndexColorModel
 145  * @see ComponentColorModel
 146  * @see PackedColorModel
 147  * @see DirectColorModel
 148  * @see java.awt.Image
 149  * @see BufferedImage
 150  * @see RenderedImage
 151  * @see java.awt.color.ColorSpace
 152  * @see SampleModel
 153  * @see Raster
 154  * @see DataBuffer
 155  */
 156 public abstract class ColorModel implements Transparency{
 157     private long pData;         // Placeholder for data for native functions
 158 
 159     /**
 160      * The total number of bits in the pixel.
 161      */
 162     protected int pixel_bits;
 163     int[] nBits;
 164     int transparency = Transparency.TRANSLUCENT;
 165     boolean supportsAlpha = true;
 166     boolean isAlphaPremultiplied = false;
 167     int numComponents = -1;
 168     int numColorComponents = -1;
 169     ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
 170     int colorSpaceType = ColorSpace.TYPE_RGB;
 171     int maxBits;
 172     boolean is_sRGB = true;
 173 
 174     /**
 175      * Data type of the array used to represent pixel values.
 176      */
 177     protected int transferType;
 178 
 179     /**
 180      * This is copied from java.awt.Toolkit since we need the library
 181      * loaded in java.awt.image also:
 182      *
 183      * WARNING: This is a temporary workaround for a problem in the
 184      * way the AWT loads native libraries. A number of classes in the
 185      * AWT package have a native method, initIDs(), which initializes
 186      * the JNI field and method ids used in the native portion of
 187      * their implementation.
 188      *
 189      * Since the use and storage of these ids is done by the
 190      * implementation libraries, the implementation of these method is
 191      * provided by the particular AWT implementations (for example,
 192      * "Toolkit"s/Peer), such as Motif, Microsoft Windows, or Tiny. The
 193      * problem is that this means that the native libraries must be
 194      * loaded by the java.* classes, which do not necessarily know the
 195      * names of the libraries to load. A better way of doing this
 196      * would be to provide a separate library which defines java.awt.*
 197      * initIDs, and exports the relevant symbols out to the
 198      * implementation libraries.
 199      *
 200      * For now, we know it's done by the implementation, and we assume
 201      * that the name of the library is "awt".  -br.
 202      */
 203     private static boolean loaded = false;
 204     static void loadLibraries() {
 205         if (!loaded) {
 206             jdk.internal.access.SharedSecrets.getJavaLangAccess().loadLibrary("awt");
 207             loaded = true;
 208         }
 209     }
 210     private static native void initIDs();
 211     static {
 212         /* ensure that the proper libraries are loaded */
 213         loadLibraries();
 214         initIDs();
 215     }
 216     private static ColorModel RGBdefault;
 217 
 218     /**
 219      * Returns a {@code DirectColorModel} that describes the default
 220      * format for integer RGB values used in many of the methods in the
 221      * AWT image interfaces for the convenience of the programmer.
 222      * The color space is the default {@link ColorSpace}, sRGB.
 223      * The format for the RGB values is an integer with 8 bits
 224      * each of alpha, red, green, and blue color components ordered
 225      * correspondingly from the most significant byte to the least
 226      * significant byte, as in:  0xAARRGGBB.  Color components are
 227      * not premultiplied by the alpha component.  This format does not
 228      * necessarily represent the native or the most efficient
 229      * {@code ColorModel} for a particular device or for all images.
 230      * It is merely used as a common color model format.
 231      * @return a {@code DirectColorModel} object describing default
 232      *          RGB values.
 233      */
 234     public static ColorModel getRGBdefault() {
 235         if (RGBdefault == null) {
 236             RGBdefault = new DirectColorModel(32,
 237                                               0x00ff0000,       // Red
 238                                               0x0000ff00,       // Green
 239                                               0x000000ff,       // Blue
 240                                               0xff000000        // Alpha
 241                                               );
 242         }
 243         return RGBdefault;
 244     }
 245 
 246     /**
 247      * Constructs a {@code ColorModel} that translates pixels of the
 248      * specified number of bits to color/alpha components.  The color
 249      * space is the default RGB {@code ColorSpace}, which is sRGB.
 250      * Pixel values are assumed to include alpha information.  If color
 251      * and alpha information are represented in the pixel value as
 252      * separate spatial bands, the color bands are assumed not to be
 253      * premultiplied with the alpha value. The transparency type is
 254      * java.awt.Transparency.TRANSLUCENT.  The transfer type will be the
 255      * smallest of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
 256      * or DataBuffer.TYPE_INT that can hold a single pixel
 257      * (or DataBuffer.TYPE_UNDEFINED if bits is greater
 258      * than 32).  Since this constructor has no information about the
 259      * number of bits per color and alpha component, any subclass calling
 260      * this constructor should override any method that requires this
 261      * information.
 262      * @param bits the number of bits of a pixel
 263      * @throws IllegalArgumentException if the number
 264      *          of bits in {@code bits} is less than 1
 265      */
 266     public ColorModel(int bits) {
 267         pixel_bits = bits;
 268         if (bits < 1) {
 269             throw new IllegalArgumentException("Number of bits must be > 0");
 270         }
 271         numComponents = 4;
 272         numColorComponents = 3;
 273         maxBits = bits;
 274         // REMIND: make sure transferType is set correctly
 275         transferType = ColorModel.getDefaultTransferType(bits);
 276     }
 277 
 278     /**
 279      * Constructs a {@code ColorModel} that translates pixel values
 280      * to color/alpha components.  Color components will be in the
 281      * specified {@code ColorSpace}. {@code pixel_bits} is the
 282      * number of bits in the pixel values.  The bits array
 283      * specifies the number of significant bits per color and alpha component.
 284      * Its length should be the number of components in the
 285      * {@code ColorSpace} if there is no alpha information in the
 286      * pixel values, or one more than this number if there is alpha
 287      * information.  {@code hasAlpha} indicates whether or not alpha
 288      * information is present.  The {@code boolean}
 289      * {@code isAlphaPremultiplied} specifies how to interpret pixel
 290      * values in which color and alpha information are represented as
 291      * separate spatial bands.  If the {@code boolean}
 292      * is {@code true}, color samples are assumed to have been
 293      * multiplied by the alpha sample.  The {@code transparency}
 294      * specifies what alpha values can be represented by this color model.
 295      * The transfer type is the type of primitive array used to represent
 296      * pixel values.  Note that the bits array contains the number of
 297      * significant bits per color/alpha component after the translation
 298      * from pixel values.  For example, for an
 299      * {@code IndexColorModel} with {@code pixel_bits} equal to
 300      * 16, the bits array might have four elements with each element set
 301      * to 8.
 302      * @param pixel_bits the number of bits in the pixel values
 303      * @param bits array that specifies the number of significant bits
 304      *          per color and alpha component
 305      * @param cspace the specified {@code ColorSpace}
 306      * @param hasAlpha {@code true} if alpha information is present;
 307      *          {@code false} otherwise
 308      * @param isAlphaPremultiplied {@code true} if color samples are
 309      *          assumed to be premultiplied by the alpha samples;
 310      *          {@code false} otherwise
 311      * @param transparency what alpha values can be represented by this
 312      *          color model
 313      * @param transferType the type of the array used to represent pixel
 314      *          values
 315      * @throws IllegalArgumentException if the length of
 316      *          the bit array is less than the number of color or alpha
 317      *          components in this {@code ColorModel}, or if the
 318      *          transparency is not a valid value.
 319      * @throws IllegalArgumentException if the sum of the number
 320      *          of bits in {@code bits} is less than 1 or if
 321      *          any of the elements in {@code bits} is less than 0.
 322      * @see java.awt.Transparency
 323      */
 324     protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace,
 325                          boolean hasAlpha,
 326                          boolean isAlphaPremultiplied,
 327                          int transparency,
 328                          int transferType) {
 329         colorSpace                = cspace;
 330         colorSpaceType            = cspace.getType();
 331         numColorComponents        = cspace.getNumComponents();
 332         numComponents             = numColorComponents + (hasAlpha ? 1 : 0);
 333         supportsAlpha             = hasAlpha;
 334         if (bits.length < numComponents) {
 335             throw new IllegalArgumentException("Number of color/alpha "+
 336                                                "components should be "+
 337                                                numComponents+
 338                                                " but length of bits array is "+
 339                                                bits.length);
 340         }
 341 
 342         // 4186669
 343         if (transparency < Transparency.OPAQUE ||
 344             transparency > Transparency.TRANSLUCENT)
 345         {
 346             throw new IllegalArgumentException("Unknown transparency: "+
 347                                                transparency);
 348         }
 349 
 350         if (supportsAlpha == false) {
 351             this.isAlphaPremultiplied = false;
 352             this.transparency = Transparency.OPAQUE;
 353         }
 354         else {
 355             this.isAlphaPremultiplied = isAlphaPremultiplied;
 356             this.transparency         = transparency;
 357         }
 358 
 359         /*
 360          * We need significant bits value only for the length
 361          * of number of components, so we truncate remaining part.
 362          * It also helps in hashCode calculation since bits[] can contain
 363          * different values after the length of number of components between
 364          * two ColorModels.
 365          */
 366         nBits = Arrays.copyOf(bits, numComponents);
 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      * This method simply delegates to the default implementation in {@code Object}
1446      * which is identical to an {@code ==} test since this class cannot enforce the
1447      * issues of a proper equality test among multiple independent subclass
1448      * branches.
1449      * Subclasses are encouraged to override this method and provide equality
1450      * testing for their own properties in addition to equality tests for the
1451      * following common base properties of {@code ColorModel}:
1452      * <ul>
1453      * <li>Support for alpha component.</li>
1454      * <li>Is alpha premultiplied.</li>
1455      * <li>Number of bits per pixel.</li>
1456      * <li>Type of transparency like Opaque, Bitmask or Translucent.</li>
1457      * <li>Number of components in a pixel.</li>
1458      * <li>{@code ColorSpace} type.</li>
1459      * <li>Type of the array used to represent pixel values.</li>
1460      * <li>Number of significant bits per color and alpha component.</li>
1461      * </ul>
1462      * @param obj the reference object with which to compare.
1463      * @return {@code true} if this object is the same as the obj
1464      *         argument; {@code false} otherwise.
1465      */
1466     @Override
1467     public boolean equals(Object obj) {
1468         return super.equals(obj);
1469     }
1470 
1471     /**
1472      * This method simply delegates to the default implementation in {@code Object}
1473      * which returns the system ID for the class.
1474      * Subclasses are encouraged to override this method and provide a hash
1475      * for their own properties in addition to hashing the values of the
1476      * following common base properties of {@code ColorModel}:
1477      * <ul>
1478      * <li>Support for alpha component.</li>
1479      * <li>Is alpha premultiplied.</li>
1480      * <li>Number of bits per pixel.</li>
1481      * <li>Type of transparency like Opaque, Bitmask or Translucent.</li>
1482      * <li>Number of components in a pixel.</li>
1483      * <li>{@code ColorSpace} type.</li>
1484      * <li>Type of the array used to represent pixel values.</li>
1485      * <li>Number of significant bits per color and alpha component.</li>
1486      * </ul>
1487      * @return a hash code value for this object.
1488      */
1489     @Override
1490     public int hashCode() {
1491         return super.hashCode();
1492     }
1493 
1494     /**
1495      * Returns the {@code ColorSpace} associated with this
1496      * {@code ColorModel}.
1497      * @return the {@code ColorSpace} of this
1498      * {@code ColorModel}.
1499      */
1500     public final ColorSpace getColorSpace() {
1501         return colorSpace;
1502     }
1503 
1504     /**
1505      * Forces the raster data to match the state specified in the
1506      * {@code isAlphaPremultiplied} variable, assuming the data is
1507      * currently correctly described by this {@code ColorModel}.  It
1508      * may multiply or divide the color raster data by alpha, or do
1509      * nothing if the data is in the correct state.  If the data needs to
1510      * be coerced, this method will also return an instance of this
1511      * {@code ColorModel} with the {@code isAlphaPremultiplied}
1512      * flag set appropriately.  This method will throw a
1513      * {@code UnsupportedOperationException} if it is not supported
1514      * by this {@code ColorModel}.
1515      * Since {@code ColorModel} is an abstract class,
1516      * any instance is an instance of a subclass.  Subclasses must
1517      * override this method since the implementation in this abstract
1518      * class throws an {@code UnsupportedOperationException}.
1519      * @param raster the {@code WritableRaster} data
1520      * @param isAlphaPremultiplied {@code true} if the alpha is
1521      * premultiplied; {@code false} otherwise
1522      * @return a {@code ColorModel} object that represents the
1523      * coerced data.
1524      */
1525     public ColorModel coerceData (WritableRaster raster,
1526                                   boolean isAlphaPremultiplied) {
1527         throw new UnsupportedOperationException
1528             ("This method is not supported by this color model");
1529     }
1530 
1531     /**
1532       * Returns {@code true} if {@code raster} is compatible
1533       * with this {@code ColorModel} and {@code false} if it is
1534       * not.
1535       * Since {@code ColorModel} is an abstract class,
1536       * any instance is an instance of a subclass.  Subclasses must
1537       * override this method since the implementation in this abstract
1538       * class throws an {@code UnsupportedOperationException}.
1539       * @param raster the {@link Raster} object to test for compatibility
1540       * @return {@code true} if {@code raster} is compatible
1541       * with this {@code ColorModel}.
1542       * @throws UnsupportedOperationException if this
1543       *         method has not been implemented for this
1544       *         {@code ColorModel}
1545       */
1546     public boolean isCompatibleRaster(Raster raster) {
1547         throw new UnsupportedOperationException(
1548             "This method has not been implemented for this ColorModel.");
1549     }
1550 
1551     /**
1552      * Creates a {@code WritableRaster} with the specified width and
1553      * height that has a data layout ({@code SampleModel}) compatible
1554      * with this {@code ColorModel}.
1555      * Since {@code ColorModel} is an abstract class,
1556      * any instance is an instance of a subclass.  Subclasses must
1557      * override this method since the implementation in this abstract
1558      * class throws an {@code UnsupportedOperationException}.
1559      * @param w the width to apply to the new {@code WritableRaster}
1560      * @param h the height to apply to the new {@code WritableRaster}
1561      * @return a {@code WritableRaster} object with the specified
1562      * width and height.
1563      * @throws UnsupportedOperationException if this
1564      *          method is not supported by this {@code ColorModel}
1565      * @see WritableRaster
1566      * @see SampleModel
1567      */
1568     public WritableRaster createCompatibleWritableRaster(int w, int h) {
1569         throw new UnsupportedOperationException
1570             ("This method is not supported by this color model");
1571     }
1572 
1573     /**
1574      * Creates a {@code SampleModel} with the specified width and
1575      * height that has a data layout compatible with this
1576      * {@code ColorModel}.
1577      * Since {@code ColorModel} is an abstract class,
1578      * any instance is an instance of a subclass.  Subclasses must
1579      * override this method since the implementation in this abstract
1580      * class throws an {@code UnsupportedOperationException}.
1581      * @param w the width to apply to the new {@code SampleModel}
1582      * @param h the height to apply to the new {@code SampleModel}
1583      * @return a {@code SampleModel} object with the specified
1584      * width and height.
1585      * @throws UnsupportedOperationException if this
1586      *          method is not supported by this {@code ColorModel}
1587      * @see SampleModel
1588      */
1589     public SampleModel createCompatibleSampleModel(int w, int h) {
1590         throw new UnsupportedOperationException
1591             ("This method is not supported by this color model");
1592     }
1593 
1594     /** Checks if the {@code SampleModel} is compatible with this
1595      * {@code ColorModel}.
1596      * Since {@code ColorModel} is an abstract class,
1597      * any instance is an instance of a subclass.  Subclasses must
1598      * override this method since the implementation in this abstract
1599      * class throws an {@code UnsupportedOperationException}.
1600      * @param sm the specified {@code SampleModel}
1601      * @return {@code true} if the specified {@code SampleModel}
1602      * is compatible with this {@code ColorModel}; {@code false}
1603      * otherwise.
1604      * @throws UnsupportedOperationException if this
1605      *          method is not supported by this {@code ColorModel}
1606      * @see SampleModel
1607      */
1608     public boolean isCompatibleSampleModel(SampleModel sm) {
1609         throw new UnsupportedOperationException
1610             ("This method is not supported by this color model");
1611     }
1612 
1613     /**
1614      * Disposes of system resources associated with this
1615      * {@code ColorModel} once this {@code ColorModel} is no
1616      * longer referenced.
1617      *
1618      * @deprecated The {@code finalize} method has been deprecated.
1619      *     Subclasses that override {@code finalize} in order to perform cleanup
1620      *     should be modified to use alternative cleanup mechanisms and
1621      *     to remove the overriding {@code finalize} method.
1622      *     When overriding the {@code finalize} method, its implementation must explicitly
1623      *     ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
1624      *     See the specification for {@link Object#finalize()} for further
1625      *     information about migration options.
1626      */
1627     @Deprecated(since="9")
1628     public void finalize() {
1629     }
1630 
1631 
1632     /**
1633      * Returns a {@code Raster} representing the alpha channel of an
1634      * image, extracted from the input {@code Raster}, provided that
1635      * pixel values of this {@code ColorModel} represent color and
1636      * alpha information as separate spatial bands (e.g.
1637      * {@link ComponentColorModel} and {@code DirectColorModel}).
1638      * This method assumes that {@code Raster} objects associated
1639      * with such a {@code ColorModel} store the alpha band, if
1640      * present, as the last band of image data.  Returns {@code null}
1641      * if there is no separate spatial alpha channel associated with this
1642      * {@code ColorModel}.  If this is an
1643      * {@code IndexColorModel} which has alpha in the lookup table,
1644      * this method will return {@code null} since
1645      * there is no spatially discrete alpha channel.
1646      * This method will create a new {@code Raster} (but will share
1647      * the data array).
1648      * Since {@code ColorModel} is an abstract class, any instance
1649      * is an instance of a subclass.  Subclasses must override this
1650      * method to get any behavior other than returning {@code null}
1651      * because the implementation in this abstract class returns
1652      * {@code null}.
1653      * @param raster the specified {@code Raster}
1654      * @return a {@code Raster} representing the alpha channel of
1655      * an image, obtained from the specified {@code Raster}.
1656      */
1657     public WritableRaster getAlphaRaster(WritableRaster raster) {
1658         return null;
1659     }
1660 
1661     /**
1662      * Returns the {@code String} representation of the contents of
1663      * this {@code ColorModel} object.
1664      * @return a {@code String} representing the contents of this
1665      * {@code ColorModel} object.
1666      */
1667     public String toString() {
1668        return new String("ColorModel: #pixelBits = "+pixel_bits
1669                          + " numComponents = "+numComponents
1670                          + " color space = "+colorSpace
1671                          + " transparency = "+transparency
1672                          + " has alpha = "+supportsAlpha
1673                          + " isAlphaPre = "+isAlphaPremultiplied
1674                          );
1675     }
1676 
1677     static int getDefaultTransferType(int pixel_bits) {
1678         if (pixel_bits <= 8) {
1679             return DataBuffer.TYPE_BYTE;
1680         } else if (pixel_bits <= 16) {
1681             return DataBuffer.TYPE_USHORT;
1682         } else if (pixel_bits <= 32) {
1683             return DataBuffer.TYPE_INT;
1684         } else {
1685             return DataBuffer.TYPE_UNDEFINED;
1686         }
1687     }
1688 
1689     static byte[] l8Tos8 = null;   // 8-bit linear to 8-bit non-linear sRGB LUT
1690     static byte[] s8Tol8 = null;   // 8-bit non-linear sRGB to 8-bit linear LUT
1691     static byte[] l16Tos8 = null;  // 16-bit linear to 8-bit non-linear sRGB LUT
1692     static short[] s8Tol16 = null; // 8-bit non-linear sRGB to 16-bit linear LUT
1693 
1694                                 // Maps to hold LUTs for grayscale conversions
1695     static Map<ICC_ColorSpace, byte[]> g8Tos8Map = null;     // 8-bit gray values to 8-bit sRGB values
1696     static Map<ICC_ColorSpace, byte[]> lg16Toog8Map = null;  // 16-bit linear to 8-bit "other" gray
1697     static Map<ICC_ColorSpace, byte[]> g16Tos8Map = null;    // 16-bit gray values to 8-bit sRGB values
1698     static Map<ICC_ColorSpace, short[]> lg16Toog16Map = null; // 16-bit linear to 16-bit "other" gray
1699 
1700     static boolean isLinearRGBspace(ColorSpace cs) {
1701         // Note: CMM.LINEAR_RGBspace will be null if the linear
1702         // RGB space has not been created yet.
1703         return (cs == CMSManager.LINEAR_RGBspace);
1704     }
1705 
1706     static boolean isLinearGRAYspace(ColorSpace cs) {
1707         // Note: CMM.GRAYspace will be null if the linear
1708         // gray space has not been created yet.
1709         return (cs == CMSManager.GRAYspace);
1710     }
1711 
1712     static byte[] getLinearRGB8TosRGB8LUT() {
1713         if (l8Tos8 == null) {
1714             l8Tos8 = new byte[256];
1715             float input, output;
1716             // algorithm for linear RGB to nonlinear sRGB conversion
1717             // is from the IEC 61966-2-1 International Standard,
1718             // Colour Management - Default RGB colour space - sRGB,
1719             // First Edition, 1999-10,
1720             // available for order at http://www.iec.ch
1721             for (int i = 0; i <= 255; i++) {
1722                 input = ((float) i) / 255.0f;
1723                 if (input <= 0.0031308f) {
1724                     output = input * 12.92f;
1725                 } else {
1726                     output = 1.055f * ((float) Math.pow(input, (1.0 / 2.4)))
1727                              - 0.055f;
1728                 }
1729                 l8Tos8[i] = (byte) Math.round(output * 255.0f);
1730             }
1731         }
1732         return l8Tos8;
1733     }
1734 
1735     static byte[] getsRGB8ToLinearRGB8LUT() {
1736         if (s8Tol8 == null) {
1737             s8Tol8 = new byte[256];
1738             float input, output;
1739             // algorithm from IEC 61966-2-1 International Standard
1740             for (int i = 0; i <= 255; i++) {
1741                 input = ((float) i) / 255.0f;
1742                 if (input <= 0.04045f) {
1743                     output = input / 12.92f;
1744                 } else {
1745                     output = (float) Math.pow((input + 0.055f) / 1.055f, 2.4);
1746                 }
1747                 s8Tol8[i] = (byte) Math.round(output * 255.0f);
1748             }
1749         }
1750         return s8Tol8;
1751     }
1752 
1753     static byte[] getLinearRGB16TosRGB8LUT() {
1754         if (l16Tos8 == null) {
1755             l16Tos8 = new byte[65536];
1756             float input, output;
1757             // algorithm from IEC 61966-2-1 International Standard
1758             for (int i = 0; i <= 65535; i++) {
1759                 input = ((float) i) / 65535.0f;
1760                 if (input <= 0.0031308f) {
1761                     output = input * 12.92f;
1762                 } else {
1763                     output = 1.055f * ((float) Math.pow(input, (1.0 / 2.4)))
1764                              - 0.055f;
1765                 }
1766                 l16Tos8[i] = (byte) Math.round(output * 255.0f);
1767             }
1768         }
1769         return l16Tos8;
1770     }
1771 
1772     static short[] getsRGB8ToLinearRGB16LUT() {
1773         if (s8Tol16 == null) {
1774             s8Tol16 = new short[256];
1775             float input, output;
1776             // algorithm from IEC 61966-2-1 International Standard
1777             for (int i = 0; i <= 255; i++) {
1778                 input = ((float) i) / 255.0f;
1779                 if (input <= 0.04045f) {
1780                     output = input / 12.92f;
1781                 } else {
1782                     output = (float) Math.pow((input + 0.055f) / 1.055f, 2.4);
1783                 }
1784                 s8Tol16[i] = (short) Math.round(output * 65535.0f);
1785             }
1786         }
1787         return s8Tol16;
1788     }
1789 
1790     /*
1791      * Return a byte LUT that converts 8-bit gray values in the grayCS
1792      * ColorSpace to the appropriate 8-bit sRGB value.  I.e., if lut
1793      * is the byte array returned by this method and sval = lut[gval],
1794      * then the sRGB triple (sval,sval,sval) is the best match to gval.
1795      * Cache references to any computed LUT in a Map.
1796      */
1797     static byte[] getGray8TosRGB8LUT(ICC_ColorSpace grayCS) {
1798         if (isLinearGRAYspace(grayCS)) {
1799             return getLinearRGB8TosRGB8LUT();
1800         }
1801         if (g8Tos8Map != null) {
1802             byte[] g8Tos8LUT = g8Tos8Map.get(grayCS);
1803             if (g8Tos8LUT != null) {
1804                 return g8Tos8LUT;
1805             }
1806         }
1807         byte[] g8Tos8LUT = new byte[256];
1808         for (int i = 0; i <= 255; i++) {
1809             g8Tos8LUT[i] = (byte) i;
1810         }
1811         ColorTransform[] transformList = new ColorTransform[2];
1812         PCMM mdl = CMSManager.getModule();
1813         ICC_ColorSpace srgbCS =
1814             (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_sRGB);
1815         transformList[0] = mdl.createTransform(
1816             grayCS.getProfile(), ColorTransform.Any, ColorTransform.In);
1817         transformList[1] = mdl.createTransform(
1818             srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
1819         ColorTransform t = mdl.createTransform(transformList);
1820         byte[] tmp = t.colorConvert(g8Tos8LUT, null);
1821         for (int i = 0, j= 2; i <= 255; i++, j += 3) {
1822             // All three components of tmp should be equal, since
1823             // the input color space to colorConvert is a gray scale
1824             // space.  However, there are slight anomalies in the results.
1825             // Copy tmp starting at index 2, since colorConvert seems
1826             // to be slightly more accurate for the third component!
1827             g8Tos8LUT[i] = tmp[j];
1828         }
1829         if (g8Tos8Map == null) {
1830             g8Tos8Map = Collections.synchronizedMap(new WeakHashMap<ICC_ColorSpace, byte[]>(2));
1831         }
1832         g8Tos8Map.put(grayCS, g8Tos8LUT);
1833         return g8Tos8LUT;
1834     }
1835 
1836     /*
1837      * Return a byte LUT that converts 16-bit gray values in the CS_GRAY
1838      * linear gray ColorSpace to the appropriate 8-bit value in the
1839      * grayCS ColorSpace.  Cache references to any computed LUT in a Map.
1840      */
1841     static byte[] getLinearGray16ToOtherGray8LUT(ICC_ColorSpace grayCS) {
1842         if (lg16Toog8Map != null) {
1843             byte[] lg16Toog8LUT = lg16Toog8Map.get(grayCS);
1844             if (lg16Toog8LUT != null) {
1845                 return lg16Toog8LUT;
1846             }
1847         }
1848         short[] tmp = new short[65536];
1849         for (int i = 0; i <= 65535; i++) {
1850             tmp[i] = (short) i;
1851         }
1852         ColorTransform[] transformList = new ColorTransform[2];
1853         PCMM mdl = CMSManager.getModule();
1854         ICC_ColorSpace lgCS =
1855             (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_GRAY);
1856         transformList[0] = mdl.createTransform (
1857             lgCS.getProfile(), ColorTransform.Any, ColorTransform.In);
1858         transformList[1] = mdl.createTransform (
1859             grayCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
1860         ColorTransform t = mdl.createTransform(transformList);
1861         tmp = t.colorConvert(tmp, null);
1862         byte[] lg16Toog8LUT = new byte[65536];
1863         for (int i = 0; i <= 65535; i++) {
1864             // scale unsigned short (0 - 65535) to unsigned byte (0 - 255)
1865             lg16Toog8LUT[i] =
1866                 (byte) (((float) (tmp[i] & 0xffff)) * (1.0f /257.0f) + 0.5f);
1867         }
1868         if (lg16Toog8Map == null) {
1869             lg16Toog8Map = Collections.synchronizedMap(new WeakHashMap<ICC_ColorSpace, byte[]>(2));
1870         }
1871         lg16Toog8Map.put(grayCS, lg16Toog8LUT);
1872         return lg16Toog8LUT;
1873     }
1874 
1875     /*
1876      * Return a byte LUT that converts 16-bit gray values in the grayCS
1877      * ColorSpace to the appropriate 8-bit sRGB value.  I.e., if lut
1878      * is the byte array returned by this method and sval = lut[gval],
1879      * then the sRGB triple (sval,sval,sval) is the best match to gval.
1880      * Cache references to any computed LUT in a Map.
1881      */
1882     static byte[] getGray16TosRGB8LUT(ICC_ColorSpace grayCS) {
1883         if (isLinearGRAYspace(grayCS)) {
1884             return getLinearRGB16TosRGB8LUT();
1885         }
1886         if (g16Tos8Map != null) {
1887             byte[] g16Tos8LUT = g16Tos8Map.get(grayCS);
1888             if (g16Tos8LUT != null) {
1889                 return g16Tos8LUT;
1890             }
1891         }
1892         short[] tmp = new short[65536];
1893         for (int i = 0; i <= 65535; i++) {
1894             tmp[i] = (short) i;
1895         }
1896         ColorTransform[] transformList = new ColorTransform[2];
1897         PCMM mdl = CMSManager.getModule();
1898         ICC_ColorSpace srgbCS =
1899             (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_sRGB);
1900         transformList[0] = mdl.createTransform (
1901             grayCS.getProfile(), ColorTransform.Any, ColorTransform.In);
1902         transformList[1] = mdl.createTransform (
1903             srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
1904         ColorTransform t = mdl.createTransform(transformList);
1905         tmp = t.colorConvert(tmp, null);
1906         byte[] g16Tos8LUT = new byte[65536];
1907         for (int i = 0, j= 2; i <= 65535; i++, j += 3) {
1908             // All three components of tmp should be equal, since
1909             // the input color space to colorConvert is a gray scale
1910             // space.  However, there are slight anomalies in the results.
1911             // Copy tmp starting at index 2, since colorConvert seems
1912             // to be slightly more accurate for the third component!
1913 
1914             // scale unsigned short (0 - 65535) to unsigned byte (0 - 255)
1915             g16Tos8LUT[i] =
1916                 (byte) (((float) (tmp[j] & 0xffff)) * (1.0f /257.0f) + 0.5f);
1917         }
1918         if (g16Tos8Map == null) {
1919             g16Tos8Map = Collections.synchronizedMap(new WeakHashMap<ICC_ColorSpace, byte[]>(2));
1920         }
1921         g16Tos8Map.put(grayCS, g16Tos8LUT);
1922         return g16Tos8LUT;
1923     }
1924 
1925     /*
1926      * Return a short LUT that converts 16-bit gray values in the CS_GRAY
1927      * linear gray ColorSpace to the appropriate 16-bit value in the
1928      * grayCS ColorSpace.  Cache references to any computed LUT in a Map.
1929      */
1930     static short[] getLinearGray16ToOtherGray16LUT(ICC_ColorSpace grayCS) {
1931         if (lg16Toog16Map != null) {
1932             short[] lg16Toog16LUT = lg16Toog16Map.get(grayCS);
1933             if (lg16Toog16LUT != null) {
1934                 return lg16Toog16LUT;
1935             }
1936         }
1937         short[] tmp = new short[65536];
1938         for (int i = 0; i <= 65535; i++) {
1939             tmp[i] = (short) i;
1940         }
1941         ColorTransform[] transformList = new ColorTransform[2];
1942         PCMM mdl = CMSManager.getModule();
1943         ICC_ColorSpace lgCS =
1944             (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_GRAY);
1945         transformList[0] = mdl.createTransform (
1946             lgCS.getProfile(), ColorTransform.Any, ColorTransform.In);
1947         transformList[1] = mdl.createTransform(
1948             grayCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
1949         ColorTransform t = mdl.createTransform(
1950             transformList);
1951         short[] lg16Toog16LUT = t.colorConvert(tmp, null);
1952         if (lg16Toog16Map == null) {
1953             lg16Toog16Map = Collections.synchronizedMap(new WeakHashMap<ICC_ColorSpace, short[]>(2));
1954         }
1955         lg16Toog16Map.put(grayCS, lg16Toog16LUT);
1956         return lg16Toog16LUT;
1957     }
1958 
1959 }