ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/tmaptiff.c
Revision: 3.8
Committed: Mon Feb 9 20:48:08 2009 UTC (15 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R0
Changes since 3.7: +2 -1 lines
Log Message:
Eliminated redefinition of malloc(3)

File Contents

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