Showing the changes to java/pkg/java/awt/color (20 of 18352 files). Show all
Unified · Split
Binary file not shown.
| @@ -0,0 +1,57 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | Created by gbp, October 25, 1997 | ||
| 27 | |||
| 28 | * | ||
| 29 | */ | ||
| 30 | /********************************************************************** | ||
| 31 | ********************************************************************** | ||
| 32 | ********************************************************************** | ||
| 33 | *** COPYRIGHT (c) Eastman Kodak Company, 1997 *** | ||
| 34 | *** As an unpublished work pursuant to Title 17 of the United *** | ||
| 35 | *** States Code. All rights reserved. *** | ||
| 36 | ********************************************************************** | ||
| 37 | ********************************************************************** | ||
| 38 | **********************************************************************/ | ||
| 39 | |||
| 40 | |||
| 41 | package java.awt.color; | ||
| 42 | |||
| 43 | |||
| 44 | /** | ||
| 45 | * This exception is thrown if the native CMM returns an error. | ||
| 46 | */ | ||
| 47 | |||
| 48 | public class CMMException extends java.lang.RuntimeException { | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Constructs a CMMException with the specified detail message. | ||
| 52 | * @param s the specified detail message | ||
| 53 | */ | ||
| 54 | public CMMException (String s) { | ||
| 55 | super (s); | ||
| 56 | } | ||
| 57 | } | ||
Binary file not shown.
| @@ -0,0 +1,611 @@ | |||
| 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 | } | ||
Binary file not shown.
| @@ -0,0 +1,616 @@ | |||
| 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.ColorTransform; | ||
| 39 | import sun.java2d.cmm.CMSManager; | ||
| 40 | import sun.java2d.cmm.PCMM; | ||
| 41 | |||
| 42 | |||
| 43 | /** | ||
| 44 | * | ||
| 45 | * The ICC_ColorSpace class is an implementation of the abstract | ||
| 46 | * ColorSpace class. This representation of | ||
| 47 | * device independent and device dependent color spaces is based on the | ||
| 48 | * International Color Consortium Specification ICC.1:2001-12, File Format for | ||
| 49 | * Color Profiles (see <A href="http://www.color.org">http://www.color.org</A>). | ||
| 50 | * <p> | ||
| 51 | * Typically, a Color or ColorModel would be associated with an ICC | ||
| 52 | * Profile which is either an input, display, or output profile (see | ||
| 53 | * the ICC specification). There are other types of ICC Profiles, e.g. | ||
| 54 | * abstract profiles, device link profiles, and named color profiles, | ||
| 55 | * which do not contain information appropriate for representing the color | ||
| 56 | * space of a color, image, or device (see ICC_Profile). | ||
| 57 | * Attempting to create an ICC_ColorSpace object from an inappropriate ICC | ||
| 58 | * Profile is an error. | ||
| 59 | * <p> | ||
| 60 | * ICC Profiles represent transformations from the color space of | ||
| 61 | * the profile (e.g. a monitor) to a Profile Connection Space (PCS). | ||
| 62 | * Profiles of interest for tagging images or colors have a | ||
| 63 | * PCS which is one of the device independent | ||
| 64 | * spaces (one CIEXYZ space and two CIELab spaces) defined in the | ||
| 65 | * ICC Profile Format Specification. Most profiles of interest | ||
| 66 | * either have invertible transformations or explicitly specify | ||
| 67 | * transformations going both directions. Should an ICC_ColorSpace | ||
| 68 | * object be used in a way requiring a conversion from PCS to | ||
| 69 | * the profile's native space and there is inadequate data to | ||
| 70 | * correctly perform the conversion, the ICC_ColorSpace object will | ||
| 71 | * produce output in the specified type of color space (e.g. TYPE_RGB, | ||
| 72 | * TYPE_CMYK, etc.), but the specific color values of the output data | ||
| 73 | * will be undefined. | ||
| 74 | * <p> | ||
| 75 | * The details of this class are not important for simple applets, | ||
| 76 | * which draw in a default color space or manipulate and display | ||
| 77 | * imported images with a known color space. At most, such applets | ||
| 78 | * would need to get one of the default color spaces via | ||
| 79 | * ColorSpace.getInstance(). | ||
| 80 | * <p> | ||
| 81 | * @see ColorSpace | ||
| 82 | * @see ICC_Profile | ||
| 83 | */ | ||
| 84 | |||
| 85 | |||
| 86 | |||
| 87 | public class ICC_ColorSpace extends ColorSpace { | ||
| 88 | |||
| 89 | static final long serialVersionUID = 3455889114070431483L; | ||
| 90 | |||
| 91 | private ICC_Profile thisProfile; | ||
| 92 | private float[] minVal; | ||
| 93 | private float[] maxVal; | ||
| 94 | private float[] diffMinMax; | ||
| 95 | private float[] invDiffMinMax; | ||
| 96 | private boolean needScaleInit = true; | ||
| 97 | |||
| 98 | // {to,from}{RGB,CIEXYZ} methods create and cache these when needed | ||
| 99 | private transient ColorTransform this2srgb; | ||
| 100 | private transient ColorTransform srgb2this; | ||
| 101 | private transient ColorTransform this2xyz; | ||
| 102 | private transient ColorTransform xyz2this; | ||
| 103 | |||
| 104 | |||
| 105 | /** | ||
| 106 | * Constructs a new ICC_ColorSpace from an ICC_Profile object. | ||
| 107 | * @param profile the specified ICC_Profile object | ||
| 108 | * @exception IllegalArgumentException if profile is inappropriate for | ||
| 109 | * representing a ColorSpace. | ||
| 110 | */ | ||
| 111 | public ICC_ColorSpace (ICC_Profile profile) { | ||
| 112 | super (profile.getColorSpaceType(), profile.getNumComponents()); | ||
| 113 | |||
| 114 | int profileClass = profile.getProfileClass(); | ||
| 115 | |||
| 116 | /* REMIND - is NAMEDCOLOR OK? */ | ||
| 117 | if ((profileClass != ICC_Profile.CLASS_INPUT) && | ||
| 118 | (profileClass != ICC_Profile.CLASS_DISPLAY) && | ||
| 119 | (profileClass != ICC_Profile.CLASS_OUTPUT) && | ||
| 120 | (profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) && | ||
| 121 | (profileClass != ICC_Profile.CLASS_NAMEDCOLOR) && | ||
| 122 | (profileClass != ICC_Profile.CLASS_ABSTRACT)) { | ||
| 123 | throw new IllegalArgumentException("Invalid profile type"); | ||
| 124 | } | ||
| 125 | |||
| 126 | thisProfile = profile; | ||
| 127 | setMinMax(); | ||
| 128 | } | ||
| 129 | |||
| 130 | /** | ||
| 131 | * Returns the ICC_Profile for this ICC_ColorSpace. | ||
| 132 | * @return the ICC_Profile for this ICC_ColorSpace. | ||
| 133 | */ | ||
| 134 | public ICC_Profile getProfile() { | ||
| 135 | return thisProfile; | ||
| 136 | } | ||
| 137 | |||
| 138 | /** | ||
| 139 | * Transforms a color value assumed to be in this ColorSpace | ||
| 140 | * into a value in the default CS_sRGB color space. | ||
| 141 | * <p> | ||
| 142 | * This method transforms color values using algorithms designed | ||
| 143 | * to produce the best perceptual match between input and output | ||
| 144 | * colors. In order to do colorimetric conversion of color values, | ||
| 145 | * you should use the <code>toCIEXYZ</code> | ||
| 146 | * method of this color space to first convert from the input | ||
| 147 | * color space to the CS_CIEXYZ color space, and then use the | ||
| 148 | * <code>fromCIEXYZ</code> method of the CS_sRGB color space to | ||
| 149 | * convert from CS_CIEXYZ to the output color space. | ||
| 150 | * See {@link #toCIEXYZ(float[]) toCIEXYZ} and | ||
| 151 | * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information. | ||
| 152 | * <p> | ||
| 153 | * @param colorvalue a float array with length of at least the number | ||
| 154 | * of components in this ColorSpace. | ||
| 155 | * @return a float array of length 3. | ||
| 156 | * @throws ArrayIndexOutOfBoundsException if array length is not | ||
| 157 | * at least the number of components in this ColorSpace. | ||
| 158 | */ | ||
| 159 | public float[] toRGB (float[] colorvalue) { | ||
| 160 | |||
| 161 | if (this2srgb == null) { | ||
| 162 | ColorTransform[] transformList = new ColorTransform [2]; | ||
| 163 | ICC_ColorSpace srgbCS = | ||
| 164 | (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB); | ||
| 165 | PCMM mdl = CMSManager.getModule(); | ||
| 166 | transformList[0] = mdl.createTransform( | ||
| 167 | thisProfile, ColorTransform.Any, ColorTransform.In); | ||
| 168 | transformList[1] = mdl.createTransform( | ||
| 169 | srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out); | ||
| 170 | this2srgb = mdl.createTransform(transformList); | ||
| 171 | if (needScaleInit) { | ||
| 172 | setComponentScaling(); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | int nc = this.getNumComponents(); | ||
| 177 | short tmp[] = new short[nc]; | ||
| 178 | for (int i = 0; i < nc; i++) { | ||
| 179 | tmp[i] = (short) | ||
| 180 | ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f); | ||
| 181 | } | ||
| 182 | tmp = this2srgb.colorConvert(tmp, null); | ||
| 183 | float[] result = new float [3]; | ||
| 184 | for (int i = 0; i < 3; i++) { | ||
| 185 | result[i] = ((float) (tmp[i] & 0xffff)) / 65535.0f; | ||
| 186 | } | ||
| 187 | return result; | ||
| 188 | } | ||
| 189 | |||
| 190 | /** | ||
| 191 | * Transforms a color value assumed to be in the default CS_sRGB | ||
| 192 | * color space into this ColorSpace. | ||
| 193 | * <p> | ||
| 194 | * This method transforms color values using algorithms designed | ||
| 195 | * to produce the best perceptual match between input and output | ||
| 196 | * colors. In order to do colorimetric conversion of color values, | ||
| 197 | * you should use the <code>toCIEXYZ</code> | ||
| 198 | * method of the CS_sRGB color space to first convert from the input | ||
| 199 | * color space to the CS_CIEXYZ color space, and then use the | ||
| 200 | * <code>fromCIEXYZ</code> method of this color space to | ||
| 201 | * convert from CS_CIEXYZ to the output color space. | ||
| 202 | * See {@link #toCIEXYZ(float[]) toCIEXYZ} and | ||
| 203 | * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information. | ||
| 204 | * <p> | ||
| 205 | * @param rgbvalue a float array with length of at least 3. | ||
| 206 | * @return a float array with length equal to the number of | ||
| 207 | * components in this ColorSpace. | ||
| 208 | * @throws ArrayIndexOutOfBoundsException if array length is not | ||
| 209 | * at least 3. | ||
| 210 | */ | ||
| 211 | public float[] fromRGB(float[] rgbvalue) { | ||
| 212 | |||
| 213 | if (srgb2this == null) { | ||
| 214 | ColorTransform[] transformList = new ColorTransform [2]; | ||
| 215 | ICC_ColorSpace srgbCS = | ||
| 216 | (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB); | ||
| 217 | PCMM mdl = CMSManager.getModule(); | ||
| 218 | transformList[0] = mdl.createTransform( | ||
| 219 | srgbCS.getProfile(), ColorTransform.Any, ColorTransform.In); | ||
| 220 | transformList[1] = mdl.createTransform( | ||
| 221 | thisProfile, ColorTransform.Any, ColorTransform.Out); | ||
| 222 | srgb2this = mdl.createTransform(transformList); | ||
| 223 | if (needScaleInit) { | ||
| 224 | setComponentScaling(); | ||
| 225 | } | ||
| 226 | } | ||
| 227 | |||
| 228 | short tmp[] = new short[3]; | ||
| 229 | for (int i = 0; i < 3; i++) { | ||
| 230 | tmp[i] = (short) ((rgbvalue[i] * 65535.0f) + 0.5f); | ||
| 231 | } | ||
| 232 | tmp = srgb2this.colorConvert(tmp, null); | ||
| 233 | int nc = this.getNumComponents(); | ||
| 234 | float[] result = new float [nc]; | ||
| 235 | for (int i = 0; i < nc; i++) { | ||
| 236 | result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * | ||
| 237 | diffMinMax[i] + minVal[i]; | ||
| 238 | } | ||
| 239 | return result; | ||
| 240 | } | ||
| 241 | |||
| 242 | |||
| 243 | /** | ||
| 244 | * Transforms a color value assumed to be in this ColorSpace | ||
| 245 | * into the CS_CIEXYZ conversion color space. | ||
| 246 | * <p> | ||
| 247 | * This method transforms color values using relative colorimetry, | ||
| 248 | * as defined by the ICC Specification. This | ||
| 249 | * means that the XYZ values returned by this method are represented | ||
| 250 | * relative to the D50 white point of the CS_CIEXYZ color space. | ||
| 251 | * This representation is useful in a two-step color conversion | ||
| 252 | * process in which colors are transformed from an input color | ||
| 253 | * space to CS_CIEXYZ and then to an output color space. This | ||
| 254 | * representation is not the same as the XYZ values that would | ||
| 255 | * be measured from the given color value by a colorimeter. | ||
| 256 | * A further transformation is necessary to compute the XYZ values | ||
| 257 | * that would be measured using current CIE recommended practices. | ||
| 258 | * The paragraphs below explain this in more detail. | ||
| 259 | * <p> | ||
| 260 | * The ICC standard uses a device independent color space (DICS) as the | ||
| 261 | * mechanism for converting color from one device to another device. In | ||
| 262 | * this architecture, colors are converted from the source device's color | ||
| 263 | * space to the ICC DICS and then from the ICC DICS to the destination | ||
| 264 | * device's color space. The ICC standard defines device profiles which | ||
| 265 | * contain transforms which will convert between a device's color space | ||
| 266 | * and the ICC DICS. The overall conversion of colors from a source | ||
| 267 | * device to colors of a destination device is done by connecting the | ||
| 268 | * device-to-DICS transform of the profile for the source device to the | ||
| 269 | * DICS-to-device transform of the profile for the destination device. | ||
| 270 | * For this reason, the ICC DICS is commonly referred to as the profile | ||
| 271 | * connection space (PCS). The color space used in the methods | ||
| 272 | * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC | ||
| 273 | * Specification. This is also the color space represented by | ||
| 274 | * ColorSpace.CS_CIEXYZ. | ||
| 275 | * <p> | ||
| 276 | * The XYZ values of a color are often represented as relative to some | ||
| 277 | * white point, so the actual meaning of the XYZ values cannot be known | ||
| 278 | * without knowing the white point of those values. This is known as | ||
| 279 | * relative colorimetry. The PCS uses a white point of D50, so the XYZ | ||
| 280 | * values of the PCS are relative to D50. For example, white in the PCS | ||
| 281 | * will have the XYZ values of D50, which is defined to be X=.9642, | ||
| 282 | * Y=1.000, and Z=0.8249. This white point is commonly used for graphic | ||
| 283 | * arts applications, but others are often used in other applications. | ||
| 284 | * <p> | ||
| 285 | * To quantify the color characteristics of a device such as a printer | ||
| 286 | * or monitor, measurements of XYZ values for particular device colors | ||
| 287 | * are typically made. For purposes of this discussion, the term | ||
| 288 | * device XYZ values is used to mean the XYZ values that would be | ||
| 289 | * measured from device colors using current CIE recommended practices. | ||
| 290 | * <p> | ||
| 291 | * Converting between device XYZ values and the PCS XYZ values returned | ||
| 292 | * by this method corresponds to converting between the device's color | ||
| 293 | * space, as represented by CIE colorimetric values, and the PCS. There | ||
| 294 | * are many factors involved in this process, some of which are quite | ||
| 295 | * subtle. The most important, however, is the adjustment made to account | ||
| 296 | * for differences between the device's white point and the white point of | ||
| 297 | * the PCS. There are many techniques for doing this and it is the | ||
| 298 | * subject of much current research and controversy. Some commonly used | ||
| 299 | * methods are XYZ scaling, the von Kries transform, and the Bradford | ||
| 300 | * transform. The proper method to use depends upon each particular | ||
| 301 | * application. | ||
| 302 | * <p> | ||
| 303 | * The simplest method is XYZ scaling. In this method each device XYZ | ||
| 304 | * value is converted to a PCS XYZ value by multiplying it by the ratio | ||
| 305 | * of the PCS white point (D50) to the device white point. | ||
| 306 | * <pre> | ||
| 307 | * | ||
| 308 | * Xd, Yd, Zd are the device XYZ values | ||
| 309 | * Xdw, Ydw, Zdw are the device XYZ white point values | ||
| 310 | * Xp, Yp, Zp are the PCS XYZ values | ||
| 311 | * Xd50, Yd50, Zd50 are the PCS XYZ white point values | ||
| 312 | * | ||
| 313 | * Xp = Xd * (Xd50 / Xdw) | ||
| 314 | * Yp = Yd * (Yd50 / Ydw) | ||
| 315 | * Zp = Zd * (Zd50 / Zdw) | ||
| 316 | * | ||
| 317 | * </pre> | ||
| 318 | * <p> | ||
| 319 | * Conversion from the PCS to the device would be done by inverting these | ||
| 320 | * equations: | ||
| 321 | * <pre> | ||
| 322 | * | ||
| 323 | * Xd = Xp * (Xdw / Xd50) | ||
| 324 | * Yd = Yp * (Ydw / Yd50) | ||
| 325 | * Zd = Zp * (Zdw / Zd50) | ||
| 326 | * | ||
| 327 | * </pre> | ||
| 328 | * <p> | ||
| 329 | * Note that the media white point tag in an ICC profile is not the same | ||
| 330 | * as the device white point. The media white point tag is expressed in | ||
| 331 | * PCS values and is used to represent the difference between the XYZ of | ||
| 332 | * device illuminant and the XYZ of the device media when measured under | ||
| 333 | * that illuminant. The device white point is expressed as the device | ||
| 334 | * XYZ values corresponding to white displayed on the device. For | ||
| 335 | * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device | ||
| 336 | * will result in a measured device XYZ value of D65. This will not | ||
| 337 | * be the same as the media white point tag XYZ value in the ICC | ||
| 338 | * profile for an sRGB device. | ||
| 339 | * <p> | ||
| 340 | * @param colorvalue a float array with length of at least the number | ||
| 341 | * of components in this ColorSpace. | ||
| 342 | * @return a float array of length 3. | ||
| 343 | * @throws ArrayIndexOutOfBoundsException if array length is not | ||
| 344 | * at least the number of components in this ColorSpace. | ||
| 345 | */ | ||
| 346 | public float[] toCIEXYZ(float[] colorvalue) { | ||
| 347 | |||
| 348 | if (this2xyz == null) { | ||
| 349 | ColorTransform[] transformList = new ColorTransform [2]; | ||
| 350 | ICC_ColorSpace xyzCS = | ||
| 351 | (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ); | ||
| 352 | PCMM mdl = CMSManager.getModule(); | ||
| 353 | try { | ||
| 354 | transformList[0] = mdl.createTransform( | ||
| 355 | thisProfile, ICC_Profile.icRelativeColorimetric, | ||
| 356 | ColorTransform.In); | ||
| 357 | } catch (CMMException e) { | ||
| 358 | transformList[0] = mdl.createTransform( | ||
| 359 | thisProfile, ColorTransform.Any, ColorTransform.In); | ||
| 360 | } | ||
| 361 | transformList[1] = mdl.createTransform( | ||
| 362 | xyzCS.getProfile(), ColorTransform.Any, ColorTransform.Out); | ||
| 363 | this2xyz = mdl.createTransform (transformList); | ||
| 364 | if (needScaleInit) { | ||
| 365 | setComponentScaling(); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | |||
| 369 | int nc = this.getNumComponents(); | ||
| 370 | short tmp[] = new short[nc]; | ||
| 371 | for (int i = 0; i < nc; i++) { | ||
| 372 | tmp[i] = (short) | ||
| 373 | ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f); | ||
| 374 | } | ||
| 375 | tmp = this2xyz.colorConvert(tmp, null); | ||
| 376 | float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f); | ||
| 377 | // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components | ||
| 378 | float[] result = new float [3]; | ||
| 379 | for (int i = 0; i < 3; i++) { | ||
| 380 | result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * ALMOST_TWO; | ||
| 381 | } | ||
| 382 | return result; | ||
| 383 | } | ||
| 384 | |||
| 385 | |||
| 386 | /** | ||
| 387 | * Transforms a color value assumed to be in the CS_CIEXYZ conversion | ||
| 388 | * color space into this ColorSpace. | ||
| 389 | * <p> | ||
| 390 | * This method transforms color values using relative colorimetry, | ||
| 391 | * as defined by the ICC Specification. This | ||
| 392 | * means that the XYZ argument values taken by this method are represented | ||
| 393 | * relative to the D50 white point of the CS_CIEXYZ color space. | ||
| 394 | * This representation is useful in a two-step color conversion | ||
| 395 | * process in which colors are transformed from an input color | ||
| 396 | * space to CS_CIEXYZ and then to an output color space. The color | ||
| 397 | * values returned by this method are not those that would produce | ||
| 398 | * the XYZ value passed to the method when measured by a colorimeter. | ||
| 399 | * If you have XYZ values corresponding to measurements made using | ||
| 400 | * current CIE recommended practices, they must be converted to D50 | ||
| 401 | * relative values before being passed to this method. | ||
| 402 | * The paragraphs below explain this in more detail. | ||
| 403 | * <p> | ||
| 404 | * The ICC standard uses a device independent color space (DICS) as the | ||
| 405 | * mechanism for converting color from one device to another device. In | ||
| 406 | * this architecture, colors are converted from the source device's color | ||
| 407 | * space to the ICC DICS and then from the ICC DICS to the destination | ||
| 408 | * device's color space. The ICC standard defines device profiles which | ||
| 409 | * contain transforms which will convert between a device's color space | ||
| 410 | * and the ICC DICS. The overall conversion of colors from a source | ||
| 411 | * device to colors of a destination device is done by connecting the | ||
| 412 | * device-to-DICS transform of the profile for the source device to the | ||
| 413 | * DICS-to-device transform of the profile for the destination device. | ||
| 414 | * For this reason, the ICC DICS is commonly referred to as the profile | ||
| 415 | * connection space (PCS). The color space used in the methods | ||
| 416 | * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC | ||
| 417 | * Specification. This is also the color space represented by | ||
| 418 | * ColorSpace.CS_CIEXYZ. | ||
| 419 | * <p> | ||
| 420 | * The XYZ values of a color are often represented as relative to some | ||
| 421 | * white point, so the actual meaning of the XYZ values cannot be known | ||
| 422 | * without knowing the white point of those values. This is known as | ||
| 423 | * relative colorimetry. The PCS uses a white point of D50, so the XYZ | ||
| 424 | * values of the PCS are relative to D50. For example, white in the PCS | ||
| 425 | * will have the XYZ values of D50, which is defined to be X=.9642, | ||
| 426 | * Y=1.000, and Z=0.8249. This white point is commonly used for graphic | ||
| 427 | * arts applications, but others are often used in other applications. | ||
| 428 | * <p> | ||
| 429 | * To quantify the color characteristics of a device such as a printer | ||
| 430 | * or monitor, measurements of XYZ values for particular device colors | ||
| 431 | * are typically made. For purposes of this discussion, the term | ||
| 432 | * device XYZ values is used to mean the XYZ values that would be | ||
| 433 | * measured from device colors using current CIE recommended practices. | ||
| 434 | * <p> | ||
| 435 | * Converting between device XYZ values and the PCS XYZ values taken as | ||
| 436 | * arguments by this method corresponds to converting between the device's | ||
| 437 | * color space, as represented by CIE colorimetric values, and the PCS. | ||
| 438 | * There are many factors involved in this process, some of which are quite | ||
| 439 | * subtle. The most important, however, is the adjustment made to account | ||
| 440 | * for differences between the device's white point and the white point of | ||
| 441 | * the PCS. There are many techniques for doing this and it is the | ||
| 442 | * subject of much current research and controversy. Some commonly used | ||
| 443 | * methods are XYZ scaling, the von Kries transform, and the Bradford | ||
| 444 | * transform. The proper method to use depends upon each particular | ||
| 445 | * application. | ||
| 446 | * <p> | ||
| 447 | * The simplest method is XYZ scaling. In this method each device XYZ | ||
| 448 | * value is converted to a PCS XYZ value by multiplying it by the ratio | ||
| 449 | * of the PCS white point (D50) to the device white point. | ||
| 450 | * <pre> | ||
| 451 | * | ||
| 452 | * Xd, Yd, Zd are the device XYZ values | ||
| 453 | * Xdw, Ydw, Zdw are the device XYZ white point values | ||
| 454 | * Xp, Yp, Zp are the PCS XYZ values | ||
| 455 | * Xd50, Yd50, Zd50 are the PCS XYZ white point values | ||
| 456 | * | ||
| 457 | * Xp = Xd * (Xd50 / Xdw) | ||
| 458 | * Yp = Yd * (Yd50 / Ydw) | ||
| 459 | * Zp = Zd * (Zd50 / Zdw) | ||
| 460 | * | ||
| 461 | * </pre> | ||
| 462 | * <p> | ||
| 463 | * Conversion from the PCS to the device would be done by inverting these | ||
| 464 | * equations: | ||
| 465 | * <pre> | ||
| 466 | * | ||
| 467 | * Xd = Xp * (Xdw / Xd50) | ||
| 468 | * Yd = Yp * (Ydw / Yd50) | ||
| 469 | * Zd = Zp * (Zdw / Zd50) | ||
| 470 | * | ||
| 471 | * </pre> | ||
| 472 | * <p> | ||
| 473 | * Note that the media white point tag in an ICC profile is not the same | ||
| 474 | * as the device white point. The media white point tag is expressed in | ||
| 475 | * PCS values and is used to represent the difference between the XYZ of | ||
| 476 | * device illuminant and the XYZ of the device media when measured under | ||
| 477 | * that illuminant. The device white point is expressed as the device | ||
| 478 | * XYZ values corresponding to white displayed on the device. For | ||
| 479 | * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device | ||
| 480 | * will result in a measured device XYZ value of D65. This will not | ||
| 481 | * be the same as the media white point tag XYZ value in the ICC | ||
| 482 | * profile for an sRGB device. | ||
| 483 | * <p> | ||
| 484 | * <p> | ||
| 485 | * @param colorvalue a float array with length of at least 3. | ||
| 486 | * @return a float array with length equal to the number of | ||
| 487 | * components in this ColorSpace. | ||
| 488 | * @throws ArrayIndexOutOfBoundsException if array length is not | ||
| 489 | * at least 3. | ||
| 490 | */ | ||
| 491 | public float[] fromCIEXYZ(float[] colorvalue) { | ||
| 492 | |||
| 493 | if (xyz2this == null) { | ||
| 494 | ColorTransform[] transformList = new ColorTransform [2]; | ||
| 495 | ICC_ColorSpace xyzCS = | ||
| 496 | (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ); | ||
| 497 | PCMM mdl = CMSManager.getModule(); | ||
| 498 | transformList[0] = mdl.createTransform ( | ||
| 499 | xyzCS.getProfile(), ColorTransform.Any, ColorTransform.In); | ||
| 500 | try { | ||
| 501 | transformList[1] = mdl.createTransform( | ||
| 502 | thisProfile, ICC_Profile.icRelativeColorimetric, | ||
| 503 | ColorTransform.Out); | ||
| 504 | } catch (CMMException e) { | ||
| 505 | transformList[1] = CMSManager.getModule().createTransform( | ||
| 506 | thisProfile, ColorTransform.Any, ColorTransform.Out); | ||
| 507 | } | ||
| 508 | xyz2this = mdl.createTransform(transformList); | ||
| 509 | if (needScaleInit) { | ||
| 510 | setComponentScaling(); | ||
| 511 | } | ||
| 512 | } | ||
| 513 | |||
| 514 | short tmp[] = new short[3]; | ||
| 515 | float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f); | ||
| 516 | float factor = 65535.0f / ALMOST_TWO; | ||
| 517 | // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components | ||
| 518 | for (int i = 0; i < 3; i++) { | ||
| 519 | tmp[i] = (short) ((colorvalue[i] * factor) + 0.5f); | ||
| 520 | } | ||
| 521 | tmp = xyz2this.colorConvert(tmp, null); | ||
| 522 | int nc = this.getNumComponents(); | ||
| 523 | float[] result = new float [nc]; | ||
| 524 | for (int i = 0; i < nc; i++) { | ||
| 525 | result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * | ||
| 526 | diffMinMax[i] + minVal[i]; | ||
| 527 | } | ||
| 528 | return result; | ||
| 529 | } | ||
| 530 | |||
| 531 | /** | ||
| 532 | * Returns the minimum normalized color component value for the | ||
| 533 | * specified component. For TYPE_XYZ spaces, this method returns | ||
| 534 | * minimum values of 0.0 for all components. For TYPE_Lab spaces, | ||
| 535 | * this method returns 0.0 for L and -128.0 for a and b components. | ||
| 536 | * This is consistent with the encoding of the XYZ and Lab Profile | ||
| 537 | * Connection Spaces in the ICC specification. For all other types, this | ||
| 538 | * method returns 0.0 for all components. When using an ICC_ColorSpace | ||
| 539 | * with a profile that requires different minimum component values, | ||
| 540 | * it is necessary to subclass this class and override this method. | ||
| 541 | * @param component The component index. | ||
| 542 | * @return The minimum normalized component value. | ||
| 543 | * @throws IllegalArgumentException if component is less than 0 or | ||
| 544 | * greater than numComponents - 1. | ||
| 545 | * @since 1.4 | ||
| 546 | */ | ||
| 547 | public float getMinValue(int component) { | ||
| 548 | if ((component < 0) || (component > this.getNumComponents() - 1)) { | ||
| 549 | throw new IllegalArgumentException( | ||
| 550 | "Component index out of range: + component"); | ||
| 551 | } | ||
| 552 | return minVal[component]; | ||
| 553 | } | ||
| 554 | |||
| 555 | /** | ||
| 556 | * Returns the maximum normalized color component value for the | ||
| 557 | * specified component. For TYPE_XYZ spaces, this method returns | ||
| 558 | * maximum values of 1.0 + (32767.0 / 32768.0) for all components. | ||
| 559 | * For TYPE_Lab spaces, | ||
| 560 | * this method returns 100.0 for L and 127.0 for a and b components. | ||
| 561 | * This is consistent with the encoding of the XYZ and Lab Profile | ||
| 562 | * Connection Spaces in the ICC specification. For all other types, this | ||
| 563 | * method returns 1.0 for all components. When using an ICC_ColorSpace | ||
| 564 | * with a profile that requires different maximum component values, | ||
| 565 | * it is necessary to subclass this class and override this method. | ||
| 566 | * @param component The component index. | ||
| 567 | * @return The maximum normalized component value. | ||
| 568 | * @throws IllegalArgumentException if component is less than 0 or | ||
| 569 | * greater than numComponents - 1. | ||
| 570 | * @since 1.4 | ||
| 571 | */ | ||
| 572 | public float getMaxValue(int component) { | ||
| 573 | if ((component < 0) || (component > this.getNumComponents() - 1)) { | ||
| 574 | throw new IllegalArgumentException( | ||
| 575 | "Component index out of range: + component"); | ||
| 576 | } | ||
| 577 | return maxVal[component]; | ||
| 578 | } | ||
| 579 | |||
| 580 | private void setMinMax() { | ||
| 581 | int nc = this.getNumComponents(); | ||
| 582 | int type = this.getType(); | ||
| 583 | minVal = new float[nc]; | ||
| 584 | maxVal = new float[nc]; | ||
| 585 | if (type == ColorSpace.TYPE_Lab) { | ||
| 586 | minVal[0] = 0.0f; // L | ||
| 587 | maxVal[0] = 100.0f; | ||
| 588 | minVal[1] = -128.0f; // a | ||
| 589 | maxVal[1] = 127.0f; | ||
| 590 | minVal[2] = -128.0f; // b | ||
| 591 | maxVal[2] = 127.0f; | ||
| 592 | } else if (type == ColorSpace.TYPE_XYZ) { | ||
| 593 | minVal[0] = minVal[1] = minVal[2] = 0.0f; // X, Y, Z | ||
| 594 | maxVal[0] = maxVal[1] = maxVal[2] = 1.0f + (32767.0f/ 32768.0f); | ||
| 595 | } else { | ||
| 596 | for (int i = 0; i < nc; i++) { | ||
| 597 | minVal[i] = 0.0f; | ||
| 598 | maxVal[i] = 1.0f; | ||
| 599 | } | ||
| 600 | } | ||
| 601 | } | ||
| 602 | |||
| 603 | private void setComponentScaling() { | ||
| 604 | int nc = this.getNumComponents(); | ||
| 605 | diffMinMax = new float[nc]; | ||
| 606 | invDiffMinMax = new float[nc]; | ||
| 607 | for (int i = 0; i < nc; i++) { | ||
| 608 | minVal[i] = this.getMinValue(i); // in case getMinVal is overridden | ||
| 609 | maxVal[i] = this.getMaxValue(i); // in case getMaxVal is overridden | ||
| 610 | diffMinMax[i] = maxVal[i] - minVal[i]; | ||
| 611 | invDiffMinMax[i] = 65535.0f / diffMinMax[i]; | ||
| 612 | } | ||
| 613 | needScaleInit = false; | ||
| 614 | } | ||
| 615 | |||
| 616 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,2073 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2011, 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 | import sun.java2d.cmm.ProfileDeferralMgr; | ||
| 41 | import sun.java2d.cmm.ProfileDeferralInfo; | ||
| 42 | import sun.java2d.cmm.ProfileActivator; | ||
| 43 | |||
| 44 | import java.io.File; | ||
| 45 | import java.io.FileInputStream; | ||
| 46 | import java.io.FileNotFoundException; | ||
| 47 | import java.io.FileOutputStream; | ||
| 48 | import java.io.IOException; | ||
| 49 | import java.io.InputStream; | ||
| 50 | import java.io.ObjectInputStream; | ||
| 51 | import java.io.ObjectOutputStream; | ||
| 52 | import java.io.ObjectStreamException; | ||
| 53 | import java.io.OutputStream; | ||
| 54 | import java.io.Serializable; | ||
| 55 | |||
| 56 | import java.util.StringTokenizer; | ||
| 57 | |||
| 58 | import java.security.AccessController; | ||
| 59 | import java.security.PrivilegedAction; | ||
| 60 | |||
| 61 | |||
| 62 | /** | ||
| 63 | * A representation of color profile data for device independent and | ||
| 64 | * device dependent color spaces based on the International Color | ||
| 65 | * Consortium Specification ICC.1:2001-12, File Format for Color Profiles, | ||
| 66 | * (see <A href="http://www.color.org"> http://www.color.org</A>). | ||
| 67 | * <p> | ||
| 68 | * An ICC_ColorSpace object can be constructed from an appropriate | ||
| 69 | * ICC_Profile. | ||
| 70 | * Typically, an ICC_ColorSpace would be associated with an ICC | ||
| 71 | * Profile which is either an input, display, or output profile (see | ||
| 72 | * the ICC specification). There are also device link, abstract, | ||
| 73 | * color space conversion, and named color profiles. These are less | ||
| 74 | * useful for tagging a color or image, but are useful for other | ||
| 75 | * purposes (in particular device link profiles can provide improved | ||
| 76 | * performance for converting from one device's color space to | ||
| 77 | * another's). | ||
| 78 | * <p> | ||
| 79 | * ICC Profiles represent transformations from the color space of | ||
| 80 | * the profile (e.g. a monitor) to a Profile Connection Space (PCS). | ||
| 81 | * Profiles of interest for tagging images or colors have a PCS | ||
| 82 | * which is one of the two specific device independent | ||
| 83 | * spaces (one CIEXYZ space and one CIELab space) defined in the | ||
| 84 | * ICC Profile Format Specification. Most profiles of interest | ||
| 85 | * either have invertible transformations or explicitly specify | ||
| 86 | * transformations going both directions. | ||
| 87 | * <p> | ||
| 88 | * @see ICC_ColorSpace | ||
| 89 | */ | ||
| 90 | |||
| 91 | |||
| 92 | public class ICC_Profile implements Serializable { | ||
| 93 | |||
| 94 | private static final long serialVersionUID = -3938515861990936766L; | ||
| 95 | |||
| 96 | transient long ID; | ||
| 97 | |||
| 98 | private transient ProfileDeferralInfo deferralInfo; | ||
| 99 | private transient ProfileActivator profileActivator; | ||
| 100 | |||
| 101 | // Registry of singleton profile objects for specific color spaces | ||
| 102 | // defined in the ColorSpace class (e.g. CS_sRGB), see | ||
| 103 | // getInstance(int cspace) factory method. | ||
| 104 | private static ICC_Profile sRGBprofile; | ||
| 105 | private static ICC_Profile XYZprofile; | ||
| 106 | private static ICC_Profile PYCCprofile; | ||
| 107 | private static ICC_Profile GRAYprofile; | ||
| 108 | private static ICC_Profile LINEAR_RGBprofile; | ||
| 109 | |||
| 110 | |||
| 111 | /** | ||
| 112 | * Profile class is input. | ||
| 113 | */ | ||
| 114 | public static final int CLASS_INPUT = 0; | ||
| 115 | |||
| 116 | /** | ||
| 117 | * Profile class is display. | ||
| 118 | */ | ||
| 119 | public static final int CLASS_DISPLAY = 1; | ||
| 120 | |||
| 121 | /** | ||
| 122 | * Profile class is output. | ||
| 123 | */ | ||
| 124 | public static final int CLASS_OUTPUT = 2; | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Profile class is device link. | ||
| 128 | */ | ||
| 129 | public static final int CLASS_DEVICELINK = 3; | ||
| 130 | |||
| 131 | /** | ||
| 132 | * Profile class is color space conversion. | ||
| 133 | */ | ||
| 134 | public static final int CLASS_COLORSPACECONVERSION = 4; | ||
| 135 | |||
| 136 | /** | ||
| 137 | * Profile class is abstract. | ||
| 138 | */ | ||
| 139 | public static final int CLASS_ABSTRACT = 5; | ||
| 140 | |||
| 141 | /** | ||
| 142 | * Profile class is named color. | ||
| 143 | */ | ||
| 144 | public static final int CLASS_NAMEDCOLOR = 6; | ||
| 145 | |||
| 146 | |||
| 147 | /** | ||
| 148 | * ICC Profile Color Space Type Signature: 'XYZ '. | ||
| 149 | */ | ||
| 150 | public static final int icSigXYZData = 0x58595A20; /* 'XYZ ' */ | ||
| 151 | |||
| 152 | /** | ||
| 153 | * ICC Profile Color Space Type Signature: 'Lab '. | ||
| 154 | */ | ||
| 155 | public static final int icSigLabData = 0x4C616220; /* 'Lab ' */ | ||
| 156 | |||
| 157 | /** | ||
| 158 | * ICC Profile Color Space Type Signature: 'Luv '. | ||
| 159 | */ | ||
| 160 | public static final int icSigLuvData = 0x4C757620; /* 'Luv ' */ | ||
| 161 | |||
| 162 | /** | ||
| 163 | * ICC Profile Color Space Type Signature: 'YCbr'. | ||
| 164 | */ | ||
| 165 | public static final int icSigYCbCrData = 0x59436272; /* 'YCbr' */ | ||
| 166 | |||
| 167 | /** | ||
| 168 | * ICC Profile Color Space Type Signature: 'Yxy '. | ||
| 169 | */ | ||
| 170 | public static final int icSigYxyData = 0x59787920; /* 'Yxy ' */ | ||
| 171 | |||
| 172 | /** | ||
| 173 | * ICC Profile Color Space Type Signature: 'RGB '. | ||
| 174 | */ | ||
| 175 | public static final int icSigRgbData = 0x52474220; /* 'RGB ' */ | ||
| 176 | |||
| 177 | /** | ||
| 178 | * ICC Profile Color Space Type Signature: 'GRAY'. | ||
| 179 | */ | ||
| 180 | public static final int icSigGrayData = 0x47524159; /* 'GRAY' */ | ||
| 181 | |||
| 182 | /** | ||
| 183 | * ICC Profile Color Space Type Signature: 'HSV'. | ||
| 184 | */ | ||
| 185 | public static final int icSigHsvData = 0x48535620; /* 'HSV ' */ | ||
| 186 | |||
| 187 | /** | ||
| 188 | * ICC Profile Color Space Type Signature: 'HLS'. | ||
| 189 | */ | ||
| 190 | public static final int icSigHlsData = 0x484C5320; /* 'HLS ' */ | ||
| 191 | |||
| 192 | /** | ||
| 193 | * ICC Profile Color Space Type Signature: 'CMYK'. | ||
| 194 | */ | ||
| 195 | public static final int icSigCmykData = 0x434D594B; /* 'CMYK' */ | ||
| 196 | |||
| 197 | /** | ||
| 198 | * ICC Profile Color Space Type Signature: 'CMY '. | ||
| 199 | */ | ||
| 200 | public static final int icSigCmyData = 0x434D5920; /* 'CMY ' */ | ||
| 201 | |||
| 202 | /** | ||
| 203 | * ICC Profile Color Space Type Signature: '2CLR'. | ||
| 204 | */ | ||
| 205 | public static final int icSigSpace2CLR = 0x32434C52; /* '2CLR' */ | ||
| 206 | |||
| 207 | /** | ||
| 208 | * ICC Profile Color Space Type Signature: '3CLR'. | ||
| 209 | */ | ||
| 210 | public static final int icSigSpace3CLR = 0x33434C52; /* '3CLR' */ | ||
| 211 | |||
| 212 | /** | ||
| 213 | * ICC Profile Color Space Type Signature: '4CLR'. | ||
| 214 | */ | ||
| 215 | public static final int icSigSpace4CLR = 0x34434C52; /* '4CLR' */ | ||
| 216 | |||
| 217 | /** | ||
| 218 | * ICC Profile Color Space Type Signature: '5CLR'. | ||
| 219 | */ | ||
| 220 | public static final int icSigSpace5CLR = 0x35434C52; /* '5CLR' */ | ||
| 221 | |||
| 222 | /** | ||
| 223 | * ICC Profile Color Space Type Signature: '6CLR'. | ||
| 224 | */ | ||
| 225 | public static final int icSigSpace6CLR = 0x36434C52; /* '6CLR' */ | ||
| 226 | |||
| 227 | /** | ||
| 228 | * ICC Profile Color Space Type Signature: '7CLR'. | ||
| 229 | */ | ||
| 230 | public static final int icSigSpace7CLR = 0x37434C52; /* '7CLR' */ | ||
| 231 | |||
| 232 | /** | ||
| 233 | * ICC Profile Color Space Type Signature: '8CLR'. | ||
| 234 | */ | ||
| 235 | public static final int icSigSpace8CLR = 0x38434C52; /* '8CLR' */ | ||
| 236 | |||
| 237 | /** | ||
| 238 | * ICC Profile Color Space Type Signature: '9CLR'. | ||
| 239 | */ | ||
| 240 | public static final int icSigSpace9CLR = 0x39434C52; /* '9CLR' */ | ||
| 241 | |||
| 242 | /** | ||
| 243 | * ICC Profile Color Space Type Signature: 'ACLR'. | ||
| 244 | */ | ||
| 245 | public static final int icSigSpaceACLR = 0x41434C52; /* 'ACLR' */ | ||
| 246 | |||
| 247 | /** | ||
| 248 | * ICC Profile Color Space Type Signature: 'BCLR'. | ||
| 249 | */ | ||
| 250 | public static final int icSigSpaceBCLR = 0x42434C52; /* 'BCLR' */ | ||
| 251 | |||
| 252 | /** | ||
| 253 | * ICC Profile Color Space Type Signature: 'CCLR'. | ||
| 254 | */ | ||
| 255 | public static final int icSigSpaceCCLR = 0x43434C52; /* 'CCLR' */ | ||
| 256 | |||
| 257 | /** | ||
| 258 | * ICC Profile Color Space Type Signature: 'DCLR'. | ||
| 259 | */ | ||
| 260 | public static final int icSigSpaceDCLR = 0x44434C52; /* 'DCLR' */ | ||
| 261 | |||
| 262 | /** | ||
| 263 | * ICC Profile Color Space Type Signature: 'ECLR'. | ||
| 264 | */ | ||
| 265 | public static final int icSigSpaceECLR = 0x45434C52; /* 'ECLR' */ | ||
| 266 | |||
| 267 | /** | ||
| 268 | * ICC Profile Color Space Type Signature: 'FCLR'. | ||
| 269 | */ | ||
| 270 | public static final int icSigSpaceFCLR = 0x46434C52; /* 'FCLR' */ | ||
| 271 | |||
| 272 | |||
| 273 | /** | ||
| 274 | * ICC Profile Class Signature: 'scnr'. | ||
| 275 | */ | ||
| 276 | public static final int icSigInputClass = 0x73636E72; /* 'scnr' */ | ||
| 277 | |||
| 278 | /** | ||
| 279 | * ICC Profile Class Signature: 'mntr'. | ||
| 280 | */ | ||
| 281 | public static final int icSigDisplayClass = 0x6D6E7472; /* 'mntr' */ | ||
| 282 | |||
| 283 | /** | ||
| 284 | * ICC Profile Class Signature: 'prtr'. | ||
| 285 | */ | ||
| 286 | public static final int icSigOutputClass = 0x70727472; /* 'prtr' */ | ||
| 287 | |||
| 288 | /** | ||
| 289 | * ICC Profile Class Signature: 'link'. | ||
| 290 | */ | ||
| 291 | public static final int icSigLinkClass = 0x6C696E6B; /* 'link' */ | ||
| 292 | |||
| 293 | /** | ||
| 294 | * ICC Profile Class Signature: 'abst'. | ||
| 295 | */ | ||
| 296 | public static final int icSigAbstractClass = 0x61627374; /* 'abst' */ | ||
| 297 | |||
| 298 | /** | ||
| 299 | * ICC Profile Class Signature: 'spac'. | ||
| 300 | */ | ||
| 301 | public static final int icSigColorSpaceClass = 0x73706163; /* 'spac' */ | ||
| 302 | |||
| 303 | /** | ||
| 304 | * ICC Profile Class Signature: 'nmcl'. | ||
| 305 | */ | ||
| 306 | public static final int icSigNamedColorClass = 0x6e6d636c; /* 'nmcl' */ | ||
| 307 | |||
| 308 | |||
| 309 | /** | ||
| 310 | * ICC Profile Rendering Intent: Perceptual. | ||
| 311 | */ | ||
| 312 | public static final int icPerceptual = 0; | ||
| 313 | |||
| 314 | /** | ||
| 315 | * ICC Profile Rendering Intent: RelativeColorimetric. | ||
| 316 | */ | ||
| 317 | public static final int icRelativeColorimetric = 1; | ||
| 318 | |||
| 319 | /** | ||
| 320 | * ICC Profile Rendering Intent: Media-RelativeColorimetric. | ||
| 321 | * @since 1.5 | ||
| 322 | */ | ||
| 323 | public static final int icMediaRelativeColorimetric = 1; | ||
| 324 | |||
| 325 | /** | ||
| 326 | * ICC Profile Rendering Intent: Saturation. | ||
| 327 | */ | ||
| 328 | public static final int icSaturation = 2; | ||
| 329 | |||
| 330 | /** | ||
| 331 | * ICC Profile Rendering Intent: AbsoluteColorimetric. | ||
| 332 | */ | ||
| 333 | public static final int icAbsoluteColorimetric = 3; | ||
| 334 | |||
| 335 | /** | ||
| 336 | * ICC Profile Rendering Intent: ICC-AbsoluteColorimetric. | ||
| 337 | * @since 1.5 | ||
| 338 | */ | ||
| 339 | public static final int icICCAbsoluteColorimetric = 3; | ||
| 340 | |||
| 341 | |||
| 342 | /** | ||
| 343 | * ICC Profile Tag Signature: 'head' - special. | ||
| 344 | */ | ||
| 345 | public static final int icSigHead = 0x68656164; /* 'head' - special */ | ||
| 346 | |||
| 347 | /** | ||
| 348 | * ICC Profile Tag Signature: 'A2B0'. | ||
| 349 | */ | ||
| 350 | public static final int icSigAToB0Tag = 0x41324230; /* 'A2B0' */ | ||
| 351 | |||
| 352 | /** | ||
| 353 | * ICC Profile Tag Signature: 'A2B1'. | ||
| 354 | */ | ||
| 355 | public static final int icSigAToB1Tag = 0x41324231; /* 'A2B1' */ | ||
| 356 | |||
| 357 | /** | ||
| 358 | * ICC Profile Tag Signature: 'A2B2'. | ||
| 359 | */ | ||
| 360 | public static final int icSigAToB2Tag = 0x41324232; /* 'A2B2' */ | ||
| 361 | |||
| 362 | /** | ||
| 363 | * ICC Profile Tag Signature: 'bXYZ'. | ||
| 364 | */ | ||
| 365 | public static final int icSigBlueColorantTag = 0x6258595A; /* 'bXYZ' */ | ||
| 366 | |||
| 367 | /** | ||
| 368 | * ICC Profile Tag Signature: 'bXYZ'. | ||
| 369 | * @since 1.5 | ||
| 370 | */ | ||
| 371 | public static final int icSigBlueMatrixColumnTag = 0x6258595A; /* 'bXYZ' */ | ||
| 372 | |||
| 373 | /** | ||
| 374 | * ICC Profile Tag Signature: 'bTRC'. | ||
| 375 | */ | ||
| 376 | public static final int icSigBlueTRCTag = 0x62545243; /* 'bTRC' */ | ||
| 377 | |||
| 378 | /** | ||
| 379 | * ICC Profile Tag Signature: 'B2A0'. | ||
| 380 | */ | ||
| 381 | public static final int icSigBToA0Tag = 0x42324130; /* 'B2A0' */ | ||
| 382 | |||
| 383 | /** | ||
| 384 | * ICC Profile Tag Signature: 'B2A1'. | ||
| 385 | */ | ||
| 386 | public static final int icSigBToA1Tag = 0x42324131; /* 'B2A1' */ | ||
| 387 | |||
| 388 | /** | ||
| 389 | * ICC Profile Tag Signature: 'B2A2'. | ||
| 390 | */ | ||
| 391 | public static final int icSigBToA2Tag = 0x42324132; /* 'B2A2' */ | ||
| 392 | |||
| 393 | /** | ||
| 394 | * ICC Profile Tag Signature: 'calt'. | ||
| 395 | */ | ||
| 396 | public static final int icSigCalibrationDateTimeTag = 0x63616C74; | ||
| 397 | /* 'calt' */ | ||
| 398 | |||
| 399 | /** | ||
| 400 | * ICC Profile Tag Signature: 'targ'. | ||
| 401 | */ | ||
| 402 | public static final int icSigCharTargetTag = 0x74617267; /* 'targ' */ | ||
| 403 | |||
| 404 | /** | ||
| 405 | * ICC Profile Tag Signature: 'cprt'. | ||
| 406 | */ | ||
| 407 | public static final int icSigCopyrightTag = 0x63707274; /* 'cprt' */ | ||
| 408 | |||
| 409 | /** | ||
| 410 | * ICC Profile Tag Signature: 'crdi'. | ||
| 411 | */ | ||
| 412 | public static final int icSigCrdInfoTag = 0x63726469; /* 'crdi' */ | ||
| 413 | |||
| 414 | /** | ||
| 415 | * ICC Profile Tag Signature: 'dmnd'. | ||
| 416 | */ | ||
| 417 | public static final int icSigDeviceMfgDescTag = 0x646D6E64; /* 'dmnd' */ | ||
| 418 | |||
| 419 | /** | ||
| 420 | * ICC Profile Tag Signature: 'dmdd'. | ||
| 421 | */ | ||
| 422 | public static final int icSigDeviceModelDescTag = 0x646D6464; /* 'dmdd' */ | ||
| 423 | |||
| 424 | /** | ||
| 425 | * ICC Profile Tag Signature: 'devs'. | ||
| 426 | */ | ||
| 427 | public static final int icSigDeviceSettingsTag = 0x64657673; /* 'devs' */ | ||
| 428 | |||
| 429 | /** | ||
| 430 | * ICC Profile Tag Signature: 'gamt'. | ||
| 431 | */ | ||
| 432 | public static final int icSigGamutTag = 0x67616D74; /* 'gamt' */ | ||
| 433 | |||
| 434 | /** | ||
| 435 | * ICC Profile Tag Signature: 'kTRC'. | ||
| 436 | */ | ||
| 437 | public static final int icSigGrayTRCTag = 0x6b545243; /* 'kTRC' */ | ||
| 438 | |||
| 439 | /** | ||
| 440 | * ICC Profile Tag Signature: 'gXYZ'. | ||
| 441 | */ | ||
| 442 | public static final int icSigGreenColorantTag = 0x6758595A; /* 'gXYZ' */ | ||
| 443 | |||
| 444 | /** | ||
| 445 | * ICC Profile Tag Signature: 'gXYZ'. | ||
| 446 | * @since 1.5 | ||
| 447 | */ | ||
| 448 | public static final int icSigGreenMatrixColumnTag = 0x6758595A;/* 'gXYZ' */ | ||
| 449 | |||
| 450 | /** | ||
| 451 | * ICC Profile Tag Signature: 'gTRC'. | ||
| 452 | */ | ||
| 453 | public static final int icSigGreenTRCTag = 0x67545243; /* 'gTRC' */ | ||
| 454 | |||
| 455 | /** | ||
| 456 | * ICC Profile Tag Signature: 'lumi'. | ||
| 457 | */ | ||
| 458 | public static final int icSigLuminanceTag = 0x6C756d69; /* 'lumi' */ | ||
| 459 | |||
| 460 | /** | ||
| 461 | * ICC Profile Tag Signature: 'meas'. | ||
| 462 | */ | ||
| 463 | public static final int icSigMeasurementTag = 0x6D656173; /* 'meas' */ | ||
| 464 | |||
| 465 | /** | ||
| 466 | * ICC Profile Tag Signature: 'bkpt'. | ||
| 467 | */ | ||
| 468 | public static final int icSigMediaBlackPointTag = 0x626B7074; /* 'bkpt' */ | ||
| 469 | |||
| 470 | /** | ||
| 471 | * ICC Profile Tag Signature: 'wtpt'. | ||
| 472 | */ | ||
| 473 | public static final int icSigMediaWhitePointTag = 0x77747074; /* 'wtpt' */ | ||
| 474 | |||
| 475 | /** | ||
| 476 | * ICC Profile Tag Signature: 'ncl2'. | ||
| 477 | */ | ||
| 478 | public static final int icSigNamedColor2Tag = 0x6E636C32; /* 'ncl2' */ | ||
| 479 | |||
| 480 | /** | ||
| 481 | * ICC Profile Tag Signature: 'resp'. | ||
| 482 | */ | ||
| 483 | public static final int icSigOutputResponseTag = 0x72657370; /* 'resp' */ | ||
| 484 | |||
| 485 | /** | ||
| 486 | * ICC Profile Tag Signature: 'pre0'. | ||
| 487 | */ | ||
| 488 | public static final int icSigPreview0Tag = 0x70726530; /* 'pre0' */ | ||
| 489 | |||
| 490 | /** | ||
| 491 | * ICC Profile Tag Signature: 'pre1'. | ||
| 492 | */ | ||
| 493 | public static final int icSigPreview1Tag = 0x70726531; /* 'pre1' */ | ||
| 494 | |||
| 495 | /** | ||
| 496 | * ICC Profile Tag Signature: 'pre2'. | ||
| 497 | */ | ||
| 498 | public static final int icSigPreview2Tag = 0x70726532; /* 'pre2' */ | ||
| 499 | |||
| 500 | /** | ||
| 501 | * ICC Profile Tag Signature: 'desc'. | ||
| 502 | */ | ||
| 503 | public static final int icSigProfileDescriptionTag = 0x64657363; | ||
| 504 | /* 'desc' */ | ||
| 505 | |||
| 506 | /** | ||
| 507 | * ICC Profile Tag Signature: 'pseq'. | ||
| 508 | */ | ||
| 509 | public static final int icSigProfileSequenceDescTag = 0x70736571; | ||
| 510 | /* 'pseq' */ | ||
| 511 | |||
| 512 | /** | ||
| 513 | * ICC Profile Tag Signature: 'psd0'. | ||
| 514 | */ | ||
| 515 | public static final int icSigPs2CRD0Tag = 0x70736430; /* 'psd0' */ | ||
| 516 | |||
| 517 | /** | ||
| 518 | * ICC Profile Tag Signature: 'psd1'. | ||
| 519 | */ | ||
| 520 | public static final int icSigPs2CRD1Tag = 0x70736431; /* 'psd1' */ | ||
| 521 | |||
| 522 | /** | ||
| 523 | * ICC Profile Tag Signature: 'psd2'. | ||
| 524 | */ | ||
| 525 | public static final int icSigPs2CRD2Tag = 0x70736432; /* 'psd2' */ | ||
| 526 | |||
| 527 | /** | ||
| 528 | * ICC Profile Tag Signature: 'psd3'. | ||
| 529 | */ | ||
| 530 | public static final int icSigPs2CRD3Tag = 0x70736433; /* 'psd3' */ | ||
| 531 | |||
| 532 | /** | ||
| 533 | * ICC Profile Tag Signature: 'ps2s'. | ||
| 534 | */ | ||
| 535 | public static final int icSigPs2CSATag = 0x70733273; /* 'ps2s' */ | ||
| 536 | |||
| 537 | /** | ||
| 538 | * ICC Profile Tag Signature: 'ps2i'. | ||
| 539 | */ | ||
| 540 | public static final int icSigPs2RenderingIntentTag = 0x70733269; | ||
| 541 | /* 'ps2i' */ | ||
| 542 | |||
| 543 | /** | ||
| 544 | * ICC Profile Tag Signature: 'rXYZ'. | ||
| 545 | */ | ||
| 546 | public static final int icSigRedColorantTag = 0x7258595A; /* 'rXYZ' */ | ||
| 547 | |||
| 548 | /** | ||
| 549 | * ICC Profile Tag Signature: 'rXYZ'. | ||
| 550 | * @since 1.5 | ||
| 551 | */ | ||
| 552 | public static final int icSigRedMatrixColumnTag = 0x7258595A; /* 'rXYZ' */ | ||
| 553 | |||
| 554 | /** | ||
| 555 | * ICC Profile Tag Signature: 'rTRC'. | ||
| 556 | */ | ||
| 557 | public static final int icSigRedTRCTag = 0x72545243; /* 'rTRC' */ | ||
| 558 | |||
| 559 | /** | ||
| 560 | * ICC Profile Tag Signature: 'scrd'. | ||
| 561 | */ | ||
| 562 | public static final int icSigScreeningDescTag = 0x73637264; /* 'scrd' */ | ||
| 563 | |||
| 564 | /** | ||
| 565 | * ICC Profile Tag Signature: 'scrn'. | ||
| 566 | */ | ||
| 567 | public static final int icSigScreeningTag = 0x7363726E; /* 'scrn' */ | ||
| 568 | |||
| 569 | /** | ||
| 570 | * ICC Profile Tag Signature: 'tech'. | ||
| 571 | */ | ||
| 572 | public static final int icSigTechnologyTag = 0x74656368; /* 'tech' */ | ||
| 573 | |||
| 574 | /** | ||
| 575 | * ICC Profile Tag Signature: 'bfd '. | ||
| 576 | */ | ||
| 577 | public static final int icSigUcrBgTag = 0x62666420; /* 'bfd ' */ | ||
| 578 | |||
| 579 | /** | ||
| 580 | * ICC Profile Tag Signature: 'vued'. | ||
| 581 | */ | ||
| 582 | public static final int icSigViewingCondDescTag = 0x76756564; /* 'vued' */ | ||
| 583 | |||
| 584 | /** | ||
| 585 | * ICC Profile Tag Signature: 'view'. | ||
| 586 | */ | ||
| 587 | public static final int icSigViewingConditionsTag = 0x76696577;/* 'view' */ | ||
| 588 | |||
| 589 | /** | ||
| 590 | * ICC Profile Tag Signature: 'chrm'. | ||
| 591 | */ | ||
| 592 | public static final int icSigChromaticityTag = 0x6368726d; /* 'chrm' */ | ||
| 593 | |||
| 594 | /** | ||
| 595 | * ICC Profile Tag Signature: 'chad'. | ||
| 596 | * @since 1.5 | ||
| 597 | */ | ||
| 598 | public static final int icSigChromaticAdaptationTag = 0x63686164;/* 'chad' */ | ||
| 599 | |||
| 600 | /** | ||
| 601 | * ICC Profile Tag Signature: 'clro'. | ||
| 602 | * @since 1.5 | ||
| 603 | */ | ||
| 604 | public static final int icSigColorantOrderTag = 0x636C726F; /* 'clro' */ | ||
| 605 | |||
| 606 | /** | ||
| 607 | * ICC Profile Tag Signature: 'clrt'. | ||
| 608 | * @since 1.5 | ||
| 609 | */ | ||
| 610 | public static final int icSigColorantTableTag = 0x636C7274; /* 'clrt' */ | ||
| 611 | |||
| 612 | |||
| 613 | /** | ||
| 614 | * ICC Profile Header Location: profile size in bytes. | ||
| 615 | */ | ||
| 616 | public static final int icHdrSize = 0; /* Profile size in bytes */ | ||
| 617 | |||
| 618 | /** | ||
| 619 | * ICC Profile Header Location: CMM for this profile. | ||
| 620 | */ | ||
| 621 | public static final int icHdrCmmId = 4; /* CMM for this profile */ | ||
| 622 | |||
| 623 | /** | ||
| 624 | * ICC Profile Header Location: format version number. | ||
| 625 | */ | ||
| 626 | public static final int icHdrVersion = 8; /* Format version number */ | ||
| 627 | |||
| 628 | /** | ||
| 629 | * ICC Profile Header Location: type of profile. | ||
| 630 | */ | ||
| 631 | public static final int icHdrDeviceClass = 12; /* Type of profile */ | ||
| 632 | |||
| 633 | /** | ||
| 634 | * ICC Profile Header Location: color space of data. | ||
| 635 | */ | ||
| 636 | public static final int icHdrColorSpace = 16; /* Color space of data */ | ||
| 637 | |||
| 638 | /** | ||
| 639 | * ICC Profile Header Location: PCS - XYZ or Lab only. | ||
| 640 | */ | ||
| 641 | public static final int icHdrPcs = 20; /* PCS - XYZ or Lab only */ | ||
| 642 | |||
| 643 | /** | ||
| 644 | * ICC Profile Header Location: date profile was created. | ||
| 645 | */ | ||
| 646 | public static final int icHdrDate = 24; /* Date profile was created */ | ||
| 647 | |||
| 648 | /** | ||
| 649 | * ICC Profile Header Location: icMagicNumber. | ||
| 650 | */ | ||
| 651 | public static final int icHdrMagic = 36; /* icMagicNumber */ | ||
| 652 | |||
| 653 | /** | ||
| 654 | * ICC Profile Header Location: primary platform. | ||
| 655 | */ | ||
| 656 | public static final int icHdrPlatform = 40; /* Primary Platform */ | ||
| 657 | |||
| 658 | /** | ||
| 659 | * ICC Profile Header Location: various bit settings. | ||
| 660 | */ | ||
| 661 | public static final int icHdrFlags = 44; /* Various bit settings */ | ||
| 662 | |||
| 663 | /** | ||
| 664 | * ICC Profile Header Location: device manufacturer. | ||
| 665 | */ | ||
| 666 | public static final int icHdrManufacturer = 48; /* Device manufacturer */ | ||
| 667 | |||
| 668 | /** | ||
| 669 | * ICC Profile Header Location: device model number. | ||
| 670 | */ | ||
| 671 | public static final int icHdrModel = 52; /* Device model number */ | ||
| 672 | |||
| 673 | /** | ||
| 674 | * ICC Profile Header Location: device attributes. | ||
| 675 | */ | ||
| 676 | public static final int icHdrAttributes = 56; /* Device attributes */ | ||
| 677 | |||
| 678 | /** | ||
| 679 | * ICC Profile Header Location: rendering intent. | ||
| 680 | */ | ||
| 681 | public static final int icHdrRenderingIntent = 64; /* Rendering intent */ | ||
| 682 | |||
| 683 | /** | ||
| 684 | * ICC Profile Header Location: profile illuminant. | ||
| 685 | */ | ||
| 686 | public static final int icHdrIlluminant = 68; /* Profile illuminant */ | ||
| 687 | |||
| 688 | /** | ||
| 689 | * ICC Profile Header Location: profile creator. | ||
| 690 | */ | ||
| 691 | public static final int icHdrCreator = 80; /* Profile creator */ | ||
| 692 | |||
| 693 | /** | ||
| 694 | * ICC Profile Header Location: profile's ID. | ||
| 695 | * @since 1.5 | ||
| 696 | */ | ||
| 697 | public static final int icHdrProfileID = 84; /* Profile's ID */ | ||
| 698 | |||
| 699 | |||
| 700 | /** | ||
| 701 | * ICC Profile Constant: tag type signaturE. | ||
| 702 | */ | ||
| 703 | public static final int icTagType = 0; /* tag type signature */ | ||
| 704 | |||
| 705 | /** | ||
| 706 | * ICC Profile Constant: reserved. | ||
| 707 | */ | ||
| 708 | public static final int icTagReserved = 4; /* reserved */ | ||
| 709 | |||
| 710 | /** | ||
| 711 | * ICC Profile Constant: curveType count. | ||
| 712 | */ | ||
| 713 | public static final int icCurveCount = 8; /* curveType count */ | ||
| 714 | |||
| 715 | /** | ||
| 716 | * ICC Profile Constant: curveType data. | ||
| 717 | */ | ||
| 718 | public static final int icCurveData = 12; /* curveType data */ | ||
| 719 | |||
| 720 | /** | ||
| 721 | * ICC Profile Constant: XYZNumber X. | ||
| 722 | */ | ||
| 723 | public static final int icXYZNumberX = 8; /* XYZNumber X */ | ||
| 724 | |||
| 725 | |||
| 726 | /** | ||
| 727 | * Constructs an ICC_Profile object with a given ID. | ||
| 728 | */ | ||
| 729 | ICC_Profile(long ID) { | ||
| 730 | this.ID = ID; | ||
| 731 | } | ||
| 732 | |||
| 733 | |||
| 734 | /** | ||
| 735 | * Constructs an ICC_Profile object whose loading will be deferred. | ||
| 736 | * The ID will be 0 until the profile is loaded. | ||
| 737 | */ | ||
| 738 | ICC_Profile(ProfileDeferralInfo pdi) { | ||
| 739 | this.deferralInfo = pdi; | ||
| 740 | this.profileActivator = new ProfileActivator() { | ||
| 741 | public void activate() throws ProfileDataException { | ||
| 742 | activateDeferredProfile(); | ||
| 743 | } | ||
| 744 | }; | ||
| 745 | ProfileDeferralMgr.registerDeferral(this.profileActivator); | ||
| 746 | } | ||
| 747 | |||
| 748 | |||
| 749 | /** | ||
| 750 | * Frees the resources associated with an ICC_Profile object. | ||
| 751 | */ | ||
| 752 | protected void finalize () { | ||
| 753 | if (ID != 0) { | ||
| 754 | CMSManager.getModule().freeProfile(ID); | ||
| 755 | } else if (profileActivator != null) { | ||
| 756 | ProfileDeferralMgr.unregisterDeferral(profileActivator); | ||
| 757 | } | ||
| 758 | } | ||
| 759 | |||
| 760 | |||
| 761 | /** | ||
| 762 | * Constructs an ICC_Profile object corresponding to the data in | ||
| 763 | * a byte array. Throws an IllegalArgumentException if the data | ||
| 764 | * does not correspond to a valid ICC Profile. | ||
| 765 | * @param data the specified ICC Profile data | ||
| 766 | * @return an <code>ICC_Profile</code> object corresponding to | ||
| 767 | * the data in the specified <code>data</code> array. | ||
| 768 | */ | ||
| 769 | public static ICC_Profile getInstance(byte[] data) { | ||
| 770 | ICC_Profile thisProfile; | ||
| 771 | |||
| 772 | long theID; | ||
| 773 | |||
| 774 | if (ProfileDeferralMgr.deferring) { | ||
| 775 | ProfileDeferralMgr.activateProfiles(); | ||
| 776 | } | ||
| 777 | |||
| 778 | try { | ||
| 779 | theID = CMSManager.getModule().loadProfile(data); | ||
| 780 | } catch (CMMException c) { | ||
| 781 | throw new IllegalArgumentException("Invalid ICC Profile Data"); | ||
| 782 | } | ||
| 783 | |||
| 784 | try { | ||
| 785 | if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) && | ||
| 786 | (getData (theID, icSigMediaWhitePointTag) != null) && | ||
| 787 | (getData (theID, icSigGrayTRCTag) != null)) { | ||
| 788 | thisProfile = new ICC_ProfileGray (theID); | ||
| 789 | } | ||
| 790 | else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) && | ||
| 791 | (getData (theID, icSigMediaWhitePointTag) != null) && | ||
| 792 | (getData (theID, icSigRedColorantTag) != null) && | ||
| 793 | (getData (theID, icSigGreenColorantTag) != null) && | ||
| 794 | (getData (theID, icSigBlueColorantTag) != null) && | ||
| 795 | (getData (theID, icSigRedTRCTag) != null) && | ||
| 796 | (getData (theID, icSigGreenTRCTag) != null) && | ||
| 797 | (getData (theID, icSigBlueTRCTag) != null)) { | ||
| 798 | thisProfile = new ICC_ProfileRGB (theID); | ||
| 799 | } | ||
| 800 | else { | ||
| 801 | thisProfile = new ICC_Profile (theID); | ||
| 802 | } | ||
| 803 | } catch (CMMException c) { | ||
| 804 | thisProfile = new ICC_Profile (theID); | ||
| 805 | } | ||
| 806 | return thisProfile; | ||
| 807 | } | ||
| 808 | |||
| 809 | |||
| 810 | |||
| 811 | /** | ||
| 812 | * Constructs an ICC_Profile corresponding to one of the specific color | ||
| 813 | * spaces defined by the ColorSpace class (for example CS_sRGB). | ||
| 814 | * Throws an IllegalArgumentException if cspace is not one of the | ||
| 815 | * defined color spaces. | ||
| 816 | * | ||
| 817 | * @param cspace the type of color space to create a profile for. | ||
| 818 | * The specified type is one of the color | ||
| 819 | * space constants defined in the <CODE>ColorSpace</CODE> class. | ||
| 820 | * | ||
| 821 | * @return an <code>ICC_Profile</code> object corresponding to | ||
| 822 | * the specified <code>ColorSpace</code> type. | ||
| 823 | * @exception IllegalArgumentException If <CODE>cspace</CODE> is not | ||
| 824 | * one of the predefined color space types. | ||
| 825 | */ | ||
| 826 | public static ICC_Profile getInstance (int cspace) { | ||
| 827 | ICC_Profile thisProfile = null; | ||
| 828 | String fileName; | ||
| 829 | |||
| 830 | switch (cspace) { | ||
| 831 | case ColorSpace.CS_sRGB: | ||
| 832 | synchronized(ICC_Profile.class) { | ||
| 833 | if (sRGBprofile == null) { | ||
| 834 | /* | ||
| 835 | * Deferral is only used for standard profiles. | ||
| 836 | * Enabling the appropriate access privileges is handled | ||
| 837 | * at a lower level. | ||
| 838 | */ | ||
| 839 | ProfileDeferralInfo pInfo = | ||
| 840 | new ProfileDeferralInfo("sRGB.pf", | ||
| 841 | ColorSpace.TYPE_RGB, 3, | ||
| 842 | CLASS_DISPLAY); | ||
| 843 | sRGBprofile = getDeferredInstance(pInfo); | ||
| 844 | } | ||
| 845 | thisProfile = sRGBprofile; | ||
| 846 | } | ||
| 847 | |||
| 848 | break; | ||
| 849 | |||
| 850 | case ColorSpace.CS_CIEXYZ: | ||
| 851 | synchronized(ICC_Profile.class) { | ||
| 852 | if (XYZprofile == null) { | ||
| 853 | ProfileDeferralInfo pInfo = | ||
| 854 | new ProfileDeferralInfo("CIEXYZ.pf", | ||
| 855 | ColorSpace.TYPE_XYZ, 3, | ||
| 856 | CLASS_DISPLAY); | ||
| 857 | XYZprofile = getDeferredInstance(pInfo); | ||
| 858 | } | ||
| 859 | thisProfile = XYZprofile; | ||
| 860 | } | ||
| 861 | |||
| 862 | break; | ||
| 863 | |||
| 864 | case ColorSpace.CS_PYCC: | ||
| 865 | synchronized(ICC_Profile.class) { | ||
| 866 | if (PYCCprofile == null) { | ||
| 867 | if (standardProfileExists("PYCC.pf")) | ||
| 868 | { | ||
| 869 | ProfileDeferralInfo pInfo = | ||
| 870 | new ProfileDeferralInfo("PYCC.pf", | ||
| 871 | ColorSpace.TYPE_3CLR, 3, | ||
| 872 | CLASS_DISPLAY); | ||
| 873 | PYCCprofile = getDeferredInstance(pInfo); | ||
| 874 | } else { | ||
| 875 | throw new IllegalArgumentException( | ||
| 876 | "Can't load standard profile: PYCC.pf"); | ||
| 877 | } | ||
| 878 | } | ||
| 879 | thisProfile = PYCCprofile; | ||
| 880 | } | ||
| 881 | |||
| 882 | break; | ||
| 883 | |||
| 884 | case ColorSpace.CS_GRAY: | ||
| 885 | synchronized(ICC_Profile.class) { | ||
| 886 | if (GRAYprofile == null) { | ||
| 887 | ProfileDeferralInfo pInfo = | ||
| 888 | new ProfileDeferralInfo("GRAY.pf", | ||
| 889 | ColorSpace.TYPE_GRAY, 1, | ||
| 890 | CLASS_DISPLAY); | ||
| 891 | GRAYprofile = getDeferredInstance(pInfo); | ||
| 892 | } | ||
| 893 | thisProfile = GRAYprofile; | ||
| 894 | } | ||
| 895 | |||
| 896 | break; | ||
| 897 | |||
| 898 | case ColorSpace.CS_LINEAR_RGB: | ||
| 899 | synchronized(ICC_Profile.class) { | ||
| 900 | if (LINEAR_RGBprofile == null) { | ||
| 901 | ProfileDeferralInfo pInfo = | ||
| 902 | new ProfileDeferralInfo("LINEAR_RGB.pf", | ||
| 903 | ColorSpace.TYPE_RGB, 3, | ||
| 904 | CLASS_DISPLAY); | ||
| 905 | LINEAR_RGBprofile = getDeferredInstance(pInfo); | ||
| 906 | } | ||
| 907 | thisProfile = LINEAR_RGBprofile; | ||
| 908 | } | ||
| 909 | |||
| 910 | break; | ||
| 911 | |||
| 912 | default: | ||
| 913 | throw new IllegalArgumentException("Unknown color space"); | ||
| 914 | } | ||
| 915 | |||
| 916 | return thisProfile; | ||
| 917 | } | ||
| 918 | |||
| 919 | /* This asserts system privileges, so is used only for the | ||
| 920 | * standard profiles. | ||
| 921 | */ | ||
| 922 | private static ICC_Profile getStandardProfile(final String name) { | ||
| 923 | |||
| 924 | return (ICC_Profile) AccessController.doPrivileged( | ||
| 925 | new PrivilegedAction() { | ||
| 926 | public Object run() { | ||
| 927 | ICC_Profile p = null; | ||
| 928 | try { | ||
| 929 | p = getInstance (name); | ||
| 930 | } catch (IOException ex) { | ||
| 931 | throw new IllegalArgumentException( | ||
| 932 | "Can't load standard profile: " + name); | ||
| 933 | } | ||
| 934 | return p; | ||
| 935 | } | ||
| 936 | }); | ||
| 937 | } | ||
| 938 | |||
| 939 | /** | ||
| 940 | * Constructs an ICC_Profile corresponding to the data in a file. | ||
| 941 | * fileName may be an absolute or a relative file specification. | ||
| 942 | * Relative file names are looked for in several places: first, relative | ||
| 943 | * to any directories specified by the java.iccprofile.path property; | ||
| 944 | * second, relative to any directories specified by the java.class.path | ||
| 945 | * property; finally, in a directory used to store profiles always | ||
| 946 | * available, such as the profile for sRGB. Built-in profiles use .pf as | ||
| 947 | * the file name extension for profiles, e.g. sRGB.pf. | ||
| 948 | * This method throws an IOException if the specified file cannot be | ||
| 949 | * opened or if an I/O error occurs while reading the file. It throws | ||
| 950 | * an IllegalArgumentException if the file does not contain valid ICC | ||
| 951 | * Profile data. | ||
| 952 | * @param fileName The file that contains the data for the profile. | ||
| 953 | * | ||
| 954 | * @return an <code>ICC_Profile</code> object corresponding to | ||
| 955 | * the data in the specified file. | ||
| 956 | * @exception IOException If the specified file cannot be opened or | ||
| 957 | * an I/O error occurs while reading the file. | ||
| 958 | * | ||
| 959 | * @exception IllegalArgumentException If the file does not | ||
| 960 | * contain valid ICC Profile data. | ||
| 961 | * | ||
| 962 | * @exception SecurityException If a security manager is installed | ||
| 963 | * and it does not permit read access to the given file. | ||
| 964 | */ | ||
| 965 | public static ICC_Profile getInstance(String fileName) throws IOException { | ||
| 966 | ICC_Profile thisProfile; | ||
| 967 | FileInputStream fis = null; | ||
| 968 | |||
| 969 | |||
| 970 | File f = getProfileFile(fileName); | ||
| 971 | if (f != null) { | ||
| 972 | fis = new FileInputStream(f); | ||
| 973 | } | ||
| 974 | if (fis == null) { | ||
| 975 | throw new IOException("Cannot open file " + fileName); | ||
| 976 | } | ||
| 977 | |||
| 978 | thisProfile = getInstance(fis); | ||
| 979 | |||
| 980 | fis.close(); /* close the file */ | ||
| 981 | |||
| 982 | return thisProfile; | ||
| 983 | } | ||
| 984 | |||
| 985 | |||
| 986 | /** | ||
| 987 | * Constructs an ICC_Profile corresponding to the data in an InputStream. | ||
| 988 | * This method throws an IllegalArgumentException if the stream does not | ||
| 989 | * contain valid ICC Profile data. It throws an IOException if an I/O | ||
| 990 | * error occurs while reading the stream. | ||
| 991 | * @param s The input stream from which to read the profile data. | ||
| 992 | * | ||
| 993 | * @return an <CODE>ICC_Profile</CODE> object corresponding to the | ||
| 994 | * data in the specified <code>InputStream</code>. | ||
| 995 | * | ||
| 996 | * @exception IOException If an I/O error occurs while reading the stream. | ||
| 997 | * | ||
| 998 | * @exception IllegalArgumentException If the stream does not | ||
| 999 | * contain valid ICC Profile data. | ||
| 1000 | */ | ||
| 1001 | public static ICC_Profile getInstance(InputStream s) throws IOException { | ||
| 1002 | byte profileData[]; | ||
| 1003 | |||
| 1004 | if (s instanceof ProfileDeferralInfo) { | ||
| 1005 | /* hack to detect profiles whose loading can be deferred */ | ||
| 1006 | return getDeferredInstance((ProfileDeferralInfo) s); | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | if ((profileData = getProfileDataFromStream(s)) == null) { | ||
| 1010 | throw new IllegalArgumentException("Invalid ICC Profile Data"); | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | return getInstance(profileData); | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | |||
| 1017 | static byte[] getProfileDataFromStream(InputStream s) throws IOException { | ||
| 1018 | byte profileData[]; | ||
| 1019 | int profileSize; | ||
| 1020 | |||
| 1021 | byte header[] = new byte[128]; | ||
| 1022 | int bytestoread = 128; | ||
| 1023 | int bytesread = 0; | ||
| 1024 | int n; | ||
| 1025 | |||
| 1026 | while (bytestoread != 0) { | ||
| 1027 | if ((n = s.read(header, bytesread, bytestoread)) < 0) { | ||
| 1028 | return null; | ||
| 1029 | } | ||
| 1030 | bytesread += n; | ||
| 1031 | bytestoread -= n; | ||
| 1032 | } | ||
| 1033 | if (header[36] != 0x61 || header[37] != 0x63 || | ||
| 1034 | header[38] != 0x73 || header[39] != 0x70) { | ||
| 1035 | return null; /* not a valid profile */ | ||
| 1036 | } | ||
| 1037 | profileSize = ((header[0] & 0xff) << 24) | | ||
| 1038 | ((header[1] & 0xff) << 16) | | ||
| 1039 | ((header[2] & 0xff) << 8) | | ||
| 1040 | (header[3] & 0xff); | ||
| 1041 | profileData = new byte[profileSize]; | ||
| 1042 | System.arraycopy(header, 0, profileData, 0, 128); | ||
| 1043 | bytestoread = profileSize - 128; | ||
| 1044 | bytesread = 128; | ||
| 1045 | while (bytestoread != 0) { | ||
| 1046 | if ((n = s.read(profileData, bytesread, bytestoread)) < 0) { | ||
| 1047 | return null; | ||
| 1048 | } | ||
| 1049 | bytesread += n; | ||
| 1050 | bytestoread -= n; | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | return profileData; | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | |||
| 1057 | /** | ||
| 1058 | * Constructs an ICC_Profile for which the actual loading of the | ||
| 1059 | * profile data from a file and the initialization of the CMM should | ||
| 1060 | * be deferred as long as possible. | ||
| 1061 | * Deferral is only used for standard profiles. | ||
| 1062 | * If deferring is disabled, then getStandardProfile() ensures | ||
| 1063 | * that all of the appropriate access privileges are granted | ||
| 1064 | * when loading this profile. | ||
| 1065 | * If deferring is enabled, then the deferred activation | ||
| 1066 | * code will take care of access privileges. | ||
| 1067 | * @see activateDeferredProfile() | ||
| 1068 | */ | ||
| 1069 | static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi) { | ||
| 1070 | if (!ProfileDeferralMgr.deferring) { | ||
| 1071 | return getStandardProfile(pdi.filename); | ||
| 1072 | } | ||
| 1073 | if (pdi.colorSpaceType == ColorSpace.TYPE_RGB) { | ||
| 1074 | return new ICC_ProfileRGB(pdi); | ||
| 1075 | } else if (pdi.colorSpaceType == ColorSpace.TYPE_GRAY) { | ||
| 1076 | return new ICC_ProfileGray(pdi); | ||
| 1077 | } else { | ||
| 1078 | return new ICC_Profile(pdi); | ||
| 1079 | } | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | |||
| 1083 | void activateDeferredProfile() throws ProfileDataException { | ||
| 1084 | byte profileData[]; | ||
| 1085 | FileInputStream fis; | ||
| 1086 | final String fileName = deferralInfo.filename; | ||
| 1087 | |||
| 1088 | profileActivator = null; | ||
| 1089 | deferralInfo = null; | ||
| 1090 | PrivilegedAction<FileInputStream> pa = new PrivilegedAction<FileInputStream>() { | ||
| 1091 | public FileInputStream run() { | ||
| 1092 | File f = getStandardProfileFile(fileName); | ||
| 1093 | if (f != null) { | ||
| 1094 | try { | ||
| 1095 | return new FileInputStream(f); | ||
| 1096 | } catch (FileNotFoundException e) {} | ||
| 1097 | } | ||
| 1098 | return null; | ||
| 1099 | } | ||
| 1100 | }; | ||
| 1101 | if ((fis = AccessController.doPrivileged(pa)) == null) { | ||
| 1102 | throw new ProfileDataException("Cannot open file " + fileName); | ||
| 1103 | } | ||
| 1104 | try { | ||
| 1105 | profileData = getProfileDataFromStream(fis); | ||
| 1106 | fis.close(); /* close the file */ | ||
| 1107 | } | ||
| 1108 | catch (IOException e) { | ||
| 1109 | ProfileDataException pde = new | ||
| 1110 | ProfileDataException("Invalid ICC Profile Data" + fileName); | ||
| 1111 | pde.initCause(e); | ||
| 1112 | throw pde; | ||
| 1113 | } | ||
| 1114 | if (profileData == null) { | ||
| 1115 | throw new ProfileDataException("Invalid ICC Profile Data" + | ||
| 1116 | fileName); | ||
| 1117 | } | ||
| 1118 | try { | ||
| 1119 | ID = CMSManager.getModule().loadProfile(profileData); | ||
| 1120 | } catch (CMMException c) { | ||
| 1121 | ProfileDataException pde = new | ||
| 1122 | ProfileDataException("Invalid ICC Profile Data" + fileName); | ||
| 1123 | pde.initCause(c); | ||
| 1124 | throw pde; | ||
| 1125 | } | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | |||
| 1129 | /** | ||
| 1130 | * Returns profile major version. | ||
| 1131 | * @return The major version of the profile. | ||
| 1132 | */ | ||
| 1133 | public int getMajorVersion() { | ||
| 1134 | byte[] theHeader; | ||
| 1135 | |||
| 1136 | theHeader = getData(icSigHead); /* getData will activate deferred | ||
| 1137 | profiles if necessary */ | ||
| 1138 | |||
| 1139 | return (int) theHeader[8]; | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | /** | ||
| 1143 | * Returns profile minor version. | ||
| 1144 | * @return The minor version of the profile. | ||
| 1145 | */ | ||
| 1146 | public int getMinorVersion() { | ||
| 1147 | byte[] theHeader; | ||
| 1148 | |||
| 1149 | theHeader = getData(icSigHead); /* getData will activate deferred | ||
| 1150 | profiles if necessary */ | ||
| 1151 | |||
| 1152 | return (int) theHeader[9]; | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | /** | ||
| 1156 | * Returns the profile class. | ||
| 1157 | * @return One of the predefined profile class constants. | ||
| 1158 | */ | ||
| 1159 | public int getProfileClass() { | ||
| 1160 | byte[] theHeader; | ||
| 1161 | int theClassSig, theClass; | ||
| 1162 | |||
| 1163 | if (deferralInfo != null) { | ||
| 1164 | return deferralInfo.profileClass; /* Need to have this info for | ||
| 1165 | ICC_ColorSpace without | ||
| 1166 | causing a deferred profile | ||
| 1167 | to be loaded */ | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | theHeader = getData(icSigHead); | ||
| 1171 | |||
| 1172 | theClassSig = intFromBigEndian (theHeader, icHdrDeviceClass); | ||
| 1173 | |||
| 1174 | switch (theClassSig) { | ||
| 1175 | case icSigInputClass: | ||
| 1176 | theClass = CLASS_INPUT; | ||
| 1177 | break; | ||
| 1178 | |||
| 1179 | case icSigDisplayClass: | ||
| 1180 | theClass = CLASS_DISPLAY; | ||
| 1181 | break; | ||
| 1182 | |||
| 1183 | case icSigOutputClass: | ||
| 1184 | theClass = CLASS_OUTPUT; | ||
| 1185 | break; | ||
| 1186 | |||
| 1187 | case icSigLinkClass: | ||
| 1188 | theClass = CLASS_DEVICELINK; | ||
| 1189 | break; | ||
| 1190 | |||
| 1191 | case icSigColorSpaceClass: | ||
| 1192 | theClass = CLASS_COLORSPACECONVERSION; | ||
| 1193 | break; | ||
| 1194 | |||
| 1195 | case icSigAbstractClass: | ||
| 1196 | theClass = CLASS_ABSTRACT; | ||
| 1197 | break; | ||
| 1198 | |||
| 1199 | case icSigNamedColorClass: | ||
| 1200 | theClass = CLASS_NAMEDCOLOR; | ||
| 1201 | break; | ||
| 1202 | |||
| 1203 | default: | ||
| 1204 | throw new IllegalArgumentException("Unknown profile class"); | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | return theClass; | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | /** | ||
| 1211 | * Returns the color space type. Returns one of the color space type | ||
| 1212 | * constants defined by the ColorSpace class. This is the | ||
| 1213 | * "input" color space of the profile. The type defines the | ||
| 1214 | * number of components of the color space and the interpretation, | ||
| 1215 | * e.g. TYPE_RGB identifies a color space with three components - red, | ||
| 1216 | * green, and blue. It does not define the particular color | ||
| 1217 | * characteristics of the space, e.g. the chromaticities of the | ||
| 1218 | * primaries. | ||
| 1219 | * @return One of the color space type constants defined in the | ||
| 1220 | * <CODE>ColorSpace</CODE> class. | ||
| 1221 | */ | ||
| 1222 | public int getColorSpaceType() { | ||
| 1223 | if (deferralInfo != null) { | ||
| 1224 | return deferralInfo.colorSpaceType; /* Need to have this info for | ||
| 1225 | ICC_ColorSpace without | ||
| 1226 | causing a deferred profile | ||
| 1227 | to be loaded */ | ||
| 1228 | } | ||
| 1229 | return getColorSpaceType(ID); | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | static int getColorSpaceType(long profileID) { | ||
| 1233 | byte[] theHeader; | ||
| 1234 | int theColorSpaceSig, theColorSpace; | ||
| 1235 | |||
| 1236 | theHeader = getData(profileID, icSigHead); | ||
| 1237 | theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace); | ||
| 1238 | theColorSpace = iccCStoJCS (theColorSpaceSig); | ||
| 1239 | return theColorSpace; | ||
| 1240 | } | ||
| 1241 | |||
| 1242 | /** | ||
| 1243 | * Returns the color space type of the Profile Connection Space (PCS). | ||
| 1244 | * Returns one of the color space type constants defined by the | ||
| 1245 | * ColorSpace class. This is the "output" color space of the | ||
| 1246 | * profile. For an input, display, or output profile useful | ||
| 1247 | * for tagging colors or images, this will be either TYPE_XYZ or | ||
| 1248 | * TYPE_Lab and should be interpreted as the corresponding specific | ||
| 1249 | * color space defined in the ICC specification. For a device | ||
| 1250 | * link profile, this could be any of the color space type constants. | ||
| 1251 | * @return One of the color space type constants defined in the | ||
| 1252 | * <CODE>ColorSpace</CODE> class. | ||
| 1253 | */ | ||
| 1254 | public int getPCSType() { | ||
| 1255 | if (ProfileDeferralMgr.deferring) { | ||
| 1256 | ProfileDeferralMgr.activateProfiles(); | ||
| 1257 | } | ||
| 1258 | return getPCSType(ID); | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | |||
| 1262 | static int getPCSType(long profileID) { | ||
| 1263 | byte[] theHeader; | ||
| 1264 | int thePCSSig, thePCS; | ||
| 1265 | |||
| 1266 | theHeader = getData(profileID, icSigHead); | ||
| 1267 | thePCSSig = intFromBigEndian(theHeader, icHdrPcs); | ||
| 1268 | thePCS = iccCStoJCS(thePCSSig); | ||
| 1269 | return thePCS; | ||
| 1270 | } | ||
| 1271 | |||
| 1272 | |||
| 1273 | /** | ||
| 1274 | * Write this ICC_Profile to a file. | ||
| 1275 | * | ||
| 1276 | * @param fileName The file to write the profile data to. | ||
| 1277 | * | ||
| 1278 | * @exception IOException If the file cannot be opened for writing | ||
| 1279 | * or an I/O error occurs while writing to the file. | ||
| 1280 | */ | ||
| 1281 | public void write(String fileName) throws IOException { | ||
| 1282 | FileOutputStream outputFile; | ||
| 1283 | byte profileData[]; | ||
| 1284 | |||
| 1285 | profileData = getData(); /* this will activate deferred | ||
| 1286 | profiles if necessary */ | ||
| 1287 | outputFile = new FileOutputStream(fileName); | ||
| 1288 | outputFile.write(profileData); | ||
| 1289 | outputFile.close (); | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | |||
| 1293 | /** | ||
| 1294 | * Write this ICC_Profile to an OutputStream. | ||
| 1295 | * | ||
| 1296 | * @param s The stream to write the profile data to. | ||
| 1297 | * | ||
| 1298 | * @exception IOException If an I/O error occurs while writing to the | ||
| 1299 | * stream. | ||
| 1300 | */ | ||
| 1301 | public void write(OutputStream s) throws IOException { | ||
| 1302 | byte profileData[]; | ||
| 1303 | |||
| 1304 | profileData = getData(); /* this will activate deferred | ||
| 1305 | profiles if necessary */ | ||
| 1306 | s.write(profileData); | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | |||
| 1310 | /** | ||
| 1311 | * Returns a byte array corresponding to the data of this ICC_Profile. | ||
| 1312 | * @return A byte array that contains the profile data. | ||
| 1313 | * @see #setData(int, byte[]) | ||
| 1314 | */ | ||
| 1315 | public byte[] getData() { | ||
| 1316 | int profileSize; | ||
| 1317 | byte[] profileData; | ||
| 1318 | |||
| 1319 | if (ProfileDeferralMgr.deferring) { | ||
| 1320 | ProfileDeferralMgr.activateProfiles(); | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | PCMM mdl = CMSManager.getModule(); | ||
| 1324 | |||
| 1325 | /* get the number of bytes needed for this profile */ | ||
| 1326 | profileSize = mdl.getProfileSize(ID); | ||
| 1327 | |||
| 1328 | profileData = new byte [profileSize]; | ||
| 1329 | |||
| 1330 | /* get the data for the profile */ | ||
| 1331 | mdl.getProfileData(ID, profileData); | ||
| 1332 | |||
| 1333 | return profileData; | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | |||
| 1337 | /** | ||
| 1338 | * Returns a particular tagged data element from the profile as | ||
| 1339 | * a byte array. Elements are identified by signatures | ||
| 1340 | * as defined in the ICC specification. The signature | ||
| 1341 | * icSigHead can be used to get the header. This method is useful | ||
| 1342 | * for advanced applets or applications which need to access | ||
| 1343 | * profile data directly. | ||
| 1344 | * | ||
| 1345 | * @param tagSignature The ICC tag signature for the data element you | ||
| 1346 | * want to get. | ||
| 1347 | * | ||
| 1348 | * @return A byte array that contains the tagged data element. Returns | ||
| 1349 | * <code>null</code> if the specified tag doesn't exist. | ||
| 1350 | * @see #setData(int, byte[]) | ||
| 1351 | */ | ||
| 1352 | public byte[] getData(int tagSignature) { | ||
| 1353 | |||
| 1354 | if (ProfileDeferralMgr.deferring) { | ||
| 1355 | ProfileDeferralMgr.activateProfiles(); | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | return getData(ID, tagSignature); | ||
| 1359 | } | ||
| 1360 | |||
| 1361 | |||
| 1362 | static byte[] getData(long profileID, int tagSignature) { | ||
| 1363 | int tagSize; | ||
| 1364 | byte[] tagData; | ||
| 1365 | |||
| 1366 | try { | ||
| 1367 | PCMM mdl = CMSManager.getModule(); | ||
| 1368 | |||
| 1369 | /* get the number of bytes needed for this tag */ | ||
| 1370 | tagSize = mdl.getTagSize(profileID, tagSignature); | ||
| 1371 | |||
| 1372 | tagData = new byte[tagSize]; /* get an array for the tag */ | ||
| 1373 | |||
| 1374 | /* get the tag's data */ | ||
| 1375 | mdl.getTagData(profileID, tagSignature, tagData); | ||
| 1376 | } catch(CMMException c) { | ||
| 1377 | tagData = null; | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | return tagData; | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | /** | ||
| 1384 | * Sets a particular tagged data element in the profile from | ||
| 1385 | * a byte array. The array should contain data in a format, corresponded | ||
| 1386 | * to the {@code tagSignature} as defined in the ICC specification, section 10. | ||
| 1387 | * This method is useful for advanced applets or applications which need to | ||
| 1388 | * access profile data directly. | ||
| 1389 | * | ||
| 1390 | * @param tagSignature The ICC tag signature for the data element | ||
| 1391 | * you want to set. | ||
| 1392 | * @param tagData the data to set for the specified tag signature | ||
| 1393 | * @throws IllegalArgumentException if {@code tagSignature} is not a signature | ||
| 1394 | * as defined in the ICC specification. | ||
| 1395 | * @throws IllegalArgumentException if a content of the {@code tagData} | ||
| 1396 | * array can not be interpreted as valid tag data, corresponding | ||
| 1397 | * to the {@code tagSignature}. | ||
| 1398 | * @see #getData | ||
| 1399 | */ | ||
| 1400 | public void setData(int tagSignature, byte[] tagData) { | ||
| 1401 | |||
| 1402 | if (ProfileDeferralMgr.deferring) { | ||
| 1403 | ProfileDeferralMgr.activateProfiles(); | ||
| 1404 | } | ||
| 1405 | |||
| 1406 | CMSManager.getModule().setTagData(ID, tagSignature, tagData); | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | /** | ||
| 1410 | * Sets the rendering intent of the profile. | ||
| 1411 | * This is used to select the proper transform from a profile that | ||
| 1412 | * has multiple transforms. | ||
| 1413 | */ | ||
| 1414 | void setRenderingIntent(int renderingIntent) { | ||
| 1415 | byte[] theHeader = getData(icSigHead);/* getData will activate deferred | ||
| 1416 | profiles if necessary */ | ||
| 1417 | intToBigEndian (renderingIntent, theHeader, icHdrRenderingIntent); | ||
| 1418 | /* set the rendering intent */ | ||
| 1419 | setData (icSigHead, theHeader); | ||
| 1420 | } | ||
| 1421 | |||
| 1422 | |||
| 1423 | /** | ||
| 1424 | * Returns the rendering intent of the profile. | ||
| 1425 | * This is used to select the proper transform from a profile that | ||
| 1426 | * has multiple transforms. It is typically set in a source profile | ||
| 1427 | * to select a transform from an output profile. | ||
| 1428 | */ | ||
| 1429 | int getRenderingIntent() { | ||
| 1430 | byte[] theHeader = getData(icSigHead);/* getData will activate deferred | ||
| 1431 | profiles if necessary */ | ||
| 1432 | |||
| 1433 | int renderingIntent = intFromBigEndian(theHeader, icHdrRenderingIntent); | ||
| 1434 | /* set the rendering intent */ | ||
| 1435 | return renderingIntent; | ||
| 1436 | } | ||
| 1437 | |||
| 1438 | |||
| 1439 | /** | ||
| 1440 | * Returns the number of color components in the "input" color | ||
| 1441 | * space of this profile. For example if the color space type | ||
| 1442 | * of this profile is TYPE_RGB, then this method will return 3. | ||
| 1443 | * | ||
| 1444 | * @return The number of color components in the profile's input | ||
| 1445 | * color space. | ||
| 1446 | * | ||
| 1447 | * @throws ProfileDataException if color space is in the profile | ||
| 1448 | * is invalid | ||
| 1449 | */ | ||
| 1450 | public int getNumComponents() { | ||
| 1451 | byte[] theHeader; | ||
| 1452 | int theColorSpaceSig, theNumComponents; | ||
| 1453 | |||
| 1454 | if (deferralInfo != null) { | ||
| 1455 | return deferralInfo.numComponents; /* Need to have this info for | ||
| 1456 | ICC_ColorSpace without | ||
| 1457 | causing a deferred profile | ||
| 1458 | to be loaded */ | ||
| 1459 | } | ||
| 1460 | theHeader = getData(icSigHead); | ||
| 1461 | |||
| 1462 | theColorSpaceSig = intFromBigEndian (theHeader, icHdrColorSpace); | ||
| 1463 | |||
| 1464 | switch (theColorSpaceSig) { | ||
| 1465 | case icSigGrayData: | ||
| 1466 | theNumComponents = 1; | ||
| 1467 | break; | ||
| 1468 | |||
| 1469 | case icSigSpace2CLR: | ||
| 1470 | theNumComponents = 2; | ||
| 1471 | break; | ||
| 1472 | |||
| 1473 | case icSigXYZData: | ||
| 1474 | case icSigLabData: | ||
| 1475 | case icSigLuvData: | ||
| 1476 | case icSigYCbCrData: | ||
| 1477 | case icSigYxyData: | ||
| 1478 | case icSigRgbData: | ||
| 1479 | case icSigHsvData: | ||
| 1480 | case icSigHlsData: | ||
| 1481 | case icSigCmyData: | ||
| 1482 | case icSigSpace3CLR: | ||
| 1483 | theNumComponents = 3; | ||
| 1484 | break; | ||
| 1485 | |||
| 1486 | case icSigCmykData: | ||
| 1487 | case icSigSpace4CLR: | ||
| 1488 | theNumComponents = 4; | ||
| 1489 | break; | ||
| 1490 | |||
| 1491 | case icSigSpace5CLR: | ||
| 1492 | theNumComponents = 5; | ||
| 1493 | break; | ||
| 1494 | |||
| 1495 | case icSigSpace6CLR: | ||
| 1496 | theNumComponents = 6; | ||
| 1497 | break; | ||
| 1498 | |||
| 1499 | case icSigSpace7CLR: | ||
| 1500 | theNumComponents = 7; | ||
| 1501 | break; | ||
| 1502 | |||
| 1503 | case icSigSpace8CLR: | ||
| 1504 | theNumComponents = 8; | ||
| 1505 | break; | ||
| 1506 | |||
| 1507 | case icSigSpace9CLR: | ||
| 1508 | theNumComponents = 9; | ||
| 1509 | break; | ||
| 1510 | |||
| 1511 | case icSigSpaceACLR: | ||
| 1512 | theNumComponents = 10; | ||
| 1513 | break; | ||
| 1514 | |||
| 1515 | case icSigSpaceBCLR: | ||
| 1516 | theNumComponents = 11; | ||
| 1517 | break; | ||
| 1518 | |||
| 1519 | case icSigSpaceCCLR: | ||
| 1520 | theNumComponents = 12; | ||
| 1521 | break; | ||
| 1522 | |||
| 1523 | case icSigSpaceDCLR: | ||
| 1524 | theNumComponents = 13; | ||
| 1525 | break; | ||
| 1526 | |||
| 1527 | case icSigSpaceECLR: | ||
| 1528 | theNumComponents = 14; | ||
| 1529 | break; | ||
| 1530 | |||
| 1531 | case icSigSpaceFCLR: | ||
| 1532 | theNumComponents = 15; | ||
| 1533 | break; | ||
| 1534 | |||
| 1535 | default: | ||
| 1536 | throw new ProfileDataException ("invalid ICC color space"); | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | return theNumComponents; | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | |||
| 1543 | /** | ||
| 1544 | * Returns a float array of length 3 containing the X, Y, and Z | ||
| 1545 | * components of the mediaWhitePointTag in the ICC profile. | ||
| 1546 | */ | ||
| 1547 | float[] getMediaWhitePoint() { | ||
| 1548 | return getXYZTag(icSigMediaWhitePointTag); | ||
| 1549 | /* get the media white point tag */ | ||
| 1550 | } | ||
| 1551 | |||
| 1552 | |||
| 1553 | /** | ||
| 1554 | * Returns a float array of length 3 containing the X, Y, and Z | ||
| 1555 | * components encoded in an XYZType tag. | ||
| 1556 | */ | ||
| 1557 | float[] getXYZTag(int theTagSignature) { | ||
| 1558 | byte[] theData; | ||
| 1559 | float[] theXYZNumber; | ||
| 1560 | int i1, i2, theS15Fixed16; | ||
| 1561 | |||
| 1562 | theData = getData(theTagSignature); /* get the tag data */ | ||
| 1563 | /* getData will activate deferred | ||
| 1564 | profiles if necessary */ | ||
| 1565 | |||
| 1566 | theXYZNumber = new float [3]; /* array to return */ | ||
| 1567 | |||
| 1568 | /* convert s15Fixed16Number to float */ | ||
| 1569 | for (i1 = 0, i2 = icXYZNumberX; i1 < 3; i1++, i2 += 4) { | ||
| 1570 | theS15Fixed16 = intFromBigEndian(theData, i2); | ||
| 1571 | theXYZNumber [i1] = ((float) theS15Fixed16) / 65536.0f; | ||
| 1572 | } | ||
| 1573 | return theXYZNumber; | ||
| 1574 | } | ||
| 1575 | |||
| 1576 | |||
| 1577 | /** | ||
| 1578 | * Returns a gamma value representing a tone reproduction | ||
| 1579 | * curve (TRC). If the profile represents the TRC as a table rather | ||
| 1580 | * than a single gamma value, then an exception is thrown. In this | ||
| 1581 | * case the actual table can be obtained via getTRC(). | ||
| 1582 | * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag, | ||
| 1583 | * icSigGreenTRCTag, or icSigBlueTRCTag. | ||
| 1584 | * @return the gamma value as a float. | ||
| 1585 | * @exception ProfileDataException if the profile does not specify | ||
| 1586 | * the TRC as a single gamma value. | ||
| 1587 | */ | ||
| 1588 | float getGamma(int theTagSignature) { | ||
| 1589 | byte[] theTRCData; | ||
| 1590 | float theGamma; | ||
| 1591 | int theU8Fixed8; | ||
| 1592 | |||
| 1593 | theTRCData = getData(theTagSignature); /* get the TRC */ | ||
| 1594 | /* getData will activate deferred | ||
| 1595 | profiles if necessary */ | ||
| 1596 | |||
| 1597 | if (intFromBigEndian (theTRCData, icCurveCount) != 1) { | ||
| 1598 | throw new ProfileDataException ("TRC is not a gamma"); | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | /* convert u8Fixed8 to float */ | ||
| 1602 | theU8Fixed8 = (shortFromBigEndian(theTRCData, icCurveData)) & 0xffff; | ||
| 1603 | |||
| 1604 | theGamma = ((float) theU8Fixed8) / 256.0f; | ||
| 1605 | |||
| 1606 | return theGamma; | ||
| 1607 | } | ||
| 1608 | |||
| 1609 | |||
| 1610 | /** | ||
| 1611 | * Returns the TRC as an array of shorts. If the profile has | ||
| 1612 | * specified the TRC as linear (gamma = 1.0) or as a simple gamma | ||
| 1613 | * value, this method throws an exception, and the getGamma() method | ||
| 1614 | * should be used to get the gamma value. Otherwise the short array | ||
| 1615 | * returned here represents a lookup table where the input Gray value | ||
| 1616 | * is conceptually in the range [0.0, 1.0]. Value 0.0 maps | ||
| 1617 | * to array index 0 and value 1.0 maps to array index length-1. | ||
| 1618 | * Interpolation may be used to generate output values for | ||
| 1619 | * input values which do not map exactly to an index in the | ||
| 1620 | * array. Output values also map linearly to the range [0.0, 1.0]. | ||
| 1621 | * Value 0.0 is represented by an array value of 0x0000 and | ||
| 1622 | * value 1.0 by 0xFFFF, i.e. the values are really unsigned | ||
| 1623 | * short values, although they are returned in a short array. | ||
| 1624 | * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag, | ||
| 1625 | * icSigGreenTRCTag, or icSigBlueTRCTag. | ||
| 1626 | * @return a short array representing the TRC. | ||
| 1627 | * @exception ProfileDataException if the profile does not specify | ||
| 1628 | * the TRC as a table. | ||
| 1629 | */ | ||
| 1630 | short[] getTRC(int theTagSignature) { | ||
| 1631 | byte[] theTRCData; | ||
| 1632 | short[] theTRC; | ||
| 1633 | int i1, i2, nElements, theU8Fixed8; | ||
| 1634 | |||
| 1635 | theTRCData = getData(theTagSignature); /* get the TRC */ | ||
| 1636 | /* getData will activate deferred | ||
| 1637 | profiles if necessary */ | ||
| 1638 | |||
| 1639 | nElements = intFromBigEndian(theTRCData, icCurveCount); | ||
| 1640 | |||
| 1641 | if (nElements == 1) { | ||
| 1642 | throw new ProfileDataException("TRC is not a table"); | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | /* make the short array */ | ||
| 1646 | theTRC = new short [nElements]; | ||
| 1647 | |||
| 1648 | for (i1 = 0, i2 = icCurveData; i1 < nElements; i1++, i2 += 2) { | ||
| 1649 | theTRC[i1] = shortFromBigEndian(theTRCData, i2); | ||
| 1650 | } | ||
| 1651 | |||
| 1652 | return theTRC; | ||
| 1653 | } | ||
| 1654 | |||
| 1655 | |||
| 1656 | /* convert an ICC color space signature into a Java color space type */ | ||
| 1657 | static int iccCStoJCS(int theColorSpaceSig) { | ||
| 1658 | int theColorSpace; | ||
| 1659 | |||
| 1660 | switch (theColorSpaceSig) { | ||
| 1661 | case icSigXYZData: | ||
| 1662 | theColorSpace = ColorSpace.TYPE_XYZ; | ||
| 1663 | break; | ||
| 1664 | |||
| 1665 | case icSigLabData: | ||
| 1666 | theColorSpace = ColorSpace.TYPE_Lab; | ||
| 1667 | break; | ||
| 1668 | |||
| 1669 | case icSigLuvData: | ||
| 1670 | theColorSpace = ColorSpace.TYPE_Luv; | ||
| 1671 | break; | ||
| 1672 | |||
| 1673 | case icSigYCbCrData: | ||
| 1674 | theColorSpace = ColorSpace.TYPE_YCbCr; | ||
| 1675 | break; | ||
| 1676 | |||
| 1677 | case icSigYxyData: | ||
| 1678 | theColorSpace = ColorSpace.TYPE_Yxy; | ||
| 1679 | break; | ||
| 1680 | |||
| 1681 | case icSigRgbData: | ||
| 1682 | theColorSpace = ColorSpace.TYPE_RGB; | ||
| 1683 | break; | ||
| 1684 | |||
| 1685 | case icSigGrayData: | ||
| 1686 | theColorSpace = ColorSpace.TYPE_GRAY; | ||
| 1687 | break; | ||
| 1688 | |||
| 1689 | case icSigHsvData: | ||
| 1690 | theColorSpace = ColorSpace.TYPE_HSV; | ||
| 1691 | break; | ||
| 1692 | |||
| 1693 | case icSigHlsData: | ||
| 1694 | theColorSpace = ColorSpace.TYPE_HLS; | ||
| 1695 | break; | ||
| 1696 | |||
| 1697 | case icSigCmykData: | ||
| 1698 | theColorSpace = ColorSpace.TYPE_CMYK; | ||
| 1699 | break; | ||
| 1700 | |||
| 1701 | case icSigCmyData: | ||
| 1702 | theColorSpace = ColorSpace.TYPE_CMY; | ||
| 1703 | break; | ||
| 1704 | |||
| 1705 | case icSigSpace2CLR: | ||
| 1706 | theColorSpace = ColorSpace.TYPE_2CLR; | ||
| 1707 | break; | ||
| 1708 | |||
| 1709 | case icSigSpace3CLR: | ||
| 1710 | theColorSpace = ColorSpace.TYPE_3CLR; | ||
| 1711 | break; | ||
| 1712 | |||
| 1713 | case icSigSpace4CLR: | ||
| 1714 | theColorSpace = ColorSpace.TYPE_4CLR; | ||
| 1715 | break; | ||
| 1716 | |||
| 1717 | case icSigSpace5CLR: | ||
| 1718 | theColorSpace = ColorSpace.TYPE_5CLR; | ||
| 1719 | break; | ||
| 1720 | |||
| 1721 | case icSigSpace6CLR: | ||
| 1722 | theColorSpace = ColorSpace.TYPE_6CLR; | ||
| 1723 | break; | ||
| 1724 | |||
| 1725 | case icSigSpace7CLR: | ||
| 1726 | theColorSpace = ColorSpace.TYPE_7CLR; | ||
| 1727 | break; | ||
| 1728 | |||
| 1729 | case icSigSpace8CLR: | ||
| 1730 | theColorSpace = ColorSpace.TYPE_8CLR; | ||
| 1731 | break; | ||
| 1732 | |||
| 1733 | case icSigSpace9CLR: | ||
| 1734 | theColorSpace = ColorSpace.TYPE_9CLR; | ||
| 1735 | break; | ||
| 1736 | |||
| 1737 | case icSigSpaceACLR: | ||
| 1738 | theColorSpace = ColorSpace.TYPE_ACLR; | ||
| 1739 | break; | ||
| 1740 | |||
| 1741 | case icSigSpaceBCLR: | ||
| 1742 | theColorSpace = ColorSpace.TYPE_BCLR; | ||
| 1743 | break; | ||
| 1744 | |||
| 1745 | case icSigSpaceCCLR: | ||
| 1746 | theColorSpace = ColorSpace.TYPE_CCLR; | ||
| 1747 | break; | ||
| 1748 | |||
| 1749 | case icSigSpaceDCLR: | ||
| 1750 | theColorSpace = ColorSpace.TYPE_DCLR; | ||
| 1751 | break; | ||
| 1752 | |||
| 1753 | case icSigSpaceECLR: | ||
| 1754 | theColorSpace = ColorSpace.TYPE_ECLR; | ||
| 1755 | break; | ||
| 1756 | |||
| 1757 | case icSigSpaceFCLR: | ||
| 1758 | theColorSpace = ColorSpace.TYPE_FCLR; | ||
| 1759 | break; | ||
| 1760 | |||
| 1761 | default: | ||
| 1762 | throw new IllegalArgumentException ("Unknown color space"); | ||
| 1763 | } | ||
| 1764 | |||
| 1765 | return theColorSpace; | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | |||
| 1769 | static int intFromBigEndian(byte[] array, int index) { | ||
| 1770 | return (((array[index] & 0xff) << 24) | | ||
| 1771 | ((array[index+1] & 0xff) << 16) | | ||
| 1772 | ((array[index+2] & 0xff) << 8) | | ||
| 1773 | (array[index+3] & 0xff)); | ||
| 1774 | } | ||
| 1775 | |||
| 1776 | |||
| 1777 | static void intToBigEndian(int value, byte[] array, int index) { | ||
| 1778 | array[index] = (byte) (value >> 24); | ||
| 1779 | array[index+1] = (byte) (value >> 16); | ||
| 1780 | array[index+2] = (byte) (value >> 8); | ||
| 1781 | array[index+3] = (byte) (value); | ||
| 1782 | } | ||
| 1783 | |||
| 1784 | |||
| 1785 | static short shortFromBigEndian(byte[] array, int index) { | ||
| 1786 | return (short) (((array[index] & 0xff) << 8) | | ||
| 1787 | (array[index+1] & 0xff)); | ||
| 1788 | } | ||
| 1789 | |||
| 1790 | |||
| 1791 | static void shortToBigEndian(short value, byte[] array, int index) { | ||
| 1792 | array[index] = (byte) (value >> 8); | ||
| 1793 | array[index+1] = (byte) (value); | ||
| 1794 | } | ||
| 1795 | |||
| 1796 | |||
| 1797 | /* | ||
| 1798 | * fileName may be an absolute or a relative file specification. | ||
| 1799 | * Relative file names are looked for in several places: first, relative | ||
| 1800 | * to any directories specified by the java.iccprofile.path property; | ||
| 1801 | * second, relative to any directories specified by the java.class.path | ||
| 1802 | * property; finally, in a directory used to store profiles always | ||
| 1803 | * available, such as a profile for sRGB. Built-in profiles use .pf as | ||
| 1804 | * the file name extension for profiles, e.g. sRGB.pf. | ||
| 1805 | */ | ||
| 1806 | private static File getProfileFile(String fileName) { | ||
| 1807 | String path, dir, fullPath; | ||
| 1808 | |||
| 1809 | File f = new File(fileName); /* try absolute file name */ | ||
| 1810 | if (f.isAbsolute()) { | ||
| 1811 | /* Rest of code has little sense for an absolute pathname, | ||
| 1812 | so return here. */ | ||
| 1813 | return f.isFile() ? f : null; | ||
| 1814 | } | ||
| 1815 | if ((!f.isFile()) && | ||
| 1816 | ((path = System.getProperty("java.iccprofile.path")) != null)){ | ||
| 1817 | /* try relative to java.iccprofile.path */ | ||
| 1818 | StringTokenizer st = | ||
| 1819 | new StringTokenizer(path, File.pathSeparator); | ||
| 1820 | while (st.hasMoreTokens() && ((f == null) || (!f.isFile()))) { | ||
| 1821 | dir = st.nextToken(); | ||
| 1822 | fullPath = dir + File.separatorChar + fileName; | ||
| 1823 | f = new File(fullPath); | ||
| 1824 | if (!isChildOf(f, dir)) { | ||
| 1825 | f = null; | ||
| 1826 | } | ||
| 1827 | } | ||
| 1828 | } | ||
| 1829 | |||
| 1830 | if (((f == null) || (!f.isFile())) && | ||
| 1831 | ((path = System.getProperty("java.class.path")) != null)) { | ||
| 1832 | /* try relative to java.class.path */ | ||
| 1833 | StringTokenizer st = | ||
| 1834 | new StringTokenizer(path, File.pathSeparator); | ||
| 1835 | while (st.hasMoreTokens() && ((f == null) || (!f.isFile()))) { | ||
| 1836 | dir = st.nextToken(); | ||
| 1837 | fullPath = dir + File.separatorChar + fileName; | ||
| 1838 | f = new File(fullPath); | ||
| 1839 | } | ||
| 1840 | } | ||
| 1841 | |||
| 1842 | if ((f == null) || (!f.isFile())) { | ||
| 1843 | /* try the directory of built-in profiles */ | ||
| 1844 | f = getStandardProfileFile(fileName); | ||
| 1845 | } | ||
| 1846 | if (f != null && f.isFile()) { | ||
| 1847 | return f; | ||
| 1848 | } | ||
| 1849 | return null; | ||
| 1850 | } | ||
| 1851 | |||
| 1852 | /** | ||
| 1853 | * Returns a file object corresponding to a built-in profile | ||
| 1854 | * specified by fileName. | ||
| 1855 | * If there is no built-in profile with such name, then the method | ||
| 1856 | * returns null. | ||
| 1857 | */ | ||
| 1858 | private static File getStandardProfileFile(String fileName) { | ||
| 1859 | String dir = System.getProperty("java.home") + | ||
| 1860 | File.separatorChar + "lib" + File.separatorChar + "cmm"; | ||
| 1861 | String fullPath = dir + File.separatorChar + fileName; | ||
| 1862 | File f = new File(fullPath); | ||
| 1863 | return (f.isFile() && isChildOf(f, dir)) ? f : null; | ||
| 1864 | } | ||
| 1865 | |||
| 1866 | /** | ||
| 1867 | * Checks whether given file resides inside give directory. | ||
| 1868 | */ | ||
| 1869 | private static boolean isChildOf(File f, String dirName) { | ||
| 1870 | try { | ||
| 1871 | File dir = new File(dirName); | ||
| 1872 | String canonicalDirName = dir.getCanonicalPath(); | ||
| 1873 | if (!canonicalDirName.endsWith(File.separator)) { | ||
| 1874 | canonicalDirName += File.separator; | ||
| 1875 | } | ||
| 1876 | String canonicalFileName = f.getCanonicalPath(); | ||
| 1877 | return canonicalFileName.startsWith(canonicalDirName); | ||
| 1878 | } catch (IOException e) { | ||
| 1879 | /* we do not expect the IOException here, because invocation | ||
| 1880 | * of this function is always preceeded by isFile() call. | ||
| 1881 | */ | ||
| 1882 | return false; | ||
| 1883 | } | ||
| 1884 | } | ||
| 1885 | |||
| 1886 | /** | ||
| 1887 | * Checks whether built-in profile specified by fileName exists. | ||
| 1888 | */ | ||
| 1889 | private static boolean standardProfileExists(final String fileName) { | ||
| 1890 | return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { | ||
| 1891 | public Boolean run() { | ||
| 1892 | return getStandardProfileFile(fileName) != null; | ||
| 1893 | } | ||
| 1894 | }); | ||
| 1895 | } | ||
| 1896 | |||
| 1897 | |||
| 1898 | /* | ||
| 1899 | * Serialization support. | ||
| 1900 | * | ||
| 1901 | * Directly deserialized profiles are useless since they are not | ||
| 1902 | * registered with CMM. We don't allow constructor to be called | ||
| 1903 | * directly and instead have clients to call one of getInstance | ||
| 1904 | * factory methods that will register the profile with CMM. For | ||
| 1905 | * deserialization we implement readResolve method that will | ||
| 1906 | * resolve the bogus deserialized profile object with one obtained | ||
| 1907 | * with getInstance as well. | ||
| 1908 | * | ||
| 1909 | * There're two primary factory methods for construction of ICC | ||
| 1910 | * profiles: getInstance(int cspace) and getInstance(byte[] data). | ||
| 1911 | * This implementation of ICC_Profile uses the former to return a | ||
| 1912 | * cached singleton profile object, other implementations will | ||
| 1913 | * likely use this technique too. To preserve the singleton | ||
| 1914 | * pattern across serialization we serialize cached singleton | ||
| 1915 | * profiles in such a way that deserializing VM could call | ||
| 1916 | * getInstance(int cspace) method that will resolve deserialized | ||
| 1917 | * object into the corresponding singleton as well. | ||
| 1918 | * | ||
| 1919 | * Since the singletons are private to ICC_Profile the readResolve | ||
| 1920 | * method have to be `protected' instead of `private' so that | ||
| 1921 | * singletons that are instances of subclasses of ICC_Profile | ||
| 1922 | * could be correctly deserialized. | ||
| 1923 | */ | ||
| 1924 | |||
| 1925 | |||
| 1926 | /** | ||
| 1927 | * Version of the format of additional serialized data in the | ||
| 1928 | * stream. Version <code>1</code> corresponds to Java 2 | ||
| 1929 | * Platform, v1.3. | ||
| 1930 | * @since 1.3 | ||
| 1931 | * @serial | ||
| 1932 | */ | ||
| 1933 | private int iccProfileSerializedDataVersion = 1; | ||
| 1934 | |||
| 1935 | |||
| 1936 | /** | ||
| 1937 | * Writes default serializable fields to the stream. Writes a | ||
| 1938 | * string and an array of bytes to the stream as additional data. | ||
| 1939 | * | ||
| 1940 | * @param s stream used for serialization. | ||
| 1941 | * @throws IOException | ||
| 1942 | * thrown by <code>ObjectInputStream</code>. | ||
| 1943 | * @serialData | ||
| 1944 | * The <code>String</code> is the name of one of | ||
| 1945 | * <code>CS_<var>*</var></code> constants defined in the | ||
| 1946 | * {@link ColorSpace} class if the profile object is a profile | ||
| 1947 | * for a predefined color space (for example | ||
| 1948 | * <code>"CS_sRGB"</code>). The string is <code>null</code> | ||
| 1949 | * otherwise. | ||
| 1950 | * <p> | ||
| 1951 | * The <code>byte[]</code> array is the profile data for the | ||
| 1952 | * profile. For predefined color spaces <code>null</code> is | ||
| 1953 | * written instead of the profile data. If in the future | ||
| 1954 | * versions of Java API new predefined color spaces will be | ||
| 1955 | * added, future versions of this class may choose to write | ||
| 1956 | * for new predefined color spaces not only the color space | ||
| 1957 | * name, but the profile data as well so that older versions | ||
| 1958 | * could still deserialize the object. | ||
| 1959 | */ | ||
| 1960 | private void writeObject(ObjectOutputStream s) | ||
| 1961 | throws IOException | ||
| 1962 | { | ||
| 1963 | s.defaultWriteObject(); | ||
| 1964 | |||
| 1965 | String csName = null; | ||
| 1966 | if (this == sRGBprofile) { | ||
| 1967 | csName = "CS_sRGB"; | ||
| 1968 | } else if (this == XYZprofile) { | ||
| 1969 | csName = "CS_CIEXYZ"; | ||
| 1970 | } else if (this == PYCCprofile) { | ||
| 1971 | csName = "CS_PYCC"; | ||
| 1972 | } else if (this == GRAYprofile) { | ||
| 1973 | csName = "CS_GRAY"; | ||
| 1974 | } else if (this == LINEAR_RGBprofile) { | ||
| 1975 | csName = "CS_LINEAR_RGB"; | ||
| 1976 | } | ||
| 1977 | |||
| 1978 | // Future versions may choose to write profile data for new | ||
| 1979 | // predefined color spaces as well, if any will be introduced, | ||
| 1980 | // so that old versions that don't recognize the new CS name | ||
| 1981 | // may fall back to constructing profile from the data. | ||
| 1982 | byte[] data = null; | ||
| 1983 | if (csName == null) { | ||
| 1984 | // getData will activate deferred profile if necessary | ||
| 1985 | data = getData(); | ||
| 1986 | } | ||
| 1987 | |||
| 1988 | s.writeObject(csName); | ||
| 1989 | s.writeObject(data); | ||
| 1990 | } | ||
| 1991 | |||
| 1992 | // Temporary storage used by readObject to store resolved profile | ||
| 1993 | // (obtained with getInstance) for readResolve to return. | ||
| 1994 | private transient ICC_Profile resolvedDeserializedProfile; | ||
| 1995 | |||
| 1996 | /** | ||
| 1997 | * Reads default serializable fields from the stream. Reads from | ||
| 1998 | * the stream a string and an array of bytes as additional data. | ||
| 1999 | * | ||
| 2000 | * @param s stream used for deserialization. | ||
| 2001 | * @throws IOException | ||
| 2002 | * thrown by <code>ObjectInputStream</code>. | ||
| 2003 | * @throws ClassNotFoundException | ||
| 2004 | * thrown by <code>ObjectInputStream</code>. | ||
| 2005 | * @serialData | ||
| 2006 | * The <code>String</code> is the name of one of | ||
| 2007 | * <code>CS_<var>*</var></code> constants defined in the | ||
| 2008 | * {@link ColorSpace} class if the profile object is a profile | ||
| 2009 | * for a predefined color space (for example | ||
| 2010 | * <code>"CS_sRGB"</code>). The string is <code>null</code> | ||
| 2011 | * otherwise. | ||
| 2012 | * <p> | ||
| 2013 | * The <code>byte[]</code> array is the profile data for the | ||
| 2014 | * profile. It will usually be <code>null</code> for the | ||
| 2015 | * predefined profiles. | ||
| 2016 | * <p> | ||
| 2017 | * If the string is recognized as a constant name for | ||
| 2018 | * predefined color space the object will be resolved into | ||
| 2019 | * profile obtained with | ||
| 2020 | * <code>getInstance(int cspace)</code> and the profile | ||
| 2021 | * data are ignored. Otherwise the object will be resolved | ||
| 2022 | * into profile obtained with | ||
| 2023 | * <code>getInstance(byte[] data)</code>. | ||
| 2024 | * @see #readResolve() | ||
| 2025 | * @see #getInstance(int) | ||
| 2026 | * @see #getInstance(byte[]) | ||
| 2027 | */ | ||
| 2028 | private void readObject(ObjectInputStream s) | ||
| 2029 | throws IOException, ClassNotFoundException | ||
| 2030 | { | ||
| 2031 | s.defaultReadObject(); | ||
| 2032 | |||
| 2033 | String csName = (String)s.readObject(); | ||
| 2034 | byte[] data = (byte[])s.readObject(); | ||
| 2035 | |||
| 2036 | int cspace = 0; // ColorSpace.CS_* constant if known | ||
| 2037 | boolean isKnownPredefinedCS = false; | ||
| 2038 | if (csName != null) { | ||
| 2039 | isKnownPredefinedCS = true; | ||
| 2040 | if (csName.equals("CS_sRGB")) { | ||
| 2041 | cspace = ColorSpace.CS_sRGB; | ||
| 2042 | } else if (csName.equals("CS_CIEXYZ")) { | ||
| 2043 | cspace = ColorSpace.CS_CIEXYZ; | ||
| 2044 | } else if (csName.equals("CS_PYCC")) { | ||
| 2045 | cspace = ColorSpace.CS_PYCC; | ||
| 2046 | } else if (csName.equals("CS_GRAY")) { | ||
| 2047 | cspace = ColorSpace.CS_GRAY; | ||
| 2048 | } else if (csName.equals("CS_LINEAR_RGB")) { | ||
| 2049 | cspace = ColorSpace.CS_LINEAR_RGB; | ||
| 2050 | } else { | ||
| 2051 | isKnownPredefinedCS = false; | ||
| 2052 | } | ||
| 2053 | } | ||
| 2054 | |||
| 2055 | if (isKnownPredefinedCS) { | ||
| 2056 | resolvedDeserializedProfile = getInstance(cspace); | ||
| 2057 | } else { | ||
| 2058 | resolvedDeserializedProfile = getInstance(data); | ||
| 2059 | } | ||
| 2060 | } | ||
| 2061 | |||
| 2062 | /** | ||
| 2063 | * Resolves instances being deserialized into instances registered | ||
| 2064 | * with CMM. | ||
| 2065 | * @return ICC_Profile object for profile registered with CMM. | ||
| 2066 | * @throws ObjectStreamException | ||
| 2067 | * never thrown, but mandated by the serialization spec. | ||
| 2068 | * @since 1.3 | ||
| 2069 | */ | ||
| 2070 | protected Object readResolve() throws ObjectStreamException { | ||
| 2071 | return resolvedDeserializedProfile; | ||
| 2072 | } | ||
| 2073 | } | ||
Binary file not shown.
| @@ -0,0 +1,150 @@ | |||
| 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 java.awt.image.LookupTable; | ||
| 39 | import sun.java2d.cmm.ProfileDeferralInfo; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * | ||
| 43 | * A subclass of the ICC_Profile class which represents profiles | ||
| 44 | * which meet the following criteria: the color space type of the | ||
| 45 | * profile is TYPE_GRAY and the profile includes the grayTRCTag and | ||
| 46 | * mediaWhitePointTag tags. Examples of this kind of profile are | ||
| 47 | * monochrome input profiles, monochrome display profiles, and | ||
| 48 | * monochrome output profiles. The getInstance methods in the | ||
| 49 | * ICC_Profile class will | ||
| 50 | * return an ICC_ProfileGray object when the above conditions are | ||
| 51 | * met. The advantage of this class is that it provides a lookup | ||
| 52 | * table that Java or native methods may be able to use directly to | ||
| 53 | * optimize color conversion in some cases. | ||
| 54 | * <p> | ||
| 55 | * To transform from a GRAY device profile color space to the CIEXYZ Profile | ||
| 56 | * Connection Space, the device gray component is transformed by | ||
| 57 | * a lookup through the tone reproduction curve (TRC). The result is | ||
| 58 | * treated as the achromatic component of the PCS. | ||
| 59 | <pre> | ||
| 60 | |||
| 61 | PCSY = grayTRC[deviceGray] | ||
| 62 | |||
| 63 | </pre> | ||
| 64 | * The inverse transform is done by converting the PCS Y components to | ||
| 65 | * device Gray via the inverse of the grayTRC. | ||
| 66 | * <p> | ||
| 67 | */ | ||
| 68 | |||
| 69 | |||
| 70 | |||
| 71 | public class ICC_ProfileGray | ||
| 72 | extends ICC_Profile { | ||
| 73 | |||
| 74 | static final long serialVersionUID = -1124721290732002649L; | ||
| 75 | |||
| 76 | /** | ||
| 77 | * Constructs a new ICC_ProfileGray from a CMM ID. | ||
| 78 | */ | ||
| 79 | ICC_ProfileGray(long ID) { | ||
| 80 | super(ID); | ||
| 81 | } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * Constructs a new ICC_ProfileGray from a ProfileDeferralInfo object. | ||
| 85 | */ | ||
| 86 | ICC_ProfileGray(ProfileDeferralInfo pdi) { | ||
| 87 | super(pdi); | ||
| 88 | } | ||
| 89 | |||
| 90 | |||
| 91 | /** | ||
| 92 | * Returns a float array of length 3 containing the X, Y, and Z | ||
| 93 | * components of the mediaWhitePointTag in the ICC profile. | ||
| 94 | * @return an array containing the components of the | ||
| 95 | * mediaWhitePointTag in the ICC profile. | ||
| 96 | */ | ||
| 97 | public float[] getMediaWhitePoint() { | ||
| 98 | return super.getMediaWhitePoint(); | ||
| 99 | } | ||
| 100 | |||
| 101 | |||
| 102 | /** | ||
| 103 | * Returns a gamma value representing the tone reproduction | ||
| 104 | * curve (TRC). If the profile represents the TRC as a table rather | ||
| 105 | * than a single gamma value, then an exception is thrown. In this | ||
| 106 | * case the actual table can be obtained via getTRC(). When | ||
| 107 | * using a gamma value, the PCS Y component is computed as follows: | ||
| 108 | <pre> | ||
| 109 | |||
| 110 | gamma | ||
| 111 | PCSY = deviceGray | ||
| 112 | |||
| 113 | </pre> | ||
| 114 | * @return the gamma value as a float. | ||
| 115 | * @exception ProfileDataException if the profile does not specify | ||
| 116 | * the TRC as a single gamma value. | ||
| 117 | */ | ||
| 118 | public float getGamma() { | ||
| 119 | float theGamma; | ||
| 120 | |||
| 121 | theGamma = super.getGamma(ICC_Profile.icSigGrayTRCTag); | ||
| 122 | return theGamma; | ||
| 123 | } | ||
| 124 | |||
| 125 | /** | ||
| 126 | * Returns the TRC as an array of shorts. If the profile has | ||
| 127 | * specified the TRC as linear (gamma = 1.0) or as a simple gamma | ||
| 128 | * value, this method throws an exception, and the getGamma() method | ||
| 129 | * should be used to get the gamma value. Otherwise the short array | ||
| 130 | * returned here represents a lookup table where the input Gray value | ||
| 131 | * is conceptually in the range [0.0, 1.0]. Value 0.0 maps | ||
| 132 | * to array index 0 and value 1.0 maps to array index length-1. | ||
| 133 | * Interpolation may be used to generate output values for | ||
| 134 | * input values which do not map exactly to an index in the | ||
| 135 | * array. Output values also map linearly to the range [0.0, 1.0]. | ||
| 136 | * Value 0.0 is represented by an array value of 0x0000 and | ||
| 137 | * value 1.0 by 0xFFFF, i.e. the values are really unsigned | ||
| 138 | * short values, although they are returned in a short array. | ||
| 139 | * @return a short array representing the TRC. | ||
| 140 | * @exception ProfileDataException if the profile does not specify | ||
| 141 | * the TRC as a table. | ||
| 142 | */ | ||
| 143 | public short[] getTRC() { | ||
| 144 | short[] theTRC; | ||
| 145 | |||
| 146 | theTRC = super.getTRC(ICC_Profile.icSigGrayTRCTag); | ||
| 147 | return theTRC; | ||
| 148 | } | ||
| 149 | |||
| 150 | } | ||
Binary file not shown.
| @@ -0,0 +1,282 @@ | |||
| 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 java.awt.image.LookupTable; | ||
| 39 | import sun.java2d.cmm.ProfileDeferralInfo; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * | ||
| 43 | * The ICC_ProfileRGB class is a subclass of the ICC_Profile class | ||
| 44 | * that represents profiles which meet the following criteria: | ||
| 45 | * <ul> | ||
| 46 | * <li>The profile's color space type is RGB.</li> | ||
| 47 | * <li>The profile includes the <code>redColorantTag</code>, | ||
| 48 | * <code>greenColorantTag</code>, <code>blueColorantTag</code>, | ||
| 49 | * <code>redTRCTag</code>, <code>greenTRCTag</code>, | ||
| 50 | * <code>blueTRCTag</code>, and <code>mediaWhitePointTag</code> tags.</li> | ||
| 51 | * </ul> | ||
| 52 | * The <code>ICC_Profile</code> <code>getInstance</code> method will | ||
| 53 | * return an <code>ICC_ProfileRGB</code> object when these conditions are met. | ||
| 54 | * Three-component, matrix-based input profiles and RGB display profiles are | ||
| 55 | * examples of this type of profile. | ||
| 56 | * <p> | ||
| 57 | * This profile class provides color transform matrices and lookup tables | ||
| 58 | * that Java or native methods can use directly to | ||
| 59 | * optimize color conversion in some cases. | ||
| 60 | * <p> | ||
| 61 | * To transform from a device profile color space to the CIEXYZ Profile | ||
| 62 | * Connection Space, each device color component is first linearized by | ||
| 63 | * a lookup through the corresponding tone reproduction curve (TRC). | ||
| 64 | * The resulting linear RGB components are converted to the CIEXYZ PCS | ||
| 65 | * using a a 3x3 matrix constructed from the RGB colorants. | ||
| 66 | * <pre> | ||
| 67 | * | ||
| 68 | * linearR = redTRC[deviceR] | ||
| 69 | * | ||
| 70 | * linearG = greenTRC[deviceG] | ||
| 71 | * | ||
| 72 | * linearB = blueTRC[deviceB] | ||
| 73 | * | ||
| 74 | * _ _ _ _ _ _ | ||
| 75 | * [ PCSX ] [ redColorantX greenColorantX blueColorantX ] [ linearR ] | ||
| 76 | * [ ] [ ] [ ] | ||
| 77 | * [ PCSY ] = [ redColorantY greenColorantY blueColorantY ] [ linearG ] | ||
| 78 | * [ ] [ ] [ ] | ||
| 79 | * [_ PCSZ _] [_ redColorantZ greenColorantZ blueColorantZ _] [_ linearB _] | ||
| 80 | * | ||
| 81 | * </pre> | ||
| 82 | * The inverse transform is performed by converting PCS XYZ components to linear | ||
| 83 | * RGB components through the inverse of the above 3x3 matrix, and then converting | ||
| 84 | * linear RGB to device RGB through inverses of the TRCs. | ||
| 85 | * <p> | ||
| 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</code> from a CMM ID. | ||
| 113 | * | ||
| 114 | * @param ID The CMM ID for the profile. | ||
| 115 | * | ||
| 116 | */ | ||
| 117 | ICC_ProfileRGB(long ID) { | ||
| 118 | super(ID); | ||
| 119 | } | ||
| 120 | |||
| 121 | /** | ||
| 122 | * Constructs a new <code>ICC_ProfileRGB</code> 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</CODE>. | ||
| 135 | * | ||
| 136 | * @return A 3-element <CODE>float</CODE> array containing the x, y, | ||
| 137 | * and z components of the profile's <CODE>mediaWhitePointTag</CODE>. | ||
| 138 | */ | ||
| 139 | public float[] getMediaWhitePoint() { | ||
| 140 | return super.getMediaWhitePoint(); | ||
| 141 | } | ||
| 142 | |||
| 143 | |||
| 144 | /** | ||
| 145 | * Returns a 3x3 <CODE>float</CODE> matrix constructed from the | ||
| 146 | * X, Y, and Z components of the profile's <CODE>redColorantTag</CODE>, | ||
| 147 | * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>. | ||
| 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</CODE> array that contains the x, y, and z | ||
| 154 | * components of the profile's <CODE>redColorantTag</CODE>, | ||
| 155 | * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>. | ||
| 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</CODE> 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</code>, | ||
| 229 | * <code>GREENCOMPONENT</code>, or <code>BLUECOMPONENT</code>. | ||
| 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</code> values even though they are returned in a | ||
| 240 | * <code>short</code> 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</CODE> constant that | ||
| 248 | * represents the component whose TRC you want to retrieve: | ||
| 249 | * <CODE>REDCOMPONENT</CODE>, <CODE>GREENCOMPONENT</CODE>, or | ||
| 250 | * <CODE>BLUECOMPONENT</CODE>. | ||
| 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 | } | ||
Binary file not shown.
| @@ -0,0 +1,42 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2000, 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 | package java.awt.color; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This exception is thrown when an error occurs in accessing or | ||
| 30 | * processing an ICC_Profile object. | ||
| 31 | */ | ||
| 32 | |||
| 33 | public class ProfileDataException extends java.lang.RuntimeException { | ||
| 34 | |||
| 35 | /** | ||
| 36 | * Constructs a ProfileDataException with the specified detail message. | ||
| 37 | * @param s the specified detail message | ||
| 38 | */ | ||
| 39 | public ProfileDataException(String s) { | ||
| 40 | super (s); | ||
| 41 | } | ||
| 42 | } | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
| 3 | TARG=\ | ||
| 4 | CMMException.dis\ | ||
| 5 | ColorSpace.dis\ | ||
| 6 | ICC_ColorSpace.dis\ | ||
| 7 | ICC_Profile.dis\ | ||
| 8 | ICC_ProfileGray.dis\ | ||
| 9 | ICC_ProfileRGB.dis\ | ||
| 10 | ProfileDataException.dis\ | ||
| 11 | |||
| 12 | DISBIN=$ROOT/java/dis/java/java/java/awt/color | ||
| 13 | |||
| 14 | <$ROOT/mkfiles/mkjava | ||
| @@ -0,0 +1,54 @@ | |||
| 1 | <!-- | ||
| 2 | Copyright (c) 1998, 1999, 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 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> | ||
| 27 | <html> | ||
| 28 | <body bgcolor="white"> | ||
| 29 | |||
| 30 | Provides classes for color spaces. It contains an | ||
| 31 | implementation of a color space based on the International Color | ||
| 32 | Consortium (ICC) Profile Format Specification, Version 3.4, August 15, | ||
| 33 | 1997. It also contains color profiles based on the ICC Profile Format | ||
| 34 | Specification. | ||
| 35 | |||
| 36 | <!-- | ||
| 37 | <h2>Package Specification</h2> | ||
| 38 | |||
| 39 | ##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT ##### | ||
| 40 | <ul> | ||
| 41 | <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a> | ||
| 42 | </ul> | ||
| 43 | |||
| 44 | <h2>Related Documentation</h2> | ||
| 45 | |||
| 46 | For overviews, tutorials, examples, guides, and tool documentation, please see: | ||
| 47 | <ul> | ||
| 48 | <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a> | ||
| 49 | </ul> | ||
| 50 | --> | ||
| 51 | |||
| 52 | @since 1.2 | ||
| 53 | </body> | ||
| 54 | </html> | ||