1. /*
  2. * @(#)ICC_ColorSpace.java 1.29 03/01/23
  3. *
  4. * Copyright 2003 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.ICC_Transform;
  18. /**
  19. *
  20. * The ICC_ColorSpace class is an implementation of the abstract
  21. * ColorSpace class. This representation of
  22. * device independent and device dependent color spaces is based on the
  23. * International Color Consortium Specification ICC.1:1998-09, File Format for
  24. * Color Profiles, September 1998, and the addendum ICC.1A:1999-04, April 1999,
  25. * to that specification (see <A href="http://www.color.org">
  26. * http://www.color.org</A>).
  27. * <p>
  28. * Typically, a Color or ColorModel would be associated with an ICC
  29. * Profile which is either an input, display, or output profile (see
  30. * the ICC specification). There are other types of ICC Profiles, e.g.
  31. * abstract profiles, device link profiles, and named color profiles,
  32. * which do not contain information appropriate for representing the color
  33. * space of a color, image, or device (see ICC_Profile).
  34. * Attempting to create an ICC_ColorSpace object from an inappropriate ICC
  35. * Profile is an error.
  36. * <p>
  37. * ICC Profiles represent transformations from the color space of
  38. * the profile (e.g. a monitor) to a Profile Connection Space (PCS).
  39. * Profiles of interest for tagging images or colors have a
  40. * PCS which is one of the device independent
  41. * spaces (one CIEXYZ space and two CIELab spaces) defined in the
  42. * ICC Profile Format Specification. Most profiles of interest
  43. * either have invertible transformations or explicitly specify
  44. * transformations going both directions. Should an ICC_ColorSpace
  45. * object be used in a way requiring a conversion from PCS to
  46. * the profile's native space and there is inadequate data to
  47. * correctly perform the conversion, the ICC_ColorSpace object will
  48. * produce output in the specified type of color space (e.g. TYPE_RGB,
  49. * TYPE_CMYK, etc.), but the specific color values of the output data
  50. * will be undefined.
  51. * <p>
  52. * The details of this class are not important for simple applets,
  53. * which draw in a default color space or manipulate and display
  54. * imported images with a known color space. At most, such applets
  55. * would need to get one of the default color spaces via
  56. * ColorSpace.getInstance().
  57. * <p>
  58. * @see ColorSpace
  59. * @see ICC_Profile
  60. */
  61. public class ICC_ColorSpace extends ColorSpace {
  62. static final long serialVersionUID = 3455889114070431483L;
  63. private ICC_Profile thisProfile;
  64. private float[] minVal;
  65. private float[] maxVal;
  66. private float[] diffMinMax;
  67. private float[] invDiffMinMax;
  68. private boolean needScaleInit = true;
  69. // {to,from}{RGB,CIEXYZ} methods create and cache these when needed
  70. private transient ICC_Transform this2srgb;
  71. private transient ICC_Transform srgb2this;
  72. private transient ICC_Transform this2xyz;
  73. private transient ICC_Transform xyz2this;
  74. /**
  75. * Constructs a new ICC_ColorSpace from an ICC_Profile object.
  76. * @param profile the specified ICC_Profile object
  77. * @exception IllegalArgumentException if profile is inappropriate for
  78. * representing a ColorSpace.
  79. */
  80. public ICC_ColorSpace (ICC_Profile profile) {
  81. super (profile.getColorSpaceType(), profile.getNumComponents());
  82. int profileClass = profile.getProfileClass();
  83. /* REMIND - is NAMEDCOLOR OK? */
  84. if ((profileClass != ICC_Profile.CLASS_INPUT) &&
  85. (profileClass != ICC_Profile.CLASS_DISPLAY) &&
  86. (profileClass != ICC_Profile.CLASS_OUTPUT) &&
  87. (profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) &&
  88. (profileClass != ICC_Profile.CLASS_NAMEDCOLOR) ) {
  89. throw new IllegalArgumentException("Invalid profile type");
  90. }
  91. thisProfile = profile;
  92. setMinMax();
  93. }
  94. /**
  95. * Returns the ICC_Profile for this ICC_ColorSpace.
  96. * @return the ICC_Profile for this ICC_ColorSpace.
  97. */
  98. public ICC_Profile getProfile() {
  99. return thisProfile;
  100. }
  101. /**
  102. * Transforms a color value assumed to be in this ColorSpace
  103. * into a value in the default CS_sRGB color space.
  104. * <p>
  105. * This method transforms color values using algorithms designed
  106. * to produce the best perceptual match between input and output
  107. * colors. In order to do colorimetric conversion of color values,
  108. * you should use the <code>toCIEXYZ</code>
  109. * method of this color space to first convert from the input
  110. * color space to the CS_CIEXYZ color space, and then use the
  111. * <code>fromCIEXYZ</code> method of the CS_sRGB color space to
  112. * convert from CS_CIEXYZ to the output color space.
  113. * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
  114. * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
  115. * <p>
  116. * @param colorvalue a float array with length of at least the number
  117. * of components in this ColorSpace.
  118. * @return a float array of length 3.
  119. * @throws ArrayIndexOutOfBoundsException if array length is not
  120. * at least the number of components in this ColorSpace.
  121. */
  122. public float[] toRGB (float[] colorvalue) {
  123. if (this2srgb == null) {
  124. ICC_Transform[] transformList = new ICC_Transform [2];
  125. ICC_ColorSpace srgbCS =
  126. (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
  127. transformList[0] = new ICC_Transform (
  128. thisProfile, ICC_Transform.Any, ICC_Transform.In);
  129. transformList[1] = new ICC_Transform (
  130. srgbCS.getProfile(), ICC_Transform.Any, ICC_Transform.Out);
  131. this2srgb = new ICC_Transform (transformList);
  132. if (needScaleInit) {
  133. setComponentScaling();
  134. }
  135. }
  136. int nc = this.getNumComponents();
  137. short tmp[] = new short[nc];
  138. for (int i = 0; i < nc; i++) {
  139. tmp[i] = (short)
  140. ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
  141. }
  142. tmp = this2srgb.colorConvert(tmp, null);
  143. float[] result = new float [3];
  144. for (int i = 0; i < 3; i++) {
  145. result[i] = ((float) (tmp[i] & 0xffff)) / 65535.0f;
  146. }
  147. return result;
  148. }
  149. /**
  150. * Transforms a color value assumed to be in the default CS_sRGB
  151. * color space into this ColorSpace.
  152. * <p>
  153. * This method transforms color values using algorithms designed
  154. * to produce the best perceptual match between input and output
  155. * colors. In order to do colorimetric conversion of color values,
  156. * you should use the <code>toCIEXYZ</code>
  157. * method of the CS_sRGB color space to first convert from the input
  158. * color space to the CS_CIEXYZ color space, and then use the
  159. * <code>fromCIEXYZ</code> method of this color space to
  160. * convert from CS_CIEXYZ to the output color space.
  161. * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
  162. * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
  163. * <p>
  164. * @param rgbvalue a float array with length of at least 3.
  165. * @return a float array with length equal to the number of
  166. * components in this ColorSpace.
  167. * @throws ArrayIndexOutOfBoundsException if array length is not
  168. * at least 3.
  169. */
  170. public float[] fromRGB(float[] rgbvalue) {
  171. if (srgb2this == null) {
  172. ICC_Transform[] transformList = new ICC_Transform [2];
  173. ICC_ColorSpace srgbCS =
  174. (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
  175. transformList[0] = new ICC_Transform (
  176. srgbCS.getProfile(), ICC_Transform.Any, ICC_Transform.In);
  177. transformList[1] = new ICC_Transform (
  178. thisProfile, ICC_Transform.Any, ICC_Transform.Out);
  179. srgb2this = new ICC_Transform (transformList);
  180. if (needScaleInit) {
  181. setComponentScaling();
  182. }
  183. }
  184. short tmp[] = new short[3];
  185. for (int i = 0; i < 3; i++) {
  186. tmp[i] = (short) ((rgbvalue[i] * 65535.0f) + 0.5f);
  187. }
  188. tmp = srgb2this.colorConvert(tmp, null);
  189. int nc = this.getNumComponents();
  190. float[] result = new float [nc];
  191. for (int i = 0; i < nc; i++) {
  192. result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
  193. diffMinMax[i] + minVal[i];
  194. }
  195. return result;
  196. }
  197. /**
  198. * Transforms a color value assumed to be in this ColorSpace
  199. * into the CS_CIEXYZ conversion color space.
  200. * <p>
  201. * This method transforms color values using relative colorimetry,
  202. * as defined by the ICC Specification. This
  203. * means that the XYZ values returned by this method are represented
  204. * relative to the D50 white point of the CS_CIEXYZ color space.
  205. * This representation is useful in a two-step color conversion
  206. * process in which colors are transformed from an input color
  207. * space to CS_CIEXYZ and then to an output color space. This
  208. * representation is not the same as the XYZ values that would
  209. * be measured from the given color value by a colorimeter.
  210. * A further transformation is necessary to compute the XYZ values
  211. * that would be measured using current CIE recommended practices.
  212. * The paragraphs below explain this in more detail.
  213. * <p>
  214. * The ICC standard uses a device independent color space (DICS) as the
  215. * mechanism for converting color from one device to another device. In
  216. * this architecture, colors are converted from the source device's color
  217. * space to the ICC DICS and then from the ICC DICS to the destination
  218. * device's color space. The ICC standard defines device profiles which
  219. * contain transforms which will convert between a device's color space
  220. * and the ICC DICS. The overall conversion of colors from a source
  221. * device to colors of a destination device is done by connecting the
  222. * device-to-DICS transform of the profile for the source device to the
  223. * DICS-to-device transform of the profile for the destination device.
  224. * For this reason, the ICC DICS is commonly referred to as the profile
  225. * connection space (PCS). The color space used in the methods
  226. * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
  227. * Specification. This is also the color space represented by
  228. * ColorSpace.CS_CIEXYZ.
  229. * <p>
  230. * The XYZ values of a color are often represented as relative to some
  231. * white point, so the actual meaning of the XYZ values cannot be known
  232. * without knowing the white point of those values. This is known as
  233. * relative colorimetry. The PCS uses a white point of D50, so the XYZ
  234. * values of the PCS are relative to D50. For example, white in the PCS
  235. * will have the XYZ values of D50, which is defined to be X=.9642,
  236. * Y=1.000, and Z=0.8249. This white point is commonly used for graphic
  237. * arts applications, but others are often used in other applications.
  238. * <p>
  239. * To quantify the color characteristics of a device such as a printer
  240. * or monitor, measurements of XYZ values for particular device colors
  241. * are typically made. For purposes of this discussion, the term
  242. * device XYZ values is used to mean the XYZ values that would be
  243. * measured from device colors using current CIE recommended practices.
  244. * <p>
  245. * Converting between device XYZ values and the PCS XYZ values returned
  246. * by this method corresponds to converting between the device's color
  247. * space, as represented by CIE colorimetric values, and the PCS. There
  248. * are many factors involved in this process, some of which are quite
  249. * subtle. The most important, however, is the adjustment made to account
  250. * for differences between the device's white point and the white point of
  251. * the PCS. There are many techniques for doing this and it is the
  252. * subject of much current research and controversy. Some commonly used
  253. * methods are XYZ scaling, the von Kries transform, and the Bradford
  254. * transform. The proper method to use depends upon each particular
  255. * application.
  256. * <p>
  257. * The simplest method is XYZ scaling. In this method each device XYZ
  258. * value is converted to a PCS XYZ value by multiplying it by the ratio
  259. * of the PCS white point (D50) to the device white point.
  260. * <pre>
  261. *
  262. * Xd, Yd, Zd are the device XYZ values
  263. * Xdw, Ydw, Zdw are the device XYZ white point values
  264. * Xp, Yp, Zp are the PCS XYZ values
  265. * Xd50, Yd50, Zd50 are the PCS XYZ white point values
  266. *
  267. * Xp = Xd * (Xd50 / Xdw)
  268. * Yp = Yd * (Yd50 / Ydw)
  269. * Zp = Zd * (Zd50 / Zdw)
  270. *
  271. * </pre>
  272. * <p>
  273. * Conversion from the PCS to the device would be done by inverting these
  274. * equations:
  275. * <pre>
  276. *
  277. * Xd = Xp * (Xdw / Xd50)
  278. * Yd = Yp * (Ydw / Yd50)
  279. * Zd = Zp * (Zdw / Zd50)
  280. *
  281. * </pre>
  282. * <p>
  283. * Note that the media white point tag in an ICC profile is not the same
  284. * as the device white point. The media white point tag is expressed in
  285. * PCS values and is used to represent the difference between the XYZ of
  286. * device illuminant and the XYZ of the device media when measured under
  287. * that illuminant. The device white point is expressed as the device
  288. * XYZ values corresponding to white displayed on the device. For
  289. * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
  290. * will result in a measured device XYZ value of D65. This will not
  291. * be the same as the media white point tag XYZ value in the ICC
  292. * profile for an sRGB device.
  293. * <p>
  294. * @param colorvalue a float array with length of at least the number
  295. * of components in this ColorSpace.
  296. * @return a float array of length 3.
  297. * @throws ArrayIndexOutOfBoundsException if array length is not
  298. * at least the number of components in this ColorSpace.
  299. */
  300. public float[] toCIEXYZ(float[] colorvalue) {
  301. if (this2xyz == null) {
  302. ICC_Transform[] transformList = new ICC_Transform [2];
  303. ICC_ColorSpace xyzCS =
  304. (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
  305. try {
  306. transformList[0] = new ICC_Transform (thisProfile,
  307. ICC_Profile.icRelativeColorimetric, ICC_Transform.In);
  308. } catch (CMMException e) {
  309. transformList[0] = new ICC_Transform (thisProfile,
  310. ICC_Transform.Any, ICC_Transform.In);
  311. }
  312. transformList[1] = new ICC_Transform (xyzCS.getProfile(),
  313. ICC_Transform.Any, ICC_Transform.Out);
  314. this2xyz = new ICC_Transform (transformList);
  315. if (needScaleInit) {
  316. setComponentScaling();
  317. }
  318. }
  319. int nc = this.getNumComponents();
  320. short tmp[] = new short[nc];
  321. for (int i = 0; i < nc; i++) {
  322. tmp[i] = (short)
  323. ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
  324. }
  325. tmp = this2xyz.colorConvert(tmp, null);
  326. float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
  327. // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
  328. float[] result = new float [3];
  329. for (int i = 0; i < 3; i++) {
  330. result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * ALMOST_TWO;
  331. }
  332. return result;
  333. }
  334. /**
  335. * Transforms a color value assumed to be in the CS_CIEXYZ conversion
  336. * color space into this ColorSpace.
  337. * <p>
  338. * This method transforms color values using relative colorimetry,
  339. * as defined by the ICC Specification. This
  340. * means that the XYZ argument values taken by this method are represented
  341. * relative to the D50 white point of the CS_CIEXYZ color space.
  342. * This representation is useful in a two-step color conversion
  343. * process in which colors are transformed from an input color
  344. * space to CS_CIEXYZ and then to an output color space. The color
  345. * values returned by this method are not those that would produce
  346. * the XYZ value passed to the method when measured by a colorimeter.
  347. * If you have XYZ values corresponding to measurements made using
  348. * current CIE recommended practices, they must be converted to D50
  349. * relative values before being passed to this method.
  350. * The paragraphs below explain this in more detail.
  351. * <p>
  352. * The ICC standard uses a device independent color space (DICS) as the
  353. * mechanism for converting color from one device to another device. In
  354. * this architecture, colors are converted from the source device's color
  355. * space to the ICC DICS and then from the ICC DICS to the destination
  356. * device's color space. The ICC standard defines device profiles which
  357. * contain transforms which will convert between a device's color space
  358. * and the ICC DICS. The overall conversion of colors from a source
  359. * device to colors of a destination device is done by connecting the
  360. * device-to-DICS transform of the profile for the source device to the
  361. * DICS-to-device transform of the profile for the destination device.
  362. * For this reason, the ICC DICS is commonly referred to as the profile
  363. * connection space (PCS). The color space used in the methods
  364. * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
  365. * Specification. This is also the color space represented by
  366. * ColorSpace.CS_CIEXYZ.
  367. * <p>
  368. * The XYZ values of a color are often represented as relative to some
  369. * white point, so the actual meaning of the XYZ values cannot be known
  370. * without knowing the white point of those values. This is known as
  371. * relative colorimetry. The PCS uses a white point of D50, so the XYZ
  372. * values of the PCS are relative to D50. For example, white in the PCS
  373. * will have the XYZ values of D50, which is defined to be X=.9642,
  374. * Y=1.000, and Z=0.8249. This white point is commonly used for graphic
  375. * arts applications, but others are often used in other applications.
  376. * <p>
  377. * To quantify the color characteristics of a device such as a printer
  378. * or monitor, measurements of XYZ values for particular device colors
  379. * are typically made. For purposes of this discussion, the term
  380. * device XYZ values is used to mean the XYZ values that would be
  381. * measured from device colors using current CIE recommended practices.
  382. * <p>
  383. * Converting between device XYZ values and the PCS XYZ values taken as
  384. * arguments by this method corresponds to converting between the device's
  385. * color space, as represented by CIE colorimetric values, and the PCS.
  386. * There are many factors involved in this process, some of which are quite
  387. * subtle. The most important, however, is the adjustment made to account
  388. * for differences between the device's white point and the white point of
  389. * the PCS. There are many techniques for doing this and it is the
  390. * subject of much current research and controversy. Some commonly used
  391. * methods are XYZ scaling, the von Kries transform, and the Bradford
  392. * transform. The proper method to use depends upon each particular
  393. * application.
  394. * <p>
  395. * The simplest method is XYZ scaling. In this method each device XYZ
  396. * value is converted to a PCS XYZ value by multiplying it by the ratio
  397. * of the PCS white point (D50) to the device white point.
  398. * <pre>
  399. *
  400. * Xd, Yd, Zd are the device XYZ values
  401. * Xdw, Ydw, Zdw are the device XYZ white point values
  402. * Xp, Yp, Zp are the PCS XYZ values
  403. * Xd50, Yd50, Zd50 are the PCS XYZ white point values
  404. *
  405. * Xp = Xd * (Xd50 / Xdw)
  406. * Yp = Yd * (Yd50 / Ydw)
  407. * Zp = Zd * (Zd50 / Zdw)
  408. *
  409. * </pre>
  410. * <p>
  411. * Conversion from the PCS to the device would be done by inverting these
  412. * equations:
  413. * <pre>
  414. *
  415. * Xd = Xp * (Xdw / Xd50)
  416. * Yd = Yp * (Ydw / Yd50)
  417. * Zd = Zp * (Zdw / Zd50)
  418. *
  419. * </pre>
  420. * <p>
  421. * Note that the media white point tag in an ICC profile is not the same
  422. * as the device white point. The media white point tag is expressed in
  423. * PCS values and is used to represent the difference between the XYZ of
  424. * device illuminant and the XYZ of the device media when measured under
  425. * that illuminant. The device white point is expressed as the device
  426. * XYZ values corresponding to white displayed on the device. For
  427. * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
  428. * will result in a measured device XYZ value of D65. This will not
  429. * be the same as the media white point tag XYZ value in the ICC
  430. * profile for an sRGB device.
  431. * <p>
  432. * <p>
  433. * @param colorvalue a float array with length of at least 3.
  434. * @return a float array with length equal to the number of
  435. * components in this ColorSpace.
  436. * @throws ArrayIndexOutOfBoundsException if array length is not
  437. * at least 3.
  438. */
  439. public float[] fromCIEXYZ(float[] colorvalue) {
  440. if (xyz2this == null) {
  441. ICC_Transform[] transformList = new ICC_Transform [2];
  442. ICC_ColorSpace xyzCS =
  443. (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
  444. transformList[0] = new ICC_Transform (xyzCS.getProfile(),
  445. ICC_Transform.Any, ICC_Transform.In);
  446. try {
  447. transformList[1] = new ICC_Transform (thisProfile,
  448. ICC_Profile.icRelativeColorimetric, ICC_Transform.Out);
  449. } catch (CMMException e) {
  450. transformList[1] = new ICC_Transform (thisProfile,
  451. ICC_Transform.Any, ICC_Transform.Out);
  452. }
  453. xyz2this = new ICC_Transform (transformList);
  454. if (needScaleInit) {
  455. setComponentScaling();
  456. }
  457. }
  458. short tmp[] = new short[3];
  459. float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
  460. float factor = 65535.0f / ALMOST_TWO;
  461. // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
  462. for (int i = 0; i < 3; i++) {
  463. tmp[i] = (short) ((colorvalue[i] * factor) + 0.5f);
  464. }
  465. tmp = xyz2this.colorConvert(tmp, null);
  466. int nc = this.getNumComponents();
  467. float[] result = new float [nc];
  468. for (int i = 0; i < nc; i++) {
  469. result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
  470. diffMinMax[i] + minVal[i];
  471. }
  472. return result;
  473. }
  474. /**
  475. * Returns the minimum normalized color component value for the
  476. * specified component. For TYPE_XYZ spaces, this method returns
  477. * minimum values of 0.0 for all components. For TYPE_Lab spaces,
  478. * this method returns 0.0 for L and -128.0 for a and b components.
  479. * This is consistent with the encoding of the XYZ and Lab Profile
  480. * Connection Spaces in the ICC specification. For all other types, this
  481. * method returns 0.0 for all components. When using an ICC_ColorSpace
  482. * with a profile that requires different minimum component values,
  483. * it is necessary to subclass this class and override this method.
  484. * @param component The component index.
  485. * @return The minimum normalized component value.
  486. * @throws IllegalArgumentException if component is less than 0 or
  487. * greater than numComponents - 1.
  488. * @since 1.4
  489. */
  490. public float getMinValue(int component) {
  491. if ((component < 0) || (component > this.getNumComponents() - 1)) {
  492. throw new IllegalArgumentException(
  493. "Component index out of range: + component");
  494. }
  495. return minVal[component];
  496. }
  497. /**
  498. * Returns the maximum normalized color component value for the
  499. * specified component. For TYPE_XYZ spaces, this method returns
  500. * maximum values of 1.0 + (32767.0 / 32768.0) for all components.
  501. * For TYPE_Lab spaces,
  502. * this method returns 100.0 for L and 127.0 for a and b components.
  503. * This is consistent with the encoding of the XYZ and Lab Profile
  504. * Connection Spaces in the ICC specification. For all other types, this
  505. * method returns 1.0 for all components. When using an ICC_ColorSpace
  506. * with a profile that requires different maximum component values,
  507. * it is necessary to subclass this class and override this method.
  508. * @param component The component index.
  509. * @return The maximum normalized component value.
  510. * @throws IllegalArgumentException if component is less than 0 or
  511. * greater than numComponents - 1.
  512. * @since 1.4
  513. */
  514. public float getMaxValue(int component) {
  515. if ((component < 0) || (component > this.getNumComponents() - 1)) {
  516. throw new IllegalArgumentException(
  517. "Component index out of range: + component");
  518. }
  519. return maxVal[component];
  520. }
  521. private void setMinMax() {
  522. int nc = this.getNumComponents();
  523. int type = this.getType();
  524. minVal = new float[nc];
  525. maxVal = new float[nc];
  526. if (type == ColorSpace.TYPE_Lab) {
  527. minVal[0] = 0.0f; // L
  528. maxVal[0] = 100.0f;
  529. minVal[1] = -128.0f; // a
  530. maxVal[1] = 127.0f;
  531. minVal[2] = -128.0f; // b
  532. maxVal[2] = 127.0f;
  533. } else if (type == ColorSpace.TYPE_XYZ) {
  534. minVal[0] = minVal[1] = minVal[2] = 0.0f; // X, Y, Z
  535. maxVal[0] = maxVal[1] = maxVal[2] = 1.0f + (32767.0f 32768.0f);
  536. } else {
  537. for (int i = 0; i < nc; i++) {
  538. minVal[i] = 0.0f;
  539. maxVal[i] = 1.0f;
  540. }
  541. }
  542. }
  543. private void setComponentScaling() {
  544. int nc = this.getNumComponents();
  545. diffMinMax = new float[nc];
  546. invDiffMinMax = new float[nc];
  547. for (int i = 0; i < nc; i++) {
  548. minVal[i] = this.getMinValue(i); // in case getMinVal is overridden
  549. maxVal[i] = this.getMaxValue(i); // in case getMaxVal is overridden
  550. diffMinMax[i] = maxVal[i] - minVal[i];
  551. invDiffMinMax[i] = 65535.0f / diffMinMax[i];
  552. }
  553. needScaleInit = false;
  554. }
  555. }