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