001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Igor V. Stolyarov
019: * @version $Revision$
020: */package java.awt.image;
021:
022: import java.awt.color.ColorSpace;
023: import java.awt.Transparency;
024: import java.util.Arrays;
025:
026: import org.apache.harmony.awt.gl.color.LUTColorConverter;
027: import org.apache.harmony.awt.internal.nls.Messages;
028:
029: public class DirectColorModel extends PackedColorModel {
030:
031: private byte from_LINEAR_RGB_LUT[]; // Lookup table for conversion from
032: // Linear RGB Color Space into sRGB
033:
034: private byte to_LINEAR_8RGB_LUT[]; // Lookup table for conversion from
035: // sRGB Color Space into Linear RGB
036: // 8 bit
037:
038: private short to_LINEAR_16RGB_LUT[]; // Lookup table for conversion from
039: // sRGB Color Space into Linear RGB
040: // 16 bit
041:
042: private byte alphaLUT[]; // Lookup table for scale alpha value
043:
044: private byte colorLUTs[][]; // Lookup tables for scale color values
045:
046: private boolean is_sRGB; // ColorModel has sRGB ColorSpace
047:
048: private boolean is_LINEAR_RGB; // Color Model has Linear RGB Color
049: // Space
050:
051: private int LINEAR_RGB_Length; // Linear RGB bit length
052:
053: private float fFactor; // Scale factor
054:
055: public DirectColorModel(ColorSpace space, int bits, int rmask,
056: int gmask, int bmask, int amask,
057: boolean isAlphaPremultiplied, int transferType) {
058:
059: super (space, bits, rmask, gmask, bmask, amask,
060: isAlphaPremultiplied, (amask == 0 ? Transparency.OPAQUE
061: : Transparency.TRANSLUCENT), transferType);
062:
063: initLUTs();
064: }
065:
066: public DirectColorModel(int bits, int rmask, int gmask, int bmask,
067: int amask) {
068:
069: super (ColorSpace.getInstance(ColorSpace.CS_sRGB), bits, rmask,
070: gmask, bmask, amask, false,
071: (amask == 0 ? Transparency.OPAQUE
072: : Transparency.TRANSLUCENT), ColorModel
073: .getTransferType(bits));
074:
075: initLUTs();
076: }
077:
078: public DirectColorModel(int bits, int rmask, int gmask, int bmask) {
079: this (bits, rmask, gmask, bmask, 0);
080: }
081:
082: @Override
083: public Object getDataElements(int components[], int offset,
084: Object obj) {
085: int pixel = 0;
086: for (int i = 0; i < numComponents; i++) {
087: pixel |= (components[offset + i] << offsets[i])
088: & componentMasks[i];
089: }
090:
091: switch (transferType) {
092: case DataBuffer.TYPE_BYTE:
093: byte ba[];
094: if (obj == null) {
095: ba = new byte[1];
096: } else {
097: ba = (byte[]) obj;
098: }
099: ba[0] = (byte) pixel;
100: obj = ba;
101: break;
102:
103: case DataBuffer.TYPE_USHORT:
104: short sa[];
105: if (obj == null) {
106: sa = new short[1];
107: } else {
108: sa = (short[]) obj;
109: }
110: sa[0] = (short) pixel;
111: obj = sa;
112: break;
113:
114: case DataBuffer.TYPE_INT:
115: int ia[];
116: if (obj == null) {
117: ia = new int[1];
118: } else {
119: ia = (int[]) obj;
120: }
121: ia[0] = pixel;
122: obj = ia;
123: break;
124:
125: default:
126: // awt.214=This Color Model doesn't support this transferType
127: throw new UnsupportedOperationException(Messages
128: .getString("awt.214")); //$NON-NLS-1$
129: }
130:
131: return obj;
132: }
133:
134: @Override
135: public Object getDataElements(int rgb, Object pixel) {
136: if (equals(ColorModel.getRGBdefault())) {
137: int ia[];
138: if (pixel == null) {
139: ia = new int[1];
140: } else {
141: ia = (int[]) pixel;
142: }
143: ia[0] = rgb;
144: return ia;
145: }
146:
147: int alpha = (rgb >> 24) & 0xff;
148: int red = (rgb >> 16) & 0xff;
149: int green = (rgb >> 8) & 0xff;
150: int blue = rgb & 0xff;
151:
152: float comp[] = new float[numColorComponents];
153: float normComp[] = null;
154:
155: if (is_sRGB || is_LINEAR_RGB) {
156: if (is_LINEAR_RGB) {
157: if (LINEAR_RGB_Length == 8) {
158: red = to_LINEAR_8RGB_LUT[red] & 0xff;
159: green = to_LINEAR_8RGB_LUT[green] & 0xff;
160: blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
161: } else {
162: red = to_LINEAR_16RGB_LUT[red] & 0xffff;
163: green = to_LINEAR_16RGB_LUT[green] & 0xffff;
164: blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
165: }
166: }
167: comp[0] = red / fFactor;
168: comp[1] = green / fFactor;
169: comp[2] = blue / fFactor;
170: if (!hasAlpha) {
171: normComp = comp;
172: } else {
173: float normAlpha = alpha / 255.0f;
174: normComp = new float[numComponents];
175: for (int i = 0; i < numColorComponents; i++) {
176: normComp[i] = comp[i];
177: }
178: normComp[numColorComponents] = normAlpha;
179: }
180: } else {
181: comp[0] = red / fFactor;
182: comp[1] = green / fFactor;
183: comp[2] = blue / fFactor;
184: float rgbComp[] = cs.fromRGB(comp);
185: if (!hasAlpha) {
186: normComp = rgbComp;
187: } else {
188: float normAlpha = alpha / 255.0f;
189: normComp = new float[numComponents];
190: for (int i = 0; i < numColorComponents; i++) {
191: normComp[i] = rgbComp[i];
192: }
193: normComp[numColorComponents] = normAlpha;
194: }
195: }
196:
197: int pxl = 0;
198: if (hasAlpha) {
199: float normAlpha = normComp[numColorComponents];
200: alpha = (int) (normAlpha * maxValues[numColorComponents] + 0.5f);
201: if (isAlphaPremultiplied) {
202: red = (int) (normComp[0] * normAlpha * maxValues[0] + 0.5f);
203: green = (int) (normComp[1] * normAlpha * maxValues[1] + 0.5f);
204: blue = (int) (normComp[2] * normAlpha * maxValues[2] + 0.5f);
205: } else {
206: red = (int) (normComp[0] * maxValues[0] + 0.5f);
207: green = (int) (normComp[1] * maxValues[1] + 0.5f);
208: blue = (int) (normComp[2] * maxValues[2] + 0.5f);
209: }
210: pxl = (alpha << offsets[3]) & componentMasks[3];
211: } else {
212: red = (int) (normComp[0] * maxValues[0] + 0.5f);
213: green = (int) (normComp[1] * maxValues[1] + 0.5f);
214: blue = (int) (normComp[2] * maxValues[2] + 0.5f);
215: }
216:
217: pxl |= ((red << offsets[0]) & componentMasks[0])
218: | ((green << offsets[1]) & componentMasks[1])
219: | ((blue << offsets[2]) & componentMasks[2]);
220:
221: switch (transferType) {
222: case DataBuffer.TYPE_BYTE:
223: byte ba[];
224: if (pixel == null) {
225: ba = new byte[1];
226: } else {
227: ba = (byte[]) pixel;
228: }
229: ba[0] = (byte) pxl;
230: return ba;
231:
232: case DataBuffer.TYPE_USHORT:
233: short sa[];
234: if (pixel == null) {
235: sa = new short[1];
236: } else {
237: sa = (short[]) pixel;
238: }
239: sa[0] = (short) pxl;
240: return sa;
241:
242: case DataBuffer.TYPE_INT:
243: int ia[];
244: if (pixel == null) {
245: ia = new int[1];
246: } else {
247: ia = (int[]) pixel;
248: }
249: ia[0] = pxl;
250: return ia;
251:
252: default:
253: // awt.214=This Color Model doesn't support this transferType
254: throw new UnsupportedOperationException(Messages
255: .getString("awt.214")); //$NON-NLS-1$
256: }
257: }
258:
259: @Override
260: public final ColorModel coerceData(WritableRaster raster,
261: boolean isAlphaPremultiplied) {
262:
263: if (!hasAlpha
264: || this .isAlphaPremultiplied == isAlphaPremultiplied) {
265: return this ;
266: }
267:
268: int minX = raster.getMinX();
269: int minY = raster.getMinY();
270: int w = raster.getWidth();
271: int h = raster.getHeight();
272:
273: int components[] = null;
274: int transparentComponents[] = new int[numComponents];
275:
276: float alphaFactor = maxValues[numColorComponents];
277:
278: if (isAlphaPremultiplied) {
279: switch (transferType) {
280: case DataBuffer.TYPE_BYTE:
281: case DataBuffer.TYPE_USHORT:
282: case DataBuffer.TYPE_INT:
283: for (int i = 0; i < h; i++, minY++) {
284: for (int j = 0, x = minX; j < w; j++, x++) {
285: components = raster.getPixel(x, minY,
286: components);
287: if (components[numColorComponents] == 0) {
288: raster.setPixel(x, minY,
289: transparentComponents);
290: } else {
291: float alpha = components[numColorComponents]
292: / alphaFactor;
293: for (int n = 0; n < numColorComponents; n++) {
294: components[n] = (int) (alpha
295: * components[n] + 0.5f);
296: }
297: raster.setPixel(x, minY, components);
298: }
299: }
300:
301: }
302: break;
303:
304: default:
305: // awt.214=This Color Model doesn't support this transferType
306: throw new UnsupportedOperationException(Messages
307: .getString("awt.214")); //$NON-NLS-1$
308: }
309: } else {
310: switch (transferType) {
311: case DataBuffer.TYPE_BYTE:
312: case DataBuffer.TYPE_USHORT:
313: case DataBuffer.TYPE_INT:
314: for (int i = 0; i < h; i++, minY++) {
315: for (int j = 0, x = minX; j < w; j++, x++) {
316: components = raster.getPixel(x, minY,
317: components);
318: if (components[numColorComponents] != 0) {
319: float alpha = alphaFactor
320: / components[numColorComponents];
321: for (int n = 0; n < numColorComponents; n++) {
322: components[n] = (int) (alpha
323: * components[n] + 0.5f);
324: }
325: raster.setPixel(x, minY, components);
326: }
327: }
328:
329: }
330: break;
331:
332: default:
333: // awt.214=This Color Model doesn't support this transferType
334: throw new UnsupportedOperationException(Messages
335: .getString("awt.214")); //$NON-NLS-1$
336: }
337:
338: }
339:
340: return new DirectColorModel(cs, pixel_bits, componentMasks[0],
341: componentMasks[1], componentMasks[2],
342: componentMasks[3], isAlphaPremultiplied, transferType);
343: }
344:
345: @Override
346: public String toString() {
347: // The output format based on 1.5 release behaviour.
348: // It could be reveled such way:
349: // BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
350: // ColorModel cm = bi.getColorModel();
351: // System.out.println(cm.toString());
352: String str = "DirectColorModel:" + " rmask = " + //$NON-NLS-1$ //$NON-NLS-2$
353: Integer.toHexString(componentMasks[0]) + " gmask = " + //$NON-NLS-1$
354: Integer.toHexString(componentMasks[1]) + " bmask = " + //$NON-NLS-1$
355: Integer.toHexString(componentMasks[2])
356: + " amask = " + //$NON-NLS-1$
357: (!hasAlpha ? "0" : Integer.toHexString(componentMasks[3])); //$NON-NLS-1$
358:
359: return str;
360: }
361:
362: @Override
363: public final int[] getComponents(Object pixel, int components[],
364: int offset) {
365:
366: if (components == null) {
367: components = new int[numComponents + offset];
368: }
369:
370: int intPixel = 0;
371:
372: switch (transferType) {
373: case DataBuffer.TYPE_BYTE:
374: byte ba[] = (byte[]) pixel;
375: intPixel = ba[0] & 0xff;
376: break;
377:
378: case DataBuffer.TYPE_USHORT:
379: short sa[] = (short[]) pixel;
380: intPixel = sa[0] & 0xffff;
381: break;
382:
383: case DataBuffer.TYPE_INT:
384: int ia[] = (int[]) pixel;
385: intPixel = ia[0];
386: break;
387:
388: default:
389: // awt.22D=This transferType ( {0} ) is not supported by this color model
390: throw new UnsupportedOperationException(Messages.getString(
391: "awt.22D", //$NON-NLS-1$
392: transferType));
393: }
394:
395: return getComponents(intPixel, components, offset);
396: }
397:
398: @Override
399: public int getRed(Object inData) {
400: int pixel = 0;
401: switch (transferType) {
402: case DataBuffer.TYPE_BYTE:
403: byte ba[] = (byte[]) inData;
404: pixel = ba[0] & 0xff;
405: break;
406:
407: case DataBuffer.TYPE_USHORT:
408: short sa[] = (short[]) inData;
409: pixel = sa[0] & 0xffff;
410: break;
411:
412: case DataBuffer.TYPE_INT:
413: int ia[] = (int[]) inData;
414: pixel = ia[0];
415: break;
416:
417: default:
418: // awt.214=This Color Model doesn't support this transferType
419: throw new UnsupportedOperationException(Messages
420: .getString("awt.214")); //$NON-NLS-1$
421: }
422: return getRed(pixel);
423: }
424:
425: @Override
426: public int getRGB(Object inData) {
427: int pixel = 0;
428: switch (transferType) {
429: case DataBuffer.TYPE_BYTE:
430: byte ba[] = (byte[]) inData;
431: pixel = ba[0] & 0xff;
432: break;
433:
434: case DataBuffer.TYPE_USHORT:
435: short sa[] = (short[]) inData;
436: pixel = sa[0] & 0xffff;
437: break;
438:
439: case DataBuffer.TYPE_INT:
440: int ia[] = (int[]) inData;
441: pixel = ia[0];
442: break;
443:
444: default:
445: // awt.214=This Color Model doesn't support this transferType
446: throw new UnsupportedOperationException(Messages
447: .getString("awt.214")); //$NON-NLS-1$
448: }
449: return getRGB(pixel);
450: }
451:
452: @Override
453: public int getGreen(Object inData) {
454: int pixel = 0;
455: switch (transferType) {
456: case DataBuffer.TYPE_BYTE:
457: byte ba[] = (byte[]) inData;
458: pixel = ba[0] & 0xff;
459: break;
460:
461: case DataBuffer.TYPE_USHORT:
462: short sa[] = (short[]) inData;
463: pixel = sa[0] & 0xffff;
464: break;
465:
466: case DataBuffer.TYPE_INT:
467: int ia[] = (int[]) inData;
468: pixel = ia[0];
469: break;
470:
471: default:
472: // awt.214=This Color Model doesn't support this transferType
473: throw new UnsupportedOperationException(Messages
474: .getString("awt.214")); //$NON-NLS-1$
475: }
476: return getGreen(pixel);
477: }
478:
479: @Override
480: public int getBlue(Object inData) {
481: int pixel = 0;
482: switch (transferType) {
483: case DataBuffer.TYPE_BYTE:
484: byte ba[] = (byte[]) inData;
485: pixel = ba[0] & 0xff;
486: break;
487:
488: case DataBuffer.TYPE_USHORT:
489: short sa[] = (short[]) inData;
490: pixel = sa[0] & 0xffff;
491: break;
492:
493: case DataBuffer.TYPE_INT:
494: int ia[] = (int[]) inData;
495: pixel = ia[0];
496: break;
497:
498: default:
499: // awt.214=This Color Model doesn't support this transferType
500: throw new UnsupportedOperationException(Messages
501: .getString("awt.214")); //$NON-NLS-1$
502: }
503: return getBlue(pixel);
504: }
505:
506: @Override
507: public int getAlpha(Object inData) {
508: int pixel = 0;
509: switch (transferType) {
510: case DataBuffer.TYPE_BYTE:
511: byte ba[] = (byte[]) inData;
512: pixel = ba[0] & 0xff;
513: break;
514:
515: case DataBuffer.TYPE_USHORT:
516: short sa[] = (short[]) inData;
517: pixel = sa[0] & 0xffff;
518: break;
519:
520: case DataBuffer.TYPE_INT:
521: int ia[] = (int[]) inData;
522: pixel = ia[0];
523: break;
524:
525: default:
526: // awt.214=This Color Model doesn't support this transferType
527: throw new UnsupportedOperationException(Messages
528: .getString("awt.214")); //$NON-NLS-1$
529: }
530: return getAlpha(pixel);
531: }
532:
533: @Override
534: public final WritableRaster createCompatibleWritableRaster(int w,
535: int h) {
536: if (w <= 0 || h <= 0) {
537: // awt.22E=w or h is less than or equal to zero
538: throw new IllegalArgumentException(Messages
539: .getString("awt.22E")); //$NON-NLS-1$
540: }
541:
542: int bandMasks[] = componentMasks.clone();
543:
544: if (pixel_bits > 16) {
545: return Raster.createPackedRaster(DataBuffer.TYPE_INT, w, h,
546: bandMasks, null);
547: } else if (pixel_bits > 8) {
548: return Raster.createPackedRaster(DataBuffer.TYPE_USHORT, w,
549: h, bandMasks, null);
550: } else {
551: return Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w,
552: h, bandMasks, null);
553: }
554: }
555:
556: @Override
557: public boolean isCompatibleRaster(Raster raster) {
558: SampleModel sm = raster.getSampleModel();
559: if (!(sm instanceof SinglePixelPackedSampleModel)) {
560: return false;
561: }
562:
563: SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
564:
565: if (sppsm.getNumBands() != numComponents) {
566: return false;
567: }
568: if (raster.getTransferType() != transferType) {
569: return false;
570: }
571:
572: int maskBands[] = sppsm.getBitMasks();
573: return Arrays.equals(maskBands, componentMasks);
574: }
575:
576: @Override
577: public int getDataElement(int components[], int offset) {
578: int pixel = 0;
579: for (int i = 0; i < numComponents; i++) {
580: pixel |= (components[offset + i] << offsets[i])
581: & componentMasks[i];
582: }
583: return pixel;
584: }
585:
586: @Override
587: public final int[] getComponents(int pixel, int components[],
588: int offset) {
589: if (components == null) {
590: components = new int[numComponents + offset];
591: }
592: for (int i = 0; i < numComponents; i++) {
593: components[offset + i] = (pixel & componentMasks[i]) >> offsets[i];
594: }
595: return components;
596: }
597:
598: @Override
599: public final int getRed(int pixel) {
600: if (is_sRGB) {
601: return getComponentFrom_sRGB(pixel, 0);
602: }
603: if (is_LINEAR_RGB) {
604: return getComponentFrom_LINEAR_RGB(pixel, 0);
605: }
606: return getComponentFrom_RGB(pixel, 0);
607: }
608:
609: @Override
610: public final int getRGB(int pixel) {
611: return (getAlpha(pixel) << 24) | (getRed(pixel) << 16)
612: | (getGreen(pixel) << 8) | getBlue(pixel);
613: }
614:
615: @Override
616: public final int getGreen(int pixel) {
617: if (is_sRGB) {
618: return getComponentFrom_sRGB(pixel, 1);
619: }
620: if (is_LINEAR_RGB) {
621: return getComponentFrom_LINEAR_RGB(pixel, 1);
622: }
623: return getComponentFrom_RGB(pixel, 1);
624: }
625:
626: @Override
627: public final int getBlue(int pixel) {
628: if (is_sRGB) {
629: return getComponentFrom_sRGB(pixel, 2);
630: }
631: if (is_LINEAR_RGB) {
632: return getComponentFrom_LINEAR_RGB(pixel, 2);
633: }
634: return getComponentFrom_RGB(pixel, 2);
635: }
636:
637: @Override
638: public final int getAlpha(int pixel) {
639: if (!hasAlpha) {
640: return 255;
641: }
642: int a = (pixel & componentMasks[3]) >>> offsets[3];
643: if (bits[3] == 8) {
644: return a;
645: }
646: return alphaLUT[a] & 0xff;
647: }
648:
649: public final int getRedMask() {
650: return componentMasks[0];
651: }
652:
653: public final int getGreenMask() {
654: return componentMasks[1];
655: }
656:
657: public final int getBlueMask() {
658: return componentMasks[2];
659: }
660:
661: public final int getAlphaMask() {
662: if (hasAlpha) {
663: return componentMasks[3];
664: }
665: return 0;
666: }
667:
668: /**
669: * Initialization of Lookup tables
670: */
671: private void initLUTs() {
672: is_sRGB = cs.isCS_sRGB();
673: is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
674:
675: if (is_LINEAR_RGB) {
676: if (maxBitLength > 8) {
677: LINEAR_RGB_Length = 16;
678: from_LINEAR_RGB_LUT = LUTColorConverter
679: .getFrom16lRGBtosRGB_LUT();
680: to_LINEAR_16RGB_LUT = LUTColorConverter
681: .getFromsRGBto16lRGB_LUT();
682: } else {
683: LINEAR_RGB_Length = 8;
684: from_LINEAR_RGB_LUT = LUTColorConverter
685: .getFrom8lRGBtosRGB_LUT();
686: to_LINEAR_8RGB_LUT = LUTColorConverter
687: .getFromsRGBto8lRGB_LUT();
688: }
689: fFactor = ((1 << LINEAR_RGB_Length) - 1);
690: } else {
691: fFactor = 255.0f;
692: }
693:
694: if (hasAlpha && bits[3] != 8) {
695: alphaLUT = new byte[maxValues[3] + 1];
696: for (int i = 0; i <= maxValues[3]; i++) {
697: alphaLUT[i] = (byte) (scales[3] * i + 0.5f);
698: }
699:
700: }
701:
702: if (!isAlphaPremultiplied) {
703: colorLUTs = new byte[3][];
704:
705: if (is_sRGB) {
706: for (int i = 0; i < numColorComponents; i++) {
707: if (bits[i] != 8) {
708: for (int j = 0; j < i; j++) {
709: if (bits[i] == bits[j]) {
710: colorLUTs[i] = colorLUTs[j];
711: break;
712: }
713: }
714: colorLUTs[i] = new byte[maxValues[i] + 1];
715: for (int j = 0; j <= maxValues[i]; j++) {
716: colorLUTs[i][j] = (byte) (scales[i] * j + 0.5f);
717: }
718: }
719: }
720: }
721:
722: if (is_LINEAR_RGB) {
723: for (int i = 0; i < numColorComponents; i++) {
724: if (bits[i] != LINEAR_RGB_Length) {
725: for (int j = 0; j < i; j++) {
726: if (bits[i] == bits[j]) {
727: colorLUTs[i] = colorLUTs[j];
728: break;
729: }
730: }
731: colorLUTs[i] = new byte[maxValues[i] + 1];
732: for (int j = 0; j <= maxValues[0]; j++) {
733: int idx;
734: if (LINEAR_RGB_Length == 8) {
735: idx = (int) (scales[i] * j + 0.5f);
736: } else {
737: idx = (int) (scales[i] * j * 257.0f + 0.5f);
738: }
739: colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
740: }
741: }
742: }
743: }
744:
745: }
746: }
747:
748: /**
749: * This method return RGB component value if Color Model has
750: * sRGB ColorSpace
751: * @param pixel - INT representation of pixel
752: * @param idx - index of pixel component
753: * @return - value of the pixel component scaled fro 0 to 255
754: */
755: private int getComponentFrom_sRGB(int pixel, int idx) {
756: int comp = (pixel & componentMasks[idx]) >> offsets[idx];
757: if (isAlphaPremultiplied) {
758: int alpha = (pixel & componentMasks[3]) >>> offsets[3];
759: comp = alpha == 0 ? 0 : (int) (scales[idx] * comp * 255.0f
760: / (scales[3] * alpha) + 0.5f);
761: } else if (bits[idx] != 8) {
762: comp = colorLUTs[idx][comp] & 0xff;
763: }
764: return comp;
765: }
766:
767: /**
768: * This method return RGB component value if Color Model has
769: * Linear RGB ColorSpace
770: * @param pixel - INT representation of pixel
771: * @param idx - index of pixel component
772: * @return - value of the pixel component scaled fro 0 to 255
773: */
774: private int getComponentFrom_LINEAR_RGB(int pixel, int idx) {
775: int comp = (pixel & componentMasks[idx]) >> offsets[idx];
776: if (isAlphaPremultiplied) {
777: float factor = ((1 << LINEAR_RGB_Length) - 1);
778: int alpha = (pixel & componentMasks[3]) >> offsets[3];
779: comp = alpha == 0 ? 0 : (int) (scales[idx] * comp * factor
780: / (scales[3] * alpha) + 0.5f);
781: } else if (bits[idx] != LINEAR_RGB_Length) {
782: comp = colorLUTs[idx][comp] & 0xff;
783: } else {
784: comp = from_LINEAR_RGB_LUT[comp] & 0xff;
785: }
786: return comp;
787: }
788:
789: /**
790: * This method return RGB component value if Color Model has
791: * arbitrary RGB ColorSapce
792: * @param pixel - INT representation of pixel
793: * @param idx - index of pixel component
794: * @return - value of the pixel component scaled fro 0 to 255
795: */
796: private int getComponentFrom_RGB(int pixel, int idx) {
797: int components[] = getComponents(pixel, null, 0);
798: float[] normComponents = getNormalizedComponents(components, 0,
799: null, 0);
800: float[] sRGBcomponents = cs.toRGB(normComponents);
801: return (int) (sRGBcomponents[idx] * 255.0f + 0.5f);
802: }
803:
804: }
|