1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44:
45:
59: public class RgbProfileConverter implements ColorSpaceConverter
60: {
61: private float[][] matrix;
62: private float[][] inv_matrix;
63: private ToneReproductionCurve rTRC;
64: private ToneReproductionCurve gTRC;
65: private ToneReproductionCurve bTRC;
66: private ColorLookUpTable toPCS;
67: private ColorLookUpTable fromPCS;
68:
69:
72: private static float[] D50 = { 0.96422f, 1.00f, 0.82521f };
73:
74:
77: public RgbProfileConverter(ICC_ProfileRGB profile)
78: {
79: toPCS = fromPCS = null;
80: matrix = profile.getMatrix();
81:
82:
83: try
84: {
85: rTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.REDCOMPONENT));
86: }
87: catch (ProfileDataException e)
88: {
89: rTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.REDCOMPONENT));
90: }
91: try
92: {
93: gTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.GREENCOMPONENT));
94: }
95: catch (ProfileDataException e)
96: {
97: gTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.GREENCOMPONENT));
98: }
99: try
100: {
101: bTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.BLUECOMPONENT));
102: }
103: catch (ProfileDataException e)
104: {
105: bTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.BLUECOMPONENT));
106: }
107:
108:
109:
110:
111:
112:
113: try
114: {
115: toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB0Tag);
116: }
117: catch (Exception e)
118: {
119: toPCS = null;
120: }
121:
122: try
123: {
124: fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA0Tag);
125: }
126: catch (Exception e)
127: {
128: fromPCS = null;
129: }
130:
131:
132: if(fromPCS == null)
133: inv_matrix = invertMatrix(matrix);
134: else
135: {
136:
137: inv_matrix = new float[3][3];
138: inv_matrix[0][0] = inv_matrix[1][1] = inv_matrix[2][2] = 1.0f;
139: }
140: }
141:
142: public float[] toCIEXYZ(float[] in)
143: {
144:
145: if (toPCS != null)
146: return toPCS.lookup(in);
147:
148: float[] temp = new float[3];
149: float[] out = new float[3];
150:
151:
152: temp[0] = rTRC.lookup(in[0]);
153: temp[1] = gTRC.lookup(in[1]);
154: temp[2] = bTRC.lookup(in[2]);
155:
156:
157: out[0] = matrix[0][0] * temp[0] + matrix[0][1] * temp[1]
158: + matrix[0][2] * temp[2];
159: out[1] = matrix[1][0] * temp[0] + matrix[1][1] * temp[1]
160: + matrix[1][2] * temp[2];
161: out[2] = matrix[2][0] * temp[0] + matrix[2][1] * temp[1]
162: + matrix[2][2] * temp[2];
163:
164: return out;
165: }
166:
167: public float[] toRGB(float[] in)
168: {
169: return SrgbConverter.XYZtoRGB(toCIEXYZ(in));
170: }
171:
172: public float[] fromCIEXYZ(float[] in)
173: {
174: if (fromPCS != null)
175: return fromPCS.lookup(in);
176:
177: float[] temp = new float[3];
178: float[] out = new float[3];
179:
180:
181: temp[0] = inv_matrix[0][0] * in[0] + inv_matrix[0][1] * in[1]
182: + inv_matrix[0][2] * in[2];
183: temp[1] = inv_matrix[1][0] * in[0] + inv_matrix[1][1] * in[1]
184: + inv_matrix[1][2] * in[2];
185: temp[2] = inv_matrix[2][0] * in[0] + inv_matrix[2][1] * in[1]
186: + inv_matrix[2][2] * in[2];
187:
188:
189: out[0] = rTRC.reverseLookup(temp[0]);
190: out[1] = gTRC.reverseLookup(temp[1]);
191: out[2] = bTRC.reverseLookup(temp[2]);
192:
193:
194:
195:
196:
197: return out;
198: }
199:
200: public float[] fromRGB(float[] in)
201: {
202: return fromCIEXYZ(SrgbConverter.RGBtoXYZ(in));
203: }
204:
205:
210: private float[][] invertMatrix(float[][] matrix)
211: {
212: float[][] out = new float[3][3];
213: double determinant = matrix[0][0] * (matrix[1][1] * matrix[2][2]
214: - matrix[2][1] * matrix[1][2])
215: - matrix[0][1] * (matrix[1][0] * matrix[2][2]
216: - matrix[2][0] * matrix[1][2])
217: + matrix[0][2] * (matrix[1][0] * matrix[2][1]
218: - matrix[2][0] * matrix[1][1]);
219:
220: if (determinant == 0.0)
221: throw new IllegalArgumentException("Can't invert conversion matrix.");
222: float invdet = (float) (1.0 / determinant);
223:
224: out[0][0] = invdet * (matrix[1][1] * matrix[2][2]
225: - matrix[1][2] * matrix[2][1]);
226: out[0][1] = invdet * (matrix[0][2] * matrix[2][1]
227: - matrix[0][1] * matrix[2][2]);
228: out[0][2] = invdet * (matrix[0][1] * matrix[1][2]
229: - matrix[0][2] * matrix[1][1]);
230: out[1][0] = invdet * (matrix[1][2] * matrix[2][0]
231: - matrix[1][0] * matrix[2][2]);
232: out[1][1] = invdet * (matrix[0][0] * matrix[2][2]
233: - matrix[0][2] * matrix[2][0]);
234: out[1][2] = invdet * (matrix[0][2] * matrix[1][0]
235: - matrix[0][0] * matrix[1][2]);
236: out[2][0] = invdet * (matrix[1][0] * matrix[2][1]
237: - matrix[1][1] * matrix[2][0]);
238: out[2][1] = invdet * (matrix[0][1] * matrix[2][0]
239: - matrix[0][0] * matrix[2][1]);
240: out[2][2] = invdet * (matrix[0][0] * matrix[1][1]
241: - matrix[0][1] * matrix[1][0]);
242: return out;
243: }
244: }