corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /// <summary>**************************************************************************
2 ///
3 /// $Id: MatrixBasedTransformTosRGB.java,v 1.1 2002/07/25 14:56:49 grosbois Exp $
4 ///
5 /// Copyright Eastman Kodak Company, 343 State Street, Rochester, NY 14650
6 /// $Date $
7 /// ***************************************************************************
8 /// </summary>
9 using System;
10 using ColorSpace = CSJ2K.Color.ColorSpace;
11 using ICCProfile = CSJ2K.Icc.ICCProfile;
12 using RestrictedICCProfile = CSJ2K.Icc.RestrictedICCProfile;
13 using ICCXYZType = CSJ2K.Icc.Tags.ICCXYZType;
14 using DataBlkInt = CSJ2K.j2k.image.DataBlkInt;
15 using DataBlkFloat = CSJ2K.j2k.image.DataBlkFloat;
16 namespace CSJ2K.Icc.Lut
17 {
18  
19 /// <summary> Transform for applying ICCProfiling to an input DataBlk
20 ///
21 /// </summary>
22 /// <seealso cref="jj2000.j2k.image.DataBlkInt">
23 /// </seealso>
24 /// <seealso cref="jj2000.j2k.image.DataBlkFloat">
25 /// </seealso>
26 /// <version> 1.0
27 /// </version>
28 /// <author> Bruce A. Kern
29 /// </author>
30 public class MatrixBasedTransformTosRGB
31 {
32  
33 //UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
34 private static readonly System.String eol = System.Environment.NewLine;
35  
36 // Start of contant definitions:
37  
38 //UPGRADE_NOTE: Final was removed from the declaration of 'RED '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
39 //UPGRADE_NOTE: The initialization of 'RED' was moved to static method 'icc.lut.MatrixBasedTransformTosRGB'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
40 //UPGRADE_NOTE: Final was removed from the declaration of 'GREEN '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
41 //UPGRADE_NOTE: The initialization of 'GREEN' was moved to static method 'icc.lut.MatrixBasedTransformTosRGB'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
42 //UPGRADE_NOTE: Final was removed from the declaration of 'BLUE '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
43 //UPGRADE_NOTE: The initialization of 'BLUE' was moved to static method 'icc.lut.MatrixBasedTransformTosRGB'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
44 private static readonly int RED;
45 private static readonly int GREEN;
46 private static readonly int BLUE;
47  
48 private const double SRGB00 = 3.1337;
49 private const double SRGB01 = - 1.6173;
50 private const double SRGB02 = - 0.4907;
51 private const double SRGB10 = - 0.9785;
52 private const double SRGB11 = 1.9162;
53 private const double SRGB12 = 0.0334;
54 private const double SRGB20 = 0.0720;
55 private const double SRGB21 = - 0.2290;
56 private const double SRGB22 = 1.4056;
57  
58 // Define constants representing the indices into the matrix array
59 private const int M00 = 0;
60 private const int M01 = 1;
61 private const int M02 = 2;
62 private const int M10 = 3;
63 private const int M11 = 4;
64 private const int M12 = 5;
65 private const int M20 = 6;
66 private const int M21 = 7;
67 private const int M22 = 8;
68  
69 private const double ksRGBExponent = (1.0 / 2.4);
70 private const double ksRGBScaleAfterExp = 1.055;
71 private const double ksRGBReduceAfterExp = 0.055;
72 private const double ksRGBShadowCutoff = 0.0031308;
73 private const double ksRGBShadowSlope = 12.92;
74  
75 // End of contant definitions:
76  
77 //UPGRADE_NOTE: Final was removed from the declaration of 'matrix '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
78 private double[] matrix; // Matrix coefficients
79  
80 private LookUpTableFP[] fLut = new LookUpTableFP[3];
81 private LookUpTable32LinearSRGBtoSRGB lut; // Linear sRGB to sRGB LUT
82  
83 //UPGRADE_NOTE: Final was removed from the declaration of 'dwMaxValue '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
84 private int[] dwMaxValue;
85 //UPGRADE_NOTE: Final was removed from the declaration of 'dwShiftValue '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
86 private int[] dwShiftValue;
87  
88 //private int dwMaxCols = 0; // Maximum number of columns that can be processed
89 //private int dwMaxRows = 0; // Maximum number of rows that can be processed
90  
91 private float[][] fBuf = null; // Intermediate output of the first LUT operation.
92  
93 /// <summary> String representation of class</summary>
94 /// <returns> suitable representation for class
95 /// </returns>
96 public override System.String ToString()
97 {
98 int i, j;
99  
100 System.Text.StringBuilder rep = new System.Text.StringBuilder("[MatrixBasedTransformTosRGB: ");
101  
102 System.Text.StringBuilder body = new System.Text.StringBuilder(" ");
103 body.Append(eol).Append("ksRGBExponent= ").Append(System.Convert.ToString(ksRGBExponent));
104 body.Append(eol).Append("ksRGBScaleAfterExp= ").Append(System.Convert.ToString(ksRGBScaleAfterExp));
105 body.Append(eol).Append("ksRGBReduceAfterExp= ").Append(System.Convert.ToString(ksRGBReduceAfterExp));
106  
107  
108 body.Append(eol).Append("dwMaxValues= ").Append(System.Convert.ToString(dwMaxValue[0])).Append(", ").Append(System.Convert.ToString(dwMaxValue[1])).Append(", ").Append(System.Convert.ToString(dwMaxValue[2]));
109  
110 body.Append(eol).Append("dwShiftValues= ").Append(System.Convert.ToString(dwShiftValue[0])).Append(", ").Append(System.Convert.ToString(dwShiftValue[1])).Append(", ").Append(System.Convert.ToString(dwShiftValue[2]));
111  
112 //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
113 body.Append(eol).Append(eol).Append("fLut= ").Append(eol).Append(ColorSpace.indent(" ", "fLut[RED]= " + fLut[0].ToString())).Append(eol).Append(ColorSpace.indent(" ", "fLut[GRN]= " + fLut[1].ToString())).Append(eol).Append(ColorSpace.indent(" ", "fLut[BLU]= " + fLut[2].ToString()));
114  
115 // Print the matrix
116 body.Append(eol).Append(eol).Append("[matrix ");
117 for (i = 0; i < 3; ++i)
118 {
119 body.Append(eol).Append(" ");
120 for (j = 0; j < 3; ++j)
121 {
122 body.Append(matrix[3 * i + j] + " ");
123 }
124 }
125 body.Append("]");
126  
127  
128 // Print the LinearSRGBtoSRGB lut.
129 body.Append(eol).Append(eol).Append(lut.ToString());
130  
131 rep.Append(ColorSpace.indent(" ", body)).Append("]");
132 return rep.Append("]").ToString();
133 }
134  
135  
136 /// <summary> Construct a 3 component transform based on an input RestricedICCProfile
137 /// This transform will pass the input throught a floating point lut (LookUpTableFP),
138 /// apply a matrix to the output and finally pass the intermediate buffer through
139 /// a 8-bit lut (LookUpTable8). This operation will be designated (LFP*M*L8) * Data
140 /// The operators (LFP*M*L8) are constructed here. Although the data for
141 /// only one component is returned, the transformation must be done for all
142 /// components, because the matrix application involves a linear combination of
143 /// component input to produce the output.
144 /// </summary>
145 /// <param name="ricc">input profile
146 /// </param>
147 /// <param name="dwMaxValue">clipping value for output.
148 /// </param>
149 /// <param name="dwMaxCols">number of columns to transform
150 /// </param>
151 /// <param name="dwMaxRows">number of rows to transform
152 /// </param>
153 public MatrixBasedTransformTosRGB(RestrictedICCProfile ricc, int[] dwMaxValue, int[] dwShiftValue)
154 {
155  
156 // Assure the proper type profile for this xform.
157 if (ricc.Type != RestrictedICCProfile.kThreeCompInput)
158 throw new System.ArgumentException("MatrixBasedTransformTosRGB: wrong type ICCProfile supplied");
159  
160 int c; // component index.
161 this.dwMaxValue = dwMaxValue;
162 this.dwShiftValue = dwShiftValue;
163  
164 // Create the LUTFP from the input profile.
165 for (c = 0; c < 3; ++c)
166 {
167 fLut[c] = LookUpTableFP.createInstance(ricc.trc[c], dwMaxValue[c] + 1);
168 }
169  
170 // Create the Input linear to PCS matrix
171 matrix = createMatrix(ricc, dwMaxValue); // Create and matrix from the ICC profile.
172  
173 // Create the final LUT32
174 lut = LookUpTable32LinearSRGBtoSRGB.createInstance(dwMaxValue[0], dwMaxValue[0], ksRGBShadowCutoff, ksRGBShadowSlope, ksRGBScaleAfterExp, ksRGBExponent, ksRGBReduceAfterExp);
175 }
176  
177  
178 private double[] createMatrix(RestrictedICCProfile ricc, int[] maxValues)
179 {
180  
181 // Coefficients from the input linear to PCS matrix
182 double dfPCS00 = ICCXYZType.XYZToDouble(ricc.colorant[RED].x);
183 double dfPCS01 = ICCXYZType.XYZToDouble(ricc.colorant[GREEN].x);
184 double dfPCS02 = ICCXYZType.XYZToDouble(ricc.colorant[BLUE].x);
185 double dfPCS10 = ICCXYZType.XYZToDouble(ricc.colorant[RED].y);
186 double dfPCS11 = ICCXYZType.XYZToDouble(ricc.colorant[GREEN].y);
187 double dfPCS12 = ICCXYZType.XYZToDouble(ricc.colorant[BLUE].y);
188 double dfPCS20 = ICCXYZType.XYZToDouble(ricc.colorant[RED].z);
189 double dfPCS21 = ICCXYZType.XYZToDouble(ricc.colorant[GREEN].z);
190 double dfPCS22 = ICCXYZType.XYZToDouble(ricc.colorant[BLUE].z);
191  
192 double[] matrix = new double[9];
193 matrix[M00] = maxValues[0] * (SRGB00 * dfPCS00 + SRGB01 * dfPCS10 + SRGB02 * dfPCS20);
194 matrix[M01] = maxValues[0] * (SRGB00 * dfPCS01 + SRGB01 * dfPCS11 + SRGB02 * dfPCS21);
195 matrix[M02] = maxValues[0] * (SRGB00 * dfPCS02 + SRGB01 * dfPCS12 + SRGB02 * dfPCS22);
196 matrix[M10] = maxValues[1] * (SRGB10 * dfPCS00 + SRGB11 * dfPCS10 + SRGB12 * dfPCS20);
197 matrix[M11] = maxValues[1] * (SRGB10 * dfPCS01 + SRGB11 * dfPCS11 + SRGB12 * dfPCS21);
198 matrix[M12] = maxValues[1] * (SRGB10 * dfPCS02 + SRGB11 * dfPCS12 + SRGB12 * dfPCS22);
199 matrix[M20] = maxValues[2] * (SRGB20 * dfPCS00 + SRGB21 * dfPCS10 + SRGB22 * dfPCS20);
200 matrix[M21] = maxValues[2] * (SRGB20 * dfPCS01 + SRGB21 * dfPCS11 + SRGB22 * dfPCS21);
201 matrix[M22] = maxValues[2] * (SRGB20 * dfPCS02 + SRGB21 * dfPCS12 + SRGB22 * dfPCS22);
202  
203 return matrix;
204 }
205  
206  
207 /// <summary> Performs the transform. Pass the input throught the LookUpTableFP, apply the
208 /// matrix to the output and finally pass the intermediate buffer through the
209 /// LookUpTable8. This operation is designated (LFP*M*L8) * Data are already
210 /// constructed. Although the data for only one component is returned, the
211 /// transformation must be done for all components, because the matrix application
212 /// involves a linear combination of component input to produce the output.
213 /// </summary>
214 /// <param name="ncols">number of columns in the input
215 /// </param>
216 /// <param name="nrows">number of rows in the input
217 /// </param>
218 /// <param name="inb">input data block
219 /// </param>
220 /// <param name="outb">output data block
221 /// </param>
222 /// <exception cref="MatrixBasedTransformException">
223 /// </exception>
224 public virtual void apply(DataBlkInt[] inb, DataBlkInt[] outb)
225 {
226 int[][] in_Renamed = new int[3][], out_Renamed = new int[3][]; // data references.
227  
228 int nrows = inb[0].h, ncols = inb[0].w;
229  
230 if ((fBuf == null) || (fBuf[0].Length < ncols * nrows))
231 {
232 float[][] tmpArray = new float[3][];
233 for (int i = 0; i < 3; i++)
234 {
235 tmpArray[i] = new float[ncols * nrows];
236 }
237 fBuf = tmpArray;
238 }
239  
240 // for each component (rgb)
241 for (int c = 0; c < 3; ++c)
242 {
243  
244 // Reference the input and output samples.
245 in_Renamed[c] = (int[]) inb[c].Data;
246 out_Renamed[c] = (int[]) outb[c].Data;
247  
248 // Assure a properly sized output buffer.
249 if (out_Renamed[c] == null || out_Renamed[c].Length < in_Renamed[c].Length)
250 {
251 out_Renamed[c] = new int[in_Renamed[c].Length];
252 outb[c].Data = out_Renamed[c];
253 }
254  
255 // The first thing to do is to process the input into a standard form
256 // and through the first input LUT, producing floating point output values
257 standardizeMatrixLineThroughLut(inb[c], fBuf[c], dwMaxValue[c], fLut[c]);
258 }
259  
260 // For each row and column
261 float[] ra = fBuf[RED];
262 float[] ga = fBuf[GREEN];
263 float[] ba = fBuf[BLUE];
264  
265 int[] ro = out_Renamed[RED];
266 int[] go = out_Renamed[GREEN];
267 int[] bo = out_Renamed[BLUE];
268 int[] lut32 = lut.lut;
269  
270 double r, g, b;
271 int val, index = 0;
272 for (int y = 0; y < inb[0].h; ++y)
273 {
274 int end = index + inb[0].w;
275 while (index < end)
276 {
277 // Calculate the rgb pixel indices for this row / column
278 r = ra[index];
279 g = ga[index];
280 b = ba[index];
281  
282 // Apply the matrix to the intermediate floating point data in order to index the
283 // final LUT.
284 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
285 val = (int) (matrix[M00] * r + matrix[M01] * g + matrix[M02] * b + 0.5);
286 // Clip the calculated value if necessary..
287 if (val < 0)
288 ro[index] = lut32[0];
289 else if (val >= lut32.Length)
290 ro[index] = lut32[lut32.Length - 1];
291 else
292 ro[index] = lut32[val];
293  
294 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
295 val = (int) (matrix[M10] * r + matrix[M11] * g + matrix[M12] * b + 0.5);
296 // Clip the calculated value if necessary..
297 if (val < 0)
298 go[index] = lut32[0];
299 else if (val >= lut32.Length)
300 go[index] = lut32[lut32.Length - 1];
301 else
302 go[index] = lut32[val];
303  
304 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
305 val = (int) (matrix[M20] * r + matrix[M21] * g + matrix[M22] * b + 0.5);
306 // Clip the calculated value if necessary..
307 if (val < 0)
308 bo[index] = lut32[0];
309 else if (val >= lut32.Length)
310 bo[index] = lut32[lut32.Length - 1];
311 else
312 bo[index] = lut32[val];
313  
314 index++;
315 }
316 }
317 }
318  
319 /// <summary> Performs the transform. Pass the input throught the LookUpTableFP, apply the
320 /// matrix to the output and finally pass the intermediate buffer through the
321 /// LookUpTable8. This operation is designated (LFP*M*L8) * Data are already
322 /// constructed. Although the data for only one component is returned, the
323 /// transformation must be done for all components, because the matrix application
324 /// involves a linear combination of component input to produce the output.
325 /// </summary>
326 /// <param name="ncols">number of columns in the input
327 /// </param>
328 /// <param name="nrows">number of rows in the input
329 /// </param>
330 /// <param name="inb">input data block
331 /// </param>
332 /// <param name="outb">output data block
333 /// </param>
334 /// <exception cref="MatrixBasedTransformException">
335 /// </exception>
336 public virtual void apply(DataBlkFloat[] inb, DataBlkFloat[] outb)
337 {
338  
339 float[][] in_Renamed = new float[3][], out_Renamed = new float[3][]; // data references.
340  
341 int nrows = inb[0].h, ncols = inb[0].w;
342  
343 if ((fBuf == null) || (fBuf[0].Length < ncols * nrows))
344 {
345 float[][] tmpArray = new float[3][];
346 for (int i = 0; i < 3; i++)
347 {
348 tmpArray[i] = new float[ncols * nrows];
349 }
350 fBuf = tmpArray;
351 }
352  
353 // for each component (rgb)
354 for (int c = 0; c < 3; ++c)
355 {
356  
357 // Reference the input and output pixels.
358 in_Renamed[c] = (float[]) inb[c].Data;
359 out_Renamed[c] = (float[]) outb[c].Data;
360  
361 // Assure a properly sized output buffer.
362 if (out_Renamed[c] == null || out_Renamed[c].Length < in_Renamed[c].Length)
363 {
364 out_Renamed[c] = new float[in_Renamed[c].Length];
365 outb[c].Data = out_Renamed[c];
366 }
367  
368 // The first thing to do is to process the input into a standard form
369 // and through the first input LUT, producing floating point output values
370 standardizeMatrixLineThroughLut(inb[c], fBuf[c], dwMaxValue[c], fLut[c]);
371 }
372  
373 int[] lut32 = lut.lut;
374  
375 // For each row and column
376 int index = 0, val;
377 for (int y = 0; y < inb[0].h; ++y)
378 {
379 int end = index + inb[0].w;
380 while (index < end)
381 {
382 // Calculate the rgb pixel indices for this row / column
383  
384 // Apply the matrix to the intermediate floating point data inorder to index the
385 // final LUT.
386 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
387 val = (int) (matrix[M00] * fBuf[RED][index] + matrix[M01] * fBuf[GREEN][index] + matrix[M02] * fBuf[BLUE][index] + 0.5);
388 // Clip the calculated value if necessary..
389 if (val < 0)
390 out_Renamed[0][index] = lut32[0];
391 else if (val >= lut32.Length)
392 out_Renamed[0][index] = lut32[lut32.Length - 1];
393 else
394 out_Renamed[0][index] = lut32[val];
395  
396 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
397 val = (int) (matrix[M10] * fBuf[RED][index] + matrix[M11] * fBuf[GREEN][index] + matrix[M12] * fBuf[BLUE][index] + 0.5);
398 // Clip the calculated value if necessary..
399 if (val < 0)
400 out_Renamed[1][index] = lut32[0];
401 else if (val >= lut32.Length)
402 out_Renamed[1][index] = lut32[lut32.Length - 1];
403 else
404 out_Renamed[1][index] = lut32[val];
405  
406 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
407 val = (int) (matrix[M20] * fBuf[RED][index] + matrix[M21] * fBuf[GREEN][index] + matrix[M22] * fBuf[BLUE][index] + 0.5);
408 // Clip the calculated value if necessary..
409 if (val < 0)
410 out_Renamed[2][index] = lut32[0];
411 else if (val >= lut32.Length)
412 out_Renamed[2][index] = lut32[lut32.Length - 1];
413 else
414 out_Renamed[2][index] = lut32[val];
415  
416 index++;
417 }
418 }
419 }
420  
421 private static void standardizeMatrixLineThroughLut(DataBlkInt inb, float[] out_Renamed, int dwInputMaxValue, LookUpTableFP lut)
422 {
423 int wTemp, j = 0;
424 int[] in_Renamed = (int[]) inb.Data; // input pixel reference
425 float[] lutFP = lut.lut;
426 for (int y = inb.uly; y < inb.uly + inb.h; ++y)
427 {
428 for (int x = inb.ulx; x < inb.ulx + inb.w; ++x)
429 {
430 int i = inb.offset + (y - inb.uly) * inb.scanw + (x - inb.ulx); // pixel index.
431 if (in_Renamed[i] > dwInputMaxValue)
432 wTemp = dwInputMaxValue;
433 else if (in_Renamed[i] < 0)
434 wTemp = 0;
435 else
436 wTemp = in_Renamed[i];
437 out_Renamed[j++] = lutFP[wTemp];
438 }
439 }
440 }
441  
442  
443 private static void standardizeMatrixLineThroughLut(DataBlkFloat inb, float[] out_Renamed, float dwInputMaxValue, LookUpTableFP lut)
444 {
445 int j = 0;
446 float wTemp;
447 float[] in_Renamed = (float[]) inb.Data; // input pixel reference
448 float[] lutFP = lut.lut;
449  
450 for (int y = inb.uly; y < inb.uly + inb.h; ++y)
451 {
452 for (int x = inb.ulx; x < inb.ulx + inb.w; ++x)
453 {
454 int i = inb.offset + (y - inb.uly) * inb.scanw + (x - inb.ulx); // pixel index.
455 if (in_Renamed[i] > dwInputMaxValue)
456 wTemp = dwInputMaxValue;
457 else if (in_Renamed[i] < 0)
458 wTemp = 0;
459 else
460 wTemp = in_Renamed[i];
461 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
462 out_Renamed[j++] = lutFP[(int) wTemp];
463 }
464 }
465 }
466  
467 /* end class MatrixBasedTransformTosRGB */
468 static MatrixBasedTransformTosRGB()
469 {
470 RED = ICCProfile.RED;
471 GREEN = ICCProfile.GREEN;
472 BLUE = ICCProfile.BLUE;
473 }
474 }
475 }