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