1 /*
2 * Portions Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 /**********************************************************************
27 **********************************************************************
28 **********************************************************************
29 *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
30 *** As an unpublished work pursuant to Title 17 of the United ***
31 *** States Code. All rights reserved. ***
32 **********************************************************************
33 **********************************************************************
34 **********************************************************************/
35
36 package java.awt.color;
37
38 import sun.java2d.cmm.PCMM;
39 import sun.java2d.cmm.CMSManager;
40
41
42 /**
43 * This abstract class is used to serve as a color space tag to identify the
44 * specific color space of a Color object or, via a ColorModel object,
45 * of an Image, a BufferedImage, or a GraphicsDevice. It contains
46 * methods that transform colors in a specific color space to/from sRGB
47 * and to/from a well-defined CIEXYZ color space.
48 * <p>
49 * For purposes of the methods in this class, colors are represented as
50 * arrays of color components represented as floats in a normalized range
51 * defined by each ColorSpace. For many ColorSpaces (e.g. sRGB), this
52 * range is 0.0 to 1.0. However, some ColorSpaces have components whose
53 * values have a different range. Methods are provided to inquire per
54 * component minimum and maximum normalized values.
55 * <p>
56 * Several variables are defined for purposes of referring to color
57 * space types (e.g. TYPE_RGB, TYPE_XYZ, etc.) and to refer to specific
58 * color spaces (e.g. CS_sRGB and CS_CIEXYZ).
59 * sRGB is a proposed standard RGB color space. For more information,
60 * see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
61 * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
62 * </A>.
63 * <p>
64 * The purpose of the methods to transform to/from the well-defined
65 * CIEXYZ color space is to support conversions between any two color
66 * spaces at a reasonably high degree of accuracy. It is expected that
67 * particular implementations of subclasses of ColorSpace (e.g.
68 * ICC_ColorSpace) will support high performance conversion based on
69 * underlying platform color management systems.
70 * <p>
71 * The CS_CIEXYZ space used by the toCIEXYZ/fromCIEXYZ methods can be
72 * described as follows:
73 <pre>
74
75 CIEXYZ
76 viewing illuminance: 200 lux
77 viewing white point: CIE D50
78 media white point: "that of a perfectly reflecting diffuser" -- D50
79 media black point: 0 lux or 0 Reflectance
80 flare: 1 percent
81 surround: 20percent of the media white point
82 media description: reflection print (i.e., RLAB, Hunt viewing media)
83 note: For developers creating an ICC profile for this conversion
84 space, the following is applicable. Use a simple Von Kries
85 white point adaptation folded into the 3X3 matrix parameters
86 and fold the flare and surround effects into the three
87 one-dimensional lookup tables (assuming one uses the minimal
88 model for monitors).
89
90 </pre>
91 *
92 * <p>
93 * @see ICC_ColorSpace
94 */
95
96
97
98 public abstract class ColorSpace implements java.io.Serializable {
99
100 static final long serialVersionUID = -409452704308689724L;
101
102 private int type;
103 private int numComponents;
104 private transient String [] compName = null;
105
106 // Cache of singletons for the predefined color spaces.
107 private static ColorSpace sRGBspace;
108 private static ColorSpace XYZspace;
109 private static ColorSpace PYCCspace;
110 private static ColorSpace GRAYspace;
111 private static ColorSpace LINEAR_RGBspace;
112
113 /**
114 * Any of the family of XYZ color spaces.
115 */
116 public static final int TYPE_XYZ = 0;
117
118 /**
119 * Any of the family of Lab color spaces.
120 */
121 public static final int TYPE_Lab = 1;
122
123 /**
124 * Any of the family of Luv color spaces.
125 */
126 public static final int TYPE_Luv = 2;
127
128 /**
129 * Any of the family of YCbCr color spaces.
130 */
131 public static final int TYPE_YCbCr = 3;
132
133 /**
134 * Any of the family of Yxy color spaces.
135 */
136 public static final int TYPE_Yxy = 4;
137
138 /**
139 * Any of the family of RGB color spaces.
140 */
141 public static final int TYPE_RGB = 5;
142
143 /**
144 * Any of the family of GRAY color spaces.
145 */
146 public static final int TYPE_GRAY = 6;
147
148 /**
149 * Any of the family of HSV color spaces.
150 */
151 public static final int TYPE_HSV = 7;
152
153 /**
154 * Any of the family of HLS color spaces.
155 */
156 public static final int TYPE_HLS = 8;
157
158 /**
159 * Any of the family of CMYK color spaces.
160 */
161 public static final int TYPE_CMYK = 9;
162
163 /**
164 * Any of the family of CMY color spaces.
165 */
166 public static final int TYPE_CMY = 11;
167
168 /**
169 * Generic 2 component color spaces.
170 */
171 public static final int TYPE_2CLR = 12;
172
173 /**
174 * Generic 3 component color spaces.
175 */
176 public static final int TYPE_3CLR = 13;
177
178 /**
179 * Generic 4 component color spaces.
180 */
181 public static final int TYPE_4CLR = 14;
182
183 /**
184 * Generic 5 component color spaces.
185 */
186 public static final int TYPE_5CLR = 15;
187
188 /**
189 * Generic 6 component color spaces.
190 */
191 public static final int TYPE_6CLR = 16;
192
193 /**
194 * Generic 7 component color spaces.
195 */
196 public static final int TYPE_7CLR = 17;
197
198 /**
199 * Generic 8 component color spaces.
200 */
201 public static final int TYPE_8CLR = 18;
202
203 /**
204 * Generic 9 component color spaces.
205 */
206 public static final int TYPE_9CLR = 19;
207
208 /**
209 * Generic 10 component color spaces.
210 */
211 public static final int TYPE_ACLR = 20;
212
213 /**
214 * Generic 11 component color spaces.
215 */
216 public static final int TYPE_BCLR = 21;
217
218 /**
219 * Generic 12 component color spaces.
220 */
221 public static final int TYPE_CCLR = 22;
222
223 /**
224 * Generic 13 component color spaces.
225 */
226 public static final int TYPE_DCLR = 23;
227
228 /**
229 * Generic 14 component color spaces.
230 */
231 public static final int TYPE_ECLR = 24;
232
233 /**
234 * Generic 15 component color spaces.
235 */
236 public static final int TYPE_FCLR = 25;
237
238 /**
239 * The sRGB color space defined at
240 * <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
241 * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
242 * </A>.
243 */
244 public static final int CS_sRGB = 1000;
245
246 /**
247 * A built-in linear RGB color space. This space is based on the
248 * same RGB primaries as CS_sRGB, but has a linear tone reproduction curve.
249 */
250 public static final int CS_LINEAR_RGB = 1004;
251
252 /**
253 * The CIEXYZ conversion color space defined above.
254 */
255 public static final int CS_CIEXYZ = 1001;
256
257 /**
258 * The Photo YCC conversion color space.
259 */
260 public static final int CS_PYCC = 1002;
261
262 /**
263 * The built-in linear gray scale color space.
264 */
265 public static final int CS_GRAY = 1003;
266
267
268 /**
269 * Constructs a ColorSpace object given a color space type
270 * and the number of components.
271 * @param type one of the <CODE>ColorSpace</CODE> type constants
272 * @param numcomponents the number of components in the color space
273 */
274 protected ColorSpace (int type, int numcomponents) {
275 this.type = type;
276 this.numComponents = numcomponents;
277 }
278
279
280 /**
281 * Returns a ColorSpace representing one of the specific
282 * predefined color spaces.
283 * @param colorspace a specific color space identified by one of
284 * the predefined class constants (e.g. CS_sRGB, CS_LINEAR_RGB,
285 * CS_CIEXYZ, CS_GRAY, or CS_PYCC)
286 * @return the requested <CODE>ColorSpace</CODE> object
287 */
288 // NOTE: This method may be called by privileged threads.
289 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
290 public static ColorSpace getInstance (int colorspace)
291 {
292 ColorSpace theColorSpace;
293
294 switch (colorspace) {
295 case CS_sRGB:
296 synchronized(ColorSpace.class) {
297 if (sRGBspace == null) {
298 ICC_Profile theProfile = ICC_Profile.getInstance (CS_sRGB);
299 sRGBspace = new ICC_ColorSpace (theProfile);
300 }
301
302 theColorSpace = sRGBspace;
303 }
304 break;
305
306 case CS_CIEXYZ:
307 synchronized(ColorSpace.class) {
308 if (XYZspace == null) {
309 ICC_Profile theProfile =
310 ICC_Profile.getInstance (CS_CIEXYZ);
311 XYZspace = new ICC_ColorSpace (theProfile);
312 }
313
314 theColorSpace = XYZspace;
315 }
316 break;
317
318 case CS_PYCC:
319 synchronized(ColorSpace.class) {
320 if (PYCCspace == null) {
321 ICC_Profile theProfile = ICC_Profile.getInstance (CS_PYCC);
322 PYCCspace = new ICC_ColorSpace (theProfile);
323 }
324
325 theColorSpace = PYCCspace;
326 }
327 break;
328
329
330 case CS_GRAY:
331 synchronized(ColorSpace.class) {
332 if (GRAYspace == null) {
333 ICC_Profile theProfile = ICC_Profile.getInstance (CS_GRAY);
334 GRAYspace = new ICC_ColorSpace (theProfile);
335 /* to allow access from java.awt.ColorModel */
336 CMSManager.GRAYspace = GRAYspace;
337 }
338
339 theColorSpace = GRAYspace;
340 }
341 break;
342
343
344 case CS_LINEAR_RGB:
345 synchronized(ColorSpace.class) {
346 if (LINEAR_RGBspace == null) {
347 ICC_Profile theProfile =
348 ICC_Profile.getInstance(CS_LINEAR_RGB);
349 LINEAR_RGBspace = new ICC_ColorSpace (theProfile);
350 /* to allow access from java.awt.ColorModel */
351 CMSManager.LINEAR_RGBspace = LINEAR_RGBspace;
352 }
353
354 theColorSpace = LINEAR_RGBspace;
355 }
356 break;
357
358
359 default:
360 throw new IllegalArgumentException ("Unknown color space");
361 }
362
363 return theColorSpace;
364 }
365
366
367 /**
368 * Returns true if the ColorSpace is CS_sRGB.
369 * @return <CODE>true</CODE> if this is a <CODE>CS_sRGB</CODE> color
370 * space, <code>false</code> if it is not
371 */
372 public boolean isCS_sRGB () {
373 /* REMIND - make sure we know sRGBspace exists already */
374 return (this == sRGBspace);
375 }
376
377 /**
378 * Transforms a color value assumed to be in this ColorSpace
379 * into a value in the default CS_sRGB color space.
380 * <p>
381 * This method transforms color values using algorithms designed
382 * to produce the best perceptual match between input and output
383 * colors. In order to do colorimetric conversion of color values,
384 * you should use the <code>toCIEXYZ</code>
385 * method of this color space to first convert from the input
386 * color space to the CS_CIEXYZ color space, and then use the
387 * <code>fromCIEXYZ</code> method of the CS_sRGB color space to
388 * convert from CS_CIEXYZ to the output color space.
389 * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
390 * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
391 * <p>
392 * @param colorvalue a float array with length of at least the number
393 * of components in this ColorSpace
394 * @return a float array of length 3
395 * @throws ArrayIndexOutOfBoundsException if array length is not
396 * at least the number of components in this ColorSpace
397 */
398 public abstract float[] toRGB(float[] colorvalue);
399
400
401 /**
402 * Transforms a color value assumed to be in the default CS_sRGB
403 * color space into this ColorSpace.
404 * <p>
405 * This method transforms color values using algorithms designed
406 * to produce the best perceptual match between input and output
407 * colors. In order to do colorimetric conversion of color values,
408 * you should use the <code>toCIEXYZ</code>
409 * method of the CS_sRGB color space to first convert from the input
410 * color space to the CS_CIEXYZ color space, and then use the
411 * <code>fromCIEXYZ</code> method of this color space to
412 * convert from CS_CIEXYZ to the output color space.
413 * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
414 * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
415 * <p>
416 * @param rgbvalue a float array with length of at least 3
417 * @return a float array with length equal to the number of
418 * components in this ColorSpace
419 * @throws ArrayIndexOutOfBoundsException if array length is not
420 * at least 3
421 */
422 public abstract float[] fromRGB(float[] rgbvalue);
423
424
425 /**
426 * Transforms a color value assumed to be in this ColorSpace
427 * into the CS_CIEXYZ conversion color space.
428 * <p>
429 * This method transforms color values using relative colorimetry,
430 * as defined by the International Color Consortium standard. This
431 * means that the XYZ values returned by this method are represented
432 * relative to the D50 white point of the CS_CIEXYZ color space.
433 * This representation is useful in a two-step color conversion
434 * process in which colors are transformed from an input color
435 * space to CS_CIEXYZ and then to an output color space. This
436 * representation is not the same as the XYZ values that would
437 * be measured from the given color value by a colorimeter.
438 * A further transformation is necessary to compute the XYZ values
439 * that would be measured using current CIE recommended practices.
440 * See the {@link ICC_ColorSpace#toCIEXYZ(float[]) toCIEXYZ} method of
441 * <code>ICC_ColorSpace</code> for further information.
442 * <p>
443 * @param colorvalue a float array with length of at least the number
444 * of components in this ColorSpace
445 * @return a float array of length 3
446 * @throws ArrayIndexOutOfBoundsException if array length is not
447 * at least the number of components in this ColorSpace.
448 */
449 public abstract float[] toCIEXYZ(float[] colorvalue);
450
451
452 /**
453 * Transforms a color value assumed to be in the CS_CIEXYZ conversion
454 * color space into this ColorSpace.
455 * <p>
456 * This method transforms color values using relative colorimetry,
457 * as defined by the International Color Consortium standard. This
458 * means that the XYZ argument values taken by this method are represented
459 * relative to the D50 white point of the CS_CIEXYZ color space.
460 * This representation is useful in a two-step color conversion
461 * process in which colors are transformed from an input color
462 * space to CS_CIEXYZ and then to an output color space. The color
463 * values returned by this method are not those that would produce
464 * the XYZ value passed to the method when measured by a colorimeter.
465 * If you have XYZ values corresponding to measurements made using
466 * current CIE recommended practices, they must be converted to D50
467 * relative values before being passed to this method.
468 * See the {@link ICC_ColorSpace#fromCIEXYZ(float[]) fromCIEXYZ} method of
469 * <code>ICC_ColorSpace</code> for further information.
470 * <p>
471 * @param colorvalue a float array with length of at least 3
472 * @return a float array with length equal to the number of
473 * components in this ColorSpace
474 * @throws ArrayIndexOutOfBoundsException if array length is not
475 * at least 3
476 */
477 public abstract float[] fromCIEXYZ(float[] colorvalue);
478
479 /**
480 * Returns the color space type of this ColorSpace (for example
481 * TYPE_RGB, TYPE_XYZ, ...). The type defines the
482 * number of components of the color space and the interpretation,
483 * e.g. TYPE_RGB identifies a color space with three components - red,
484 * green, and blue. It does not define the particular color
485 * characteristics of the space, e.g. the chromaticities of the
486 * primaries.
487 *
488 * @return the type constant that represents the type of this
489 * <CODE>ColorSpace</CODE>
490 */
491 public int getType() {
492 return type;
493 }
494
495 /**
496 * Returns the number of components of this ColorSpace.
497 * @return The number of components in this <CODE>ColorSpace</CODE>.
498 */
499 public int getNumComponents() {
500 return numComponents;
501 }
502
503 /**
504 * Returns the name of the component given the component index.
505 *
506 * @param idx the component index
507 * @return the name of the component at the specified index
508 * @throws IllegalArgumentException if <code>idx</code> is
509 * less than 0 or greater than numComponents - 1
510 */
511 public String getName (int idx) {
512 /* REMIND - handle common cases here */
513 if ((idx < 0) || (idx > numComponents - 1)) {
514 throw new IllegalArgumentException(
515 "Component index out of range: " + idx);
516 }
517
518 if (compName == null) {
519 switch (type) {
520 case ColorSpace.TYPE_XYZ:
521 compName = new String[] {"X", "Y", "Z"};
522 break;
523 case ColorSpace.TYPE_Lab:
524 compName = new String[] {"L", "a", "b"};
525 break;
526 case ColorSpace.TYPE_Luv:
527 compName = new String[] {"L", "u", "v"};
528 break;
529 case ColorSpace.TYPE_YCbCr:
530 compName = new String[] {"Y", "Cb", "Cr"};
531 break;
532 case ColorSpace.TYPE_Yxy:
533 compName = new String[] {"Y", "x", "y"};
534 break;
535 case ColorSpace.TYPE_RGB:
536 compName = new String[] {"Red", "Green", "Blue"};
537 break;
538 case ColorSpace.TYPE_GRAY:
539 compName = new String[] {"Gray"};
540 break;
541 case ColorSpace.TYPE_HSV:
542 compName = new String[] {"Hue", "Saturation", "Value"};
543 break;
544 case ColorSpace.TYPE_HLS:
545 compName = new String[] {"Hue", "Lightness",
546 "Saturation"};
547 break;
548 case ColorSpace.TYPE_CMYK:
549 compName = new String[] {"Cyan", "Magenta", "Yellow",
550 "Black"};
551 break;
552 case ColorSpace.TYPE_CMY:
553 compName = new String[] {"Cyan", "Magenta", "Yellow"};
554 break;
555 default:
556 String [] tmp = new String[numComponents];
557 for (int i = 0; i < tmp.length; i++) {
558 tmp[i] = "Unnamed color component(" + i + ")";
559 }
560 compName = tmp;
561 }
562 }
563 return compName[idx];
564 }
565
566 /**
567 * Returns the minimum normalized color component value for the
568 * specified component. The default implementation in this abstract
569 * class returns 0.0 for all components. Subclasses should override
570 * this method if necessary.
571 *
572 * @param component the component index
573 * @return the minimum normalized component value
574 * @throws IllegalArgumentException if component is less than 0 or
575 * greater than numComponents - 1
576 * @since 1.4
577 */
578 public float getMinValue(int component) {
579 if ((component < 0) || (component > numComponents - 1)) {
580 throw new IllegalArgumentException(
581 "Component index out of range: " + component);
582 }
583 return 0.0f;
584 }
585
586 /**
587 * Returns the maximum normalized color component value for the
588 * specified component. The default implementation in this abstract
589 * class returns 1.0 for all components. Subclasses should override
590 * this method if necessary.
591 *
592 * @param component the component index
593 * @return the maximum normalized component value
594 * @throws IllegalArgumentException if component is less than 0 or
595 * greater than numComponents - 1
596 * @since 1.4
597 */
598 public float getMaxValue(int component) {
599 if ((component < 0) || (component > numComponents - 1)) {
600 throw new IllegalArgumentException(
601 "Component index out of range: " + component);
602 }
603 return 1.0f;
604 }
605
606 /* Returns true if cspace is the XYZspace.
607 */
608 static boolean isCS_CIEXYZ(ColorSpace cspace) {
609 return (cspace == XYZspace);
610 }
611 }