]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/tif_color.c
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
28 * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
29 * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
30 * the permission of John Cupitt, the VIPS author.
36 * Color space conversion routines.
43 * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
46 TIFFCIELabToXYZ(TIFFCIELabToRGB
*cielab
, uint32 l
, int32 a
, int32 b
,
47 float *X
, float *Y
, float *Z
)
49 float L
= (float)l
* 100.0F
/ 255.0F
;
53 *Y
= (L
* cielab
->Y0
) / 903.292F
;
54 cby
= 7.787F
* (*Y
/ cielab
->Y0
) + 16.0F
/ 116.0F
;
56 cby
= (L
+ 16.0F
) / 116.0F
;
57 *Y
= cielab
->Y0
* cby
* cby
* cby
;
60 tmp
= (float)a
/ 500.0F
+ cby
;
62 *X
= cielab
->X0
* (tmp
- 0.13793F
) / 7.787F
;
64 *X
= cielab
->X0
* tmp
* tmp
* tmp
;
66 tmp
= cby
- (float)b
/ 200.0F
;
68 *Z
= cielab
->Z0
* (tmp
- 0.13793F
) / 7.787F
;
70 *Z
= cielab
->Z0
* tmp
* tmp
* tmp
;
73 #define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5)))
75 * Convert color value from the XYZ space to RGB.
78 TIFFXYZToRGB(TIFFCIELabToRGB
*cielab
, float X
, float Y
, float Z
,
79 uint32
*r
, uint32
*g
, uint32
*b
)
83 float *matrix
= &cielab
->display
.d_mat
[0][0];
85 /* Multiply through the matrix to get luminosity values. */
86 Yr
= matrix
[0] * X
+ matrix
[1] * Y
+ matrix
[2] * Z
;
87 Yg
= matrix
[3] * X
+ matrix
[4] * Y
+ matrix
[5] * Z
;
88 Yb
= matrix
[6] * X
+ matrix
[7] * Y
+ matrix
[8] * Z
;
91 Yr
= TIFFmax( Yr
, cielab
->display
.d_Y0R
);
92 Yg
= TIFFmax( Yg
, cielab
->display
.d_Y0G
);
93 Yb
= TIFFmax( Yb
, cielab
->display
.d_Y0B
);
95 /* Turn luminosity to colour value. */
96 i
= TIFFmin(cielab
->range
,
97 (int)((Yr
- cielab
->display
.d_Y0R
) / cielab
->rstep
));
98 *r
= RINT(cielab
->Yr2r
[i
]);
100 i
= TIFFmin(cielab
->range
,
101 (int)((Yg
- cielab
->display
.d_Y0G
) / cielab
->gstep
));
102 *g
= RINT(cielab
->Yg2g
[i
]);
104 i
= TIFFmin(cielab
->range
,
105 (int)((Yb
- cielab
->display
.d_Y0B
) / cielab
->bstep
));
106 *b
= RINT(cielab
->Yb2b
[i
]);
109 *r
= TIFFmin( *r
, cielab
->display
.d_Vrwr
);
110 *g
= TIFFmin( *g
, cielab
->display
.d_Vrwg
);
111 *b
= TIFFmin( *b
, cielab
->display
.d_Vrwb
);
116 * Allocate conversion state structures and make look_up tables for
117 * the Yr,Yb,Yg <=> r,g,b conversions.
120 TIFFCIELabToRGBInit(TIFFCIELabToRGB
* cielab
,
121 TIFFDisplay
*display
, float *refWhite
)
126 cielab
->range
= CIELABTORGB_TABLE_RANGE
;
128 _TIFFmemcpy(&cielab
->display
, display
, sizeof(TIFFDisplay
));
131 gamma
= 1.0F
/ cielab
->display
.d_gammaR
;
133 (cielab
->display
.d_YCR
- cielab
->display
.d_Y0R
) / cielab
->range
;
134 for(i
= 0; i
<= cielab
->range
; i
++) {
135 cielab
->Yr2r
[i
] = cielab
->display
.d_Vrwr
136 * ((float)pow((double)i
/ cielab
->range
, gamma
));
140 gamma
= 1.0F
/ cielab
->display
.d_gammaG
;
142 (cielab
->display
.d_YCR
- cielab
->display
.d_Y0R
) / cielab
->range
;
143 for(i
= 0; i
<= cielab
->range
; i
++) {
144 cielab
->Yg2g
[i
] = cielab
->display
.d_Vrwg
145 * ((float)pow((double)i
/ cielab
->range
, gamma
));
149 gamma
= 1.0F
/ cielab
->display
.d_gammaB
;
151 (cielab
->display
.d_YCR
- cielab
->display
.d_Y0R
) / cielab
->range
;
152 for(i
= 0; i
<= cielab
->range
; i
++) {
153 cielab
->Yb2b
[i
] = cielab
->display
.d_Vrwb
154 * ((float)pow((double)i
/ cielab
->range
, gamma
));
157 /* Init reference white point */
158 cielab
->X0
= refWhite
[0];
159 cielab
->Y0
= refWhite
[1];
160 cielab
->Z0
= refWhite
[2];
166 * Convert color value from the YCbCr space to CIE XYZ.
167 * The colorspace conversion algorithm comes from the IJG v5a code;
168 * see below for more information on how it works.
171 #define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5))
172 #define ONE_HALF ((int32)(1<<(SHIFT-1)))
173 #define Code2V(c, RB, RW, CR) ((((c)-(int32)(RB))*(float)(CR))/(float)((RW)-(RB)))
174 #define CLAMP(f,min,max) ((f)<(min)?(min):(f)>(max)?(max):(f))
177 TIFFYCbCrtoRGB(TIFFYCbCrToRGB
*ycbcr
, uint32 Y
, int32 Cb
, int32 Cr
,
178 uint32
*r
, uint32
*g
, uint32
*b
)
180 /* XXX: Only 8-bit YCbCr input supported for now */
181 Y
= CLAMP(Y
, 0, 255), Cb
= CLAMP(Cb
, 0, 255), Cr
= CLAMP(Cr
, 0, 255);
183 *r
= ycbcr
->clamptab
[ycbcr
->Y_tab
[Y
] + ycbcr
->Cr_r_tab
[Cr
]];
184 *g
= ycbcr
->clamptab
[ycbcr
->Y_tab
[Y
]
185 + (int)((ycbcr
->Cb_g_tab
[Cb
] + ycbcr
->Cr_g_tab
[Cr
]) >> SHIFT
)];
186 *b
= ycbcr
->clamptab
[ycbcr
->Y_tab
[Y
] + ycbcr
->Cb_b_tab
[Cb
]];
190 * Initialize the YCbCr->RGB conversion tables. The conversion
191 * is done according to the 6.0 spec:
193 * R = Y + Cr*(2 - 2*LumaRed)
194 * B = Y + Cb*(2 - 2*LumaBlue)
196 * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
197 * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
199 * To avoid floating point arithmetic the fractional constants that
200 * come out of the equations are represented as fixed point values
201 * in the range 0...2^16. We also eliminate multiplications by
202 * pre-calculating possible values indexed by Cb and Cr (this code
203 * assumes conversion is being done for 8-bit samples).
206 TIFFYCbCrToRGBInit(TIFFYCbCrToRGB
* ycbcr
, float *luma
, float *refBlackWhite
)
208 TIFFRGBValue
* clamptab
;
211 #define LumaRed luma[0]
212 #define LumaGreen luma[1]
213 #define LumaBlue luma[2]
215 clamptab
= (TIFFRGBValue
*)(
216 (tidata_t
) ycbcr
+TIFFroundup(sizeof (TIFFYCbCrToRGB
), sizeof (long)));
217 _TIFFmemset(clamptab
, 0, 256); /* v < 0 => 0 */
218 ycbcr
->clamptab
= (clamptab
+= 256);
219 for (i
= 0; i
< 256; i
++)
220 clamptab
[i
] = (TIFFRGBValue
) i
;
221 _TIFFmemset(clamptab
+256, 255, 2*256); /* v > 255 => 255 */
222 ycbcr
->Cr_r_tab
= (int*) (clamptab
+ 3*256);
223 ycbcr
->Cb_b_tab
= ycbcr
->Cr_r_tab
+ 256;
224 ycbcr
->Cr_g_tab
= (int32
*) (ycbcr
->Cb_b_tab
+ 256);
225 ycbcr
->Cb_g_tab
= ycbcr
->Cr_g_tab
+ 256;
226 ycbcr
->Y_tab
= ycbcr
->Cb_g_tab
+ 256;
228 { float f1
= 2-2*LumaRed
; int32 D1
= FIX(f1
);
229 float f2
= LumaRed
*f1
/LumaGreen
; int32 D2
= -FIX(f2
);
230 float f3
= 2-2*LumaBlue
; int32 D3
= FIX(f3
);
231 float f4
= LumaBlue
*f3
/LumaGreen
; int32 D4
= -FIX(f4
);
239 * i is the actual input pixel value in the range 0..255
240 * Cb and Cr values are in the range -128..127 (actually
241 * they are in a range defined by the ReferenceBlackWhite
242 * tag) so there is some range shifting to do here when
243 * constructing tables indexed by the raw pixel data.
245 for (i
= 0, x
= -128; i
< 256; i
++, x
++) {
246 int32 Cr
= (int32
)Code2V(x
, refBlackWhite
[4] - 128.0F
,
247 refBlackWhite
[5] - 128.0F
, 127);
248 int32 Cb
= (int32
)Code2V(x
, refBlackWhite
[2] - 128.0F
,
249 refBlackWhite
[3] - 128.0F
, 127);
251 ycbcr
->Cr_r_tab
[i
] = (int32
)((D1
*Cr
+ ONE_HALF
)>>SHIFT
);
252 ycbcr
->Cb_b_tab
[i
] = (int32
)((D3
*Cb
+ ONE_HALF
)>>SHIFT
);
253 ycbcr
->Cr_g_tab
[i
] = D2
*Cr
;
254 ycbcr
->Cb_g_tab
[i
] = D4
*Cb
+ ONE_HALF
;
256 (int32
)Code2V(x
+ 128, refBlackWhite
[0], refBlackWhite
[1], 255);