1. /*
  2. * @(#)ICC_ColorSpace.java 1.15 01/11/29
  3. *
  4. * Copyright 2002 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. * An implementation of the abstract ColorSpace class. This representation of
  21. * device independent and device dependent color spaces is based on the ICC
  22. * Profile Format Specification, Version 3.4, August 15, 1997, from
  23. * the International Color Consortium (see <A href="http://www.color.org">
  24. * 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 two specific device independent
  39. * spaces (one CIEXYZ space and one CIELab space) 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
  60. extends ColorSpace {
  61. private ICC_Profile thisProfile;
  62. private ICC_Transform this2srgb, srgb2this;
  63. private ICC_Transform this2xyz, xyz2this;
  64. /**
  65. * Constructs a new ICC_ColorSpace from an ICC_Profile object.
  66. * @exception IllegalArgumentException if profile is inappropriate for
  67. * representing a ColorSpace.
  68. */
  69. public ICC_ColorSpace (ICC_Profile profile) {
  70. super (profile.getColorSpaceType(), profile.getNumComponents());
  71. int profileClass = profile.getProfileClass();
  72. /* REMIND - is NAMEDCOLOR OK? */
  73. if ((profileClass != ICC_Profile.CLASS_INPUT) &&
  74. (profileClass != ICC_Profile.CLASS_DISPLAY) &&
  75. (profileClass != ICC_Profile.CLASS_OUTPUT) &&
  76. (profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) &&
  77. (profileClass != ICC_Profile.CLASS_NAMEDCOLOR) ) {
  78. throw new IllegalArgumentException("Invalid profile type");
  79. }
  80. thisProfile = profile;
  81. }
  82. /**
  83. * Returns the ICC_Profile for this ICC_ColorSpace.
  84. */
  85. public ICC_Profile getProfile() {
  86. return thisProfile;
  87. }
  88. /**
  89. * Transforms a color value assumed to be in this ColorSpace
  90. * into a value in the default CS_sRGB color space.
  91. * @param colorvalue a float array with length of at least the number
  92. of components in this ColorSpace.
  93. * @return a float array of length 3.
  94. */
  95. public float[] toRGB (float[] colorvalue) {
  96. ICC_Transform[] transformList;
  97. float[] result;
  98. ICC_ColorSpace srgbCS;
  99. if (this2srgb == null) {
  100. transformList = new ICC_Transform [2];
  101. srgbCS = (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
  102. transformList[0] = new ICC_Transform (
  103. thisProfile, ICC_Transform.Any, ICC_Transform.In);
  104. transformList[1] = new ICC_Transform (
  105. srgbCS.getProfile(), ICC_Transform.Any, ICC_Transform.Out);
  106. this2srgb = new ICC_Transform (transformList);
  107. }
  108. result = new float [3];
  109. this2srgb.colorConvert (1, colorvalue, result);
  110. return result;
  111. }
  112. /**
  113. * Transforms a color value assumed to be in the default CS_sRGB
  114. * color space into this ColorSpace.
  115. * @param rgbvalue a float array with length of at least 3.
  116. * @return a float array with length equal to the number of
  117. components in this ColorSpace.
  118. */
  119. public float[] fromRGB(float[] rgbvalue) {
  120. ICC_Transform[] transformList;
  121. float[] result;
  122. ICC_ColorSpace srgbCS;
  123. if (srgb2this == null) {
  124. transformList = new ICC_Transform [2];
  125. srgbCS = (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
  126. transformList[0] = new ICC_Transform (
  127. srgbCS.getProfile(), ICC_Transform.Any, ICC_Transform.In);
  128. transformList[1] = new ICC_Transform (
  129. thisProfile, ICC_Transform.Any, ICC_Transform.Out);
  130. srgb2this = new ICC_Transform (transformList);
  131. }
  132. result = new float [this.getNumComponents()];
  133. srgb2this.colorConvert (1, rgbvalue, result);
  134. return result;
  135. }
  136. /**
  137. * Transforms a color value assumed to be in this ColorSpace
  138. * into the CS_CIEXYZ conversion color space.
  139. * @param colorvalue a float array with length of at least the number
  140. * of components in this ColorSpace.
  141. * @return a float array of length 3.
  142. */
  143. public float[] toCIEXYZ(float[] colorvalue) {
  144. ICC_Transform[] transformList;
  145. float[] result;
  146. ICC_ColorSpace xyzCS;
  147. if (this2xyz == null) {
  148. transformList = new ICC_Transform [2];
  149. xyzCS = (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
  150. transformList[0] = new ICC_Transform (
  151. thisProfile, ICC_Transform.Any, ICC_Transform.In);
  152. transformList[1] = new ICC_Transform (
  153. xyzCS.getProfile(), ICC_Transform.Any, ICC_Transform.Out);
  154. this2xyz = new ICC_Transform (transformList);
  155. }
  156. result = new float [3];
  157. this2xyz.colorConvert (1, colorvalue, result);
  158. return result;
  159. }
  160. /**
  161. * Transforms a color value assumed to be in the CS_CIEXYZ conversion
  162. * color space into this ColorSpace.
  163. * @param colorvalue a float array with length of at least 3.
  164. * @return a float array with length equal to the number of
  165. * components in this ColorSpace.
  166. */
  167. public float[] fromCIEXYZ(float[] colorvalue) {
  168. ICC_Transform[] transformList;
  169. float[] result;
  170. ICC_ColorSpace xyzCS;
  171. if (xyz2this == null) {
  172. transformList = new ICC_Transform [2];
  173. xyzCS = (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
  174. transformList[0] = new ICC_Transform (
  175. xyzCS.getProfile(), ICC_Transform.Any, ICC_Transform.In);
  176. transformList[1] = new ICC_Transform (
  177. thisProfile, ICC_Transform.Any, ICC_Transform.Out);
  178. xyz2this = new ICC_Transform (transformList);
  179. }
  180. result = new float [this.getNumComponents()];
  181. xyz2this.colorConvert (1, colorvalue, result);
  182. return result;
  183. }
  184. }