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