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, 2 months 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

# User Rev Content
1 greg 3.1 #ifndef lint
2 greg 3.8 static const char RCSid[] = "$Id: tmaptiff.c,v 3.7 2008/05/31 18:28:35 greg Exp $";
3 greg 3.1 #endif
4     /*
5     * Perform tone mapping on TIFF input.
6     *
7     * Externals declared in tmaptiff.h
8     */
9    
10 greg 3.2 #include "copyright.h"
11 greg 3.1
12     #include <stdio.h>
13 greg 3.8 #include <stdlib.h>
14 greg 3.7 #include "tmprivat.h"
15 greg 3.1 #include "tiffio.h"
16     #include "tmaptiff.h"
17    
18 greg 3.3 /* 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 greg 3.1
80 greg 3.3 /* load and convert TIFF */
81 greg 3.1 int
82 greg 3.5 tmLoadTIFF(TMstruct *tms, TMbright **lpp, BYTE **cpp,
83     int *xp, int *yp, char *fname, TIFF *tp)
84 greg 3.1 {
85     char *funcName = fname==NULL ? "tmLoadTIFF" : fname;
86 greg 3.5 RGBPRIMP inppri = tms->monpri;
87 greg 3.3 RGBPRIMS myprims;
88     float *fa;
89 greg 3.1 TIFF *tif;
90     int err;
91 greg 3.3 union {uint16 *w; uint32 *l; float *f; MEM_PTR p;} sl;
92 greg 3.1 uint32 width, height;
93 greg 3.3 int tcase;
94 greg 3.1 double stonits;
95     int y;
96     /* check arguments */
97 greg 3.5 if (tms == NULL)
98 greg 3.1 returnErr(TM_E_TMINVAL);
99 schorsch 3.4 if ((lpp == NULL) | (xp == NULL) | (yp == NULL) |
100     ((fname == NULL) & (tp == NULL)))
101 greg 3.1 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 greg 3.3 tcase = getTIFFtype(tif);
109     if (!tcase)
110     goto done;
111 greg 3.1 if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) ||
112     !TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))
113     goto done;
114     *xp = width; *yp = height;
115 greg 3.3 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 greg 3.1 if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits))
131     stonits = 1.;
132 greg 3.3 switch (tcase) { /* set up conversion */
133     case TC_LOGLUV32:
134     case TC_LOGLUV24:
135 greg 3.1 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_RAW);
136     sl.l = (uint32 *)malloc(width*sizeof(uint32));
137 greg 3.6 tmSetSpace(tms, TM_XYZPRIM, stonits, NULL);
138 greg 3.3 break;
139     case TC_LOGL16:
140 greg 3.1 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_16BIT);
141     sl.w = (uint16 *)malloc(width*sizeof(uint16));
142 greg 3.6 tmSetSpace(tms, tms->monpri, stonits, NULL);
143 greg 3.3 break;
144     case TC_RGBFLOAT:
145     sl.f = (float *)malloc(width*3*sizeof(float));
146 greg 3.6 tmSetSpace(tms, inppri, stonits, NULL);
147 greg 3.3 break;
148     case TC_GRYFLOAT:
149     sl.f = (float *)malloc(width*sizeof(float));
150 greg 3.6 tmSetSpace(tms, tms->monpri, stonits, NULL);
151 greg 3.3 break;
152     case TC_RGBSHORT:
153     sl.w = (uint16 *)malloc(width*3*sizeof(uint16));
154 greg 3.6 tmSetSpace(tms, inppri, stonits, NULL);
155 greg 3.3 break;
156     case TC_GRYSHORT:
157     sl.w = (uint16 *)malloc(width*sizeof(uint16));
158 greg 3.6 tmSetSpace(tms, tms->monpri, stonits, NULL);
159 greg 3.3 break;
160     default:
161     err = TM_E_CODERR1;
162 greg 3.1 goto done;
163 greg 3.3 }
164 greg 3.1 *lpp = (TMbright *)malloc(width*height*sizeof(TMbright));
165 schorsch 3.4 if ((sl.p == NULL) | (*lpp == NULL)) {
166 greg 3.1 err = TM_E_NOMEM;
167     goto done;
168     }
169 greg 3.3 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 greg 3.1 /* 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 greg 3.3 switch (tcase) {
190     case TC_LOGLUV32:
191 greg 3.5 err = tmCvLuv32(tms, *lpp + y*width,
192 greg 3.3 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
193     sl.l, width);
194     break;
195     case TC_LOGLUV24:
196 greg 3.5 err = tmCvLuv24(tms, *lpp + y*width,
197 greg 3.1 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
198     sl.l, width);
199 greg 3.3 break;
200     case TC_LOGL16:
201 greg 3.5 err = tmCvL16(tms, *lpp + y*width, sl.w, width);
202 greg 3.3 break;
203     case TC_RGBFLOAT:
204 greg 3.5 err = tmCvColors(tms, *lpp + y*width,
205 greg 3.3 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
206     (COLOR *)sl.f, width);
207     break;
208     case TC_GRYFLOAT:
209 greg 3.5 err = tmCvGrays(tms, *lpp + y*width, sl.f, width);
210 greg 3.3 break;
211     case TC_RGBSHORT:
212 greg 3.5 err = tmCvRGB48(tms, *lpp + y*width,
213 greg 3.1 cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
214 greg 3.3 (uint16 (*)[3])sl.w, width, DEFGAM);
215     break;
216     case TC_GRYSHORT:
217 greg 3.5 err = tmCvGray16(tms, *lpp + y*width,
218     sl.w, width, DEFGAM);
219 greg 3.3 break;
220     default:
221     err = TM_E_CODERR1;
222     break;
223     }
224 greg 3.1 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 greg 3.3 tmMapTIFF(BYTE **psp, int *xp, int *yp, int flags, RGBPRIMP monpri,
256     double gamval, double Lddyn, double Ldmax, char *fname, TIFF *tp)
257 greg 3.1 {
258     char *funcName = fname==NULL ? "tmMapTIFF" : fname;
259 greg 3.5 TMstruct *tms;
260 greg 3.1 TMbright *lp;
261     BYTE *cp;
262     int err;
263     /* check arguments */
264 schorsch 3.4 if ((psp == NULL) | (xp == NULL) | (yp == NULL) | (monpri == NULL) |
265     ((fname == NULL) & (tp == NULL)))
266 greg 3.1 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 greg 3.5 if ((tms = tmInit(flags, monpri, gamval)) == NULL)
273 greg 3.1 returnErr(TM_E_NOMEM);
274     /* load and convert TIFF */
275     cp = TM_NOCHROM;
276 greg 3.5 err = tmLoadTIFF(tms, &lp, flags&TM_F_BW ? TM_NOCHROMP : &cp,
277 greg 3.1 xp, yp, fname, tp);
278     if (err != TM_E_OK) {
279 greg 3.5 tmDone(tms);
280 greg 3.1 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 greg 3.5 tmDone(tms);
287 greg 3.1 returnErr(TM_E_NOMEM);
288     }
289     } else
290     *psp = cp;
291     /* compute color mapping */
292 greg 3.5 err = tmAddHisto(tms, lp, *xp * *yp, 1);
293 greg 3.1 if (err != TM_E_OK)
294     goto done;
295 greg 3.5 err = tmComputeMapping(tms, gamval, Lddyn, Ldmax);
296 greg 3.1 if (err != TM_E_OK)
297     goto done;
298     /* map pixels */
299 greg 3.5 err = tmMapPixels(tms, *psp, lp, cp, *xp * *yp);
300 greg 3.1
301     done: /* clean up */
302     free((MEM_PTR)lp);
303 greg 3.5 tmDone(tms);
304 greg 3.1 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     }