ReactOS  0.4.13-dev-551-gf37fb1f
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 <precomp.h>
38 #include <math.h>
39 
40 /*
41  * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
42  */
43 void
45  float *X, float *Y, float *Z)
46 {
47  float L = (float)l * 100.0F / 255.0F;
48  float cby, tmp;
49 
50  if( L < 8.856F ) {
51  *Y = (L * cielab->Y0) / 903.292F;
52  cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
53  } else {
54  cby = (L + 16.0F) / 116.0F;
55  *Y = cielab->Y0 * cby * cby * cby;
56  }
57 
58  tmp = (float)a / 500.0F + cby;
59  if( tmp < 0.2069F )
60  *X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
61  else
62  *X = cielab->X0 * tmp * tmp * tmp;
63 
64  tmp = cby - (float)b / 200.0F;
65  if( tmp < 0.2069F )
66  *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
67  else
68  *Z = cielab->Z0 * tmp * tmp * tmp;
69 }
70 
71 #define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5)))
72 /*
73  * Convert color value from the XYZ space to RGB.
74  */
75 void
76 TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
77  uint32 *r, uint32 *g, uint32 *b)
78 {
79  int i;
80  float Yr, Yg, Yb;
81  float *matrix = &cielab->display.d_mat[0][0];
82 
83  /* Multiply through the matrix to get luminosity values. */
84  Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z;
85  Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z;
86  Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z;
87 
88  /* Clip input */
89  Yr = TIFFmax(Yr, cielab->display.d_Y0R);
90  Yg = TIFFmax(Yg, cielab->display.d_Y0G);
91  Yb = TIFFmax(Yb, cielab->display.d_Y0B);
92 
93  /* Avoid overflow in case of wrong input values */
94  Yr = TIFFmin(Yr, cielab->display.d_YCR);
95  Yg = TIFFmin(Yg, cielab->display.d_YCG);
96  Yb = TIFFmin(Yb, cielab->display.d_YCB);
97 
98  /* Turn luminosity to colour value. */
99  i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
100  i = TIFFmin(cielab->range, i);
101  *r = RINT(cielab->Yr2r[i]);
102 
103  i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
104  i = TIFFmin(cielab->range, i);
105  *g = RINT(cielab->Yg2g[i]);
106 
107  i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
108  i = TIFFmin(cielab->range, i);
109  *b = RINT(cielab->Yb2b[i]);
110 
111  /* Clip output. */
112  *r = TIFFmin(*r, cielab->display.d_Vrwr);
113  *g = TIFFmin(*g, cielab->display.d_Vrwg);
114  *b = TIFFmin(*b, cielab->display.d_Vrwb);
115 }
116 #undef RINT
117 
118 /*
119  * Allocate conversion state structures and make look_up tables for
120  * the Yr,Yb,Yg <=> r,g,b conversions.
121  */
122 int
124  const TIFFDisplay *display, float *refWhite)
125 {
126  int i;
127  double dfGamma;
128 
129  cielab->range = CIELABTORGB_TABLE_RANGE;
130 
131  _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
132 
133  /* Red */
134  dfGamma = 1.0 / cielab->display.d_gammaR ;
135  cielab->rstep =
136  (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
137  for(i = 0; i <= cielab->range; i++) {
138  cielab->Yr2r[i] = cielab->display.d_Vrwr
139  * ((float)pow((double)i / cielab->range, dfGamma));
140  }
141 
142  /* Green */
143  dfGamma = 1.0 / cielab->display.d_gammaG ;
144  cielab->gstep =
145  (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
146  for(i = 0; i <= cielab->range; i++) {
147  cielab->Yg2g[i] = cielab->display.d_Vrwg
148  * ((float)pow((double)i / cielab->range, dfGamma));
149  }
150 
151  /* Blue */
152  dfGamma = 1.0 / cielab->display.d_gammaB ;
153  cielab->bstep =
154  (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
155  for(i = 0; i <= cielab->range; i++) {
156  cielab->Yb2b[i] = cielab->display.d_Vrwb
157  * ((float)pow((double)i / cielab->range, dfGamma));
158  }
159 
160  /* Init reference white point */
161  cielab->X0 = refWhite[0];
162  cielab->Y0 = refWhite[1];
163  cielab->Z0 = refWhite[2];
164 
165  return 0;
166 }
167 
168 /*
169  * Convert color value from the YCbCr space to RGB.
170  * The colorspace conversion algorithm comes from the IJG v5a code;
171  * see below for more information on how it works.
172  */
173 #define SHIFT 16
174 #define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5))
175 #define ONE_HALF ((int32)(1<<(SHIFT-1)))
176 #define Code2V(c, RB, RW, CR) ((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)!=0) ? ((RW)-(RB)) : 1))
177 #define CLAMP(f,min,max) ((f)<(min)?(min):(f)>(max)?(max):(f))
178 #define HICLAMP(f,max) ((f)>(max)?(max):(f))
179 
180 void
182  uint32 *r, uint32 *g, uint32 *b)
183 {
184  int32 i;
185 
186  /* XXX: Only 8-bit YCbCr input supported for now */
187  Y = HICLAMP(Y, 255);
188  Cb = CLAMP(Cb, 0, 255);
189  Cr = CLAMP(Cr, 0, 255);
190 
191  i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
192  *r = CLAMP(i, 0, 255);
193  i = ycbcr->Y_tab[Y]
194  + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
195  *g = CLAMP(i, 0, 255);
196  i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
197  *b = CLAMP(i, 0, 255);
198 }
199 
200 /* Clamp function for sanitization purposes. Normally clamping should not */
201 /* occur for well behaved chroma and refBlackWhite coefficients */
202 static float CLAMPw(float v, float vmin, float vmax)
203 {
204  if( v < vmin )
205  {
206  /* printf("%f clamped to %f\n", v, vmin); */
207  return vmin;
208  }
209  if( v > vmax )
210  {
211  /* printf("%f clamped to %f\n", v, vmax); */
212  return vmax;
213  }
214  return v;
215 }
216 
217 /*
218  * Initialize the YCbCr->RGB conversion tables. The conversion
219  * is done according to the 6.0 spec:
220  *
221  * R = Y + Cr*(2 - 2*LumaRed)
222  * B = Y + Cb*(2 - 2*LumaBlue)
223  * G = Y
224  * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
225  * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
226  *
227  * To avoid floating point arithmetic the fractional constants that
228  * come out of the equations are represented as fixed point values
229  * in the range 0...2^16. We also eliminate multiplications by
230  * pre-calculating possible values indexed by Cb and Cr (this code
231  * assumes conversion is being done for 8-bit samples).
232  */
233 int
234 TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
235 {
236  TIFFRGBValue* clamptab;
237  int i;
238 
239 #define LumaRed luma[0]
240 #define LumaGreen luma[1]
241 #define LumaBlue luma[2]
242 
243  clamptab = (TIFFRGBValue*)(
244  (uint8*) ycbcr+TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)));
245  _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
246  ycbcr->clamptab = (clamptab += 256);
247  for (i = 0; i < 256; i++)
248  clamptab[i] = (TIFFRGBValue) i;
249  _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */
250  ycbcr->Cr_r_tab = (int*) (clamptab + 3*256);
251  ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
252  ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256);
253  ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
254  ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
255 
256  { float f1 = 2-2*LumaRed; int32 D1 = FIX(CLAMP(f1,0.0F,2.0F));
257  float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(CLAMP(f2,0.0F,2.0F));
258  float f3 = 2-2*LumaBlue; int32 D3 = FIX(CLAMP(f3,0.0F,2.0F));
259  float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(CLAMP(f4,0.0F,2.0F));
260  int x;
261 
262 #undef LumaBlue
263 #undef LumaGreen
264 #undef LumaRed
265 
266  /*
267  * i is the actual input pixel value in the range 0..255
268  * Cb and Cr values are in the range -128..127 (actually
269  * they are in a range defined by the ReferenceBlackWhite
270  * tag) so there is some range shifting to do here when
271  * constructing tables indexed by the raw pixel data.
272  */
273  for (i = 0, x = -128; i < 256; i++, x++) {
274  int32 Cr = (int32)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
275  refBlackWhite[5] - 128.0F, 127),
276  -128.0F * 32, 128.0F * 32);
277  int32 Cb = (int32)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
278  refBlackWhite[3] - 128.0F, 127),
279  -128.0F * 32, 128.0F * 32);
280 
281  ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
282  ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
283  ycbcr->Cr_g_tab[i] = D2*Cr;
284  ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
285  ycbcr->Y_tab[i] =
286  (int32)CLAMPw(Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
287  -128.0F * 32, 128.0F * 32);
288  }
289  }
290 
291  return 0;
292 }
293 #undef HICLAMP
294 #undef CLAMP
295 #undef Code2V
296 #undef SHIFT
297 #undef ONE_HALF
298 #undef FIX
299 
300 /* vim: set ts=8 sts=8 sw=8 noet: */
301 /*
302  * Local Variables:
303  * mode: c
304  * c-basic-offset: 8
305  * fill-column: 78
306  * End:
307  */
#define Yb
Definition: i386-dis.c:427
#define LumaBlue
void _TIFFmemset(void *p, int v, tmsize_t c)
Definition: tif_unix.c:338
void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, uint32 *r, uint32 *g, uint32 *b)
Definition: tif_color.c:76
#define f3(x, y, z)
Definition: sha1.c:32
float Yg2g[CIELABTORGB_TABLE_RANGE+1]
Definition: tiffio.h:175
#define Y(I)
#define RINT(R)
Definition: tif_color.c:71
GLuint GLenum matrix
Definition: glext.h:9407
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
unsigned int uint32
Definition: types.h:32
float d_mat[3][3]
Definition: tiffio.h:144
TIFFRGBValue * clamptab
Definition: tiffio.h:160
float rstep
Definition: tiffio.h:171
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
unsigned char TIFFRGBValue
Definition: tiffio.h:141
float d_YCR
Definition: tiffio.h:145
int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, float *refWhite)
Definition: tif_color.c:123
float d_YCG
Definition: tiffio.h:146
#define FIX(x)
Definition: tif_color.c:174
int * display
Definition: x11stubs.c:12
float bstep
Definition: tiffio.h:171
TIFFDisplay display
Definition: tiffio.h:173
#define Z(I)
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
float pow(float __x, int __y)
Definition: _cmath.h:458
#define CLAMP(f, min, max)
Definition: tif_color.c:177
#define LumaRed
float d_gammaG
Definition: tiffio.h:155
#define CIELABTORGB_TABLE_RANGE
Definition: tiffio.h:170
float Yb2b[CIELABTORGB_TABLE_RANGE+1]
Definition: tiffio.h:176
r l[0]
Definition: byte_order.h:167
float d_Y0B
Definition: tiffio.h:153
int * Cr_r_tab
Definition: tiffio.h:161
GLboolean GLboolean g
Definition: glext.h:6204
uint32 d_Vrwg
Definition: tiffio.h:149
int * Cb_b_tab
Definition: tiffio.h:162
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
int32 * Cb_g_tab
Definition: tiffio.h:164
float d_Y0G
Definition: tiffio.h:152
void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b, float *X, float *Y, float *Z)
Definition: tif_color.c:44
#define HICLAMP(f, max)
Definition: tif_color.c:178
#define TIFFmax(A, B)
Definition: tiffiop.h:264
uint32 d_Vrwb
Definition: tiffio.h:150
float Yr2r[CIELABTORGB_TABLE_RANGE+1]
Definition: tiffio.h:174
unsigned char uint8
Definition: types.h:28
float d_gammaR
Definition: tiffio.h:154
#define SHIFT
Definition: tif_color.c:173
int32 * Y_tab
Definition: tiffio.h:165
int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
Definition: tif_color.c:234
static const WCHAR L[]
Definition: oid.c:1250
static float CLAMPw(float v, float vmin, float vmax)
Definition: tif_color.c:202
#define f4(x, y, z)
Definition: sha1.c:33
void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr, uint32 *r, uint32 *g, uint32 *b)
Definition: tif_color.c:181
GLenum GLint * range
Definition: glext.h:7539
#define LumaGreen
float gstep
Definition: tiffio.h:171
#define f1(x, y, z)
Definition: sha1.c:30
#define ONE_HALF
Definition: tif_color.c:175
uint32 d_Vrwr
Definition: tiffio.h:148
const GLdouble * v
Definition: gl.h:2040
float d_YCB
Definition: tiffio.h:147
float d_gammaB
Definition: tiffio.h:156
float d_Y0R
Definition: tiffio.h:151
int32 * Cr_g_tab
Definition: tiffio.h:163
long int32
Definition: platform.h:12
#define TIFFmin(A, B)
Definition: tiffiop.h:265
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
int f2(S1 &, S2 &)
#define Code2V(c, RB, RW, CR)
Definition: tif_color.c:176
#define TIFFroundup_32(x, y)
Definition: tiffiop.h:256
void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
Definition: tif_unix.c:344
#define F(x, y, z)
Definition: md5.c:51
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31