Frames | No Frames |
1: /* ICC_ProfileRGB.java -- the ICC profile for a RGB colorspace 2: Copyright (C) 2002, 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.awt.color; 40: 41: /** 42: * ICC_ProfileRGB - a special case of ICC_Profiles. 43: * 44: * The ICC_Profile.getInstance() method will return an instance of the 45: * ICC_ProfileRGB subclass when all the following conditions are met: 46: * The device color space of the profile is TYPE_RGB. 47: * The profile contains red, green and blue ColorantTags. 48: * The profile contains red, green and blue TRCTags. 49: * The profile contains a mediaWhitePointTag included. 50: * 51: * As per the ICC specification, the color space conversion can then 52: * be done through the following method: 53: * linearR = redTRC[deviceR] 54: * linearG = greenTRC[deviceG] 55: * linearB = blueTRC[deviceB] 56: * TRC curves are either a single gamma value, or a 1-dimensional lookup table. 57: * 58: * Followed by the matrix transform: 59: * PCS = M*linear 60: * 61: * Where PCS is the vector of profile color space (must be XYZ) coordinates, 62: * linear is the vector of linear RGB coordinates, and the matrix M is 63: * constructed from the ColorantTags, where the columns are red, green and 64: * blue respectively, and the rows are X, Y and Z. 65: * 66: * Note that if the profile contains a CLUT for the color space conversion, 67: * it should be used instead, and the TRC information ignored. 68: * 69: * @author Sven de Marothy 70: * @since 1.2 71: */ 72: public class ICC_ProfileRGB extends ICC_Profile 73: { 74: /** 75: * Compatible with JDK 1.2+. 76: */ 77: private static final long serialVersionUID = 8505067385152579334L; 78: 79: public static final int REDCOMPONENT = 0; 80: 81: public static final int GREENCOMPONENT = 1; 82: 83: public static final int BLUECOMPONENT = 2; 84: 85: private transient float[][] matrix; 86: 87: private transient float[] gamma; 88: 89: private transient float[] whitePoint; 90: 91: 92: /** 93: * Package-private constructor used by ICC_ColorSpace for creating an 94: * ICC_ProfileRGB from a predefined ColorSpace (CS_LINEAR_RGB and CS_sRGB) 95: */ 96: ICC_ProfileRGB(int cspace) 97: { 98: super(cspace); 99: matrix = createMatrix(); 100: whitePoint = getXYZData(icSigMediaWhitePointTag); 101: } 102: 103: /** 104: * Package-private constructor used by ICC_ColorSpace for creating an 105: * ICC_ProfileRGB from profile data. 106: */ 107: ICC_ProfileRGB(byte[] data) 108: { 109: super(data); 110: matrix = createMatrix(); 111: whitePoint = getXYZData(icSigMediaWhitePointTag); 112: } 113: 114: /** 115: * Returns the media white point of the profile. 116: */ 117: public float[] getMediaWhitePoint() 118: { 119: float[] wp = new float[3]; 120: wp[0] = whitePoint[0]; 121: wp[1] = whitePoint[1]; 122: wp[2] = whitePoint[2]; 123: return wp; 124: } 125: 126: /** 127: * Returns the colorant matrix of the conversion. 128: */ 129: public float[][] getMatrix() 130: { 131: float[][] mat = new float[3][3]; 132: for (int i = 0; i < 3; i++) 133: for (int j = 0; j < 3; j++) 134: mat[i][j] = matrix[i][j]; 135: return mat; 136: } 137: 138: /** 139: * Returns the gamma value of a component 140: * @throws ProfileDataException if the TRC is described by a lookup 141: * table and not a gamma value. 142: */ 143: public float getGamma(int component) 144: { 145: short[] data; 146: switch (component) 147: { 148: case REDCOMPONENT: 149: data = getCurve(icSigRedTRCTag); 150: break; 151: case GREENCOMPONENT: 152: data = getCurve(icSigGreenTRCTag); 153: break; 154: case BLUECOMPONENT: 155: data = getCurve(icSigBlueTRCTag); 156: break; 157: default: 158: throw new IllegalArgumentException("Not a valid component"); 159: } 160: if (data == null) 161: throw new IllegalArgumentException("Error reading TRC"); 162: 163: if (data.length != 1) 164: throw new ProfileDataException("Not a single-gamma TRC"); 165: 166: // convert the unsigned 7.8 fixed-point gamma to a float. 167: float gamma = (float) (((int) data[0] & 0xFF00) >> 8); 168: double fraction = ((int) data[0] & 0x00FF) / 256.0; 169: gamma += (float) fraction; 170: return gamma; 171: } 172: 173: /** 174: * Returns the TRC lookup table for a component 175: * @throws ProfileDataException if the TRC is described by a gamma 176: * value and not a lookup table. 177: */ 178: public short[] getTRC(int component) 179: { 180: short[] data; 181: switch (component) 182: { 183: case REDCOMPONENT: 184: data = getCurve(icSigRedTRCTag); 185: break; 186: case GREENCOMPONENT: 187: data = getCurve(icSigGreenTRCTag); 188: break; 189: case BLUECOMPONENT: 190: data = getCurve(icSigBlueTRCTag); 191: break; 192: default: 193: throw new IllegalArgumentException("Not a valid component"); 194: } 195: if (data == null) 196: throw new IllegalArgumentException("Error reading TRC"); 197: 198: if (data.length <= 1) 199: throw new ProfileDataException("Gamma value, not a TRC table."); 200: 201: return data; 202: } 203: 204: /** 205: * Creates the colorspace conversion matrix from the RGB tristimulus 206: * values. 207: */ 208: private float[][] createMatrix() throws IllegalArgumentException 209: { 210: float[][] mat = new float[3][3]; 211: float[] r; 212: float[] g; 213: float[] b; 214: r = getXYZData(icSigRedColorantTag); 215: g = getXYZData(icSigGreenColorantTag); 216: b = getXYZData(icSigBlueColorantTag); 217: if (r == null || g == null || b == null) 218: throw new IllegalArgumentException("Error reading colorant tags!"); 219: for (int i = 0; i < 3; i++) 220: { 221: mat[i][0] = r[i]; 222: mat[i][1] = g[i]; 223: mat[i][2] = b[i]; 224: } 225: return mat; 226: } 227: } // class ICC_ProfileRGB