• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 /**
18  * @author Igor V. Stolyarov
19  * @version $Revision$
20  */
21 
22 package java.awt.image;
23 
24 import java.awt.color.ColorSpace;
25 
26 import org.apache.harmony.awt.gl.color.LUTColorConverter;
27 import org.apache.harmony.awt.internal.nls.Messages;
28 
29 /**
30  * The Class ComponentColorModel represents a color model that is defined in
31  * terms of its components.
32  *
33  * @since Android 1.0
34  */
35 public class ComponentColorModel extends ColorModel {
36 
37     /**
38      * The signed.
39      */
40     private boolean signed; // Pixel samples are signed.
41 
42     // Samples with TransferType DataBuffer.TYPE_BYTE,
43     // DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT -
44     // unsigned. Samples with others TransferType -
45     // signed.
46 
47     /**
48      * The integral.
49      */
50     private boolean integral; // Pixel samples are integral.
51 
52     // Samples with TransferType DataBuffer.TYPE_BYTE,
53     // DataBuffer.TYPE_USHORT, DataBuffer.Short and
54     // DataBuffer.TYPE_INT - integral.
55 
56     /**
57      * The scale factors.
58      */
59     private float scaleFactors[]; // Array of factors for reduction components
60 
61     // values into the form scaled from 0 to 255
62 
63     /**
64      * The donot support unnormalized.
65      */
66     private boolean donotSupportUnnormalized; // This Color Model don't support
67 
68     // unnormolized form
69 
70     /**
71      * The need alpha divide.
72      */
73     private boolean needAlphaDivide; // hasAlpha && isAlphaPremultiplied
74 
75     /**
76      * The calc value.
77      */
78     private boolean calcValue; // Value was culculated
79 
80     /**
81      * The need scale.
82      */
83     private boolean needScale; // Normalized value need to scale
84 
85     /**
86      * The min vals.
87      */
88     private float minVals[]; // Array of Min normalized values
89 
90     /**
91      * The ranges.
92      */
93     private float ranges[]; // Array of range normalized values
94 
95     /**
96      * The alpha lut.
97      */
98     private byte alphaLUT[]; // Lookup table for scale alpha value
99 
100     /**
101      * The color lu ts.
102      */
103     private byte colorLUTs[][]; // Lookup tables for scale color values
104 
105     /**
106      * The from_ linea r_ rg b_ lut.
107      */
108     private byte from_LINEAR_RGB_LUT[]; // Lookup table for conversion from
109 
110     // Linear RGB Color Space into sRGB
111 
112     /**
113      * The to_ linea r_8 rg b_ lut.
114      */
115     private byte to_LINEAR_8RGB_LUT[]; // Lookup table for conversion from
116 
117     // sRGB Color Space into Linear RGB
118     // 8 bit
119 
120     /**
121      * The to_ linea r_16 rg b_ lut.
122      */
123     private short to_LINEAR_16RGB_LUT[]; // Lookup table for conversion from
124 
125     // sRGB Color Space into Linear RGB
126     // 16 bit
127 
128     /**
129      * The LINEA r_ rg b_ length.
130      */
131     private int LINEAR_RGB_Length; // Linear RGB bit length
132 
133     /**
134      * The factor.
135      */
136     private float fFactor; // Scale factor
137 
138     /**
139      * The is_s rgb.
140      */
141     private boolean is_sRGB; // ColorModel has sRGB ColorSpace
142 
143     /**
144      * The is_ linea r_ rgb.
145      */
146     private boolean is_LINEAR_RGB; // Color Model has Linear RGB Color
147 
148     // Space
149 
150     /**
151      * Instantiates a new component color model.
152      *
153      * @param colorSpace
154      *            the color space.
155      * @param bits
156      *            the array of component masks.
157      * @param hasAlpha
158      *            whether the color model has alpha.
159      * @param isAlphaPremultiplied
160      *            whether the alpha is pre-multiplied.
161      * @param transparency
162      *            the transparency strategy, @see java.awt.Transparency.
163      * @param transferType
164      *            the transfer type (primitive java type to use for the
165      *            components).
166      */
ComponentColorModel(ColorSpace colorSpace, int bits[], boolean hasAlpha, boolean isAlphaPremultiplied, int transparency, int transferType)167     public ComponentColorModel(ColorSpace colorSpace, int bits[], boolean hasAlpha,
168             boolean isAlphaPremultiplied, int transparency, int transferType) {
169         super(createPixelBits(colorSpace, hasAlpha, transferType), validateBits(bits, colorSpace,
170                 hasAlpha, transferType), colorSpace, hasAlpha, isAlphaPremultiplied, transparency,
171                 transferType);
172 
173         needScale = false;
174         switch (transferType) {
175             case DataBuffer.TYPE_BYTE:
176             case DataBuffer.TYPE_USHORT:
177             case DataBuffer.TYPE_INT:
178                 signed = false;
179                 integral = true;
180                 donotSupportUnnormalized = false;
181                 scaleFactors = new float[numComponents];
182                 for (int i = 0; i < numColorComponents; i++) {
183                     scaleFactors[i] = 1.0f / maxValues[i];
184                     if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
185                         donotSupportUnnormalized = true;
186                     }
187                 }
188                 if (hasAlpha) {
189                     maxValues[numColorComponents] = (1 << bits[numColorComponents]) - 1;
190                     scaleFactors[numColorComponents] = 1.0f / maxValues[numColorComponents];
191                 }
192                 break;
193             case DataBuffer.TYPE_SHORT:
194                 signed = true;
195                 integral = true;
196                 donotSupportUnnormalized = true;
197                 scaleFactors = new float[numComponents];
198                 for (int i = 0; i < numComponents; i++) {
199                     maxValues[i] = Short.MAX_VALUE;
200                     scaleFactors[i] = 1.0f / maxValues[i];
201                     if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
202                         needScale = true;
203                     }
204                 }
205                 if (needScale) {
206                     minVals = new float[numColorComponents];
207                     ranges = new float[numColorComponents];
208                     for (int i = 0; i < numColorComponents; i++) {
209                         minVals[i] = cs.getMinValue(i);
210                         ranges[i] = cs.getMaxValue(i) - minVals[i];
211                     }
212                 }
213                 break;
214             case DataBuffer.TYPE_FLOAT:
215             case DataBuffer.TYPE_DOUBLE:
216                 signed = true;
217                 integral = false;
218                 donotSupportUnnormalized = true;
219                 break;
220             default:
221                 // awt.215=transferType is not one of DataBuffer.TYPE_BYTE,
222                 // DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
223                 // DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
224                 // DataBuffer.TYPE_DOUBLE
225                 throw new IllegalArgumentException(Messages.getString("awt.215")); //$NON-NLS-1$
226         }
227 
228         needAlphaDivide = hasAlpha && isAlphaPremultiplied;
229         initLUTs();
230     }
231 
232     /**
233      * Instantiates a new component color model.
234      *
235      * @param colorSpace
236      *            the color space.
237      * @param hasAlpha
238      *            whether the color model has alpha.
239      * @param isAlphaPremultiplied
240      *            whether the alpha is pre-multiplied.
241      * @param transparency
242      *            the transparency strategy, @see java.awt.Transparency.
243      * @param transferType
244      *            the transfer type (primitive java type to use for the
245      *            components).
246      */
ComponentColorModel(ColorSpace colorSpace, boolean hasAlpha, boolean isAlphaPremultiplied, int transparency, int transferType)247     public ComponentColorModel(ColorSpace colorSpace, boolean hasAlpha,
248             boolean isAlphaPremultiplied, int transparency, int transferType) {
249 
250         this(colorSpace, createPixelBitsArray(colorSpace, hasAlpha, transferType), hasAlpha,
251                 isAlphaPremultiplied, transparency, transferType);
252     }
253 
254     /**
255      * Validate bits.
256      *
257      * @param bits
258      *            the bits.
259      * @param colorSpace
260      *            the color space.
261      * @param hasAlpha
262      *            the has alpha.
263      * @param transferType
264      *            the transfer type.
265      * @return the int[].
266      */
validateBits(int bits[], ColorSpace colorSpace, boolean hasAlpha, int transferType)267     private static int[] validateBits(int bits[], ColorSpace colorSpace, boolean hasAlpha,
268             int transferType) {
269         if (bits != null) {
270             return bits;
271         }
272 
273         int numComponents = colorSpace.getNumComponents();
274         if (hasAlpha) {
275             numComponents++;
276         }
277         bits = new int[numComponents];
278 
279         int componentLength = DataBuffer.getDataTypeSize(transferType);
280 
281         for (int i = 0; i < numComponents; i++) {
282             bits[i] = componentLength;
283         }
284 
285         return bits;
286     }
287 
288     /**
289      * Creates the pixel bits.
290      *
291      * @param colorSpace
292      *            the color space.
293      * @param hasAlpha
294      *            the has alpha.
295      * @param transferType
296      *            the transfer type.
297      * @return the int.
298      */
createPixelBits(ColorSpace colorSpace, boolean hasAlpha, int transferType)299     private static int createPixelBits(ColorSpace colorSpace, boolean hasAlpha, int transferType) {
300         int numComponents = colorSpace.getNumComponents();
301         if (hasAlpha) {
302             numComponents++;
303         }
304         int componentLength = DataBuffer.getDataTypeSize(transferType);
305         return numComponents * componentLength;
306     }
307 
308     /**
309      * Creates the pixel bits array.
310      *
311      * @param colorSpace
312      *            the color space.
313      * @param hasAlpha
314      *            the has alpha.
315      * @param transferType
316      *            the transfer type.
317      * @return the int[].
318      */
createPixelBitsArray(ColorSpace colorSpace, boolean hasAlpha, int transferType)319     private static int[] createPixelBitsArray(ColorSpace colorSpace, boolean hasAlpha,
320             int transferType) {
321 
322         int numComponents = colorSpace.getNumComponents();
323         if (hasAlpha) {
324             numComponents++;
325         }
326 
327         int bits[] = new int[numComponents];
328         for (int i = 0; i < numComponents; i++) {
329             bits[i] = DataBuffer.getDataTypeSize(transferType);
330         }
331         return bits;
332     }
333 
334     @Override
getDataElements(int components[], int offset, Object obj)335     public Object getDataElements(int components[], int offset, Object obj) {
336         if (donotSupportUnnormalized) {
337             // awt.213=This ComponentColorModel does not support the
338             // unnormalized form
339             throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
340         }
341 
342         if (offset + numComponents > components.length) {
343             // awt.216=The components array is not large enough to hold all the
344             // color and alpha components
345             throw new IllegalArgumentException(Messages.getString("awt.216")); //$NON-NLS-1$
346         }
347 
348         switch (transferType) {
349             case DataBuffer.TYPE_BYTE:
350                 byte ba[];
351                 if (obj == null) {
352                     ba = new byte[numComponents];
353                 } else {
354                     ba = (byte[])obj;
355                 }
356                 for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
357                     ba[i] = (byte)components[idx];
358                 }
359                 return ba;
360             case DataBuffer.TYPE_USHORT:
361                 short sa[];
362                 if (obj == null) {
363                     sa = new short[numComponents];
364                 } else {
365                     sa = (short[])obj;
366                 }
367                 for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
368                     sa[i] = (short)components[idx];
369                 }
370                 return sa;
371             case DataBuffer.TYPE_INT:
372                 int ia[];
373                 if (obj == null) {
374                     ia = new int[numComponents];
375                 } else {
376                     ia = (int[])obj;
377                 }
378                 for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
379                     ia[i] = components[idx];
380                 }
381                 return ia;
382             default:
383                 // awt.217=The transfer type of this ComponentColorModel is not
384                 // one
385                 // of the following transfer types: DataBuffer.TYPE_BYTE,
386                 // DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
387                 throw new UnsupportedOperationException(Messages.getString("awt.217")); //$NON-NLS-1$
388         }
389     }
390 
391     @Override
getDataElements(float normComponents[], int normOffset, Object obj)392     public Object getDataElements(float normComponents[], int normOffset, Object obj) {
393         if (needScale) {
394             for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
395                 normComponents[idx] = (normComponents[idx] - minVals[i]) / ranges[i];
396             }
397         }
398 
399         switch (transferType) {
400             case DataBuffer.TYPE_BYTE:
401                 byte ba[];
402                 if (obj == null) {
403                     ba = new byte[numComponents];
404                 } else {
405                     ba = (byte[])obj;
406                 }
407 
408                 if (needAlphaDivide) {
409                     float alpha = normComponents[normOffset + numColorComponents];
410                     for (int i = 0, idx = normOffset; i < numColorComponents; i++, idx++) {
411                         ba[i] = (byte)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
412                     }
413                     ba[numColorComponents] = (byte)(normComponents[normOffset + numColorComponents]
414                             * maxValues[numColorComponents] + 0.5f);
415                 } else {
416                     for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
417                         ba[idx] = (byte)(normComponents[idx] * maxValues[i] + 0.5f);
418                     }
419                 }
420                 return ba;
421 
422             case DataBuffer.TYPE_USHORT:
423                 short usa[];
424                 if (obj == null) {
425                     usa = new short[numComponents];
426                 } else {
427                     usa = (short[])obj;
428                 }
429 
430                 if (needAlphaDivide) {
431                     float alpha = normComponents[normOffset + numColorComponents];
432                     for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
433                         usa[i] = (short)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
434                     }
435                     usa[numColorComponents] = (short)(alpha * maxValues[numColorComponents] + 0.5f);
436                 } else {
437                     for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
438                         usa[i] = (short)(normComponents[idx] * maxValues[i] + 0.5f);
439                     }
440                 }
441                 return usa;
442 
443             case DataBuffer.TYPE_INT:
444                 int ia[];
445                 if (obj == null) {
446                     ia = new int[numComponents];
447                 } else {
448                     ia = (int[])obj;
449                 }
450 
451                 if (needAlphaDivide) {
452                     float alpha = normComponents[normOffset + numColorComponents];
453                     for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
454                         ia[i] = (int)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
455                     }
456                     ia[numColorComponents] = (int)(alpha * maxValues[numColorComponents] + 0.5f);
457                 } else {
458                     for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
459                         ia[i] = (int)(normComponents[idx] * maxValues[i] + 0.5f);
460                     }
461                 }
462                 return ia;
463 
464             case DataBuffer.TYPE_SHORT:
465                 short sa[];
466                 if (obj == null) {
467                     sa = new short[numComponents];
468                 } else {
469                     sa = (short[])obj;
470                 }
471 
472                 if (needAlphaDivide) {
473                     float alpha = normComponents[normOffset + numColorComponents];
474                     for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
475                         sa[i] = (short)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
476                     }
477                     sa[numColorComponents] = (short)(alpha * maxValues[numColorComponents] + 0.5f);
478                 } else {
479                     for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
480                         sa[i] = (short)(normComponents[idx] * maxValues[i] + 0.5f);
481                     }
482                 }
483                 return sa;
484 
485             case DataBuffer.TYPE_FLOAT:
486                 float fa[];
487                 if (obj == null) {
488                     fa = new float[numComponents];
489                 } else {
490                     fa = (float[])obj;
491                 }
492 
493                 if (needAlphaDivide) {
494                     float alpha = normComponents[normOffset + numColorComponents];
495                     for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
496                         fa[i] = normComponents[idx] * alpha;
497                     }
498                     fa[numColorComponents] = alpha;
499                 } else {
500                     for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
501                         fa[i] = normComponents[idx];
502                     }
503                 }
504                 return fa;
505 
506             case DataBuffer.TYPE_DOUBLE:
507                 double da[];
508                 if (obj == null) {
509                     da = new double[numComponents];
510                 } else {
511                     da = (double[])obj;
512                 }
513 
514                 if (needAlphaDivide) {
515                     double alpha = normComponents[normOffset + numColorComponents];
516                     for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
517                         da[i] = normComponents[idx] * alpha;
518                     }
519                     da[numColorComponents] = alpha;
520                 } else {
521                     for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
522                         da[i] = normComponents[idx];
523                     }
524                 }
525                 return da;
526 
527             default:
528                 // awt.213=This ComponentColorModel does not support the
529                 // unnormalized form
530                 throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
531         }
532     }
533 
534     @Override
getDataElements(int rgb, Object pixel)535     public Object getDataElements(int rgb, Object pixel) {
536         float normComp[];
537         float comp[];
538 
539         int red = (rgb >> 16) & 0xff;
540         int green = (rgb >> 8) & 0xff;
541         int blue = rgb & 0xff;
542         int alpha = (rgb >> 24) & 0xff;
543 
544         comp = new float[3];
545         if (is_sRGB || is_LINEAR_RGB) {
546             if (is_LINEAR_RGB) {
547                 if (LINEAR_RGB_Length == 8) {
548                     red = to_LINEAR_8RGB_LUT[red] & 0xff;
549                     green = to_LINEAR_8RGB_LUT[green] & 0xff;
550                     blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
551                 } else {
552                     red = to_LINEAR_16RGB_LUT[red] & 0xffff;
553                     green = to_LINEAR_16RGB_LUT[green] & 0xffff;
554                     blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
555                 }
556             }
557             comp[0] = red / fFactor;
558             comp[1] = green / fFactor;
559             comp[2] = blue / fFactor;
560             if (!hasAlpha) {
561                 normComp = comp;
562             } else {
563                 float normAlpha = alpha / 255.0f;
564                 normComp = new float[numComponents];
565                 for (int i = 0; i < numColorComponents; i++) {
566                     normComp[i] = comp[i];
567                 }
568                 normComp[numColorComponents] = normAlpha;
569             }
570         } else {
571             comp[0] = red / fFactor;
572             comp[1] = green / fFactor;
573             comp[2] = blue / fFactor;
574             float[] defComp = cs.fromRGB(comp);
575             if (!hasAlpha) {
576                 normComp = defComp;
577             } else {
578                 float normAlpha = alpha / 255.0f;
579                 normComp = new float[numComponents];
580                 for (int i = 0; i < numColorComponents; i++) {
581                     normComp[i] = defComp[i];
582                 }
583                 normComp[numColorComponents] = normAlpha;
584             }
585         }
586         if (hasAlpha && isAlphaPremultiplied) {
587             normComp[0] *= normComp[numColorComponents];
588             normComp[1] *= normComp[numColorComponents];
589             normComp[2] *= normComp[numColorComponents];
590         }
591 
592         return getDataElements(normComp, 0, pixel);
593     }
594 
595     @Override
getAlphaRaster(WritableRaster raster)596     public WritableRaster getAlphaRaster(WritableRaster raster) {
597         if (!hasAlpha) {
598             return null;
599         }
600 
601         int x = raster.getMinX();
602         int y = raster.getMinY();
603         int bandList[] = new int[1];
604         bandList[0] = raster.getNumBands() - 1;
605 
606         return raster.createWritableChild(x, y, raster.getWidth(), raster.getHeight(), x, y,
607                 bandList);
608     }
609 
610     @Override
coerceData(WritableRaster raster, boolean isAlphaPremultiplied)611     public ColorModel coerceData(WritableRaster raster, boolean isAlphaPremultiplied) {
612         if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
613             return this;
614         }
615 
616         int minX = raster.getMinX();
617         int minY = raster.getMinY();
618         int w = raster.getWidth();
619         int h = raster.getHeight();
620 
621         if (isAlphaPremultiplied) {
622             switch (transferType) {
623                 case DataBuffer.TYPE_BYTE:
624                 case DataBuffer.TYPE_USHORT:
625                 case DataBuffer.TYPE_INT:
626                     float alphaFactor = maxValues[numColorComponents];
627                     int iComponents[] = null;
628                     int iTransparentComponents[] = new int[numComponents];
629                     for (int i = 0; i < h; i++, minY++) {
630                         for (int j = 0, x = minX; j < w; j++, x++) {
631                             iComponents = raster.getPixel(x, minY, iComponents);
632                             if (iComponents[numColorComponents] == 0) {
633                                 raster.setPixel(x, minY, iTransparentComponents);
634                             } else {
635                                 float alpha = iComponents[numColorComponents] / alphaFactor;
636                                 for (int n = 0; n < numColorComponents; n++) {
637                                     iComponents[n] = (int)(alpha * iComponents[n] + 0.5f);
638                                 }
639                                 raster.setPixel(x, minY, iComponents);
640                             }
641                         }
642 
643                     }
644                     break;
645 
646                 case DataBuffer.TYPE_SHORT:
647                     float sAlphaFactor = maxValues[numColorComponents];
648                     short sComponents[] = null;
649                     short sTransparentComponents[] = new short[numComponents];
650                     for (int i = 0; i < h; i++, minY++) {
651                         for (int j = 0, x = minX; j < w; j++, x++) {
652                             sComponents = (short[])raster.getDataElements(x, minY, sComponents);
653                             if (sComponents[numColorComponents] == 0) {
654                                 raster.setDataElements(x, minY, sTransparentComponents);
655                             } else {
656                                 float alpha = sComponents[numColorComponents] / sAlphaFactor;
657                                 for (int n = 0; n < numColorComponents; n++) {
658                                     sComponents[n] = (byte)(alpha * sComponents[n] + 0.5f);
659                                 }
660                                 raster.setDataElements(x, minY, sComponents);
661                             }
662                         }
663 
664                     }
665                     break;
666 
667                 case DataBuffer.TYPE_FLOAT:
668                     float fComponents[] = null;
669                     float fTransparentComponents[] = new float[numComponents];
670                     for (int i = 0; i < h; i++, minY++) {
671                         for (int j = 0, x = minX; j < w; j++, x++) {
672                             fComponents = raster.getPixel(x, minY, fComponents);
673                             if (fComponents[numColorComponents] == 0.0f) {
674                                 raster.setDataElements(x, minY, fTransparentComponents);
675                             } else {
676                                 float alpha = fComponents[numColorComponents];
677                                 for (int n = 0; n < numColorComponents; n++) {
678                                     fComponents[n] = fComponents[n] * alpha;
679                                 }
680                                 raster.setPixel(x, minY, fComponents);
681                             }
682                         }
683 
684                     }
685                     break;
686 
687                 case DataBuffer.TYPE_DOUBLE:
688                     double dComponents[] = null;
689                     double dTransparentComponents[] = new double[numComponents];
690                     for (int i = 0; i < h; i++, minY++) {
691                         for (int j = 0, x = minX; j < w; j++, x++) {
692                             dComponents = raster.getPixel(x, minY, dComponents);
693                             if (dComponents[numColorComponents] == 0.0) {
694                                 raster.setPixel(x, minY, dTransparentComponents);
695                             } else {
696                                 double alpha = dComponents[numColorComponents];
697                                 for (int n = 0; n < numColorComponents; n++) {
698                                     dComponents[n] = dComponents[n] * alpha;
699                                 }
700                                 raster.setPixel(x, minY, dComponents);
701                             }
702                         }
703 
704                     }
705                     break;
706 
707                 default:
708                     // awt.219=This transferType is not supported by this color
709                     // model
710                     throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
711             }
712         } else {
713             switch (transferType) {
714                 case DataBuffer.TYPE_BYTE:
715                 case DataBuffer.TYPE_USHORT:
716                 case DataBuffer.TYPE_INT:
717                     float alphaFactor = maxValues[numColorComponents];
718                     int iComponents[] = null;
719                     int iTransparentComponents[] = new int[numComponents];
720                     for (int i = 0; i < h; i++, minY++) {
721                         for (int j = 0, x = minX; j < w; j++, x++) {
722                             iComponents = raster.getPixel(x, minY, iComponents);
723                             if (iComponents[numColorComponents] == 0) {
724                                 raster.setPixel(x, minY, iTransparentComponents);
725                             } else {
726                                 float alpha = iComponents[numColorComponents] / alphaFactor;
727                                 for (int n = 0; n < numColorComponents; n++) {
728                                     iComponents[n] = (int)(iComponents[n] / alpha + 0.5f);
729                                 }
730                                 raster.setPixel(x, minY, iComponents);
731                             }
732                         }
733 
734                     }
735                     break;
736 
737                 case DataBuffer.TYPE_SHORT:
738                     float sAlphaFactor = maxValues[numColorComponents];
739                     short sComponents[] = null;
740                     short sTransparentComponents[] = new short[numComponents];
741                     for (int i = 0; i < h; i++, minY++) {
742                         for (int j = 0, x = minX; j < w; j++, x++) {
743                             sComponents = (short[])raster.getDataElements(x, minY, sComponents);
744                             if (sComponents[numColorComponents] == 0) {
745                                 raster.setDataElements(x, minY, sTransparentComponents);
746                             } else {
747                                 float alpha = sComponents[numColorComponents] / sAlphaFactor;
748                                 for (int n = 0; n < numColorComponents; n++) {
749                                     sComponents[n] = (byte)(sComponents[n] / alpha + 0.5f);
750                                 }
751                                 raster.setDataElements(x, minY, sComponents);
752                             }
753                         }
754 
755                     }
756                     break;
757 
758                 case DataBuffer.TYPE_FLOAT:
759                     float fComponents[] = null;
760                     float fTransparentComponents[] = new float[numComponents];
761                     for (int i = 0; i < h; i++, minY++) {
762                         for (int j = 0, x = minX; j < w; j++, x++) {
763                             fComponents = raster.getPixel(x, minY, fComponents);
764                             if (fComponents[numColorComponents] == 0.0f) {
765                                 raster.setDataElements(x, minY, fTransparentComponents);
766                             } else {
767                                 float alpha = fComponents[numColorComponents];
768                                 for (int n = 0; n < numColorComponents; n++) {
769                                     fComponents[n] = fComponents[n] / alpha;
770                                 }
771                                 raster.setPixel(x, minY, fComponents);
772                             }
773                         }
774 
775                     }
776                     break;
777 
778                 case DataBuffer.TYPE_DOUBLE:
779                     double dComponents[] = null;
780                     double dTransparentComponents[] = new double[numComponents];
781                     for (int i = 0; i < h; i++, minY++) {
782                         for (int j = 0, x = minX; j < w; j++, x++) {
783                             dComponents = raster.getPixel(x, minY, dComponents);
784                             if (dComponents[numColorComponents] == 0.0) {
785                                 raster.setPixel(x, minY, dTransparentComponents);
786                             } else {
787                                 double alpha = dComponents[numColorComponents];
788                                 for (int n = 0; n < numColorComponents; n++) {
789                                     dComponents[n] = dComponents[n] / alpha;
790                                 }
791                                 raster.setPixel(x, minY, dComponents);
792                             }
793                         }
794 
795                     }
796                     break;
797                 default:
798                     // awt.219=This transferType is not supported by this color
799                     // model
800                     throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
801             }
802         }
803 
804         if (!signed) {
805             return new ComponentColorModel(cs, bits, hasAlpha, isAlphaPremultiplied, transparency,
806                     transferType);
807         }
808 
809         return new ComponentColorModel(cs, null, hasAlpha, isAlphaPremultiplied, transparency,
810                 transferType);
811     }
812 
813     @Override
getComponents(Object pixel, int[] components, int offset)814     public int[] getComponents(Object pixel, int[] components, int offset) {
815         if (donotSupportUnnormalized) {
816             // awt.213=This ComponentColorModel does not support the
817             // unnormalized form
818             throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
819         }
820 
821         if (components == null) {
822             components = new int[offset + numComponents];
823         } else if (offset + numComponents > components.length) {
824             // awt.218=The components array is not large enough to hold all the
825             // color and alpha components
826             throw new IllegalArgumentException(Messages.getString("awt.218")); //$NON-NLS-1$
827         }
828 
829         switch (transferType) {
830             case DataBuffer.TYPE_BYTE:
831                 byte ba[] = (byte[])pixel;
832 
833                 for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
834                     components[idx] = ba[i] & 0xff;
835                 }
836                 return components;
837 
838             case DataBuffer.TYPE_USHORT:
839                 short sa[] = (short[])pixel;
840                 for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
841                     components[idx] = sa[i] & 0xffff;
842                 }
843                 return components;
844 
845             case DataBuffer.TYPE_INT:
846                 int ia[] = (int[])pixel;
847                 for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
848                     components[idx] = ia[i];
849                 }
850                 return components;
851 
852             default:
853                 // awt.217=The transfer type of this ComponentColorModel is not
854                 // one
855                 // of the following transfer types: DataBuffer.TYPE_BYTE,
856                 // DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
857                 throw new UnsupportedOperationException(Messages.getString("awt.217")); //$NON-NLS-1$
858         }
859 
860     }
861 
862     @Override
getNormalizedComponents(Object pixel, float normComponents[], int normOffset)863     public float[] getNormalizedComponents(Object pixel, float normComponents[], int normOffset) {
864 
865         if (normComponents == null) {
866             normComponents = new float[numComponents + normOffset];
867         }
868 
869         switch (transferType) {
870             case DataBuffer.TYPE_BYTE:
871                 byte ba[] = (byte[])pixel;
872                 for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
873                     normComponents[idx] = (ba[i] & 0xff) * scaleFactors[i];
874                 }
875                 break;
876 
877             case DataBuffer.TYPE_USHORT:
878                 short usa[] = (short[])pixel;
879                 for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
880                     normComponents[idx] = (usa[i] & 0xffff) * scaleFactors[i];
881                 }
882                 break;
883 
884             case DataBuffer.TYPE_INT:
885                 int ia[] = (int[])pixel;
886                 for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
887                     normComponents[idx] = ia[i] * scaleFactors[i];
888                 }
889                 break;
890 
891             case DataBuffer.TYPE_SHORT:
892                 short sa[] = (short[])pixel;
893                 for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
894                     normComponents[idx] = sa[i] * scaleFactors[i];
895                 }
896                 break;
897 
898             case DataBuffer.TYPE_FLOAT:
899                 float fa[] = (float[])pixel;
900                 for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
901                     normComponents[idx] = fa[i];
902                 }
903                 break;
904 
905             case DataBuffer.TYPE_DOUBLE:
906                 double da[] = (double[])pixel;
907                 for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
908                     normComponents[idx] = (float)da[i];
909                 }
910                 break;
911 
912             default:
913                 // awt.21A=This ComponentColorModel does not support this
914                 // transferType
915                 throw new IllegalArgumentException(Messages.getString("awt.21A")); //$NON-NLS-1$
916         }
917 
918         if (needAlphaDivide) {
919             float alpha = normComponents[normOffset + numColorComponents];
920             for (int i = 0, idx = normOffset; i < numColorComponents; i++, idx++) {
921                 normComponents[idx] /= alpha;
922             }
923         }
924 
925         if (needScale) {
926             for (int i = 0, idx = normOffset; i < numColorComponents; i++, idx++) {
927                 normComponents[idx] = minVals[i] + ranges[i] * normComponents[idx];
928             }
929         }
930         return normComponents;
931     }
932 
933     @Override
equals(Object obj)934     public boolean equals(Object obj) {
935         if (!(obj instanceof ComponentColorModel)) {
936             return false;
937         }
938         return super.equals(obj);
939     }
940 
941     @Override
getRed(Object inData)942     public int getRed(Object inData) {
943         return getRGBComponent(inData, 0);
944     }
945 
946     @Override
getRGB(Object inData)947     public int getRGB(Object inData) {
948         int alpha = getAlpha(inData);
949         if (cs.getType() == ColorSpace.TYPE_GRAY) {
950             int gray = getRed(inData);
951             return (alpha << 24 | gray << 16 | gray << 8 | gray);
952         }
953         return (alpha << 24 | getRed(inData) << 16 | getGreen(inData) << 8 | getBlue(inData));
954     }
955 
956     @Override
getGreen(Object inData)957     public int getGreen(Object inData) {
958         return getRGBComponent(inData, 1);
959     }
960 
961     @Override
getBlue(Object inData)962     public int getBlue(Object inData) {
963         return getRGBComponent(inData, 2);
964     }
965 
966     @Override
getAlpha(Object inData)967     public int getAlpha(Object inData) {
968         if (!hasAlpha) {
969             return 255;
970         }
971         int alpha = 0;
972 
973         switch (transferType) {
974             case DataBuffer.TYPE_BYTE: {
975                 byte ba[] = (byte[])inData;
976                 alpha = ba[numColorComponents] & 0xff;
977                 if (bits[numColorComponents] != 8) {
978                     return alphaLUT[alpha] & 0xff;
979                 }
980                 return alpha;
981             }
982             case DataBuffer.TYPE_USHORT: {
983                 short usa[] = (short[])inData;
984                 alpha = usa[numColorComponents] & 0xffff;
985                 if (bits[numColorComponents] != 8) {
986                     return alphaLUT[alpha] & 0xff;
987                 }
988                 return alpha;
989             }
990             case DataBuffer.TYPE_INT: {
991                 int ia[] = (int[])inData;
992                 alpha = ia[numColorComponents];
993                 if (bits[numColorComponents] != 8) {
994                     return alphaLUT[alpha] & 0xff;
995                 }
996                 return alpha;
997             }
998             case DataBuffer.TYPE_SHORT: {
999                 short sa[] = (short[])inData;
1000                 alpha = sa[numColorComponents];
1001                 if (bits[numColorComponents] != 8) {
1002                     return alphaLUT[alpha] & 0xff;
1003                 }
1004                 return alpha;
1005             }
1006             case DataBuffer.TYPE_FLOAT: {
1007                 float fa[] = (float[])inData;
1008                 return (int)(fa[numColorComponents] * 255.0f + 0.5f);
1009             }
1010             case DataBuffer.TYPE_DOUBLE: {
1011                 double da[] = (double[])inData;
1012                 return (int)(da[numColorComponents] * 255.0 + 0.5);
1013             }
1014             default: {
1015                 // awt.214=This Color Model doesn't support this transferType
1016                 throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
1017             }
1018         }
1019     }
1020 
1021     @Override
createCompatibleWritableRaster(int w, int h)1022     public WritableRaster createCompatibleWritableRaster(int w, int h) {
1023         SampleModel sm = createCompatibleSampleModel(w, h);
1024         DataBuffer db = sm.createDataBuffer();
1025         return Raster.createWritableRaster(sm, db, null);
1026     }
1027 
1028     @Override
isCompatibleSampleModel(SampleModel sm)1029     public boolean isCompatibleSampleModel(SampleModel sm) {
1030         if (!(sm instanceof ComponentSampleModel)) {
1031             return false;
1032         }
1033         if (numComponents != sm.getNumBands()) {
1034             return false;
1035         }
1036         if (transferType != sm.getTransferType()) {
1037             return false;
1038         }
1039         return true;
1040     }
1041 
1042     @Override
createCompatibleSampleModel(int w, int h)1043     public SampleModel createCompatibleSampleModel(int w, int h) {
1044         int bandOffsets[] = new int[numComponents];
1045         for (int i = 0; i < numComponents; i++) {
1046             bandOffsets[i] = i;
1047         }
1048 
1049         switch (transferType) {
1050             case DataBuffer.TYPE_BYTE:
1051             case DataBuffer.TYPE_USHORT:
1052                 return new PixelInterleavedSampleModel(transferType, w, h, numComponents, w
1053                         * numComponents, bandOffsets);
1054 
1055             default:
1056                 return new ComponentSampleModel(transferType, w, h, numComponents, w
1057                         * numComponents, bandOffsets);
1058         }
1059     }
1060 
1061     @Override
isCompatibleRaster(Raster raster)1062     public boolean isCompatibleRaster(Raster raster) {
1063         SampleModel sm = raster.getSampleModel();
1064         if (!(sm instanceof ComponentSampleModel)) {
1065             return false;
1066         }
1067 
1068         if (sm.getNumBands() != numComponents) {
1069             return false;
1070         }
1071         if (raster.getTransferType() != transferType) {
1072             return false;
1073         }
1074 
1075         int sampleSizes[] = sm.getSampleSize();
1076         for (int i = 0; i < numComponents; i++) {
1077             if (bits[i] != sampleSizes[i]) {
1078                 return false;
1079             }
1080         }
1081         return true;
1082     }
1083 
1084     @Override
getNormalizedComponents(int components[], int offset, float normComponents[], int normOffset)1085     public float[] getNormalizedComponents(int components[], int offset, float normComponents[],
1086             int normOffset) {
1087         if (donotSupportUnnormalized) {
1088             // awt.213=This ComponentColorModel does not support the
1089             // unnormalized form
1090             throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
1091         }
1092 
1093         return super.getNormalizedComponents(components, offset, normComponents, normOffset);
1094     }
1095 
1096     @Override
getDataElement(int[] components, int offset)1097     public int getDataElement(int[] components, int offset) {
1098         if (numComponents > 1) {
1099             // awt.212=There is more than one component in this ColorModel
1100             throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
1101         }
1102         if (donotSupportUnnormalized) {
1103             // awt.213=This ComponentColorModel does not support the
1104             // unnormalized form
1105             throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
1106         }
1107         return components[offset];
1108     }
1109 
1110     @Override
getUnnormalizedComponents(float[] normComponents, int normOffset, int[] components, int offset)1111     public int[] getUnnormalizedComponents(float[] normComponents, int normOffset,
1112             int[] components, int offset) {
1113 
1114         if (donotSupportUnnormalized) {
1115             // awt.213=This ComponentColorModel does not support the
1116             // unnormalized form
1117             throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
1118         }
1119 
1120         if (normComponents.length - normOffset < numComponents) {
1121             // awt.21B=The length of normComponents minus normOffset is less
1122             // than numComponents
1123             throw new IllegalArgumentException(Messages.getString("awt.21B")); //$NON-NLS-1$
1124         }
1125 
1126         return super.getUnnormalizedComponents(normComponents, normOffset, components, offset);
1127     }
1128 
1129     @Override
getDataElement(float normComponents[], int normOffset)1130     public int getDataElement(float normComponents[], int normOffset) {
1131         if (numComponents > 1) {
1132             // awt.212=There is more than one component in this ColorModel
1133             throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
1134         }
1135         if (signed) {
1136             // awt.210=The component value for this ColorModel is signed
1137             throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
1138         }
1139 
1140         Object pixel = getDataElements(normComponents, normOffset, null);
1141 
1142         switch (transferType) {
1143             case DataBuffer.TYPE_BYTE:
1144                 byte ba[] = (byte[])pixel;
1145                 return ba[0] & 0xff;
1146             case DataBuffer.TYPE_USHORT:
1147                 short sa[] = (short[])pixel;
1148                 return sa[0] & 0xffff;
1149             case DataBuffer.TYPE_INT:
1150                 int ia[] = (int[])pixel;
1151                 return ia[0];
1152             default:
1153                 // awt.211=Pixel values for this ColorModel are not conveniently
1154                 // representable as a single int
1155                 throw new IllegalArgumentException(Messages.getString("awt.211")); //$NON-NLS-1$
1156         }
1157     }
1158 
1159     @Override
getComponents(int pixel, int components[], int offset)1160     public int[] getComponents(int pixel, int components[], int offset) {
1161         if (numComponents > 1) {
1162             // awt.212=There is more than one component in this ColorModel
1163             throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
1164         }
1165         if (donotSupportUnnormalized) {
1166             // awt.213=This ComponentColorModel does not support the
1167             // unnormalized form
1168             throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
1169         }
1170 
1171         if (components == null) {
1172             components = new int[offset + 1];
1173         }
1174 
1175         components[offset] = pixel & maxValues[0];
1176         return components;
1177     }
1178 
1179     @Override
getRed(int pixel)1180     public int getRed(int pixel) {
1181         float rgb[] = toRGB(pixel);
1182         return (int)(rgb[0] * 255.0f + 0.5f);
1183     }
1184 
1185     @Override
getRGB(int pixel)1186     public int getRGB(int pixel) {
1187         return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) | (getGreen(pixel) << 8)
1188                 | getBlue(pixel);
1189     }
1190 
1191     @Override
getGreen(int pixel)1192     public int getGreen(int pixel) {
1193         float rgb[] = toRGB(pixel);
1194         return (int)(rgb[1] * 255.0f + 0.5f);
1195     }
1196 
1197     @Override
getBlue(int pixel)1198     public int getBlue(int pixel) {
1199         float rgb[] = toRGB(pixel);
1200         return (int)(rgb[2] * 255.0f + 0.5f);
1201     }
1202 
1203     @Override
getAlpha(int pixel)1204     public int getAlpha(int pixel) {
1205 
1206         // This method throw IllegalArgumentException according to
1207         // Java API Spacification
1208         if (signed) {
1209             // awt.210=The component value for this ColorModel is signed
1210             throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
1211         }
1212 
1213         if (numComponents > 1) {
1214             // awt.212=There is more than one component in this ColorModel
1215             throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
1216         }
1217 
1218         return 255;
1219     }
1220 
1221     /**
1222      * Initialization of Lookup tables.
1223      */
initLUTs()1224     private void initLUTs() {
1225         is_sRGB = cs.isCS_sRGB();
1226         is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
1227 
1228         if (hasAlpha && bits[numColorComponents] != 8 && integral) {
1229             alphaLUT = new byte[maxValues[numColorComponents] + 1];
1230             for (int i = 0; i <= maxValues[numColorComponents]; i++) {
1231                 alphaLUT[i] = (byte)(scaleFactors[numColorComponents] * i + 0.5f);
1232             }
1233         }
1234 
1235         if (is_LINEAR_RGB) {
1236             if (maxBitLength > 8) {
1237                 LINEAR_RGB_Length = 16;
1238                 from_LINEAR_RGB_LUT = LUTColorConverter.getFrom16lRGBtosRGB_LUT();
1239                 to_LINEAR_16RGB_LUT = LUTColorConverter.getFromsRGBto16lRGB_LUT();
1240             } else {
1241                 LINEAR_RGB_Length = 8;
1242                 from_LINEAR_RGB_LUT = LUTColorConverter.getFrom8lRGBtosRGB_LUT();
1243                 to_LINEAR_8RGB_LUT = LUTColorConverter.getFromsRGBto8lRGB_LUT();
1244             }
1245             fFactor = ((1 << LINEAR_RGB_Length) - 1);
1246         } else {
1247             fFactor = 255.0f;
1248         }
1249 
1250         if (!isAlphaPremultiplied && integral) {
1251             colorLUTs = new byte[3][];
1252 
1253             if (is_sRGB) {
1254                 for (int i = 0; i < numColorComponents; i++) {
1255                     if (bits[i] != 8) {
1256                         for (int j = 0; j < i; j++) {
1257                             if (bits[i] == bits[j]) {
1258                                 colorLUTs[i] = colorLUTs[j];
1259                                 break;
1260                             }
1261                         }
1262                         colorLUTs[i] = new byte[maxValues[i] + 1];
1263                         for (int j = 0; j <= maxValues[0]; j++) {
1264                             colorLUTs[i][j] = (byte)(scaleFactors[i] * j + 0.5f);
1265                         }
1266                     }
1267                 }
1268             }
1269 
1270             if (is_LINEAR_RGB) {
1271 
1272                 for (int i = 0; i < numColorComponents; i++) {
1273                     if (bits[i] != LINEAR_RGB_Length) {
1274                         for (int j = 0; j < i; j++) {
1275                             if (bits[i] == bits[j]) {
1276                                 colorLUTs[i] = colorLUTs[j];
1277                                 break;
1278                             }
1279                         }
1280                         colorLUTs[i] = new byte[maxValues[i] + 1];
1281                         for (int j = 0; j <= maxValues[0]; j++) {
1282                             int idx;
1283                             if (LINEAR_RGB_Length == 8) {
1284                                 idx = (int)(scaleFactors[i] * j + 0.5f);
1285                             } else {
1286                                 idx = (int)(scaleFactors[i] * j * 257.0f + 0.5f);
1287                             }
1288                             colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
1289                         }
1290                     }
1291                 }
1292             }
1293 
1294         }
1295     }
1296 
1297     /**
1298      * To rgb.
1299      *
1300      * @param pixel
1301      *            the integer representation of the pixel.
1302      * @return the array of normalized sRGB components.
1303      */
toRGB(int pixel)1304     private float[] toRGB(int pixel) {
1305 
1306         // This method throw IllegalArgumentException according to
1307         // Java API Spacification
1308         if (signed) {
1309             // awt.210=The component value for this ColorModel is signed
1310             throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
1311         }
1312 
1313         if (numComponents > 1) {
1314             // awt.212=There is more than one component in this ColorModel
1315             throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
1316         }
1317 
1318         Object obj = null;
1319 
1320         switch (transferType) {
1321             case DataBuffer.TYPE_BYTE:
1322                 byte ba[] = new byte[1];
1323                 ba[0] = (byte)pixel;
1324                 obj = ba;
1325                 break;
1326 
1327             case DataBuffer.TYPE_USHORT:
1328                 short sa[] = new short[1];
1329                 sa[0] = (short)pixel;
1330                 obj = sa;
1331                 break;
1332 
1333             case DataBuffer.TYPE_INT:
1334                 int ia[] = new int[1];
1335                 ia[0] = pixel;
1336                 obj = ia;
1337                 break;
1338 
1339         }
1340 
1341         return cs.toRGB(getNormalizedComponents(obj, null, 0));
1342     }
1343 
1344     /**
1345      * Gets the RGB component.
1346      *
1347      * @param pixel
1348      *            the pixel.
1349      * @param idx
1350      *            the index of component.
1351      * @return the RGB value from 0 to 255 pixel's component.
1352      */
getRGBComponent(Object pixel, int idx)1353     private int getRGBComponent(Object pixel, int idx) {
1354         if (is_sRGB) {
1355             int comp = getDefComponent(pixel, idx);
1356             if (calcValue || bits[idx] == 8) {
1357                 return comp;
1358             }
1359             return colorLUTs[idx][comp] & 0xff;
1360         } else if (is_LINEAR_RGB) {
1361             int comp = getDefComponent(pixel, idx);
1362             if (calcValue || bits[idx] == LINEAR_RGB_Length) {
1363                 return from_LINEAR_RGB_LUT[comp] & 0xff;
1364             }
1365             return colorLUTs[idx][comp] & 0xff;
1366         }
1367 
1368         float normComp[] = getNormalizedComponents(pixel, null, 0);
1369         float rgbComp[] = cs.toRGB(normComp);
1370         return (int)(rgbComp[idx] * 255.0f + 0.5f);
1371     }
1372 
1373     /**
1374      * Gets the def component.
1375      *
1376      * @param pixel
1377      *            the pixel.
1378      * @param idx
1379      *            the index of component.
1380      * @return the tentative value of the pixel component.
1381      */
getDefComponent(Object pixel, int idx)1382     private int getDefComponent(Object pixel, int idx) {
1383         int comp = 0;
1384         calcValue = false;
1385 
1386         switch (transferType) {
1387             case DataBuffer.TYPE_BYTE:
1388                 byte ba[] = (byte[])pixel;
1389                 comp = ba[idx] & 0xff;
1390                 if (needAlphaDivide) {
1391                     int alpha = ba[numColorComponents] & 0xff;
1392                     if (alpha == 0) {
1393                         comp = 0;
1394                     } else {
1395                         float normAlpha = scaleFactors[numColorComponents] * alpha;
1396                         comp = (int)(comp * fFactor / normAlpha + 0.5f);
1397                     }
1398                     calcValue = true;
1399                 }
1400                 return comp;
1401 
1402             case DataBuffer.TYPE_USHORT:
1403                 short usa[] = (short[])pixel;
1404                 comp = usa[idx] & 0xffff;
1405                 if (needAlphaDivide) {
1406                     int alpha = usa[numColorComponents] & 0xffff;
1407                     if (alpha == 0) {
1408                         comp = 0;
1409                     } else {
1410                         float normAlpha = scaleFactors[numColorComponents] * alpha;
1411                         comp = (int)(comp * fFactor / normAlpha + 0.5f);
1412                     }
1413                     calcValue = true;
1414                 }
1415                 return comp;
1416 
1417             case DataBuffer.TYPE_INT:
1418                 int ia[] = (int[])pixel;
1419                 comp = ia[idx];
1420                 if (needAlphaDivide) {
1421                     int alpha = ia[numColorComponents];
1422                     if (alpha == 0) {
1423                         comp = 0;
1424                     } else {
1425                         float normAlpha = scaleFactors[numColorComponents] * alpha;
1426                         comp = (int)(comp * fFactor / normAlpha + 0.5f);
1427                     }
1428                     calcValue = true;
1429                 }
1430                 return comp;
1431 
1432             case DataBuffer.TYPE_SHORT:
1433                 short sa[] = (short[])pixel;
1434                 comp = sa[idx];
1435                 if (needAlphaDivide) {
1436                     int alpha = sa[numColorComponents];
1437                     if (alpha == 0) {
1438                         comp = 0;
1439                     } else {
1440                         float normAlpha = scaleFactors[numColorComponents] * alpha;
1441                         comp = (int)(comp * fFactor / normAlpha + 0.5f);
1442                     }
1443                     calcValue = true;
1444                 }
1445                 return comp;
1446 
1447             case DataBuffer.TYPE_FLOAT:
1448                 float fa[] = (float[])pixel;
1449                 if (needAlphaDivide) {
1450                     float alpha = fa[numColorComponents];
1451                     if (fa[numColorComponents] == 0.0f) {
1452                         comp = 0;
1453                     } else {
1454                         comp = (int)(fa[idx] * fFactor / alpha + 0.5f);
1455                     }
1456                 } else {
1457                     comp = (int)(fa[idx] * fFactor + 0.5f);
1458                 }
1459                 calcValue = true;
1460                 return comp;
1461 
1462             case DataBuffer.TYPE_DOUBLE:
1463                 double da[] = (double[])pixel;
1464                 if (needAlphaDivide) {
1465                     if (da[numColorComponents] == 0.0) {
1466                         comp = 0;
1467                     } else {
1468                         comp = (int)(da[idx] * fFactor / da[numColorComponents] + 0.5);
1469                     }
1470                 } else {
1471                     comp = (int)(da[idx] * fFactor + 0.5);
1472                 }
1473                 calcValue = true;
1474                 return comp;
1475 
1476             default:
1477                 // awt.214=This Color Model doesn't support this transferType
1478                 throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
1479         }
1480     }
1481 
1482 }
1483