ReactOS 0.4.16-dev-2613-g9533ad7
tif_color.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 1988-1997 Sam Leffler
3 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and
6 * its documentation for any purpose is hereby granted without fee, provided
7 * that (i) the above copyright notices and this permission notice appear in
8 * all copies of the software and related documentation, and (ii) the names of
9 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10 * publicity relating to the software without the specific, prior written
11 * permission of Sam Leffler and Silicon Graphics.
12 *
13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22 * OF THIS SOFTWARE.
23 */
24
25/*
26 * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
27 * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
28 * the permission of John Cupitt, the VIPS author.
29 */
30
31/*
32 * TIFF Library.
33 *
34 * Color space conversion routines.
35 */
36
37#include "tiffiop.h"
38#include <math.h>
39
40/*
41 * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
42 */
44 float *X, float *Y, float *Z)
45{
46 TIFFCIELab16ToXYZ(cielab, l * 257, a * 256, b * 256, X, Y, Z);
47}
48
49/*
50 * For CIELab encoded in 16 bits, L is an unsigned integer range [0,65535].
51 * The a* and b* components are signed integers range [-32768,32767]. The 16
52 * bit chrominance values are encoded as 256 times the 1976 CIE a* and b*
53 * values
54 */
56 int32_t b, float *X, float *Y, float *Z)
57{
58 float L = (float)l * 100.0F / 65535.0F;
59 float cby, tmp;
60
61 if (L < 8.856F)
62 {
63 *Y = (L * cielab->Y0) / 903.292F;
64 cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
65 }
66 else
67 {
68 cby = (L + 16.0F) / 116.0F;
69 *Y = cielab->Y0 * cby * cby * cby;
70 }
71
72 tmp = (float)a / 256.0F / 500.0F + cby;
73 if (tmp < 0.2069F)
74 *X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
75 else
76 *X = cielab->X0 * tmp * tmp * tmp;
77
78 tmp = cby - (float)b / 256.0F / 200.0F;
79 if (tmp < 0.2069F)
80 *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
81 else
82 *Z = cielab->Z0 * tmp * tmp * tmp;
83}
84
85#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5) : ((R)-0.5)))
86/*
87 * Convert color value from the XYZ space to RGB.
88 */
89void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
91{
92 size_t i;
93 float Yr, Yg, Yb;
94 float *matrix = &cielab->display.d_mat[0][0];
95
96 /* Multiply through the matrix to get luminosity values. */
97 Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z;
98 Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z;
99 Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z;
100
101 /* Clip input */
102 Yr = TIFFmax(Yr, cielab->display.d_Y0R);
103 Yg = TIFFmax(Yg, cielab->display.d_Y0G);
104 Yb = TIFFmax(Yb, cielab->display.d_Y0B);
105
106 /* Avoid overflow in case of wrong input values */
107 Yr = TIFFmin(Yr, cielab->display.d_YCR);
108 Yg = TIFFmin(Yg, cielab->display.d_YCG);
109 Yb = TIFFmin(Yb, cielab->display.d_YCB);
110
111 /* Turn luminosity to colour value. */
112 i = (size_t)((Yr - cielab->display.d_Y0R) / cielab->rstep);
113 i = TIFFmin((size_t)cielab->range, i);
114 *r = RINT(cielab->Yr2r[i]);
115
116 i = (size_t)((Yg - cielab->display.d_Y0G) / cielab->gstep);
117 i = TIFFmin((size_t)cielab->range, i);
118 *g = RINT(cielab->Yg2g[i]);
119
120 i = (size_t)((Yb - cielab->display.d_Y0B) / cielab->bstep);
121 i = TIFFmin((size_t)cielab->range, i);
122 *b = RINT(cielab->Yb2b[i]);
123
124 /* Clip output. */
125 *r = TIFFmin(*r, cielab->display.d_Vrwr);
126 *g = TIFFmin(*g, cielab->display.d_Vrwg);
127 *b = TIFFmin(*b, cielab->display.d_Vrwb);
128}
129#undef RINT
130
131/*
132 * Allocate conversion state structures and make look_up tables for
133 * the Yr,Yb,Yg <=> r,g,b conversions.
134 */
136 float *refWhite)
137{
138 size_t i;
139 double dfGamma;
140
142
143 _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
144
145 /* Red */
146 dfGamma = 1.0 / cielab->display.d_gammaR;
147 cielab->rstep =
148 (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
149 for (i = 0; i <= (size_t)cielab->range; i++)
150 {
151 cielab->Yr2r[i] = cielab->display.d_Vrwr *
152 ((float)pow((double)i / cielab->range, dfGamma));
153 }
154
155 /* Green */
156 dfGamma = 1.0 / cielab->display.d_gammaG;
157 cielab->gstep =
158 (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
159 for (i = 0; i <= (size_t)cielab->range; i++)
160 {
161 cielab->Yg2g[i] = cielab->display.d_Vrwg *
162 ((float)pow((double)i / cielab->range, dfGamma));
163 }
164
165 /* Blue */
166 dfGamma = 1.0 / cielab->display.d_gammaB;
167 cielab->bstep =
168 (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
169 for (i = 0; i <= (size_t)cielab->range; i++)
170 {
171 cielab->Yb2b[i] = cielab->display.d_Vrwb *
172 ((float)pow((double)i / cielab->range, dfGamma));
173 }
174
175 /* Init reference white point */
176 cielab->X0 = refWhite[0];
177 cielab->Y0 = refWhite[1];
178 cielab->Z0 = refWhite[2];
179
180 return 0;
181}
182
183/*
184 * Convert color value from the YCbCr space to RGB.
185 * The colorspace conversion algorithm comes from the IJG v5a code;
186 * see below for more information on how it works.
187 */
188#define SHIFT 16
189#define FIX(x) ((int32_t)((x) * (1L << SHIFT) + 0.5))
190#define ONE_HALF ((int32_t)(1 << (SHIFT - 1)))
191#define Code2V(c, RB, RW, CR) \
192 ((((c) - (int32_t)(RB)) * (float)(CR)) / \
193 (float)(((RW) - (RB) != 0) ? ((RW) - (RB)) : 1))
194/* !((f)>=(min)) written that way to deal with NaN */
195#define CLAMP(f, min, max) \
196 ((!((f) >= (min))) ? (min) : (f) > (max) ? (max) : (f))
197#define HICLAMP(f, max) ((f) > (max) ? (max) : (f))
198
201{
202 int32_t i;
203
204 /* XXX: Only 8-bit YCbCr input supported for now */
205 Y = HICLAMP(Y, 255);
206 Cb = CLAMP(Cb, 0, 255);
207 Cr = CLAMP(Cr, 0, 255);
208
209 i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
210 *r = CLAMP(i, 0, 255);
211 i = ycbcr->Y_tab[Y] +
212 (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
213 *g = CLAMP(i, 0, 255);
214 i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
215 *b = CLAMP(i, 0, 255);
216}
217
218/* Clamp function for sanitization purposes. Normally clamping should not */
219/* occur for well behaved chroma and refBlackWhite coefficients */
220static float CLAMPw(float v, float vmin, float vmax)
221{
222 if (v < vmin)
223 {
224 /* printf("%f clamped to %f\n", v, vmin); */
225 return vmin;
226 }
227 if (v > vmax)
228 {
229 /* printf("%f clamped to %f\n", v, vmax); */
230 return vmax;
231 }
232 return v;
233}
234
235/*
236 * Initialize the YCbCr->RGB conversion tables. The conversion
237 * is done according to the 6.0 spec:
238 *
239 * R = Y + Cr*(2 - 2*LumaRed)
240 * B = Y + Cb*(2 - 2*LumaBlue)
241 * G = Y
242 * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
243 * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
244 *
245 * To avoid floating point arithmetic the fractional constants that
246 * come out of the equations are represented as fixed point values
247 * in the range 0...2^16. We also eliminate multiplications by
248 * pre-calculating possible values indexed by Cb and Cr (this code
249 * assumes conversion is being done for 8-bit samples).
250 */
251int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
252{
253 TIFFRGBValue *clamptab;
254 int i;
255
256#define LumaRed luma[0]
257#define LumaGreen luma[1]
258#define LumaBlue luma[2]
259
260 clamptab =
261 (TIFFRGBValue *)((uint8_t *)ycbcr +
262 TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)));
263 _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
264 ycbcr->clamptab = (clamptab += 256);
265 for (i = 0; i < 256; i++)
266 clamptab[i] = (TIFFRGBValue)i;
267 _TIFFmemset(clamptab + 256, 255, 2 * 256); /* v > 255 => 255 */
268 ycbcr->Cr_r_tab = (int *)(clamptab + 3 * 256);
269 ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
270 ycbcr->Cr_g_tab = (int32_t *)(ycbcr->Cb_b_tab + 256);
271 ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
272 ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
273
274 {
275 float f1 = 2 - 2 * LumaRed;
276 int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F));
277 float f2 = LumaRed * f1 / LumaGreen;
278 int32_t D2 = -FIX(CLAMP(f2, 0.0F, 2.0F));
279 float f3 = 2 - 2 * LumaBlue;
280 int32_t D3 = FIX(CLAMP(f3, 0.0F, 2.0F));
281 float f4 = LumaBlue * f3 / LumaGreen;
282 int32_t D4 = -FIX(CLAMP(f4, 0.0F, 2.0F));
283 int x;
284
285#undef LumaBlue
286#undef LumaGreen
287#undef LumaRed
288
289 /*
290 * i is the actual input pixel value in the range 0..255
291 * Cb and Cr values are in the range -128..127 (actually
292 * they are in a range defined by the ReferenceBlackWhite
293 * tag) so there is some range shifting to do here when
294 * constructing tables indexed by the raw pixel data.
295 */
296 for (i = 0, x = -128; i < 256; i++, x++)
297 {
298 int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
299 refBlackWhite[5] - 128.0F, 127),
300 -128.0F * 32, 128.0F * 32);
301 int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
302 refBlackWhite[3] - 128.0F, 127),
303 -128.0F * 32, 128.0F * 32);
304
305 ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT);
306 ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT);
307 ycbcr->Cr_g_tab[i] = D2 * Cr;
308 ycbcr->Cb_g_tab[i] = D4 * Cb + ONE_HALF;
309 ycbcr->Y_tab[i] = (int32_t)CLAMPw(
310 Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
311 -128.0F * 32, 128.0F * 32);
312 }
313 }
314
315 return 0;
316}
317#undef HICLAMP
318#undef CLAMP
319#undef Code2V
320#undef SHIFT
321#undef ONE_HALF
322#undef FIX
r l[0]
Definition: byte_order.h:168
INT32 int32_t
Definition: types.h:71
UINT32 uint32_t
Definition: types.h:75
#define Z(I)
#define Y(I)
unsigned int size_t
Definition: corecrt.h:203
unsigned char uint8_t
Definition: stdint.h:33
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define L(x)
Definition: resources.c:13
double pow(double x, double y)
Definition: freeldr.c:179
for(i=0;i< ARRAY_SIZE(offsets);i++)
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
const GLdouble * v
Definition: gl.h:2040
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLuint GLenum matrix
Definition: glext.h:9407
GLboolean GLboolean g
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define Yb
Definition: i386-dis.c:436
static float(__cdecl *square_half_float)(float x
#define int32_t
Definition: nsiface.idl:56
#define f2(x, y, z)
Definition: sha1.c:31
#define f1(x, y, z)
Definition: sha1.c:30
#define f4(x, y, z)
Definition: sha1.c:33
#define f3(x, y, z)
Definition: sha1.c:32
float Yb2b[CIELABTORGB_TABLE_RANGE+1]
Definition: tiffio.h:188
float bstep
Definition: tiffio.h:183
TIFFDisplay display
Definition: tiffio.h:185
float rstep
Definition: tiffio.h:183
float gstep
Definition: tiffio.h:183
float Yr2r[CIELABTORGB_TABLE_RANGE+1]
Definition: tiffio.h:186
float Yg2g[CIELABTORGB_TABLE_RANGE+1]
Definition: tiffio.h:187
float d_mat[3][3]
Definition: tiffio.h:142
float d_gammaG
Definition: tiffio.h:153
float d_YCB
Definition: tiffio.h:145
uint32_t d_Vrwr
Definition: tiffio.h:146
float d_Y0R
Definition: tiffio.h:149
float d_gammaR
Definition: tiffio.h:152
float d_YCG
Definition: tiffio.h:144
float d_YCR
Definition: tiffio.h:143
float d_Y0G
Definition: tiffio.h:150
float d_Y0B
Definition: tiffio.h:151
uint32_t d_Vrwg
Definition: tiffio.h:147
float d_gammaB
Definition: tiffio.h:154
uint32_t d_Vrwb
Definition: tiffio.h:148
int * Cr_r_tab
Definition: tiffio.h:172
int32_t * Cb_g_tab
Definition: tiffio.h:175
int32_t * Y_tab
Definition: tiffio.h:176
TIFFRGBValue * clamptab
Definition: tiffio.h:171
int * Cb_b_tab
Definition: tiffio.h:173
int32_t * Cr_g_tab
Definition: tiffio.h:174
void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, float *X, float *Y, float *Z)
Definition: tif_color.c:43
void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, float *X, float *Y, float *Z)
Definition: tif_color.c:55
static float CLAMPw(float v, float vmin, float vmax)
Definition: tif_color.c:220
#define LumaRed
void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr, uint32_t *r, uint32_t *g, uint32_t *b)
Definition: tif_color.c:199
#define LumaBlue
#define FIX(x)
Definition: tif_color.c:189
#define RINT(R)
Definition: tif_color.c:85
#define Code2V(c, RB, RW, CR)
Definition: tif_color.c:191
#define CLAMP(f, min, max)
Definition: tif_color.c:195
int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
Definition: tif_color.c:251
#define ONE_HALF
Definition: tif_color.c:190
#define SHIFT
Definition: tif_color.c:188
#define LumaGreen
#define HICLAMP(f, max)
Definition: tif_color.c:197
int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, float *refWhite)
Definition: tif_color.c:135
void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, uint32_t *r, uint32_t *g, uint32_t *b)
Definition: tif_color.c:89
void _TIFFmemset(void *p, int v, tmsize_t c)
Definition: tif_unix.c:353
void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
Definition: tif_unix.c:355
unsigned char TIFFRGBValue
Definition: tiffio.h:138
#define CIELABTORGB_TABLE_RANGE
Definition: tiffio.h:182
#define TIFFroundup_32(x, y)
Definition: tiffiop.h:316
#define TIFFmax(A, B)
Definition: tiffiop.h:330
#define TIFFmin(A, B)
Definition: tiffiop.h:331
int * display
Definition: x11stubs.c:12