Source for java.awt.color.ICC_ProfileRGB

   1: /* ICC_ProfileRGB.java -- the ICC profile for a RGB colorspace
   2:    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.awt.color;
  40: 
  41: /**
  42:  * ICC_ProfileRGB - a special case of ICC_Profiles.
  43:  *
  44:  * The ICC_Profile.getInstance() method will return an instance of the 
  45:  * ICC_ProfileRGB subclass when all the following conditions are met:
  46:  * The device color space of the profile is TYPE_RGB.
  47:  * The profile contains red, green and blue ColorantTags.
  48:  * The profile contains red, green and blue TRCTags.
  49:  * The profile contains a mediaWhitePointTag included.
  50:  *
  51:  * As per the ICC specification, the color space conversion can then
  52:  * be done through the following method:
  53:  * linearR = redTRC[deviceR]
  54:  * linearG = greenTRC[deviceG]
  55:  * linearB = blueTRC[deviceB]
  56:  * TRC curves are either a single gamma value, or a 1-dimensional lookup table.
  57:  * 
  58:  * Followed by the matrix transform:
  59:  * PCS = M*linear
  60:  *
  61:  * Where PCS is the vector of profile color space (must be XYZ) coordinates,
  62:  * linear is the vector of linear RGB coordinates, and the matrix M is 
  63:  * constructed from the ColorantTags, where the columns are red, green and
  64:  * blue respectively, and the rows are X, Y and Z.
  65:  *
  66:  * Note that if the profile contains a CLUT for the color space conversion,
  67:  * it should be used instead, and the TRC information ignored. 
  68:  *
  69:  * @author Sven de Marothy
  70:  * @since 1.2
  71:  */
  72: public class ICC_ProfileRGB extends ICC_Profile
  73: {
  74:   /**
  75:    * Compatible with JDK 1.2+.
  76:    */
  77:   private static final long serialVersionUID = 8505067385152579334L;
  78: 
  79:   public static final int REDCOMPONENT = 0;
  80: 
  81:   public static final int GREENCOMPONENT = 1;
  82: 
  83:   public static final int BLUECOMPONENT = 2;
  84: 
  85:   private transient float[][] matrix;
  86: 
  87:   private transient float[] gamma;
  88: 
  89:   private transient float[] whitePoint;
  90: 
  91: 
  92:   /**
  93:    * Package-private constructor used by ICC_ColorSpace for creating an
  94:    * ICC_ProfileRGB from a predefined ColorSpace (CS_LINEAR_RGB and CS_sRGB)
  95:    */
  96:   ICC_ProfileRGB(int cspace)
  97:   {
  98:     super(cspace);
  99:     matrix = createMatrix();
 100:     whitePoint = getXYZData(icSigMediaWhitePointTag);
 101:   }
 102: 
 103:   /**
 104:    * Package-private constructor used by ICC_ColorSpace for creating an
 105:    * ICC_ProfileRGB from profile data.
 106:    */
 107:   ICC_ProfileRGB(byte[] data)
 108:   {
 109:     super(data);
 110:     matrix = createMatrix();
 111:     whitePoint = getXYZData(icSigMediaWhitePointTag);
 112:   }
 113: 
 114:   /**
 115:    * Returns the media white point of the profile.
 116:    */
 117:   public float[] getMediaWhitePoint()
 118:   {
 119:     float[] wp = new float[3];
 120:     wp[0] = whitePoint[0];
 121:     wp[1] = whitePoint[1];
 122:     wp[2] = whitePoint[2];
 123:     return wp;
 124:   }
 125: 
 126:   /**
 127:    * Returns the colorant matrix of the conversion.
 128:    */
 129:   public float[][] getMatrix()
 130:   {
 131:     float[][] mat = new float[3][3];
 132:     for (int i = 0; i < 3; i++)
 133:       for (int j = 0; j < 3; j++)
 134:     mat[i][j] = matrix[i][j];
 135:     return mat;
 136:   }
 137: 
 138:   /**
 139:    * Returns the gamma value of a component
 140:    * @throws ProfileDataException if the TRC is described by a lookup
 141:    * table and not a gamma value.
 142:    */
 143:   public float getGamma(int component)
 144:   {
 145:     short[] data;
 146:     switch (component)
 147:       {
 148:       case REDCOMPONENT:
 149:     data = getCurve(icSigRedTRCTag);
 150:     break;
 151:       case GREENCOMPONENT:
 152:     data = getCurve(icSigGreenTRCTag);
 153:     break;
 154:       case BLUECOMPONENT:
 155:     data = getCurve(icSigBlueTRCTag);
 156:     break;
 157:       default:
 158:     throw new IllegalArgumentException("Not a valid component");
 159:       }
 160:     if (data == null)
 161:       throw new IllegalArgumentException("Error reading TRC");
 162: 
 163:     if (data.length != 1)
 164:       throw new ProfileDataException("Not a single-gamma TRC");
 165: 
 166:     // convert the unsigned 7.8 fixed-point gamma to a float.
 167:     float gamma = (float) (((int) data[0] & 0xFF00) >> 8);
 168:     double fraction = ((int) data[0] & 0x00FF) / 256.0;
 169:     gamma += (float) fraction;
 170:     return gamma;
 171:   }
 172: 
 173:   /**
 174:    * Returns the TRC lookup table for a component
 175:    * @throws ProfileDataException if the TRC is described by a gamma
 176:    * value and not a lookup table.
 177:    */
 178:   public short[] getTRC(int component)
 179:   {
 180:     short[] data;
 181:     switch (component)
 182:       {
 183:       case REDCOMPONENT:
 184:     data = getCurve(icSigRedTRCTag);
 185:     break;
 186:       case GREENCOMPONENT:
 187:     data = getCurve(icSigGreenTRCTag);
 188:     break;
 189:       case BLUECOMPONENT:
 190:     data = getCurve(icSigBlueTRCTag);
 191:     break;
 192:       default:
 193:     throw new IllegalArgumentException("Not a valid component");
 194:       }
 195:     if (data == null)
 196:       throw new IllegalArgumentException("Error reading TRC");
 197: 
 198:     if (data.length <= 1)
 199:       throw new ProfileDataException("Gamma value, not a TRC table.");
 200: 
 201:     return data;
 202:   }
 203: 
 204:   /**
 205:    * Creates the colorspace conversion matrix from the RGB tristimulus
 206:    * values.
 207:    */
 208:   private float[][] createMatrix() throws IllegalArgumentException
 209:   {
 210:     float[][] mat = new float[3][3];
 211:     float[] r;
 212:     float[] g;
 213:     float[] b;
 214:     r = getXYZData(icSigRedColorantTag);
 215:     g = getXYZData(icSigGreenColorantTag);
 216:     b = getXYZData(icSigBlueColorantTag);
 217:     if (r == null || g == null || b == null)
 218:       throw new IllegalArgumentException("Error reading colorant tags!");
 219:     for (int i = 0; i < 3; i++)
 220:       {
 221:     mat[i][0] = r[i];
 222:     mat[i][1] = g[i];
 223:     mat[i][2] = b[i];
 224:       }
 225:     return mat;
 226:   }
 227: } // class ICC_ProfileRGB