ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/tmaptiff.c
Revision: 3.4
Committed: Sun Jul 27 22:12:01 2003 UTC (20 years, 8 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6, rad3R6P1
Changes since 3.3: +6 -6 lines
Log Message:
Added grouping parens to reduce ambiguity warnings.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: tmaptiff.c,v 3.3 2003/07/14 04:56:54 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(TMbright **lpp, BYTE **cpp, int *xp, int *yp, char *fname, TIFF *tp)
82 {
83 char *funcName = fname==NULL ? "tmLoadTIFF" : fname;
84 RGBPRIMP inppri = tmTop->monpri;
85 RGBPRIMS myprims;
86 float *fa;
87 TIFF *tif;
88 int err;
89 union {uint16 *w; uint32 *l; float *f; MEM_PTR p;} sl;
90 uint32 width, height;
91 int tcase;
92 double stonits;
93 int y;
94 /* check arguments */
95 if (tmTop == NULL)
96 returnErr(TM_E_TMINVAL);
97 if ((lpp == NULL) | (xp == NULL) | (yp == NULL) |
98 ((fname == NULL) & (tp == NULL)))
99 returnErr(TM_E_ILLEGAL);
100 /* check/get TIFF tags */
101 sl.p = NULL; *lpp = NULL;
102 if (cpp != TM_NOCHROMP) *cpp = TM_NOCHROM;
103 err = TM_E_BADFILE;
104 if ((tif = tp) == NULL && (tif = TIFFOpen(fname, "r")) == NULL)
105 returnErr(TM_E_BADFILE);
106 tcase = getTIFFtype(tif);
107 if (!tcase)
108 goto done;
109 if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) ||
110 !TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))
111 goto done;
112 *xp = width; *yp = height;
113 if (TIFFGetField(tif, TIFFTAG_PRIMARYCHROMATICITIES, &fa)) {
114 myprims[RED][CIEX] = fa[0];
115 myprims[RED][CIEY] = fa[1];
116 myprims[GRN][CIEX] = fa[2];
117 myprims[GRN][CIEY] = fa[3];
118 myprims[BLU][CIEX] = fa[4];
119 myprims[BLU][CIEY] = fa[5];
120 myprims[WHT][CIEX] = 1./3.;
121 myprims[WHT][CIEY] = 1./3.;
122 if (TIFFGetField(tif, TIFFTAG_WHITEPOINT, &fa)) {
123 myprims[WHT][CIEX] = fa[0];
124 myprims[WHT][CIEY] = fa[1];
125 }
126 inppri = myprims;
127 }
128 if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits))
129 stonits = 1.;
130 switch (tcase) { /* set up conversion */
131 case TC_LOGLUV32:
132 case TC_LOGLUV24:
133 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_RAW);
134 sl.l = (uint32 *)malloc(width*sizeof(uint32));
135 tmSetSpace(TM_XYZPRIM, stonits);
136 break;
137 case TC_LOGL16:
138 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_16BIT);
139 sl.w = (uint16 *)malloc(width*sizeof(uint16));
140 tmSetSpace(tmTop->monpri, stonits);
141 break;
142 case TC_RGBFLOAT:
143 sl.f = (float *)malloc(width*3*sizeof(float));
144 tmSetSpace(inppri, stonits);
145 break;
146 case TC_GRYFLOAT:
147 sl.f = (float *)malloc(width*sizeof(float));
148 tmSetSpace(tmTop->monpri, stonits);
149 break;
150 case TC_RGBSHORT:
151 sl.w = (uint16 *)malloc(width*3*sizeof(uint16));
152 tmSetSpace(inppri, stonits);
153 break;
154 case TC_GRYSHORT:
155 sl.w = (uint16 *)malloc(width*sizeof(uint16));
156 tmSetSpace(tmTop->monpri, stonits);
157 break;
158 default:
159 err = TM_E_CODERR1;
160 goto done;
161 }
162 *lpp = (TMbright *)malloc(width*height*sizeof(TMbright));
163 if ((sl.p == NULL) | (*lpp == NULL)) {
164 err = TM_E_NOMEM;
165 goto done;
166 }
167 switch (tcase) { /* allocate color if needed */
168 case TC_LOGLUV32:
169 case TC_LOGLUV24:
170 case TC_RGBFLOAT:
171 case TC_RGBSHORT:
172 if (cpp == TM_NOCHROMP)
173 break;
174 *cpp = (BYTE *)malloc(width*height*3*sizeof(BYTE));
175 if (*cpp == NULL) {
176 err = TM_E_NOMEM;
177 goto done;
178 }
179 break;
180 }
181 /* read and convert each scanline */
182 for (y = 0; y < height; y++) {
183 if (TIFFReadScanline(tif, sl.p, y, 0) < 0) {
184 err = TM_E_BADFILE;
185 break;
186 }
187 switch (tcase) {
188 case TC_LOGLUV32:
189 err = tmCvLuv32(*lpp + y*width,
190 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
191 sl.l, width);
192 break;
193 case TC_LOGLUV24:
194 err = tmCvLuv24(*lpp + y*width,
195 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
196 sl.l, width);
197 break;
198 case TC_LOGL16:
199 err = tmCvL16(*lpp + y*width, sl.w, width);
200 break;
201 case TC_RGBFLOAT:
202 err = tmCvColors(*lpp + y*width,
203 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
204 (COLOR *)sl.f, width);
205 break;
206 case TC_GRYFLOAT:
207 err = tmCvGrays(*lpp + y*width, sl.f, width);
208 break;
209 case TC_RGBSHORT:
210 err = tmCvRGB48(*lpp + y*width,
211 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
212 (uint16 (*)[3])sl.w, width, DEFGAM);
213 break;
214 case TC_GRYSHORT:
215 err = tmCvGray16(*lpp + y*width, sl.w, width, DEFGAM);
216 break;
217 default:
218 err = TM_E_CODERR1;
219 break;
220 }
221 if (err != TM_E_OK)
222 break;
223 }
224 done: /* clean up */
225 if (tp == NULL)
226 TIFFClose(tif);
227 if (sl.p != NULL)
228 free(sl.p);
229 if (err != TM_E_OK) { /* free buffers on error */
230 if (*lpp != NULL)
231 free((MEM_PTR)*lpp);
232 *lpp = NULL;
233 if (cpp != TM_NOCHROMP) {
234 if (*cpp != TM_NOCHROM)
235 free((MEM_PTR)*cpp);
236 *cpp = NULL;
237 }
238 *xp = *yp = 0;
239 returnErr(err);
240 }
241 returnOK;
242 }
243
244
245 /*
246 * Load and tone-map a SGILOG TIFF.
247 * Beware of greyscale input -- you must check the PHOTOMETRIC tag to
248 * determine that the returned array contains only grey values, not RGB.
249 * As in tmMapPicture(), grey values are also returned if flags&TM_F_BW.
250 */
251 int
252 tmMapTIFF(BYTE **psp, int *xp, int *yp, int flags, RGBPRIMP monpri,
253 double gamval, double Lddyn, double Ldmax, char *fname, TIFF *tp)
254 {
255 char *funcName = fname==NULL ? "tmMapTIFF" : fname;
256 TMbright *lp;
257 BYTE *cp;
258 int err;
259 /* check arguments */
260 if ((psp == NULL) | (xp == NULL) | (yp == NULL) | (monpri == NULL) |
261 ((fname == NULL) & (tp == NULL)))
262 returnErr(TM_E_ILLEGAL);
263 if (gamval < MINGAM) gamval = DEFGAM;
264 if (Lddyn < MINLDDYN) Lddyn = DEFLDDYN;
265 if (Ldmax < MINLDMAX) Ldmax = DEFLDMAX;
266 if (flags & TM_F_BW) monpri = stdprims;
267 /* initialize tone mapping */
268 if (tmInit(flags, monpri, gamval) == NULL)
269 returnErr(TM_E_NOMEM);
270 /* load and convert TIFF */
271 cp = TM_NOCHROM;
272 err = tmLoadTIFF(&lp, flags&TM_F_BW ? TM_NOCHROMP : &cp,
273 xp, yp, fname, tp);
274 if (err != TM_E_OK) {
275 tmDone(NULL);
276 return(err);
277 }
278 if (cp == TM_NOCHROM) {
279 *psp = (BYTE *)malloc(*xp * *yp * sizeof(BYTE));
280 if (*psp == NULL) {
281 free((MEM_PTR)lp);
282 tmDone(NULL);
283 returnErr(TM_E_NOMEM);
284 }
285 } else
286 *psp = cp;
287 /* compute color mapping */
288 err = tmAddHisto(lp, *xp * *yp, 1);
289 if (err != TM_E_OK)
290 goto done;
291 err = tmComputeMapping(gamval, Lddyn, Ldmax);
292 if (err != TM_E_OK)
293 goto done;
294 /* map pixels */
295 err = tmMapPixels(*psp, lp, cp, *xp * *yp);
296
297 done: /* clean up */
298 free((MEM_PTR)lp);
299 tmDone(NULL);
300 if (err != TM_E_OK) { /* free memory on error */
301 free((MEM_PTR)*psp);
302 *psp = NULL;
303 *xp = *yp = 0;
304 returnErr(err);
305 }
306 returnOK;
307 }