Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
tif_color.c
Go to the documentation of this file.
1 /* $Id: tif_color.c,v 1.12 2006/02/09 15:42:20 dron Exp $ */
2 
3 /*
4  * Copyright (c) 1988-1997 Sam Leffler
5  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6  *
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.
14  *
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.
18  *
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
24  * OF THIS SOFTWARE.
25  */
26 
27 /*
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.
31  */
32 
33 /*
34  * TIFF Library.
35  *
36  * Color space conversion routines.
37  */
38 
39 #include "tiffiop.h"
40 #include <math.h>
41 
42 /*
43  * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
44  */
45 void
46 TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b,
47  float *X, float *Y, float *Z)
48 {
49  float L = (float)l * 100.0F / 255.0F;
50  float cby, tmp;
51 
52  if( L < 8.856F ) {
53  *Y = (L * cielab->Y0) / 903.292F;
54  cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
55  } else {
56  cby = (L + 16.0F) / 116.0F;
57  *Y = cielab->Y0 * cby * cby * cby;
58  }
59 
60  tmp = (float)a / 500.0F + cby;
61  if( tmp < 0.2069F )
62  *X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
63  else
64  *X = cielab->X0 * tmp * tmp * tmp;
65 
66  tmp = cby - (float)b / 200.0F;
67  if( tmp < 0.2069F )
68  *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
69  else
70  *Z = cielab->Z0 * tmp * tmp * tmp;
71 }
72 
73 #define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5)))
74 /*
75  * Convert color value from the XYZ space to RGB.
76  */
77 void
78 TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
79  uint32 *r, uint32 *g, uint32 *b)
80 {
81  int i;
82  float Yr, Yg, Yb;
83  float *matrix = &cielab->display.d_mat[0][0];
84 
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;
89 
90  /* Clip input */
91  Yr = TIFFmax(Yr, cielab->display.d_Y0R);
92  Yg = TIFFmax(Yg, cielab->display.d_Y0G);
93  Yb = TIFFmax(Yb, cielab->display.d_Y0B);
94 
95  /* Avoid overflow in case of wrong input values */
96  Yr = TIFFmin(Yr, cielab->display.d_YCR);
97  Yg = TIFFmin(Yg, cielab->display.d_YCG);
98  Yb = TIFFmin(Yb, cielab->display.d_YCB);
99 
100  /* Turn luminosity to colour value. */
101  i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
102  i = TIFFmin(cielab->range, i);
103  *r = RINT(cielab->Yr2r[i]);
104 
105  i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
106  i = TIFFmin(cielab->range, i);
107  *g = RINT(cielab->Yg2g[i]);
108 
109  i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
110  i = TIFFmin(cielab->range, i);
111  *b = RINT(cielab->Yb2b[i]);
112 
113  /* Clip output. */
114  *r = TIFFmin(*r, cielab->display.d_Vrwr);
115  *g = TIFFmin(*g, cielab->display.d_Vrwg);
116  *b = TIFFmin(*b, cielab->display.d_Vrwb);
117 }
118 #undef RINT
119 
120 /*
121  * Allocate conversion state structures and make look_up tables for
122  * the Yr,Yb,Yg <=> r,g,b conversions.
123  */
124 int
126  TIFFDisplay *display, float *refWhite)
127 {
128  int i;
129  double gamma;
130 
131  cielab->range = CIELABTORGB_TABLE_RANGE;
132 
133  _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
134 
135  /* Red */
136  gamma = 1.0 / cielab->display.d_gammaR ;
137  cielab->rstep =
138  (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
139  for(i = 0; i <= cielab->range; i++) {
140  cielab->Yr2r[i] = cielab->display.d_Vrwr
141  * ((float)pow((double)i / cielab->range, gamma));
142  }
143 
144  /* Green */
145  gamma = 1.0 / cielab->display.d_gammaG ;
146  cielab->gstep =
147  (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
148  for(i = 0; i <= cielab->range; i++) {
149  cielab->Yg2g[i] = cielab->display.d_Vrwg
150  * ((float)pow((double)i / cielab->range, gamma));
151  }
152 
153  /* Blue */
154  gamma = 1.0 / cielab->display.d_gammaB ;
155  cielab->bstep =
156  (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
157  for(i = 0; i <= cielab->range; i++) {
158  cielab->Yb2b[i] = cielab->display.d_Vrwb
159  * ((float)pow((double)i / cielab->range, gamma));
160  }
161 
162  /* Init reference white point */
163  cielab->X0 = refWhite[0];
164  cielab->Y0 = refWhite[1];
165  cielab->Z0 = refWhite[2];
166 
167  return 0;
168 }
169 
170 /*
171  * Convert color value from the YCbCr space to CIE XYZ.
172  * The colorspace conversion algorithm comes from the IJG v5a code;
173  * see below for more information on how it works.
174  */
175 #define SHIFT 16
176 #define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5))
177 #define ONE_HALF ((int32)(1<<(SHIFT-1)))
178 #define Code2V(c, RB, RW, CR) ((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)) ? ((RW)-(RB)) : 1))
179 #define CLAMP(f,min,max) ((f)<(min)?(min):(f)>(max)?(max):(f))
180 #define HICLAMP(f,max) ((f)>(max)?(max):(f))
181 
182 void
183 TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
184  uint32 *r, uint32 *g, uint32 *b)
185 {
186  /* XXX: Only 8-bit YCbCr input supported for now */
187  Y = HICLAMP(Y, 255), Cb = CLAMP(Cb, 0, 255), Cr = CLAMP(Cr, 0, 255);
188 
189  *r = ycbcr->clamptab[ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]];
190  *g = ycbcr->clamptab[ycbcr->Y_tab[Y]
191  + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT)];
192  *b = ycbcr->clamptab[ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]];
193 }
194 
195 /*
196  * Initialize the YCbCr->RGB conversion tables. The conversion
197  * is done according to the 6.0 spec:
198  *
199  * R = Y + Cr*(2 - 2*LumaRed)
200  * B = Y + Cb*(2 - 2*LumaBlue)
201  * G = Y
202  * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
203  * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
204  *
205  * To avoid floating point arithmetic the fractional constants that
206  * come out of the equations are represented as fixed point values
207  * in the range 0...2^16. We also eliminate multiplications by
208  * pre-calculating possible values indexed by Cb and Cr (this code
209  * assumes conversion is being done for 8-bit samples).
210  */
211 int
212 TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
213 {
214  TIFFRGBValue* clamptab;
215  int i;
216 
217 #define LumaRed luma[0]
218 #define LumaGreen luma[1]
219 #define LumaBlue luma[2]
220 
221  clamptab = (TIFFRGBValue*)(
222  (tidata_t) ycbcr+TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long)));
223  _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
224  ycbcr->clamptab = (clamptab += 256);
225  for (i = 0; i < 256; i++)
226  clamptab[i] = (TIFFRGBValue) i;
227  _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */
228  ycbcr->Cr_r_tab = (int*) (clamptab + 3*256);
229  ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
230  ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256);
231  ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
232  ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
233 
234  { float f1 = 2-2*LumaRed; int32 D1 = FIX(f1);
235  float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2);
236  float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3);
237  float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4);
238  int x;
239 
240 #undef LumaBlue
241 #undef LumaGreen
242 #undef LumaRed
243 
244  /*
245  * i is the actual input pixel value in the range 0..255
246  * Cb and Cr values are in the range -128..127 (actually
247  * they are in a range defined by the ReferenceBlackWhite
248  * tag) so there is some range shifting to do here when
249  * constructing tables indexed by the raw pixel data.
250  */
251  for (i = 0, x = -128; i < 256; i++, x++) {
252  int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F,
253  refBlackWhite[5] - 128.0F, 127);
254  int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F,
255  refBlackWhite[3] - 128.0F, 127);
256 
257  ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
258  ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
259  ycbcr->Cr_g_tab[i] = D2*Cr;
260  ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
261  ycbcr->Y_tab[i] =
262  (int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255);
263  }
264  }
265 
266  return 0;
267 }
268 #undef HICLAMP
269 #undef CLAMP
270 #undef Code2V
271 #undef SHIFT
272 #undef ONE_HALF
273 #undef FIX
274 
275 /* vim: set ts=8 sts=8 sw=8 noet: */
#define LumaBlue
float bstep
Definition: tiffio.h:162
void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, uint32 *r, uint32 *g, uint32 *b)
Definition: tif_color.c:78
int32 * Y_tab
Definition: tiffio.h:156
GLboolean GLboolean GLboolean GLboolean a
#define RINT(R)
Definition: tif_color.c:73
int32 * Cb_g_tab
Definition: tiffio.h:155
int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, TIFFDisplay *display, float *refWhite)
Definition: tif_color.c:125
TIFFDisplay display
Definition: tiffio.h:164
GLint GLint GLint GLint GLint x
float d_gammaB
Definition: tiffio.h:147
uint32 d_Vrwr
Definition: tiffio.h:139
unsigned char TIFFRGBValue
Definition: tiffio.h:132
T pow(T a, T b)
Definition: glsl_math.hpp:434
int32 * Cr_g_tab
Definition: tiffio.h:154
GLenum GLint * range
GLboolean GLboolean GLboolean b
float d_mat[3][3]
Definition: tiffio.h:135
#define FIX(x)
Definition: tif_color.c:176
png_uint_32 i
Definition: png.h:2640
void _TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
Definition: tif_acorn.c:485
#define CLAMP(f, min, max)
Definition: tif_color.c:179
float d_YCB
Definition: tiffio.h:138
#define LumaRed
float Yg2g[CIELABTORGB_TABLE_RANGE+1]
Definition: tiffio.h:166
#define F(x, y, z)
Definition: md5.c:51
#define CIELABTORGB_TABLE_RANGE
Definition: tiffio.h:161
float Yr2r[CIELABTORGB_TABLE_RANGE+1]
Definition: tiffio.h:165
float d_YCG
Definition: tiffio.h:137
float Yb2b[CIELABTORGB_TABLE_RANGE+1]
Definition: tiffio.h:167
GLdouble GLdouble GLdouble r
uint32 d_Vrwb
Definition: tiffio.h:141
void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b, float *X, float *Y, float *Z)
Definition: tif_color.c:46
#define HICLAMP(f, max)
Definition: tif_color.c:180
TIFFRGBValue * clamptab
Definition: tiffio.h:151
#define TIFFmax(A, B)
Definition: tiffiop.h:229
float d_Y0B
Definition: tiffio.h:144
#define SHIFT
Definition: tif_color.c:175
#define TIFFroundup(x, y)
Definition: tiffiop.h:227
int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
Definition: tif_color.c:212
int * Cr_r_tab
Definition: tiffio.h:152
void _TIFFmemset(tdata_t p, int v, tsize_t c)
Definition: tif_acorn.c:479
float d_gammaG
Definition: tiffio.h:146
void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr, uint32 *r, uint32 *g, uint32 *b)
Definition: tif_color.c:183
unsigned long uint32
Definition: md5.h:41
tidataval_t * tidata_t
Definition: tiffiop.h:84
#define LumaGreen
typedef int
Definition: png.h:978
int * Cb_b_tab
Definition: tiffio.h:153
#define ONE_HALF
Definition: tif_color.c:177
GLboolean GLboolean g
float gstep
Definition: tiffio.h:162
float d_Y0G
Definition: tiffio.h:143
float d_Y0R
Definition: tiffio.h:142
float d_YCR
Definition: tiffio.h:136
#define TIFFmin(A, B)
Definition: tiffiop.h:230
GLuint GLenum matrix
#define Code2V(c, RB, RW, CR)
Definition: tif_color.c:178
float d_gammaR
Definition: tiffio.h:145
float rstep
Definition: tiffio.h:162
uint32 d_Vrwg
Definition: tiffio.h:140