001: /*
002: * $RCSfile: TIFFYCbCrColorConverter.java,v $
003: *
004: *
005: * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * - Redistribution of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * - Redistribution in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * Neither the name of Sun Microsystems, Inc. or the names of
020: * contributors may be used to endorse or promote products derived
021: * from this software without specific prior written permission.
022: *
023: * This software is provided "AS IS," without a warranty of any
024: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
025: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
026: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
027: * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
028: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
029: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
030: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
031: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
032: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
033: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
034: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
035: * POSSIBILITY OF SUCH DAMAGES.
036: *
037: * You acknowledge that this software is not designed or intended for
038: * use in the design, construction, operation or maintenance of any
039: * nuclear facility.
040: *
041: * $Revision: 1.2 $
042: * $Date: 2006/04/11 22:10:37 $
043: * $State: Exp $
044: */
045: package com.sun.media.imageioimpl.plugins.tiff;
046:
047: import java.awt.color.ColorSpace;
048: import com.sun.media.imageio.plugins.tiff.BaselineTIFFTagSet;
049: import com.sun.media.imageio.plugins.tiff.TIFFColorConverter;
050: import com.sun.media.imageio.plugins.tiff.TIFFField;
051:
052: /**
053: */
054: public class TIFFYCbCrColorConverter extends TIFFColorConverter {
055:
056: private float LumaRed = 0.299f;
057: private float LumaGreen = 0.587f;
058: private float LumaBlue = 0.114f;
059:
060: private float referenceBlackY = 0.0f;
061: private float referenceWhiteY = 255.0f;
062:
063: private float referenceBlackCb = 128.0f;
064: private float referenceWhiteCb = 255.0f;
065:
066: private float referenceBlackCr = 128.0f;
067: private float referenceWhiteCr = 255.0f;
068:
069: private float codingRangeY = 255.0f;
070: private float codingRangeCbCr = 127.0f;
071:
072: public TIFFYCbCrColorConverter(TIFFImageMetadata metadata) {
073: TIFFImageMetadata tmetadata = (TIFFImageMetadata) metadata;
074:
075: TIFFField f = tmetadata
076: .getTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_COEFFICIENTS);
077: if (f != null && f.getCount() == 3) {
078: this .LumaRed = f.getAsFloat(0);
079: this .LumaGreen = f.getAsFloat(1);
080: this .LumaBlue = f.getAsFloat(2);
081: }
082:
083: f = tmetadata
084: .getTIFFField(BaselineTIFFTagSet.TAG_REFERENCE_BLACK_WHITE);
085: if (f != null && f.getCount() == 6) {
086: this .referenceBlackY = f.getAsFloat(0);
087: this .referenceWhiteY = f.getAsFloat(1);
088: this .referenceBlackCb = f.getAsFloat(2);
089: this .referenceWhiteCb = f.getAsFloat(3);
090: this .referenceBlackCr = f.getAsFloat(4);
091: this .referenceWhiteCr = f.getAsFloat(5);
092: }
093: }
094:
095: /*
096: The full range component value is converted from the code by:
097:
098: FullRangeValue = (code - ReferenceBlack) * CodingRange
099: / (ReferenceWhite - ReferenceBlack);
100:
101: The code is converted from the full-range component value by:
102:
103: code = (FullRangeValue * (ReferenceWhite - ReferenceBlack)
104: / CodingRange) + ReferenceBlack;
105:
106: */
107: public void fromRGB(float r, float g, float b, float[] result) {
108: // Convert RGB to full-range YCbCr.
109: float Y = (LumaRed * r + LumaGreen * g + LumaBlue * b);
110: float Cb = (b - Y) / (2 - 2 * LumaBlue);
111: float Cr = (r - Y) / (2 - 2 * LumaRed);
112:
113: // Convert full-range YCbCr to code.
114: result[0] = Y * (referenceWhiteY - referenceBlackY)
115: / codingRangeY + referenceBlackY;
116: result[1] = Cb * (referenceWhiteCb - referenceBlackCb)
117: / codingRangeCbCr + referenceBlackCb;
118: result[2] = Cr * (referenceWhiteCr - referenceBlackCr)
119: / codingRangeCbCr + referenceBlackCr;
120: }
121:
122: public void toRGB(float x0, float x1, float x2, float[] rgb) {
123: // Convert YCbCr code to full-range YCbCr.
124: float Y = (x0 - referenceBlackY) * codingRangeY
125: / (referenceWhiteY - referenceBlackY);
126: float Cb = (x1 - referenceBlackCb) * codingRangeCbCr
127: / (referenceWhiteCb - referenceBlackCb);
128: float Cr = (x2 - referenceBlackCr) * codingRangeCbCr
129: / (referenceWhiteCr - referenceBlackCr);
130:
131: // Convert YCbCr to RGB.
132: rgb[0] = Cr * (2 - 2 * LumaRed) + Y;
133: rgb[2] = Cb * (2 - 2 * LumaBlue) + Y;
134: rgb[1] = (Y - LumaBlue * rgb[2] - LumaRed * rgb[0]) / LumaGreen;
135: }
136: }
|