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