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