ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/tmaptiff.c
Revision: 3.6
Committed: Fri Jan 7 22:05:30 2005 UTC (19 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad3R8, rad3R9
Changes since 3.5: +7 -7 lines
Log Message:
Added client data pointer to tmSetSpace() call

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: tmaptiff.c,v 3.5 2005/01/07 20:33:02 greg Exp $";
3 #endif
4 /*
5 * Perform tone mapping on TIFF input.
6 *
7 * Externals declared in tmaptiff.h
8 */
9
10 #include "copyright.h"
11
12 #include <stdio.h>
13 #include "tiffio.h"
14 #include "tmprivat.h"
15 #include "tmaptiff.h"
16
17 /* input cases we handle */
18 #define TC_LOGLUV32 1
19 #define TC_LOGLUV24 2
20 #define TC_LOGL16 3
21 #define TC_GRYFLOAT 4
22 #define TC_RGBFLOAT 5
23 #define TC_GRYSHORT 6
24 #define TC_RGBSHORT 7
25
26 /* figure out what kind of TIFF we have and if we can tone-map it */
27 static int
28 getTIFFtype(TIFF *tif)
29 {
30 uint16 comp, phot, pconf;
31 uint16 samp_fmt, bits_samp;
32
33 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &pconf);
34 if (pconf != PLANARCONFIG_CONTIG)
35 return(0);
36 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &phot);
37 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &comp);
38 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &samp_fmt);
39 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_samp);
40 switch (phot) {
41 case PHOTOMETRIC_LOGLUV:
42 if (comp == COMPRESSION_SGILOG)
43 return(TC_LOGLUV32);
44 if (comp == COMPRESSION_SGILOG24)
45 return(TC_LOGLUV24);
46 return(0);
47 case PHOTOMETRIC_LOGL:
48 if (comp == COMPRESSION_SGILOG)
49 return(TC_LOGL16);
50 return(0);
51 case PHOTOMETRIC_MINISBLACK:
52 if (samp_fmt == SAMPLEFORMAT_UINT) {
53 if (bits_samp == 16)
54 return(TC_GRYSHORT);
55 return(0);
56 }
57 if (samp_fmt == SAMPLEFORMAT_IEEEFP) {
58 if (bits_samp == 8*sizeof(float))
59 return(TC_GRYFLOAT);
60 return(0);
61 }
62 return(0);
63 case PHOTOMETRIC_RGB:
64 if (samp_fmt == SAMPLEFORMAT_UINT) {
65 if (bits_samp == 16)
66 return(TC_RGBSHORT);
67 return(0);
68 }
69 if (samp_fmt == SAMPLEFORMAT_IEEEFP) {
70 if (bits_samp == 8*sizeof(float))
71 return(TC_RGBFLOAT);
72 return(0);
73 }
74 return(0);
75 }
76 return(0);
77 }
78
79 /* load and convert TIFF */
80 int
81 tmLoadTIFF(TMstruct *tms, TMbright **lpp, BYTE **cpp,
82 int *xp, int *yp, char *fname, TIFF *tp)
83 {
84 char *funcName = fname==NULL ? "tmLoadTIFF" : fname;
85 RGBPRIMP inppri = tms->monpri;
86 RGBPRIMS myprims;
87 float *fa;
88 TIFF *tif;
89 int err;
90 union {uint16 *w; uint32 *l; float *f; MEM_PTR p;} sl;
91 uint32 width, height;
92 int tcase;
93 double stonits;
94 int y;
95 /* check arguments */
96 if (tms == NULL)
97 returnErr(TM_E_TMINVAL);
98 if ((lpp == NULL) | (xp == NULL) | (yp == NULL) |
99 ((fname == NULL) & (tp == NULL)))
100 returnErr(TM_E_ILLEGAL);
101 /* check/get TIFF tags */
102 sl.p = NULL; *lpp = NULL;
103 if (cpp != TM_NOCHROMP) *cpp = TM_NOCHROM;
104 err = TM_E_BADFILE;
105 if ((tif = tp) == NULL && (tif = TIFFOpen(fname, "r")) == NULL)
106 returnErr(TM_E_BADFILE);
107 tcase = getTIFFtype(tif);
108 if (!tcase)
109 goto done;
110 if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) ||
111 !TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))
112 goto done;
113 *xp = width; *yp = height;
114 if (TIFFGetField(tif, TIFFTAG_PRIMARYCHROMATICITIES, &fa)) {
115 myprims[RED][CIEX] = fa[0];
116 myprims[RED][CIEY] = fa[1];
117 myprims[GRN][CIEX] = fa[2];
118 myprims[GRN][CIEY] = fa[3];
119 myprims[BLU][CIEX] = fa[4];
120 myprims[BLU][CIEY] = fa[5];
121 myprims[WHT][CIEX] = 1./3.;
122 myprims[WHT][CIEY] = 1./3.;
123 if (TIFFGetField(tif, TIFFTAG_WHITEPOINT, &fa)) {
124 myprims[WHT][CIEX] = fa[0];
125 myprims[WHT][CIEY] = fa[1];
126 }
127 inppri = myprims;
128 }
129 if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits))
130 stonits = 1.;
131 switch (tcase) { /* set up conversion */
132 case TC_LOGLUV32:
133 case TC_LOGLUV24:
134 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_RAW);
135 sl.l = (uint32 *)malloc(width*sizeof(uint32));
136 tmSetSpace(tms, TM_XYZPRIM, stonits, NULL);
137 break;
138 case TC_LOGL16:
139 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_16BIT);
140 sl.w = (uint16 *)malloc(width*sizeof(uint16));
141 tmSetSpace(tms, tms->monpri, stonits, NULL);
142 break;
143 case TC_RGBFLOAT:
144 sl.f = (float *)malloc(width*3*sizeof(float));
145 tmSetSpace(tms, inppri, stonits, NULL);
146 break;
147 case TC_GRYFLOAT:
148 sl.f = (float *)malloc(width*sizeof(float));
149 tmSetSpace(tms, tms->monpri, stonits, NULL);
150 break;
151 case TC_RGBSHORT:
152 sl.w = (uint16 *)malloc(width*3*sizeof(uint16));
153 tmSetSpace(tms, inppri, stonits, NULL);
154 break;
155 case TC_GRYSHORT:
156 sl.w = (uint16 *)malloc(width*sizeof(uint16));
157 tmSetSpace(tms, tms->monpri, stonits, NULL);
158 break;
159 default:
160 err = TM_E_CODERR1;
161 goto done;
162 }
163 *lpp = (TMbright *)malloc(width*height*sizeof(TMbright));
164 if ((sl.p == NULL) | (*lpp == NULL)) {
165 err = TM_E_NOMEM;
166 goto done;
167 }
168 switch (tcase) { /* allocate color if needed */
169 case TC_LOGLUV32:
170 case TC_LOGLUV24:
171 case TC_RGBFLOAT:
172 case TC_RGBSHORT:
173 if (cpp == TM_NOCHROMP)
174 break;
175 *cpp = (BYTE *)malloc(width*height*3*sizeof(BYTE));
176 if (*cpp == NULL) {
177 err = TM_E_NOMEM;
178 goto done;
179 }
180 break;
181 }
182 /* read and convert each scanline */
183 for (y = 0; y < height; y++) {
184 if (TIFFReadScanline(tif, sl.p, y, 0) < 0) {
185 err = TM_E_BADFILE;
186 break;
187 }
188 switch (tcase) {
189 case TC_LOGLUV32:
190 err = tmCvLuv32(tms, *lpp + y*width,
191 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
192 sl.l, width);
193 break;
194 case TC_LOGLUV24:
195 err = tmCvLuv24(tms, *lpp + y*width,
196 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
197 sl.l, width);
198 break;
199 case TC_LOGL16:
200 err = tmCvL16(tms, *lpp + y*width, sl.w, width);
201 break;
202 case TC_RGBFLOAT:
203 err = tmCvColors(tms, *lpp + y*width,
204 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
205 (COLOR *)sl.f, width);
206 break;
207 case TC_GRYFLOAT:
208 err = tmCvGrays(tms, *lpp + y*width, sl.f, width);
209 break;
210 case TC_RGBSHORT:
211 err = tmCvRGB48(tms, *lpp + y*width,
212 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
213 (uint16 (*)[3])sl.w, width, DEFGAM);
214 break;
215 case TC_GRYSHORT:
216 err = tmCvGray16(tms, *lpp + y*width,
217 sl.w, width, DEFGAM);
218 break;
219 default:
220 err = TM_E_CODERR1;
221 break;
222 }
223 if (err != TM_E_OK)
224 break;
225 }
226 done: /* clean up */
227 if (tp == NULL)
228 TIFFClose(tif);
229 if (sl.p != NULL)
230 free(sl.p);
231 if (err != TM_E_OK) { /* free buffers on error */
232 if (*lpp != NULL)
233 free((MEM_PTR)*lpp);
234 *lpp = NULL;
235 if (cpp != TM_NOCHROMP) {
236 if (*cpp != TM_NOCHROM)
237 free((MEM_PTR)*cpp);
238 *cpp = NULL;
239 }
240 *xp = *yp = 0;
241 returnErr(err);
242 }
243 returnOK;
244 }
245
246
247 /*
248 * Load and tone-map a SGILOG TIFF.
249 * Beware of greyscale input -- you must check the PHOTOMETRIC tag to
250 * determine that the returned array contains only grey values, not RGB.
251 * As in tmMapPicture(), grey values are also returned if flags&TM_F_BW.
252 */
253 int
254 tmMapTIFF(BYTE **psp, int *xp, int *yp, int flags, RGBPRIMP monpri,
255 double gamval, double Lddyn, double Ldmax, char *fname, TIFF *tp)
256 {
257 char *funcName = fname==NULL ? "tmMapTIFF" : fname;
258 TMstruct *tms;
259 TMbright *lp;
260 BYTE *cp;
261 int err;
262 /* check arguments */
263 if ((psp == NULL) | (xp == NULL) | (yp == NULL) | (monpri == NULL) |
264 ((fname == NULL) & (tp == NULL)))
265 returnErr(TM_E_ILLEGAL);
266 if (gamval < MINGAM) gamval = DEFGAM;
267 if (Lddyn < MINLDDYN) Lddyn = DEFLDDYN;
268 if (Ldmax < MINLDMAX) Ldmax = DEFLDMAX;
269 if (flags & TM_F_BW) monpri = stdprims;
270 /* initialize tone mapping */
271 if ((tms = tmInit(flags, monpri, gamval)) == NULL)
272 returnErr(TM_E_NOMEM);
273 /* load and convert TIFF */
274 cp = TM_NOCHROM;
275 err = tmLoadTIFF(tms, &lp, flags&TM_F_BW ? TM_NOCHROMP : &cp,
276 xp, yp, fname, tp);
277 if (err != TM_E_OK) {
278 tmDone(tms);
279 return(err);
280 }
281 if (cp == TM_NOCHROM) {
282 *psp = (BYTE *)malloc(*xp * *yp * sizeof(BYTE));
283 if (*psp == NULL) {
284 free((MEM_PTR)lp);
285 tmDone(tms);
286 returnErr(TM_E_NOMEM);
287 }
288 } else
289 *psp = cp;
290 /* compute color mapping */
291 err = tmAddHisto(tms, lp, *xp * *yp, 1);
292 if (err != TM_E_OK)
293 goto done;
294 err = tmComputeMapping(tms, gamval, Lddyn, Ldmax);
295 if (err != TM_E_OK)
296 goto done;
297 /* map pixels */
298 err = tmMapPixels(tms, *psp, lp, cp, *xp * *yp);
299
300 done: /* clean up */
301 free((MEM_PTR)lp);
302 tmDone(tms);
303 if (err != TM_E_OK) { /* free memory on error */
304 free((MEM_PTR)*psp);
305 *psp = NULL;
306 *xp = *yp = 0;
307 returnErr(err);
308 }
309 returnOK;
310 }