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