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