1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /*
27 **********************************************************************
28 **********************************************************************
29 **********************************************************************
30 *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
31 *** As an unpublished work pursuant to Title 17 of the United ***
32 *** States Code. All rights reserved. ***
33 **********************************************************************
34 **********************************************************************
35 **********************************************************************/
36
37 package java.awt.color;
38
39 import sun.java2d.cmm.Profile;
40 import sun.java2d.cmm.ProfileDeferralInfo;
41
42 /**
43 *
44 * The ICC_ProfileRGB class is a subclass of the ICC_Profile class
45 * that represents profiles which meet the following criteria:
46 * <ul>
47 * <li>The profile's color space type is RGB.</li>
48 * <li>The profile includes the {@code redColorantTag},
49 * {@code greenColorantTag}, {@code blueColorantTag},
50 * {@code redTRCTag}, {@code greenTRCTag},
51 * {@code blueTRCTag}, and {@code mediaWhitePointTag} tags.</li>
52 * </ul>
53 * The {@code ICC_Profile getInstance} method will
54 * return an {@code ICC_ProfileRGB} object when these conditions are met.
55 * Three-component, matrix-based input profiles and RGB display profiles are
56 * examples of this type of profile.
57 * <p>
58 * This profile class provides color transform matrices and lookup tables
59 * that Java or native methods can use directly to
60 * optimize color conversion in some cases.
61 * <p>
62 * To transform from a device profile color space to the CIEXYZ Profile
63 * Connection Space, each device color component is first linearized by
64 * a lookup through the corresponding tone reproduction curve (TRC).
65 * The resulting linear RGB components are converted to the CIEXYZ PCS
66 * using a a 3x3 matrix constructed from the RGB colorants.
67 * <pre>
68 *
69 * linearR = redTRC[deviceR]
70 *
71 * linearG = greenTRC[deviceG]
72 *
73 * linearB = blueTRC[deviceB]
74 *
75 * _ _ _ _ _ _
76 * [ PCSX ] [ redColorantX greenColorantX blueColorantX ] [ linearR ]
77 * [ ] [ ] [ ]
78 * [ PCSY ] = [ redColorantY greenColorantY blueColorantY ] [ linearG ]
79 * [ ] [ ] [ ]
80 * [_ PCSZ _] [_ redColorantZ greenColorantZ blueColorantZ _] [_ linearB _]
81 *
82 * </pre>
83 * The inverse transform is performed by converting PCS XYZ components to linear
84 * RGB components through the inverse of the above 3x3 matrix, and then converting
85 * linear RGB to device RGB through inverses of the TRCs.
86 */
87
88
89
90 public class ICC_ProfileRGB
91 extends ICC_Profile {
92
93 static final long serialVersionUID = 8505067385152579334L;
94
95 /**
96 * Used to get a gamma value or TRC for the red component.
97 */
98 public static final int REDCOMPONENT = 0;
99
100 /**
101 * Used to get a gamma value or TRC for the green component.
102 */
103 public static final int GREENCOMPONENT = 1;
104
105 /**
106 * Used to get a gamma value or TRC for the blue component.
107 */
108 public static final int BLUECOMPONENT = 2;
109
110
111 /**
112 * Constructs an new {@code ICC_ProfileRGB} from a CMM ID.
113 *
114 * @param p The CMM ID for the profile.
115 *
116 */
117 ICC_ProfileRGB(Profile p) {
118 super(p);
119 }
120
121 /**
122 * Constructs a new {@code ICC_ProfileRGB} from a
123 * ProfileDeferralInfo object.
124 *
125 * @param pdi
126 */
127 ICC_ProfileRGB(ProfileDeferralInfo pdi) {
128 super(pdi);
129 }
130
131
132 /**
133 * Returns an array that contains the components of the profile's
134 * {@code mediaWhitePointTag}.
135 *
136 * @return A 3-element {@code float} array containing the x, y,
137 * and z components of the profile's {@code mediaWhitePointTag}.
138 */
139 public float[] getMediaWhitePoint() {
140 return super.getMediaWhitePoint();
141 }
142
143
144 /**
145 * Returns a 3x3 {@code float} matrix constructed from the
146 * X, Y, and Z components of the profile's {@code redColorantTag},
147 * {@code greenColorantTag}, and {@code blueColorantTag}.
148 * <p>
149 * This matrix can be used for color transforms in the forward
150 * direction of the profile--from the profile color space
151 * to the CIEXYZ PCS.
152 *
153 * @return A 3x3 {@code float} array that contains the x, y, and z
154 * components of the profile's {@code redColorantTag},
155 * {@code greenColorantTag}, and {@code blueColorantTag}.
156 */
157 public float[][] getMatrix() {
158 float[][] theMatrix = new float[3][3];
159 float[] tmpMatrix;
160
161 tmpMatrix = getXYZTag(ICC_Profile.icSigRedColorantTag);
162 theMatrix[0][0] = tmpMatrix[0];
163 theMatrix[1][0] = tmpMatrix[1];
164 theMatrix[2][0] = tmpMatrix[2];
165 tmpMatrix = getXYZTag(ICC_Profile.icSigGreenColorantTag);
166 theMatrix[0][1] = tmpMatrix[0];
167 theMatrix[1][1] = tmpMatrix[1];
168 theMatrix[2][1] = tmpMatrix[2];
169 tmpMatrix = getXYZTag(ICC_Profile.icSigBlueColorantTag);
170 theMatrix[0][2] = tmpMatrix[0];
171 theMatrix[1][2] = tmpMatrix[1];
172 theMatrix[2][2] = tmpMatrix[2];
173 return theMatrix;
174 }
175
176 /**
177 * Returns a gamma value representing the tone reproduction curve
178 * (TRC) for a particular component. The component parameter
179 * must be one of REDCOMPONENT, GREENCOMPONENT, or BLUECOMPONENT.
180 * <p>
181 * If the profile
182 * represents the TRC for the corresponding component
183 * as a table rather than a single gamma value, an
184 * exception is thrown. In this case the actual table
185 * can be obtained through the {@link #getTRC(int)} method.
186 * When using a gamma value,
187 * the linear component (R, G, or B) is computed as follows:
188 * <pre>
189 *
190 * gamma
191 * linearComponent = deviceComponent
192 *
193 *</pre>
194 * @param component The {@code ICC_ProfileRGB} constant that
195 * represents the component whose TRC you want to retrieve
196 * @return the gamma value as a float.
197 * @exception ProfileDataException if the profile does not specify
198 * the corresponding TRC as a single gamma value.
199 */
200 public float getGamma(int component) {
201 float theGamma;
202 int theSignature;
203
204 switch (component) {
205 case REDCOMPONENT:
206 theSignature = ICC_Profile.icSigRedTRCTag;
207 break;
208
209 case GREENCOMPONENT:
210 theSignature = ICC_Profile.icSigGreenTRCTag;
211 break;
212
213 case BLUECOMPONENT:
214 theSignature = ICC_Profile.icSigBlueTRCTag;
215 break;
216
217 default:
218 throw new IllegalArgumentException("Must be Red, Green, or Blue");
219 }
220
221 theGamma = super.getGamma(theSignature);
222
223 return theGamma;
224 }
225
226 /**
227 * Returns the TRC for a particular component as an array.
228 * Component must be {@code REDCOMPONENT},
229 * {@code GREENCOMPONENT}, or {@code BLUECOMPONENT}.
230 * Otherwise the returned array
231 * represents a lookup table where the input component value
232 * is conceptually in the range [0.0, 1.0]. Value 0.0 maps
233 * to array index 0 and value 1.0 maps to array index length-1.
234 * Interpolation might be used to generate output values for
235 * input values that do not map exactly to an index in the
236 * array. Output values also map linearly to the range [0.0, 1.0].
237 * Value 0.0 is represented by an array value of 0x0000 and
238 * value 1.0 by 0xFFFF. In other words, the values are really unsigned
239 * {@code short} values even though they are returned in a
240 * {@code short} array.
241 *
242 * If the profile has specified the corresponding TRC
243 * as linear (gamma = 1.0) or as a simple gamma value, this method
244 * throws an exception. In this case, the {@link #getGamma(int)}
245 * method should be used to get the gamma value.
246 *
247 * @param component The {@code ICC_ProfileRGB} constant that
248 * represents the component whose TRC you want to retrieve:
249 * {@code REDCOMPONENT}, {@code GREENCOMPONENT}, or
250 * {@code BLUECOMPONENT}.
251 *
252 * @return a short array representing the TRC.
253 * @exception ProfileDataException if the profile does not specify
254 * the corresponding TRC as a table.
255 */
256 public short[] getTRC(int component) {
257 short[] theTRC;
258 int theSignature;
259
260 switch (component) {
261 case REDCOMPONENT:
262 theSignature = ICC_Profile.icSigRedTRCTag;
263 break;
264
265 case GREENCOMPONENT:
266 theSignature = ICC_Profile.icSigGreenTRCTag;
267 break;
268
269 case BLUECOMPONENT:
270 theSignature = ICC_Profile.icSigBlueTRCTag;
271 break;
272
273 default:
274 throw new IllegalArgumentException("Must be Red, Green, or Blue");
275 }
276
277 theTRC = super.getTRC(theSignature);
278
279 return theTRC;
280 }
281
282 }
283