1. /*
  2. * @(#)ICC_ProfileRGB.java 1.22 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 java.awt.image.LookupTable;
  18. import sun.awt.color.ProfileDeferralInfo;
  19. /**
  20. *
  21. * The ICC_ProfileRGB class is a subclass of the ICC_Profile class
  22. * that represents profiles which meet the following criteria:
  23. * <ul>
  24. * <li>The profile's color space type is RGB.</li>
  25. * <li>The profile includes the <code>redColorantTag</code>,
  26. * <code>greenColorantTag</code>, <code>blueColorantTag</code>,
  27. * <code>redTRCTag</code>, <code>greenTRCTag</code>,
  28. * <code>blueTRCTag</code>, and <code>mediaWhitePointTag</code> tags.</li>
  29. * </ul>
  30. * The <code>ICC_Profile</code> <code>getInstance</code> method will
  31. * return an <code>ICC_ProfileRGB</code> object when these conditions are met.
  32. * Three-component, matrix-based input profiles and RGB display profiles are
  33. * examples of this type of profile.
  34. * <p>
  35. * This profile class provides color transform matrices and lookup tables
  36. * that Java or native methods can use directly to
  37. * optimize color conversion in some cases.
  38. * <p>
  39. * To transform from a device profile color space to the CIEXYZ Profile
  40. * Connection Space, each device color component is first linearized by
  41. * a lookup through the corresponding tone reproduction curve (TRC).
  42. * The resulting linear RGB components are converted to the CIEXYZ PCS
  43. * using a a 3x3 matrix constructed from the RGB colorants.
  44. * <pre>
  45. *
  46. *   linearR = redTRC[deviceR]
  47. *
  48. *   linearG = greenTRC[deviceG]
  49. *
  50. *   linearB = blueTRC[deviceB]
  51. *
  52. *   _ _ _ _ _ _
  53. *  [ PCSX ] [ redColorantX greenColorantX blueColorantX ] [ linearR ]
  54. *  [ ] [ ] [ ]
  55. *  [ PCSY ] = [ redColorantY greenColorantY blueColorantY ] [ linearG ]
  56. *  [ ] [ ] [ ]
  57. *  [_ PCSZ _] [_ redColorantZ greenColorantZ blueColorantZ _] [_ linearB _]
  58. *
  59. * </pre>
  60. * The inverse transform is performed by converting PCS XYZ components to linear
  61. * RGB components through the inverse of the above 3x3 matrix, and then converting
  62. * linear RGB to device RGB through inverses of the TRCs.
  63. * <p>
  64. */
  65. public class ICC_ProfileRGB
  66. extends ICC_Profile {
  67. /**
  68. * Used to get a gamma value or TRC for the red component.
  69. */
  70. public static final int REDCOMPONENT = 0;
  71. /**
  72. * Used to get a gamma value or TRC for the green component.
  73. */
  74. public static final int GREENCOMPONENT = 1;
  75. /**
  76. * Used to get a gamma value or TRC for the blue component.
  77. */
  78. public static final int BLUECOMPONENT = 2;
  79. /**
  80. * Constructs an new <code>ICC_ProfileRGB</code> from a CMM ID.
  81. *
  82. * @param ID The CMM ID for the profile.
  83. *
  84. */
  85. ICC_ProfileRGB(long ID) {
  86. super(ID);
  87. }
  88. /**
  89. * Constructs a new <code>ICC_ProfileRGB</code> from a
  90. * ProfileDeferralInfo object.
  91. *
  92. * @param pdi
  93. */
  94. ICC_ProfileRGB(ProfileDeferralInfo pdi) {
  95. super(pdi);
  96. }
  97. /**
  98. * Returns an array that contains the components of the profile's
  99. * <CODE>mediaWhitePointTag</CODE>.
  100. *
  101. * @return A 3-element <CODE>float</CODE> array containing the x, y,
  102. * and z components of the profile's <CODE>mediaWhitePointTag</CODE>.
  103. */
  104. public float[] getMediaWhitePoint() {
  105. return super.getMediaWhitePoint();
  106. }
  107. /**
  108. * Returns a 3x3 <CODE>float</CODE> matrix constructed from the
  109. * X, Y, and Z components of the profile's <CODE>redColorantTag</CODE>,
  110. * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
  111. * <p>
  112. * This matrix can be used for color transforms in the forward
  113. * direction of the profile--from the profile color space
  114. * to the CIEXYZ PCS.
  115. *
  116. * @return A 3x3 <CODE>float</CODE> array that contains the x, y, and z
  117. * components of the profile's <CODE>redColorantTag</CODE>,
  118. * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
  119. */
  120. public float[][] getMatrix() {
  121. float[][] theMatrix = new float[3][3];
  122. float[] tmpMatrix;
  123. tmpMatrix = getXYZTag(ICC_Profile.icSigRedColorantTag);
  124. theMatrix[0][0] = tmpMatrix[0];
  125. theMatrix[1][0] = tmpMatrix[1];
  126. theMatrix[2][0] = tmpMatrix[2];
  127. tmpMatrix = getXYZTag(ICC_Profile.icSigGreenColorantTag);
  128. theMatrix[0][1] = tmpMatrix[0];
  129. theMatrix[1][1] = tmpMatrix[1];
  130. theMatrix[2][1] = tmpMatrix[2];
  131. tmpMatrix = getXYZTag(ICC_Profile.icSigBlueColorantTag);
  132. theMatrix[0][2] = tmpMatrix[0];
  133. theMatrix[1][2] = tmpMatrix[1];
  134. theMatrix[2][2] = tmpMatrix[2];
  135. return theMatrix;
  136. }
  137. /**
  138. * Returns a gamma value representing the tone reproduction curve
  139. * (TRC) for a particular component. The component parameter
  140. * must be one of REDCOMPONENT, GREENCOMPONENT, or BLUECOMPONENT.
  141. * <p>
  142. * If the profile
  143. * represents the TRC for the corresponding component
  144. * as a table rather than a single gamma value, an
  145. * exception is thrown. In this case the actual table
  146. * can be obtained through the {@link #getTRC(int)} method.
  147. * When using a gamma value,
  148. * the linear component (R, G, or B) is computed as follows:
  149. * <pre>
  150. *
  151. *   gamma
  152. *   linearComponent = deviceComponent
  153. *
  154. *</pre>
  155. * @param component The <CODE>ICC_ProfileRGB</CODE> constant that
  156. * represents the component whose TRC you want to retrieve
  157. * @return the gamma value as a float.
  158. * @exception ProfileDataException if the profile does not specify
  159. * the corresponding TRC as a single gamma value.
  160. */
  161. public float getGamma(int component) {
  162. float theGamma;
  163. int theSignature;
  164. switch (component) {
  165. case REDCOMPONENT:
  166. theSignature = ICC_Profile.icSigRedTRCTag;
  167. break;
  168. case GREENCOMPONENT:
  169. theSignature = ICC_Profile.icSigGreenTRCTag;
  170. break;
  171. case BLUECOMPONENT:
  172. theSignature = ICC_Profile.icSigBlueTRCTag;
  173. break;
  174. default:
  175. throw new IllegalArgumentException("Must be Red, Green, or Blue");
  176. }
  177. theGamma = super.getGamma(theSignature);
  178. return theGamma;
  179. }
  180. /**
  181. * Returns the TRC for a particular component as an array.
  182. * Component must be <code>REDCOMPONENT</code>,
  183. * <code>GREENCOMPONENT</code>, or <code>BLUECOMPONENT</code>.
  184. * Otherwise the returned array
  185. * represents a lookup table where the input component value
  186. * is conceptually in the range [0.0, 1.0]. Value 0.0 maps
  187. * to array index 0 and value 1.0 maps to array index length-1.
  188. * Interpolation might be used to generate output values for
  189. * input values that do not map exactly to an index in the
  190. * array. Output values also map linearly to the range [0.0, 1.0].
  191. * Value 0.0 is represented by an array value of 0x0000 and
  192. * value 1.0 by 0xFFFF. In other words, the values are really unsigned
  193. * <code>short</code> values even though they are returned in a
  194. * <code>short</code> array.
  195. *
  196. * If the profile has specified the corresponding TRC
  197. * as linear (gamma = 1.0) or as a simple gamma value, this method
  198. * throws an exception. In this case, the {@link #getGamma(int)}
  199. * method should be used to get the gamma value.
  200. *
  201. * @param component The <CODE>ICC_ProfileRGB</CODE> constant that
  202. * represents the component whose TRC you want to retrieve:
  203. * <CODE>REDCOMPONENT</CODE>, <CODE>GREENCOMPONENT</CODE>, or
  204. * <CODE>BLUECOMPONENT</CODE>.
  205. *
  206. * @return a short array representing the TRC.
  207. * @exception ProfileDataException if the profile does not specify
  208. * the corresponding TRC as a table.
  209. */
  210. public short[] getTRC(int component) {
  211. short[] theTRC;
  212. int theSignature;
  213. switch (component) {
  214. case REDCOMPONENT:
  215. theSignature = ICC_Profile.icSigRedTRCTag;
  216. break;
  217. case GREENCOMPONENT:
  218. theSignature = ICC_Profile.icSigGreenTRCTag;
  219. break;
  220. case BLUECOMPONENT:
  221. theSignature = ICC_Profile.icSigBlueTRCTag;
  222. break;
  223. default:
  224. throw new IllegalArgumentException("Must be Red, Green, or Blue");
  225. }
  226. theTRC = super.getTRC(theSignature);
  227. return theTRC;
  228. }
  229. }