1 |
/* ICC_ColorSpace.java -- the canonical color space implementation |
/* ICC_ColorSpace.java -- the canonical color space implementation |
2 |
Copyright (C) 2000, 2002 Free Software Foundation |
Copyright (C) 2000, 2002, 2004 Free Software Foundation |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
|
|
|
|
GNU Classpath is free software; you can redistribute it and/or modify |
|
|
it under the terms of the GNU General Public License as published by |
|
|
the Free Software Foundation; either version 2, or (at your option) |
|
|
any later version. |
|
|
|
|
|
GNU Classpath is distributed in the hope that it will be useful, but |
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
|
General Public License for more details. |
|
|
|
|
|
You should have received a copy of the GNU General Public License |
|
|
along with GNU Classpath; see the file COPYING. If not, write to the |
|
|
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
|
|
02111-1307 USA. |
|
|
|
|
|
Linking this library statically or dynamically with other modules is |
|
|
making a combined work based on this library. Thus, the terms and |
|
|
conditions of the GNU General Public License cover the whole |
|
|
combination. |
|
|
|
|
|
As a special exception, the copyright holders of this library give you |
|
|
permission to link this library with independent modules to produce an |
|
|
executable, regardless of the license terms of these independent |
|
|
modules, and to copy and distribute the resulting executable under |
|
|
terms of your choice, provided that you also meet, for each linked |
|
|
independent module, the terms and conditions of the license of that |
|
|
module. An independent module is a module which is not derived from |
|
|
or based on this library. If you modify this library, you may extend |
|
|
this exception to your version of the library, but you are not |
|
|
obligated to do so. If you do not wish to do so, delete this |
|
|
exception statement from your version. */ |
|
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., 59 Temple Place, Suite 330, Boston, MA |
19 |
|
02111-1307 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 |
package java.awt.color; |
package java.awt.color; |
39 |
|
|
40 |
|
import gnu.java.awt.color.CieXyzConverter; |
41 |
|
import gnu.java.awt.color.ClutProfileConverter; |
42 |
|
import gnu.java.awt.color.ColorSpaceConverter; |
43 |
|
import gnu.java.awt.color.GrayProfileConverter; |
44 |
|
import gnu.java.awt.color.GrayScaleConverter; |
45 |
|
import gnu.java.awt.color.LinearRGBConverter; |
46 |
|
import gnu.java.awt.color.PyccConverter; |
47 |
|
import gnu.java.awt.color.RgbProfileConverter; |
48 |
|
import gnu.java.awt.color.SrgbConverter; |
49 |
|
import java.io.IOException; |
50 |
|
import java.io.ObjectInputStream; |
51 |
|
|
52 |
|
|
53 |
/** |
/** |
54 |
* NEEDS DOCUMENTATION |
* ICC_ColorSpace - an implementation of ColorSpace |
55 |
|
* |
56 |
|
* While an ICC_Profile class abstracts the data in an ICC profile file |
57 |
|
* an ICC_ColorSpace performs the color space conversions defined by |
58 |
|
* an ICC_Profile instance. |
59 |
|
* |
60 |
|
* Typically, an ICC_Profile will either be created using getInstance, |
61 |
|
* either from the built-in colorspaces, or from an ICC profile file. |
62 |
|
* Then a ICC_Colorspace will be used to perform transforms from the |
63 |
|
* device colorspace to and from the profile color space. |
64 |
* |
* |
65 |
|
* The PCS used by ColorSpace is CIE XYZ relative a D50 white point. |
66 |
|
* (Profiles using a CIE Lab PCS will have their input and output converted |
67 |
|
* to D50 CIE XYZ accordingly. |
68 |
|
* |
69 |
|
* Note that a valid profile may not contain transforms in both directions, |
70 |
|
* in which case the output may be undefined. |
71 |
|
* All built-in colorspaces have bidirectional transforms, but developers |
72 |
|
* using an ICC profile file may want to check the profile class using |
73 |
|
* the ICC_Profile.getProfileClass() method. Input class profiles are |
74 |
|
* guaranteed to have transforms to the PCS, output class profiles are |
75 |
|
* guaranteed to have transforms from the PCS to device space. |
76 |
|
* |
77 |
|
* @author Sven de Marothy |
78 |
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no> |
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no> |
79 |
* @since 1.2 |
* @since 1.2 |
80 |
*/ |
*/ |
116 |
private boolean needScaleInit; |
private boolean needScaleInit; |
117 |
|
|
118 |
/** |
/** |
119 |
|
* Tells us if the PCS is CIE LAB (must be CIEXYZ otherwise) |
120 |
|
*/ |
121 |
|
private transient int type; |
122 |
|
private transient int nComponents; |
123 |
|
private transient ColorSpaceConverter converter; |
124 |
|
|
125 |
|
/** |
126 |
* Constructs a new ICC_ColorSpace from an ICC_Profile object. |
* Constructs a new ICC_ColorSpace from an ICC_Profile object. |
127 |
* |
* |
128 |
* @exception IllegalArgumentException If profile is inappropriate for |
* @exception IllegalArgumentException If profile is inappropriate for |
130 |
*/ |
*/ |
131 |
public ICC_ColorSpace(ICC_Profile profile) |
public ICC_ColorSpace(ICC_Profile profile) |
132 |
{ |
{ |
133 |
super(CS_sRGB, profile.getNumComponents()); |
super(profile.getColorSpaceType(), profile.getNumComponents()); |
134 |
|
|
135 |
|
converter = getConverter(profile); |
136 |
thisProfile = profile; |
thisProfile = profile; |
137 |
|
nComponents = profile.getNumComponents(); |
138 |
|
type = profile.getColorSpaceType(); |
139 |
|
makeArrays(); |
140 |
} |
} |
141 |
|
|
142 |
|
/** |
143 |
|
* Return the profile |
144 |
|
*/ |
145 |
public ICC_Profile getProfile() |
public ICC_Profile getProfile() |
146 |
{ |
{ |
147 |
return thisProfile; |
return thisProfile; |
156 |
*/ |
*/ |
157 |
public float[] toRGB(float[] colorvalue) |
public float[] toRGB(float[] colorvalue) |
158 |
{ |
{ |
159 |
if (colorvalue.length < numComponents) |
return converter.toRGB(colorvalue); |
|
throw new IllegalArgumentException (); |
|
|
|
|
|
// FIXME: Always assumes sRGB: |
|
|
return colorvalue; |
|
160 |
} |
} |
161 |
|
|
162 |
/** |
/** |
168 |
*/ |
*/ |
169 |
public float[] fromRGB(float[] rgbvalue) |
public float[] fromRGB(float[] rgbvalue) |
170 |
{ |
{ |
171 |
if (rgbvalue.length < 3) |
return converter.fromRGB(rgbvalue); |
|
throw new IllegalArgumentException (); |
|
|
|
|
|
// FIXME: Always assumes sRGB: |
|
|
return rgbvalue; |
|
172 |
} |
} |
173 |
|
|
174 |
/** |
/** |
180 |
*/ |
*/ |
181 |
public float[] toCIEXYZ(float[] colorvalue) |
public float[] toCIEXYZ(float[] colorvalue) |
182 |
{ |
{ |
183 |
// FIXME: Not implemented |
return converter.toCIEXYZ(colorvalue); |
|
throw new UnsupportedOperationException(); |
|
184 |
} |
} |
185 |
|
|
186 |
/** |
/** |
192 |
*/ |
*/ |
193 |
public float[] fromCIEXYZ(float[] colorvalue) |
public float[] fromCIEXYZ(float[] colorvalue) |
194 |
{ |
{ |
195 |
// FIXME: Not implemented |
return converter.fromCIEXYZ(colorvalue); |
196 |
throw new UnsupportedOperationException(); |
} |
197 |
|
|
198 |
|
public boolean isCS_sRGB() |
199 |
|
{ |
200 |
|
return converter instanceof SrgbConverter; |
201 |
} |
} |
202 |
|
|
203 |
/** |
/** |
211 |
*/ |
*/ |
212 |
public float getMinValue(int idx) |
public float getMinValue(int idx) |
213 |
{ |
{ |
214 |
if (type == TYPE_Lab && (idx == 1 || idx == 2)) |
// FIXME: Not 100% certain of this. |
215 |
return -128; |
if (type == ColorSpace.TYPE_Lab && (idx == 1 || idx == 2)) |
216 |
if (idx < 0 || idx >= numComponents) |
return -128f; |
217 |
|
|
218 |
|
if (idx < 0 || idx >= nComponents) |
219 |
throw new IllegalArgumentException(); |
throw new IllegalArgumentException(); |
220 |
return 0; |
return 0; |
221 |
} |
} |
231 |
*/ |
*/ |
232 |
public float getMaxValue(int idx) |
public float getMaxValue(int idx) |
233 |
{ |
{ |
234 |
if (type == TYPE_XYZ && idx >= 0 && idx <= 2) |
if (type == ColorSpace.TYPE_XYZ && idx >= 0 && idx <= 2) |
235 |
return 1 + 32767 / 32768f; |
return 1 + 32767 / 32768f; |
236 |
else if (type == TYPE_Lab) |
else if (type == ColorSpace.TYPE_Lab) |
237 |
{ |
{ |
238 |
if (idx == 0) |
if (idx == 0) |
239 |
return 100; |
return 100; |
240 |
if (idx == 1 || idx == 2) |
if (idx == 1 || idx == 2) |
241 |
return 127; |
return 127; |
242 |
} |
} |
243 |
if (idx < 0 || idx >= numComponents) |
if (idx < 0 || idx >= nComponents) |
244 |
throw new IllegalArgumentException(); |
throw new IllegalArgumentException(); |
245 |
return 1; |
return 1; |
246 |
} |
} |
247 |
|
|
248 |
|
/** |
249 |
|
* Returns a colorspace converter suitable for a given profile |
250 |
|
*/ |
251 |
|
private ColorSpaceConverter getConverter(ICC_Profile profile) |
252 |
|
{ |
253 |
|
ColorSpaceConverter converter; |
254 |
|
switch (profile.isPredefined()) |
255 |
|
{ |
256 |
|
case CS_sRGB: |
257 |
|
converter = new SrgbConverter(); |
258 |
|
break; |
259 |
|
case CS_CIEXYZ: |
260 |
|
converter = new CieXyzConverter(); |
261 |
|
break; |
262 |
|
case CS_GRAY: |
263 |
|
converter = new GrayScaleConverter(); |
264 |
|
break; |
265 |
|
case CS_LINEAR_RGB: |
266 |
|
converter = new LinearRGBConverter(); |
267 |
|
break; |
268 |
|
case CS_PYCC: |
269 |
|
converter = new PyccConverter(); |
270 |
|
break; |
271 |
|
default: |
272 |
|
if (profile instanceof ICC_ProfileRGB) |
273 |
|
converter = new RgbProfileConverter((ICC_ProfileRGB) profile); |
274 |
|
else if (profile instanceof ICC_ProfileGray) |
275 |
|
converter = new GrayProfileConverter((ICC_ProfileGray) profile); |
276 |
|
else |
277 |
|
converter = new ClutProfileConverter(profile); |
278 |
|
break; |
279 |
|
} |
280 |
|
return converter; |
281 |
|
} |
282 |
|
|
283 |
|
/** |
284 |
|
* Serialization compatibility requires these variable to be set, |
285 |
|
* although we don't use them. Perhaps we should? |
286 |
|
*/ |
287 |
|
private void makeArrays() |
288 |
|
{ |
289 |
|
minVal = new float[nComponents]; |
290 |
|
maxVal = new float[nComponents]; |
291 |
|
|
292 |
|
invDiffMinMax = diffMinMax = null; |
293 |
|
for (int i = 0; i < nComponents; i++) |
294 |
|
{ |
295 |
|
minVal[i] = getMinValue(i); |
296 |
|
maxVal[i] = getMaxValue(i); |
297 |
|
} |
298 |
|
needScaleInit = true; |
299 |
|
} |
300 |
|
|
301 |
|
/** |
302 |
|
* Deserializes the object |
303 |
|
*/ |
304 |
|
private void readObject(ObjectInputStream s) |
305 |
|
throws IOException, ClassNotFoundException |
306 |
|
{ |
307 |
|
s.defaultReadObject(); |
308 |
|
// set up objects |
309 |
|
converter = getConverter(thisProfile); |
310 |
|
nComponents = thisProfile.getNumComponents(); |
311 |
|
type = thisProfile.getColorSpaceType(); |
312 |
|
} |
313 |
} // class ICC_ColorSpace |
} // class ICC_ColorSpace |