1 /* 2 * Copyright (c) 1997, 2008, 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 *** 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 }