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