OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [java/] [awt/] [color/] [RgbProfileConverter.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* RgbProfileConverter.java -- RGB Profile conversion class
2
   Copyright (C) 2004 Free Software Foundation
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 gnu.java.awt.color;
40
 
41
import java.awt.color.ICC_Profile;
42
import java.awt.color.ICC_ProfileRGB;
43
import java.awt.color.ProfileDataException;
44
 
45
/**
46
 * RgbProfileConverter - converts RGB profiles (ICC_ProfileRGB)
47
 *
48
 * This type of profile contains a matrix and three
49
 * tone reproduction curves (TRCs).
50
 *
51
 * Device RGB --> CIE XYZ is done through first multiplying with
52
 * a matrix, then each component is looked-up against it's TRC.
53
 *
54
 * The opposite transform is done using the inverse of the matrix,
55
 * and TRC:s.
56
 *
57
 * @author Sven de Marothy
58
 */
59
public class RgbProfileConverter implements ColorSpaceConverter
60
{
61
  private float[][] matrix;
62
  private float[][] inv_matrix;
63
  private ToneReproductionCurve rTRC;
64
  private ToneReproductionCurve gTRC;
65
  private ToneReproductionCurve bTRC;
66
  private ColorLookUpTable toPCS;
67
  private ColorLookUpTable fromPCS;
68
 
69
  /**
70
   * CIE 1931 D50 white point (in Lab coordinates)
71
   */
72
  private static float[] D50 = { 0.96422f, 1.00f, 0.82521f };
73
 
74
  /**
75
   * Constructs an RgbProfileConverter from a given ICC_ProfileRGB
76
   */
77
  public RgbProfileConverter(ICC_ProfileRGB profile)
78
  {
79
    toPCS = fromPCS = null;
80
    matrix = profile.getMatrix();
81
 
82
    // get TRCs
83
    try
84
      {
85
        rTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.REDCOMPONENT));
86
      }
87
    catch (ProfileDataException e)
88
      {
89
        rTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.REDCOMPONENT));
90
      }
91
    try
92
      {
93
        gTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.GREENCOMPONENT));
94
      }
95
    catch (ProfileDataException e)
96
      {
97
        gTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.GREENCOMPONENT));
98
      }
99
    try
100
      {
101
        bTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.BLUECOMPONENT));
102
      }
103
    catch (ProfileDataException e)
104
      {
105
        bTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.BLUECOMPONENT));
106
      }
107
 
108
    // If a CLUT is available, it should be used, and the TRCs ignored.
109
    // Note: A valid profile may only have CLUTs in one direction, and
110
    // TRC:s without useful info, making reverse-transforms impossible.
111
    // In this case the TRC will be used for the reverse-transform with
112
    // unpredictable results. This is in line with the Java specification,
113
    try
114
      {
115
        toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB0Tag);
116
      }
117
    catch (Exception e)
118
      {
119
        toPCS = null;
120
      }
121
 
122
    try
123
      {
124
        fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA0Tag);
125
      }
126
    catch (Exception e)
127
      {
128
        fromPCS = null;
129
      }
130
 
131
    // Calculate the inverse matrix if no reverse CLUT is available
132
    if(fromPCS == null)
133
        inv_matrix = invertMatrix(matrix);
134
    else
135
      {
136
        // otherwise just set it to an identity matrix
137
        inv_matrix = new float[3][3];
138
        inv_matrix[0][0] = inv_matrix[1][1] = inv_matrix[2][2] = 1.0f;
139
      }
140
  }
141
 
142
  public float[] toCIEXYZ(float[] in)
143
  {
144
    // CLUT takes precedence
145
    if (toPCS != null)
146
      return toPCS.lookup(in);
147
 
148
    float[] temp = new float[3];
149
    float[] out = new float[3];
150
 
151
    // device space --> linear gamma
152
    temp[0] = rTRC.lookup(in[0]);
153
    temp[1] = gTRC.lookup(in[1]);
154
    temp[2] = bTRC.lookup(in[2]);
155
 
156
    // matrix multiplication
157
    out[0] = matrix[0][0] * temp[0] + matrix[0][1] * temp[1]
158
             + matrix[0][2] * temp[2];
159
    out[1] = matrix[1][0] * temp[0] + matrix[1][1] * temp[1]
160
             + matrix[1][2] * temp[2];
161
    out[2] = matrix[2][0] * temp[0] + matrix[2][1] * temp[1]
162
             + matrix[2][2] * temp[2];
163
 
164
    return out;
165
  }
166
 
167
  public float[] toRGB(float[] in)
168
  {
169
    return SrgbConverter.XYZtoRGB(toCIEXYZ(in));
170
  }
171
 
172
  public float[] fromCIEXYZ(float[] in)
173
  {
174
    if (fromPCS != null)
175
      return fromPCS.lookup(in);
176
 
177
    float[] temp = new float[3];
178
    float[] out = new float[3];
179
 
180
    // matrix multiplication
181
    temp[0] = inv_matrix[0][0] * in[0] + inv_matrix[0][1] * in[1]
182
              + inv_matrix[0][2] * in[2];
183
    temp[1] = inv_matrix[1][0] * in[0] + inv_matrix[1][1] * in[1]
184
              + inv_matrix[1][2] * in[2];
185
    temp[2] = inv_matrix[2][0] * in[0] + inv_matrix[2][1] * in[1]
186
              + inv_matrix[2][2] * in[2];
187
 
188
    // device space --> linear gamma
189
    out[0] = rTRC.reverseLookup(temp[0]);
190
    out[1] = gTRC.reverseLookup(temp[1]);
191
    out[2] = bTRC.reverseLookup(temp[2]);
192
 
193
    // FIXME: Sun appears to clip the return values to [0,1]
194
    // I don't believe that is a Good Thing, 
195
    // (some colorspaces may allow values outside that range.)
196
    // So we return the actual values here.
197
    return out;
198
  }
199
 
200
  public float[] fromRGB(float[] in)
201
  {
202
    return fromCIEXYZ(SrgbConverter.RGBtoXYZ(in));
203
  }
204
 
205
  /**
206
   * Inverts a 3x3 matrix, returns the inverse,
207
   * throws an IllegalArgumentException if the matrix is not
208
   * invertible (this shouldn't happen for a valid profile)
209
   */
210
  private float[][] invertMatrix(float[][] matrix)
211
  {
212
    float[][] out = new float[3][3];
213
    double determinant = matrix[0][0] * (matrix[1][1] * matrix[2][2]
214
                         - matrix[2][1] * matrix[1][2])
215
                         - matrix[0][1] * (matrix[1][0] * matrix[2][2]
216
                         - matrix[2][0] * matrix[1][2])
217
                         + matrix[0][2] * (matrix[1][0] * matrix[2][1]
218
                         - matrix[2][0] * matrix[1][1]);
219
 
220
    if (determinant == 0.0)
221
      throw new IllegalArgumentException("Can't invert conversion matrix.");
222
    float invdet = (float) (1.0 / determinant);
223
 
224
    out[0][0] = invdet * (matrix[1][1] * matrix[2][2]
225
                - matrix[1][2] * matrix[2][1]);
226
    out[0][1] = invdet * (matrix[0][2] * matrix[2][1]
227
                - matrix[0][1] * matrix[2][2]);
228
    out[0][2] = invdet * (matrix[0][1] * matrix[1][2]
229
                - matrix[0][2] * matrix[1][1]);
230
    out[1][0] = invdet * (matrix[1][2] * matrix[2][0]
231
                - matrix[1][0] * matrix[2][2]);
232
    out[1][1] = invdet * (matrix[0][0] * matrix[2][2]
233
                - matrix[0][2] * matrix[2][0]);
234
    out[1][2] = invdet * (matrix[0][2] * matrix[1][0]
235
                - matrix[0][0] * matrix[1][2]);
236
    out[2][0] = invdet * (matrix[1][0] * matrix[2][1]
237
                - matrix[1][1] * matrix[2][0]);
238
    out[2][1] = invdet * (matrix[0][1] * matrix[2][0]
239
                - matrix[0][0] * matrix[2][1]);
240
    out[2][2] = invdet * (matrix[0][0] * matrix[1][1]
241
                - matrix[0][1] * matrix[1][0]);
242
    return out;
243
  }
244
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.