]>
Commit | Line | Data |
---|---|---|
8414a40c VZ |
1 | .\" |
2 | .\" Copyright (c) 2003, Andrey Kiselev <dron@ak4719.spb.edu> | |
3 | .\" | |
4 | .\" Permission to use, copy, modify, distribute, and sell this software and | |
5 | .\" its documentation for any purpose is hereby granted without fee, provided | |
6 | .\" that (i) the above copyright notices and this permission notice appear in | |
7 | .\" all copies of the software and related documentation, and (ii) the names of | |
8 | .\" Sam Leffler and Silicon Graphics may not be used in any advertising or | |
9 | .\" publicity relating to the software without the specific, prior written | |
10 | .\" permission of Sam Leffler and Silicon Graphics. | |
11 | .\" | |
12 | .\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | |
13 | .\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | |
14 | .\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |
15 | .\" | |
16 | .\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR | |
17 | .\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | |
18 | .\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
19 | .\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | |
20 | .\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
21 | .\" OF THIS SOFTWARE. | |
22 | .\" | |
23 | .if n .po 0 | |
24 | .TH COLOR 3TIFF "December 21, 2003" "libtiff" | |
25 | .SH NAME | |
26 | TIFFYCbCrToRGBInit, TIFFYCbCrtoRGB, TIFFCIELabToRGBInit, TIFFCIELabToXYZ, | |
27 | TIFFXYZToRGB \- color conversion routines. | |
28 | .SH SYNOPSIS | |
29 | .B "#include <tiffio.h>" | |
30 | .sp | |
31 | .BI "int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *" ycbcr ", float *" luma ", float *"refBlackWhite" );" | |
32 | .br | |
33 | .BI "void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *" ycbcr ", uint32 " Y ", int32 " Cb ", int32 " Cr ", uint32 *" R ", uint32 *" G ", uint32 *" B " );" | |
34 | .sp | |
80ed523f | 35 | .BI "int TIFFCIELabToRGBInit(TIFFCIELabToRGB *" cielab ", const TIFFDisplay *" display ", float *" refWhite ");" |
8414a40c VZ |
36 | .br |
37 | .BI "void TIFFCIELabToXYZ(TIFFCIELabToRGB *" cielab ", uint32 " L ", int32 " a ", int32 " b ", float *" X ", float *" Y ", float *" Z ");" | |
38 | .br | |
39 | .BI "void TIFFXYZToRGB(TIFFCIELabToRGB *" cielab ", float " X ", float " Y ", float " Z" , uint32 *" R ", uint32 *" G ", uint32 *" B ");" | |
40 | .SH DESCRIPTION | |
41 | TIFF supports several color spaces for images stored in that format. There is | |
42 | usually a problem of application to handle the data properly and convert | |
43 | between different colorspaces for displaying and printing purposes. To | |
44 | simplify this task libtiff implements several color conversion routines | |
45 | itself. In particular, these routines used in | |
46 | .B TIFFRGBAImage(3TIFF) | |
47 | interface. | |
48 | .PP | |
49 | .B TIFFYCbCrToRGBInit() | |
50 | used to initialize | |
51 | .I YCbCr | |
52 | to | |
53 | .I RGB | |
54 | conversion state. Allocating and freeing of the | |
55 | .I ycbcr | |
56 | structure belongs to programmer. | |
57 | .I TIFFYCbCrToRGB | |
58 | defined in | |
59 | .B tiffio.h | |
60 | as | |
61 | .PP | |
62 | .RS | |
63 | .nf | |
64 | typedef struct { /* YCbCr->RGB support */ | |
65 | TIFFRGBValue* clamptab; /* range clamping table */ | |
66 | int* Cr_r_tab; | |
67 | int* Cb_b_tab; | |
68 | int32* Cr_g_tab; | |
69 | int32* Cb_g_tab; | |
70 | int32* Y_tab; | |
71 | } TIFFYCbCrToRGB; | |
72 | .fi | |
73 | .RE | |
74 | .PP | |
75 | .I luma | |
76 | is a float array of three values representing proportions of the red, green | |
77 | and blue in luminance, Y (see section 21 of the TIFF 6.0 specification, where | |
78 | the YCbCr images discussed). | |
79 | .I TIFFTAG_YCBCRCOEFFICIENTS | |
80 | holds that values in TIFF file. | |
81 | .I refBlackWhite | |
82 | is a float array of 6 values which specifies a pair of headroom and footroom | |
83 | image data values (codes) for each image component (see section 20 of the | |
84 | TIFF 6.0 specification where the colorinmetry fields discussed). | |
85 | .I TIFFTAG_REFERENCEBLACKWHITE | |
86 | is responsible for storing these values in TIFF file. Following code snippet | |
87 | should helps to understand the the technique: | |
88 | .PP | |
89 | .RS | |
90 | .nf | |
91 | float *luma, *refBlackWhite; | |
92 | uint16 hs, vs; | |
93 | ||
94 | /* Initialize structures */ | |
95 | ycbcr = (TIFFYCbCrToRGB*) | |
96 | _TIFFmalloc(TIFFroundup(sizeof(TIFFYCbCrToRGB), sizeof(long)) | |
97 | + 4*256*sizeof(TIFFRGBValue) | |
98 | + 2*256*sizeof(int) | |
99 | + 3*256*sizeof(int32)); | |
100 | if (ycbcr == NULL) { | |
101 | TIFFError("YCbCr->RGB", | |
102 | "No space for YCbCr->RGB conversion state"); | |
103 | exit(0); | |
104 | } | |
105 | ||
106 | TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); | |
107 | TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite); | |
108 | if (TIFFYCbCrToRGBInit(ycbcr, luma, refBlackWhite) < 0) | |
109 | exit(0); | |
110 | ||
111 | /* Start conversion */ | |
112 | uint32 r, g, b; | |
113 | uint32 Y; | |
114 | int32 Cb, Cr; | |
115 | ||
116 | for each pixel in image | |
117 | TIFFYCbCrtoRGB(img->ycbcr, Y, Cb, Cr, &r, &g, &b); | |
118 | ||
119 | /* Free state structure */ | |
120 | _TIFFfree(ycbcr); | |
121 | .fi | |
122 | .RE | |
123 | .PP | |
124 | ||
125 | .PP | |
126 | .B TIFFCIELabToRGBInit() | |
127 | initializes the | |
128 | .I CIE L*a*b* 1976 | |
129 | to | |
130 | .I RGB | |
131 | conversion state. | |
132 | .B TIFFCIELabToRGB | |
133 | defined as | |
134 | .PP | |
135 | .RS | |
136 | .nf | |
137 | #define CIELABTORGB_TABLE_RANGE 1500 | |
138 | ||
139 | typedef struct { /* CIE Lab 1976->RGB support */ | |
140 | int range; /* Size of conversion table */ | |
141 | float rstep, gstep, bstep; | |
142 | float X0, Y0, Z0; /* Reference white point */ | |
143 | TIFFDisplay display; | |
144 | float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ | |
145 | float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ | |
146 | float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ | |
147 | } TIFFCIELabToRGB; | |
148 | .fi | |
149 | .RE | |
150 | .PP | |
151 | .I display | |
152 | is a display device description, declared as | |
153 | .PP | |
154 | .RS | |
155 | .nf | |
156 | typedef struct { | |
157 | float d_mat[3][3]; /* XYZ -> luminance matrix */ | |
158 | float d_YCR; /* Light o/p for reference white */ | |
159 | float d_YCG; | |
160 | float d_YCB; | |
161 | uint32 d_Vrwr; /* Pixel values for ref. white */ | |
162 | uint32 d_Vrwg; | |
163 | uint32 d_Vrwb; | |
164 | float d_Y0R; /* Residual light for black pixel */ | |
165 | float d_Y0G; | |
166 | float d_Y0B; | |
167 | float d_gammaR; /* Gamma values for the three guns */ | |
168 | float d_gammaG; | |
169 | float d_gammaB; | |
170 | } TIFFDisplay; | |
171 | .fi | |
172 | .RE | |
173 | .PP | |
174 | For example, the one can use sRGB device, which has the following parameters: | |
175 | .PP | |
176 | .RS | |
177 | .nf | |
178 | TIFFDisplay display_sRGB = { | |
179 | { /* XYZ -> luminance matrix */ | |
180 | { 3.2410F, -1.5374F, -0.4986F }, | |
181 | { -0.9692F, 1.8760F, 0.0416F }, | |
182 | { 0.0556F, -0.2040F, 1.0570F } | |
183 | }, | |
184 | 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */ | |
185 | 255, 255, 255, /* Pixel values for ref. white */ | |
186 | 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */ | |
187 | 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */ | |
188 | }; | |
189 | .fi | |
190 | .RE | |
191 | .PP | |
192 | .I refWhite | |
193 | is a color temperature of the reference white. The | |
194 | .I TIFFTAG_WHITEPOINT | |
195 | contains the chromaticity of the white point of the image from where the | |
196 | reference white can be calculated using following formulae: | |
197 | .PP | |
198 | .RS | |
199 | refWhite_Y = 100.0 | |
200 | .br | |
201 | refWhite_X = whitePoint_x / whitePoint_y * refWhite_Y | |
202 | .br | |
203 | refWhite_Z = (1.0 - whitePoint_x - whitePoint_y) / whitePoint_y * refWhite_X | |
204 | .br | |
205 | .RE | |
206 | .PP | |
207 | The conversion itself performed in two steps: at the first one we will convert | |
208 | .I CIE L*a*b* 1976 | |
209 | to | |
210 | .I CIE XYZ | |
211 | using | |
212 | .B TIFFCIELabToXYZ() | |
213 | routine, and at the second step we will convert | |
214 | .I CIE XYZ | |
215 | to | |
216 | .I RGB | |
217 | using | |
218 | .B TIFFXYZToRGB(). | |
219 | Look at the code sample below: | |
220 | .PP | |
221 | .RS | |
222 | .nf | |
223 | float *whitePoint; | |
224 | float refWhite[3]; | |
225 | ||
226 | /* Initialize structures */ | |
227 | img->cielab = (TIFFCIELabToRGB *) | |
228 | _TIFFmalloc(sizeof(TIFFCIELabToRGB)); | |
229 | if (!cielab) { | |
230 | TIFFError("CIE L*a*b*->RGB", | |
231 | "No space for CIE L*a*b*->RGB conversion state."); | |
232 | exit(0); | |
233 | } | |
234 | ||
235 | TIFFGetFieldDefaulted(tif, TIFFTAG_WHITEPOINT, &whitePoint); | |
236 | refWhite[1] = 100.0F; | |
237 | refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; | |
238 | refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1]) | |
239 | / whitePoint[1] * refWhite[1]; | |
240 | if (TIFFCIELabToRGBInit(cielab, &display_sRGB, refWhite) < 0) { | |
241 | TIFFError("CIE L*a*b*->RGB", | |
242 | "Failed to initialize CIE L*a*b*->RGB conversion state."); | |
243 | _TIFFfree(cielab); | |
244 | exit(0); | |
245 | } | |
246 | ||
247 | /* Now we can start to convert */ | |
248 | uint32 r, g, b; | |
249 | uint32 L; | |
250 | int32 a, b; | |
251 | float X, Y, Z; | |
252 | ||
253 | for each pixel in image | |
254 | TIFFCIELabToXYZ(cielab, L, a, b, &X, &Y, &Z); | |
255 | TIFFXYZToRGB(cielab, X, Y, Z, &r, &g, &b); | |
256 | ||
257 | /* Don't forget to free the state structure */ | |
258 | _TIFFfree(cielab); | |
259 | .fi | |
260 | .RE | |
261 | .PP | |
262 | .SH "SEE ALSO" | |
263 | .BR TIFFRGBAImage (3TIFF) | |
264 | .BR libtiff (3TIFF), | |
265 | .PP | |
266 | Libtiff library home page: | |
267 | .BR http://www.remotesensing.org/libtiff/ |