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, 3 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

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