KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > image > DirectColorModel


1 /*
2  * @(#)DirectColorModel.java 1.78 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt.image;
9
10 import java.awt.color.ColorSpace JavaDoc;
11 import java.awt.Transparency JavaDoc;
12
13 /**
14  * The <code>DirectColorModel</code> class is a <code>ColorModel</code>
15  * class that works with pixel values that represent RGB
16  * color and alpha information as separate samples and that pack all
17  * samples for a single pixel into a single int, short, or byte quantity.
18  * This class can be used only with ColorSpaces of type ColorSpace.TYPE_RGB.
19  * In addition, for each component of the ColorSpace, the minimum
20  * normalized component value obtained via the <code>getMinValue()</code>
21  * method of ColorSpace must be 0.0, and the maximum value obtained via
22  * the <code>getMaxValue()</code> method must be 1.0 (these min/max
23  * values are typical for RGB spaces).
24  * There must be three color samples in the pixel values and there can
25  * be a single alpha sample. For those methods that use a primitive array
26  * pixel representation of type <code>transferType</code>, the array
27  * length is always one. The transfer
28  * types supported are DataBuffer.TYPE_BYTE,
29  * DataBuffer.TYPE_USHORT, and DataBuffer.TYPE_INT.
30  * Color and alpha samples are stored in the single
31  * element of the array in bits indicated by bit masks. Each bit mask
32  * must be contiguous and masks must not overlap. The same masks apply to
33  * the single int pixel representation used by other methods. The
34  * correspondence of masks and color/alpha samples is as follows:
35  * <ul>
36  * <li> Masks are identified by indices running from 0 through 2
37  * if no alpha is present, or 3 if an alpha is present.
38  * <li> The first three indices refer to color samples;
39  * index 0 corresponds to red, index 1 to green, and index 2 to blue.
40  * <li> Index 3 corresponds to the alpha sample, if present.
41  * </ul>
42  * <p>
43  * The translation from pixel values to color/alpha components for
44  * display or processing purposes is a one-to-one correspondence of
45  * samples to components. A <code>DirectColorModel</code> is
46  * typically used with image data which uses masks to define packed
47  * samples. For example, a <code>DirectColorModel</code> can be used in
48  * conjunction with a <code>SinglePixelPackedSampleModel</code> to
49  * construct a {@link BufferedImage}. Normally the masks used by the
50  * {@link SampleModel} and the <code>ColorModel</code> would be the
51  * same. However, if they are different, the color interpretation
52  * of pixel data will be done according to the masks of the
53  * <code>ColorModel</code>.
54  * <p>
55  * A single int pixel representation is valid for all objects of this
56  * class, since it is always possible to represent pixel values used with
57  * this class in a single int. Therefore, methods which use this
58  * representation will not throw an <code>IllegalArgumentException</code>
59  * due to an invalid pixel value.
60  * <p>
61  * This color model is similar to an X11 TrueColor visual.
62  * The default RGB ColorModel specified by the
63  * {@link ColorModel#getRGBdefault() getRGBdefault} method is a
64  * <code>DirectColorModel</code> with the following parameters:
65  * <pre>
66  * Number of bits: 32
67  * Red mask: 0x00ff0000
68  * Green mask: 0x0000ff00
69  * Blue mask: 0x000000ff
70  * Alpha mask: 0xff000000
71  * Color space: sRGB
72  * isAlphaPremultiplied: False
73  * Transparency: Transparency.TRANSLUCENT
74  * transferType: DataBuffer.TYPE_INT
75  * </pre>
76  * <p>
77  * Many of the methods in this class are final. This is because the
78  * underlying native graphics code makes assumptions about the layout
79  * and operation of this class and those assumptions are reflected in
80  * the implementations of the methods here that are marked final. You
81  * can subclass this class for other reasons, but you cannot override
82  * or modify the behavior of those methods.
83  *
84  * @see ColorModel
85  * @see ColorSpace
86  * @see SinglePixelPackedSampleModel
87  * @see BufferedImage
88  * @see ColorModel#getRGBdefault
89  *
90  * @version 10 Feb 1997
91  */

92 public class DirectColorModel extends PackedColorModel JavaDoc {
93     private int red_mask;
94     private int green_mask;
95     private int blue_mask;
96     private int alpha_mask;
97     private int red_offset;
98     private int green_offset;
99     private int blue_offset;
100     private int alpha_offset;
101     private int red_scale;
102     private int green_scale;
103     private int blue_scale;
104     private int alpha_scale;
105     private boolean is_LinearRGB;
106     private int lRGBprecision;
107     private byte[] tosRGB8LUT;
108     private byte[] fromsRGB8LUT8;
109     private short[] fromsRGB8LUT16;
110     
111     /**
112      * Constructs a <code>DirectColorModel</code> from the specified masks
113      * that indicate which bits in an <code>int</code> pixel representation
114      * contain the red, green and blue color samples. As pixel values do not
115      * contain alpha information, all pixels are treated as opaque, which
116      * means that alpha&nbsp;=&nbsp;1.0. All of the bits
117      * in each mask must be contiguous and fit in the specified number
118      * of least significant bits of an <code>int</code> pixel representation.
119      * The <code>ColorSpace</code> is the default sRGB space. The
120      * transparency value is Transparency.OPAQUE. The transfer type
121      * is the smallest of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
122      * or DataBuffer.TYPE_INT that can hold a single pixel.
123      * @param bits the number of bits in the pixel values; for example,
124      * the sum of the number of bits in the masks.
125      * @param rmask specifies a mask indicating which bits in an
126      * integer pixel contain the red component
127      * @param gmask specifies a mask indicating which bits in an
128      * integer pixel contain the green component
129      * @param bmask specifies a mask indicating which bits in an
130      * integer pixel contain the blue component
131      *
132      */

133     public DirectColorModel(int bits,
134                 int rmask, int gmask, int bmask) {
135     this(bits, rmask, gmask, bmask, 0);
136     }
137
138     /**
139      * Constructs a <code>DirectColorModel</code> from the specified masks
140      * that indicate which bits in an <code>int</code> pixel representation
141      * contain the red, green and blue color samples and the alpha sample,
142      * if present. If <code>amask</code> is 0, pixel values do not contain
143      * alpha information and all pixels are treated as opaque, which means
144      * that alpha&nbsp;=&nbsp;1.0. All of the bits in each mask must
145      * be contiguous and fit in the specified number of least significant bits
146      * of an <code>int</code> pixel representation. Alpha, if present, is not
147      * premultiplied. The <code>ColorSpace</code> is the default sRGB space.
148      * The transparency value is Transparency.OPAQUE if no alpha is
149      * present, or Transparency.TRANSLUCENT otherwise. The transfer type
150      * is the smallest of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
151      * or DataBuffer.TYPE_INT that can hold a single pixel.
152      * @param bits the number of bits in the pixel values; for example,
153      * the sum of the number of bits in the masks.
154      * @param rmask specifies a mask indicating which bits in an
155      * integer pixel contain the red component
156      * @param gmask specifies a mask indicating which bits in an
157      * integer pixel contain the green component
158      * @param bmask specifies a mask indicating which bits in an
159      * integer pixel contain the blue component
160      * @param amask specifies a mask indicating which bits in an
161      * integer pixel contain the alpha component
162      */

163     public DirectColorModel(int bits, int rmask, int gmask,
164                             int bmask, int amask) {
165         super (ColorSpace.getInstance(ColorSpace.CS_sRGB),
166                bits, rmask, gmask, bmask, amask, false,
167                amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT,
168                ColorModel.getDefaultTransferType(bits));
169         setFields();
170     }
171
172     /**
173      * Constructs a <code>DirectColorModel</code> from the specified
174      * parameters. Color components are in the specified
175      * <code>ColorSpace</code>, which must be of type ColorSpace.TYPE_RGB
176      * and have minimum normalized component values which are all 0.0
177      * and maximum values which are all 1.0.
178      * The masks specify which bits in an <code>int</code> pixel
179      * representation contain the red, green and blue color samples and
180      * the alpha sample, if present. If <code>amask</code> is 0, pixel
181      * values do not contain alpha information and all pixels are treated
182      * as opaque, which means that alpha&nbsp;=&nbsp;1.0. All of the
183      * bits in each mask must be contiguous and fit in the specified number
184      * of least significant bits of an <code>int</code> pixel
185      * representation. If there is alpha, the <code>boolean</code>
186      * <code>isAlphaPremultiplied</code> specifies how to interpret
187      * color and alpha samples in pixel values. If the <code>boolean</code>
188      * is <code>true</code>, color samples are assumed to have been
189      * multiplied by the alpha sample. The transparency value is
190      * Transparency.OPAQUE, if no alpha is present, or
191      * Transparency.TRANSLUCENT otherwise. The transfer type
192      * is the type of primitive array used to represent pixel values and
193      * must be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or
194      * DataBuffer.TYPE_INT.
195      * @param space the specified <code>ColorSpace</code>
196      * @param bits the number of bits in the pixel values; for example,
197      * the sum of the number of bits in the masks.
198      * @param rmask specifies a mask indicating which bits in an
199      * integer pixel contain the red component
200      * @param gmask specifies a mask indicating which bits in an
201      * integer pixel contain the green component
202      * @param bmask specifies a mask indicating which bits in an
203      * integer pixel contain the blue component
204      * @param amask specifies a mask indicating which bits in an
205      * integer pixel contain the alpha component
206      * @param isAlphaPremultiplied <code>true</code> if color samples are
207      * premultiplied by the alpha sample; <code>false</code> otherwise
208      * @param transferType the type of array used to represent pixel values
209      * @throws IllegalArgumentException if <code>space</code> is not a
210      * TYPE_RGB space or if the min/max normalized component
211      * values are not 0.0/1.0.
212      */

213     public DirectColorModel(ColorSpace JavaDoc space, int bits, int rmask,
214                             int gmask, int bmask, int amask,
215                             boolean isAlphaPremultiplied,
216                             int transferType) {
217         super (space, bits, rmask, gmask, bmask, amask,
218                isAlphaPremultiplied,
219                amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT,
220                transferType);
221         if (ColorModel.isLinearRGBspace(colorSpace)) {
222             is_LinearRGB = true;
223             if (maxBits <= 8) {
224                 lRGBprecision = 8;
225                 tosRGB8LUT = ColorModel.getLinearRGB8TosRGB8LUT();
226                 fromsRGB8LUT8 = ColorModel.getsRGB8ToLinearRGB8LUT();
227             } else {
228                 lRGBprecision = 16;
229                 tosRGB8LUT = ColorModel.getLinearRGB16TosRGB8LUT();
230                 fromsRGB8LUT16 = ColorModel.getsRGB8ToLinearRGB16LUT();
231             }
232         } else if (!is_sRGB) {
233             for (int i = 0; i < 3; i++) {
234                 // super constructor checks that space is TYPE_RGB
235
// check here that min/max are all 0.0/1.0
236
if ((space.getMinValue(i) != 0.0f) ||
237                     (space.getMaxValue(i) != 1.0f)) {
238                     throw new IllegalArgumentException JavaDoc(
239                         "Illegal min/max RGB component value");
240                 }
241             }
242         }
243         setFields();
244     }
245
246     /**
247      * Returns the mask indicating which bits in an <code>int</code> pixel
248      * representation contain the red color component.
249      * @return the mask, which indicates which bits of the <code>int</code>
250      * pixel representation contain the red color sample.
251      */

252     final public int getRedMask() {
253     return maskArray[0];
254     }
255
256     /**
257      * Returns the mask indicating which bits in an <code>int</code> pixel
258      * representation contain the green color component.
259      * @return the mask, which indicates which bits of the <code>int</code>
260      * pixel representation contain the green color sample.
261      */

262     final public int getGreenMask() {
263     return maskArray[1];
264     }
265
266     /**
267      * Returns the mask indicating which bits in an <code>int</code> pixel
268      * representation contain the blue color component.
269      * @return the mask, which indicates which bits of the <code>int</code>
270      * pixel representation contain the blue color sample.
271      */

272     final public int getBlueMask() {
273     return maskArray[2];
274     }
275
276     /**
277      * Returns the mask indicating which bits in an <code>int</code> pixel
278      * representation contain the alpha component.
279      * @return the mask, which indicates which bits of the <code>int</code>
280      * pixel representation contain the alpha sample.
281      */

282     final public int getAlphaMask() {
283         if (supportsAlpha) {
284             return maskArray[3];
285         } else {
286             return 0;
287         }
288     }
289
290
291     /*
292      * Given an int pixel in this ColorModel's ColorSpace, converts
293      * it to the default sRGB ColorSpace and returns the R, G, and B
294      * components as float values between 0.0 and 1.0.
295      */

296     private float[] getDefaultRGBComponents(int pixel) {
297         int components[] = getComponents(pixel, null, 0);
298         float norm[] = getNormalizedComponents(components, 0, null, 0);
299         // Note that getNormalizedComponents returns non-premultiplied values
300
return colorSpace.toRGB(norm);
301     }
302
303
304     private int getsRGBComponentFromsRGB(int pixel, int idx) {
305     int c = ((pixel & maskArray[idx]) >>> maskOffsets[idx]);
306         if (isAlphaPremultiplied) {
307             int a = ((pixel & maskArray[3]) >>> maskOffsets[3]);
308             c = (a == 0) ? 0 :
309                          (int) (((c * scaleFactors[idx]) * 255.0f /
310                                  (a * scaleFactors[3])) + 0.5f);
311         } else if (scaleFactors[idx] != 1.0f) {
312         c = (int) ((c * scaleFactors[idx]) + 0.5f);
313         }
314     return c;
315     }
316
317
318     private int getsRGBComponentFromLinearRGB(int pixel, int idx) {
319     int c = ((pixel & maskArray[idx]) >>> maskOffsets[idx]);
320         if (isAlphaPremultiplied) {
321             float factor = (float) ((1 << lRGBprecision) - 1);
322             int a = ((pixel & maskArray[3]) >>> maskOffsets[3]);
323             c = (a == 0) ? 0 :
324                          (int) (((c * scaleFactors[idx]) * factor /
325                                  (a * scaleFactors[3])) + 0.5f);
326         } else if (nBits[idx] != lRGBprecision) {
327             if (lRGBprecision == 16) {
328                 c = (int) ((c * scaleFactors[idx] * 257.0f) + 0.5f);
329             } else {
330             c = (int) ((c * scaleFactors[idx]) + 0.5f);
331             }
332         }
333         // now range of c is 0-255 or 0-65535, depending on lRGBprecision
334
return tosRGB8LUT[c] & 0xff;
335     }
336
337
338     /**
339      * Returns the red color component for the specified pixel, scaled
340      * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB. A
341      * color conversion is done if necessary. The pixel value is specified
342      * as an <code>int</code>.
343      * The returned value is a non pre-multiplied value. Thus, if the
344      * alpha is premultiplied, this method divides it out before returning
345      * the value. If the alpha value is 0, for example, the red value
346      * is 0.
347      * @param pixel the specified pixel
348      * @return the red color component for the specified pixel, from
349      * 0 to 255 in the sRGB <code>ColorSpace</code>.
350      */

351     final public int getRed(int pixel) {
352         if (is_sRGB) {
353             return getsRGBComponentFromsRGB(pixel, 0);
354         } else if (is_LinearRGB) {
355             return getsRGBComponentFromLinearRGB(pixel, 0);
356         }
357         float rgb[] = getDefaultRGBComponents(pixel);
358         return (int) (rgb[0] * 255.0f + 0.5f);
359     }
360
361     /**
362      * Returns the green color component for the specified pixel, scaled
363      * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB. A
364      * color conversion is done if necessary. The pixel value is specified
365      * as an <code>int</code>.
366      * The returned value is a non pre-multiplied value. Thus, if the
367      * alpha is premultiplied, this method divides it out before returning
368      * the value. If the alpha value is 0, for example, the green value
369      * is 0.
370      * @param pixel the specified pixel
371      * @return the green color component for the specified pixel, from
372      * 0 to 255 in the sRGB <code>ColorSpace</code>.
373      */

374     final public int getGreen(int pixel) {
375         if (is_sRGB) {
376             return getsRGBComponentFromsRGB(pixel, 1);
377         } else if (is_LinearRGB) {
378             return getsRGBComponentFromLinearRGB(pixel, 1);
379         }
380         float rgb[] = getDefaultRGBComponents(pixel);
381         return (int) (rgb[1] * 255.0f + 0.5f);
382     }
383
384     /**
385      * Returns the blue color component for the specified pixel, scaled
386      * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB. A
387      * color conversion is done if necessary. The pixel value is specified
388      * as an <code>int</code>.
389      * The returned value is a non pre-multiplied value. Thus, if the
390      * alpha is premultiplied, this method divides it out before returning
391      * the value. If the alpha value is 0, for example, the blue value
392      * is 0.
393      * @param pixel the specified pixel
394      * @return the blue color component for the specified pixel, from
395      * 0 to 255 in the sRGB <code>ColorSpace</code>.
396      */

397     final public int getBlue(int pixel) {
398         if (is_sRGB) {
399             return getsRGBComponentFromsRGB(pixel, 2);
400         } else if (is_LinearRGB) {
401             return getsRGBComponentFromLinearRGB(pixel, 2);
402         }
403         float rgb[] = getDefaultRGBComponents(pixel);
404         return (int) (rgb[2] * 255.0f + 0.5f);
405     }
406
407     /**
408      * Returns the alpha component for the specified pixel, scaled
409      * from 0 to 255. The pixel value is specified as an <code>int</code>.
410      * @param pixel the specified pixel
411      * @return the value of the alpha component of <code>pixel</code>
412      * from 0 to 255.
413      */

414     final public int getAlpha(int pixel) {
415     if (!supportsAlpha) return 255;
416     int a = ((pixel & maskArray[3]) >>> maskOffsets[3]);
417     if (scaleFactors[3] != 1.0f) {
418         a = (int)(a * scaleFactors[3] + 0.5f);
419     }
420     return a;
421     }
422
423     /**
424      * Returns the color/alpha components of the pixel in the default
425      * RGB color model format. A color conversion is done if necessary.
426      * The pixel value is specified as an <code>int</code>.
427      * The returned value is in a non pre-multiplied format. Thus, if
428      * the alpha is premultiplied, this method divides it out of the
429      * color components. If the alpha value is 0, for example, the color
430      * values are each 0.
431      * @param pixel the specified pixel
432      * @return the RGB value of the color/alpha components of the specified
433      * pixel.
434      * @see ColorModel#getRGBdefault
435      */

436     final public int getRGB(int pixel) {
437         if (is_sRGB || is_LinearRGB) {
438         return (getAlpha(pixel) << 24)
439             | (getRed(pixel) << 16)
440             | (getGreen(pixel) << 8)
441             | (getBlue(pixel) << 0);
442         }
443         float rgb[] = getDefaultRGBComponents(pixel);
444         return (getAlpha(pixel) << 24)
445             | (((int) (rgb[0] * 255.0f + 0.5f)) << 16)
446             | (((int) (rgb[1] * 255.0f + 0.5f)) << 8)
447             | (((int) (rgb[2] * 255.0f + 0.5f)) << 0);
448     }
449     
450     /**
451      * Returns the red color component for the specified pixel, scaled
452      * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB. A
453      * color conversion is done if necessary. The pixel value is specified
454      * by an array of data elements of type <code>transferType</code> passed
455      * in as an object reference.
456      * The returned value is a non pre-multiplied value. Thus, if the
457      * alpha is premultiplied, this method divides it out before returning
458      * the value. If the alpha value is 0, for example, the red value
459      * is 0.
460      * If <code>inData</code> is not a primitive array of type
461      * <code>transferType</code>, a <code>ClassCastException</code> is
462      * thrown. An <code>ArrayIndexOutOfBoundsException</code> is
463      * thrown if <code>inData</code> is not large enough to hold a
464      * pixel value for this <code>ColorModel</code>. Since
465      * <code>DirectColorModel</code> can be subclassed, subclasses inherit
466      * the implementation of this method and if they don't override it
467      * then they throw an exception if they use an unsupported
468      * <code>transferType</code>.
469      * An <code>UnsupportedOperationException</code> is thrown if this
470      * <code>transferType</code> is not supported by this
471      * <code>ColorModel</code>.
472      * @param inData the array containing the pixel value
473      * @return the value of the red component of the specified pixel.
474      * @throws ArrayIndexOutOfBoundsException if <code>inData</code> is not
475      * large enough to hold a pixel value for this color model
476      * @throws ClassCastException if <code>inData</code> is not a
477      * primitive array of type <code>transferType</code>
478      * @throws UnsupportedOperationException if this <code>transferType</code>
479      * is not supported by this color model
480      */

481     public int getRed(Object JavaDoc inData) {
482         int pixel=0;
483         switch (transferType) {
484             case DataBuffer.TYPE_BYTE:
485                byte bdata[] = (byte[])inData;
486                pixel = bdata[0] & 0xff;
487             break;
488             case DataBuffer.TYPE_USHORT:
489                short sdata[] = (short[])inData;
490                pixel = sdata[0] & 0xffff;
491             break;
492             case DataBuffer.TYPE_INT:
493                int idata[] = (int[])inData;
494                pixel = idata[0];
495             break;
496             default:
497                throw new UnsupportedOperationException JavaDoc("This method has not been "+
498                    "implemented for transferType " + transferType);
499         }
500         return getRed(pixel);
501     }
502    
503
504     /**
505      * Returns the green color component for the specified pixel, scaled
506      * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB. A
507      * color conversion is done if necessary. The pixel value is specified
508      * by an array of data elements of type <code>transferType</code> passed
509      * in as an object reference.
510      * The returned value is a non pre-multiplied value. Thus, if the
511      * alpha is premultiplied, this method divides it out before returning
512      * the value. If the alpha value is 0, for example, the green value
513      * is 0. If <code>inData</code> is not a primitive array of type
514      * <code>transferType</code>, a <code>ClassCastException</code> is thrown.
515      * An <code>ArrayIndexOutOfBoundsException</code> is
516      * thrown if <code>inData</code> is not large enough to hold a pixel
517      * value for this <code>ColorModel</code>. Since
518      * <code>DirectColorModel</code> can be subclassed, subclasses inherit
519      * the implementation of this method and if they don't override it
520      * then they throw an exception if they use an unsupported
521      * <code>transferType</code>.
522      * An <code>UnsupportedOperationException</code> is
523      * thrown if this <code>transferType</code> is not supported by this
524      * <code>ColorModel</code>.
525      * @param inData the array containing the pixel value
526      * @return the value of the green component of the specified pixel.
527      * @throws ArrayIndexOutOfBoundsException if <code>inData</code> is not
528      * large enough to hold a pixel value for this color model
529      * @throws ClassCastException if <code>inData</code> is not a
530      * primitive array of type <code>transferType</code>
531      * @throws UnsupportedOperationException if this <code>transferType</code>
532      * is not supported by this color model
533      */

534     public int getGreen(Object JavaDoc inData) {
535         int pixel=0;
536         switch (transferType) {
537             case DataBuffer.TYPE_BYTE:
538                byte bdata[] = (byte[])inData;
539                pixel = bdata[0] & 0xff;
540             break;
541             case DataBuffer.TYPE_USHORT:
542                short sdata[] = (short[])inData;
543                pixel = sdata[0] & 0xffff;
544             break;
545             case DataBuffer.TYPE_INT:
546                int idata[] = (int[])inData;
547                pixel = idata[0];
548             break;
549             default:
550                throw new UnsupportedOperationException JavaDoc("This method has not been "+
551                    "implemented for transferType " + transferType);
552         }
553         return getGreen(pixel);
554     }
555    
556
557     /**
558      * Returns the blue color component for the specified pixel, scaled
559      * from 0 to 255 in the default RGB <code>ColorSpace</code>, sRGB. A
560      * color conversion is done if necessary. The pixel value is specified
561      * by an array of data elements of type <code>transferType</code> passed
562      * in as an object reference.
563      * The returned value is a non pre-multiplied value. Thus, if the
564      * alpha is premultiplied, this method divides it out before returning
565      * the value. If the alpha value is 0, for example, the blue value
566      * is 0. If <code>inData</code> is not a primitive array of type
567      * <code>transferType</code>, a <code>ClassCastException</code> is thrown.
568      * An <code>ArrayIndexOutOfBoundsException</code> is
569      * thrown if <code>inData</code> is not large enough to hold a pixel
570      * value for this <code>ColorModel</code>. Since
571      * <code>DirectColorModel</code> can be subclassed, subclasses inherit
572      * the implementation of this method and if they don't override it
573      * then they throw an exception if they use an unsupported
574      * <code>transferType</code>.
575      * An <code>UnsupportedOperationException</code> is
576      * thrown if this <code>transferType</code> is not supported by this
577      * <code>ColorModel</code>.
578      * @param inData the array containing the pixel value
579      * @return the value of the blue component of the specified pixel.
580      * @throws ArrayIndexOutOfBoundsException if <code>inData</code> is not
581      * large enough to hold a pixel value for this color model
582      * @throws ClassCastException if <code>inData</code> is not a
583      * primitive array of type <code>transferType</code>
584      * @throws UnsupportedOperationException if this <code>transferType</code>
585      * is not supported by this color model
586      */

587     public int getBlue(Object JavaDoc inData) {
588         int pixel=0;
589         switch (transferType) {
590             case DataBuffer.TYPE_BYTE:
591                byte bdata[] = (byte[])inData;
592                pixel = bdata[0] & 0xff;
593             break;
594             case DataBuffer.TYPE_USHORT:
595                short sdata[] = (short[])inData;
596                pixel = sdata[0] & 0xffff;
597             break;
598             case DataBuffer.TYPE_INT:
599                int idata[] = (int[])inData;
600                pixel = idata[0];
601             break;
602             default:
603                throw new UnsupportedOperationException JavaDoc("This method has not been "+
604                    "implemented for transferType " + transferType);
605         }
606         return getBlue(pixel);
607     }
608
609     /**
610      * Returns the alpha component for the specified pixel, scaled
611      * from 0 to 255. The pixel value is specified by an array of data
612      * elements of type <code>transferType</code> passed in as an object
613      * reference.
614      * If <code>inData</code> is not a primitive array of type
615      * <code>transferType</code>, a <code>ClassCastException</code> is
616      * thrown. An <code>ArrayIndexOutOfBoundsException</code> is
617      * thrown if <code>inData</code> is not large enough to hold a pixel
618      * value for this <code>ColorModel</code>. Since
619      * <code>DirectColorModel</code> can be subclassed, subclasses inherit
620      * the implementation of this method and if they don't override it
621      * then they throw an exception if they use an unsupported
622      * <code>transferType</code>.
623      * If this <code>transferType</code> is not supported, an
624      * <code>UnsupportedOperationException</code> is thrown.
625      * @param inData the specified pixel
626      * @return the alpha component of the specified pixel, scaled from
627      * 0 to 255.
628      * @exception <code>ClassCastException</code> if <code>inData</code>
629      * is not a primitive array of type <code>transferType</code>
630      * @exception <code>ArrayIndexOutOfBoundsException</code> if
631      * <code>inData</code> is not large enough to hold a pixel value
632      * for this <code>ColorModel</code>
633      * @exception <code>UnsupportedOperationException</code> if this
634      * <code>tranferType</code> is not supported by this
635      * <code>ColorModel</code>
636      */

637     public int getAlpha(Object JavaDoc inData) {
638         int pixel=0;
639         switch (transferType) {
640             case DataBuffer.TYPE_BYTE:
641                byte bdata[] = (byte[])inData;
642                pixel = bdata[0] & 0xff;
643             break;
644             case DataBuffer.TYPE_USHORT:
645                short sdata[] = (short[])inData;
646                pixel = sdata[0] & 0xffff;
647             break;
648             case DataBuffer.TYPE_INT:
649                int idata[] = (int[])inData;
650                pixel = idata[0];
651             break;
652             default:
653                throw new UnsupportedOperationException JavaDoc("This method has not been "+
654                    "implemented for transferType " + transferType);
655         }
656         return getAlpha(pixel);
657     }
658
659     /**
660      * Returns the color/alpha components for the specified pixel in the
661      * default RGB color model format. A color conversion is done if
662      * necessary. The pixel value is specified by an array of data
663      * elements of type <code>transferType</code> passed in as an object
664      * reference. If <code>inData</code> is not a primitive array of type
665      * <code>transferType</code>, a <code>ClassCastException</code> is
666      * thrown. An <code>ArrayIndexOutOfBoundsException</code> is
667      * thrown if <code>inData</code> is not large enough to hold a pixel
668      * value for this <code>ColorModel</code>.
669      * The returned value is in a non pre-multiplied format. Thus, if
670      * the alpha is premultiplied, this method divides it out of the
671      * color components. If the alpha value is 0, for example, the color
672      * values is 0. Since <code>DirectColorModel</code> can be
673      * subclassed, subclasses inherit the implementation of this method
674      * and if they don't override it then
675      * they throw an exception if they use an unsupported
676      * <code>transferType</code>.
677      *
678      * @param inData the specified pixel
679      * @return the color and alpha components of the specified pixel.
680      * @exception UnsupportedOperationException if this
681      * <code>transferType</code> is not supported by this
682      * <code>ColorModel</code>
683      * @see ColorModel#getRGBdefault
684      */

685     public int getRGB(Object JavaDoc inData) {
686         int pixel=0;
687         switch (transferType) {
688             case DataBuffer.TYPE_BYTE:
689                byte bdata[] = (byte[])inData;
690                pixel = bdata[0] & 0xff;
691             break;
692             case DataBuffer.TYPE_USHORT:
693                short sdata[] = (short[])inData;
694                pixel = sdata[0] & 0xffff;
695             break;
696             case DataBuffer.TYPE_INT:
697                int idata[] = (int[])inData;
698                pixel = idata[0];
699             break;
700             default:
701                throw new UnsupportedOperationException JavaDoc("This method has not been "+
702                    "implemented for transferType " + transferType);
703         }
704         return getRGB(pixel);
705     }
706
707     /**
708      * Returns a data element array representation of a pixel in this
709      * <code>ColorModel</code>, given an integer pixel representation in the
710      * default RGB color model.
711      * This array can then be passed to the <code>setDataElements</code>
712      * method of a <code>WritableRaster</code> object. If the pixel variable
713      * is <code>null</code>, a new array is allocated. If <code>pixel</code>
714      * is not <code>null</code>, it must be a primitive array of type
715      * <code>transferType</code>; otherwise, a
716      * <code>ClassCastException</code> is thrown. An
717      * <code>ArrayIndexOutOfBoundsException</code> is
718      * thrown if <code>pixel</code> is not large enough to hold a pixel
719      * value for this <code>ColorModel</code>. The pixel array is returned.
720      * Since <code>DirectColorModel</code> can be subclassed, subclasses
721      * inherit the implementation of this method and if they don't
722      * override it then they throw an exception if they use an unsupported
723      * <code>transferType</code>.
724      *
725      * @param rgb the integer pixel representation in the default RGB
726      * color model
727      * @param pixel the specified pixel
728      * @return an array representation of the specified pixel in this
729      * <code>ColorModel</code>
730      * @exception ClassCastException if <code>pixel</code>
731      * is not a primitive array of type <code>transferType</code>
732      * @exception ArrayIndexOutOfBoundsException if
733      * <code>pixel</code> is not large enough to hold a pixel value
734      * for this <code>ColorModel</code>
735      * @exception UnsupportedOperationException if this
736      * <code>transferType</code> is not supported by this
737      * <code>ColorModel</code>
738      * @see WritableRaster#setDataElements
739      * @see SampleModel#setDataElements
740      */

741     public Object JavaDoc getDataElements(int rgb, Object JavaDoc pixel) {
742         //REMIND: maybe more efficient not to use int array for
743
//DataBuffer.TYPE_USHORT and DataBuffer.TYPE_INT
744
int intpixel[] = null;
745         if (transferType == DataBuffer.TYPE_INT &&
746             pixel != null) {
747             intpixel = (int[])pixel;
748             intpixel[0] = 0;
749         } else {
750             intpixel = new int[1];
751         }
752
753         ColorModel JavaDoc defaultCM = ColorModel.getRGBdefault();
754         if (this == defaultCM || equals(defaultCM)) {
755             intpixel[0] = rgb;
756             return intpixel;
757         }
758
759         int red, grn, blu, alp;
760         red = (rgb>>16) & 0xff;
761         grn = (rgb>>8) & 0xff;
762         blu = rgb & 0xff;
763         if (is_sRGB || is_LinearRGB) {
764             int precision;
765             float factor;
766             if (is_LinearRGB) {
767                 if (lRGBprecision == 8) {
768                     red = fromsRGB8LUT8[red] & 0xff;
769                     grn = fromsRGB8LUT8[grn] & 0xff;
770                     blu = fromsRGB8LUT8[blu] & 0xff;
771                     precision = 8;
772                     factor = 1.0f / 255.0f;
773                 } else {
774                     red = fromsRGB8LUT16[red] & 0xffff;
775                     grn = fromsRGB8LUT16[grn] & 0xffff;
776                     blu = fromsRGB8LUT16[blu] & 0xffff;
777                     precision = 16;
778                     factor = 1.0f / 65535.0f;
779                 }
780             } else {
781                 precision = 8;
782                 factor = 1.0f / 255.0f;
783             }
784             if (supportsAlpha) {
785                 alp = (rgb>>24) & 0xff;
786                 if (isAlphaPremultiplied) {
787                     factor *= (alp * (1.0f / 255.0f));
788                     precision = -1; // force component calculations below
789
}
790                 if (nBits[3] != 8) {
791                     alp = (int)
792                         ((alp * (1.0f / 255.0f) * ((1<<nBits[3]) - 1)) + 0.5f);
793                     if (alp > ((1<<nBits[3]) - 1)) {
794                         // fix 4412670 - see comment below
795
alp = (1<<nBits[3]) - 1;
796                     }
797                 }
798                 intpixel[0] = alp << maskOffsets[3];
799             }
800             if (nBits[0] != precision) {
801                 red = (int) ((red * factor * ((1<<nBits[0]) - 1)) + 0.5f);
802             }
803             if (nBits[1] != precision) {
804                 grn = (int) ((grn * factor * ((1<<nBits[1]) - 1)) + 0.5f);
805             }
806             if (nBits[2] != precision) {
807                 blu = (int) ((blu * factor * ((1<<nBits[2]) - 1)) + 0.5f);
808             }
809         } else {
810             // Need to convert the color
811
float[] norm = new float[3];
812             float factor = 1.0f / 255.0f;
813             norm[0] = red * factor;
814             norm[1] = grn * factor;
815             norm[2] = blu * factor;
816             norm = colorSpace.fromRGB(norm);
817             if (supportsAlpha) {
818                 alp = (rgb>>24) & 0xff;
819                 if (isAlphaPremultiplied) {
820                     factor *= alp;
821                     for (int i = 0; i < 3; i++) {
822                         norm[i] *= factor;
823                     }
824                 }
825                 if (nBits[3] != 8) {
826                     alp = (int)
827                         ((alp * (1.0f / 255.0f) * ((1<<nBits[3]) - 1)) + 0.5f);
828                     if (alp > ((1<<nBits[3]) - 1)) {
829                         // fix 4412670 - see comment below
830
alp = (1<<nBits[3]) - 1;
831                     }
832                 }
833                 intpixel[0] = alp << maskOffsets[3];
834             }
835             red = (int) ((norm[0] * ((1<<nBits[0]) - 1)) + 0.5f);
836         &n