ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_tiff.c
Revision: 2.20
Committed: Sat Feb 22 02:07:28 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.19: +8 -11 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.20 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5 gregl 2.9 * Program to convert between RADIANCE and TIFF files.
6 greg 2.20 * Added LogLuv encodings 7/97 (GWL).
7     * Added white-balance adjustment 10/01 (GW).
8 greg 1.1 */
9    
10     #include <stdio.h>
11 greg 2.3 #include <math.h>
12 greg 2.20 #include <time.h>
13 greg 1.1 #include "tiffio.h"
14     #include "color.h"
15 greg 1.6 #include "resolu.h"
16    
17 greg 2.8 #define GAMCOR 2.2 /* default gamma */
18    
19 gregl 2.9 /* conversion flags */
20     #define C_CXFM 0x1 /* needs color transformation */
21     #define C_GAMUT 0x2 /* needs gamut mapping */
22     #define C_GAMMA 0x4 /* needs gamma correction */
23     #define C_GRY 0x8 /* TIFF is greyscale */
24     #define C_XYZE 0x10 /* Radiance is XYZE */
25     #define C_RFLT 0x20 /* Radiance data is float */
26     #define C_TFLT 0x40 /* TIFF data is float */
27 gwlarson 2.19 #define C_TWRD 0x80 /* TIFF data is 16-bit */
28     #define C_PRIM 0x100 /* has assigned primaries */
29 greg 1.1
30 gregl 2.9 struct {
31     uint16 flags; /* conversion flags (defined above) */
32     uint16 comp; /* TIFF compression type */
33 gregl 2.10 uint16 phot; /* TIFF photometric type */
34 gregl 2.9 uint16 pconf; /* TIFF planar configuration */
35     float gamcor; /* gamma correction value */
36     short bradj; /* Radiance exposure adjustment (stops) */
37     uint16 orient; /* visual orientation (TIFF spec.) */
38 gregl 2.11 double stonits; /* input conversion to nits */
39 gregl 2.9 float pixrat; /* pixel aspect ratio */
40     FILE *rfp; /* Radiance stream pointer */
41     TIFF *tif; /* TIFF pointer */
42     uint32 xmax, ymax; /* image dimensions */
43     COLORMAT cmat; /* color transformation matrix */
44     RGBPRIMS prims; /* RGB primaries */
45     union {
46     COLR *colrs; /* 4-byte ???E pointer */
47     COLOR *colors; /* float array pointer */
48     char *p; /* generic pointer */
49     } r; /* Radiance scanline */
50     union {
51     uint8 *bp; /* byte pointer */
52 gwlarson 2.18 uint16 *wp; /* word pointer */
53 gregl 2.9 float *fp; /* float pointer */
54     char *p; /* generic pointer */
55     } t; /* TIFF scanline */
56     int (*tf)(); /* translation procedure */
57     } cvts = { /* conversion structure */
58 gregl 2.10 0, COMPRESSION_NONE, PHOTOMETRIC_RGB,
59     PLANARCONFIG_CONTIG, GAMCOR, 0, 1, 1., 1.,
60 gregl 2.9 };
61 greg 1.4
62 gregl 2.9 #define CHK(f) (cvts.flags & (f))
63     #define SET(f) (cvts.flags |= (f))
64     #define CLR(f) (cvts.flags &= ~(f))
65     #define TGL(f) (cvts.flags ^= (f))
66 greg 1.5
67 gregl 2.9 int Luv2Color(), L2Color(), RGB2Colr(), Gry2Colr();
68     int Color2Luv(), Color2L(), Colr2RGB(), Colr2Gry();
69 gwlarson 2.18 int RRGGBB2Color(), GGry2Color();
70 greg 1.1
71 gregl 2.9 short ortab[8] = { /* orientation conversion table */
72     YMAJOR|YDECR,
73     YMAJOR|YDECR|XDECR,
74     YMAJOR|XDECR,
75     YMAJOR,
76     YDECR,
77     XDECR|YDECR,
78     XDECR,
79     0
80     };
81 greg 1.1
82 gregl 2.9 #define pixorder() ortab[cvts.orient-1]
83    
84 greg 1.1 char *progname;
85    
86    
87     main(argc, argv)
88     int argc;
89     char *argv[];
90     {
91     int reverse = 0;
92     int i;
93    
94     progname = argv[0];
95    
96     for (i = 1; i < argc; i++)
97     if (argv[i][0] == '-')
98     switch (argv[i][1]) {
99 gregl 2.9 case 'g': /* gamma correction */
100     cvts.gamcor = atof(argv[++i]);
101 greg 1.1 break;
102 gregl 2.9 case 'x': /* XYZE Radiance output */
103     TGL(C_XYZE);
104 greg 1.4 break;
105 gregl 2.9 case 'z': /* LZW compressed output */
106     cvts.comp = COMPRESSION_LZW;
107 greg 1.5 break;
108 gregl 2.9 case 'L': /* LogLuv 32-bit output */
109 gregl 2.10 cvts.comp = COMPRESSION_SGILOG;
110     cvts.phot = PHOTOMETRIC_LOGLUV;
111 gregl 2.9 break;
112     case 'l': /* LogLuv 24-bit output */
113 gregl 2.10 cvts.comp = COMPRESSION_SGILOG24;
114     cvts.phot = PHOTOMETRIC_LOGLUV;
115 gregl 2.9 break;
116     case 'b': /* greyscale output? */
117     TGL(C_GRY);
118     break;
119     case 'e': /* exposure adjustment */
120 greg 1.1 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
121     goto userr;
122 gregl 2.9 cvts.bradj = atoi(argv[++i]);
123 greg 1.1 break;
124 gregl 2.9 case 'r': /* reverse conversion? */
125 greg 1.1 reverse = !reverse;
126     break;
127     case '\0':
128     goto doneopts;
129     default:
130     goto userr;
131     }
132     else
133     break;
134     doneopts:
135 gregl 2.9 if (reverse) {
136 greg 1.1
137     if (i != argc-2 && i != argc-1)
138     goto userr;
139 gregl 2.9
140     tiff2ra(i, argv);
141    
142     } else {
143    
144 greg 1.1 if (i != argc-2)
145     goto userr;
146    
147 gregl 2.10 if (CHK(C_GRY)) /* consistency corrections */
148     if (cvts.phot == PHOTOMETRIC_RGB)
149     cvts.phot = PHOTOMETRIC_MINISBLACK;
150     else {
151     cvts.phot = PHOTOMETRIC_LOGL;
152     cvts.comp = COMPRESSION_SGILOG;
153     }
154 gregl 2.9
155     ra2tiff(i, argv);
156     }
157    
158 greg 1.1 exit(0);
159     userr:
160 greg 1.4 fprintf(stderr,
161 gregl 2.9 "Usage: %s [-z|-L|-l][-b][-e +/-stops][-g gamma] {in.pic|-} out.tif\n",
162 greg 1.1 progname);
163 gregl 2.9 fprintf(stderr,
164     " Or: %s -r [-x][-e +/-stops][-g gamma] in.tif [out.pic|-]\n",
165     progname);
166 greg 1.1 exit(1);
167     }
168    
169    
170     quiterr(err) /* print message and exit */
171     char *err;
172     {
173     if (err != NULL) {
174     fprintf(stderr, "%s: %s\n", progname, err);
175     exit(1);
176     }
177     exit(0);
178     }
179    
180    
181 gregl 2.9 allocbufs() /* allocate scanline buffers */
182 greg 1.1 {
183 gregl 2.9 int rsiz, tsiz;
184    
185     rsiz = CHK(C_RFLT) ? sizeof(COLOR) : sizeof(COLR);
186 gwlarson 2.19 tsiz = (CHK(C_TFLT) ? sizeof(float) :
187     CHK(C_TWRD) ? sizeof(uint16) : sizeof(uint8)) *
188 gregl 2.9 (CHK(C_GRY) ? 1 : 3);
189     cvts.r.p = (char *)malloc(rsiz*cvts.xmax);
190     cvts.t.p = (char *)malloc(tsiz*cvts.xmax);
191     if (cvts.r.p == NULL | cvts.t.p == NULL)
192     quiterr("no memory to allocate scanline buffers");
193     }
194    
195    
196     initfromtif() /* initialize conversion from TIFF input */
197     {
198     uint16 hi;
199     float *fa, f1, f2;
200    
201     CLR(C_GRY|C_GAMMA|C_PRIM|C_RFLT|C_TFLT|C_CXFM);
202    
203     TIFFGetFieldDefaulted(cvts.tif, TIFFTAG_PLANARCONFIG, &cvts.pconf);
204    
205     if (TIFFGetField(cvts.tif, TIFFTAG_PRIMARYCHROMATICITIES, &fa)) {
206     cvts.prims[RED][CIEX] = fa[0];
207     cvts.prims[RED][CIEY] = fa[1];
208     cvts.prims[GRN][CIEX] = fa[2];
209     cvts.prims[GRN][CIEY] = fa[3];
210     cvts.prims[BLU][CIEX] = fa[4];
211     cvts.prims[BLU][CIEY] = fa[5];
212     cvts.prims[WHT][CIEX] = 1./3.;
213     cvts.prims[WHT][CIEY] = 1./3.;
214     if (TIFFGetField(cvts.tif, TIFFTAG_WHITEPOINT, &fa)) {
215     cvts.prims[WHT][CIEX] = fa[0];
216     cvts.prims[WHT][CIEY] = fa[1];
217     }
218     SET(C_PRIM);
219     }
220    
221     if (!TIFFGetField(cvts.tif, TIFFTAG_COMPRESSION, &cvts.comp))
222     cvts.comp = COMPRESSION_NONE;
223    
224     if (TIFFGetField(cvts.tif, TIFFTAG_XRESOLUTION, &f1) &&
225     TIFFGetField(cvts.tif, TIFFTAG_YRESOLUTION, &f2))
226     cvts.pixrat = f1/f2;
227    
228 gregl 2.10 TIFFGetFieldDefaulted(cvts.tif, TIFFTAG_ORIENTATION, &cvts.orient);
229 gregl 2.9
230 gregl 2.10 if (!TIFFGetFieldDefaulted(cvts.tif, TIFFTAG_PHOTOMETRIC, &cvts.phot))
231     quiterr("TIFF has unspecified photometric type");
232    
233     switch (cvts.phot) {
234     case PHOTOMETRIC_LOGLUV:
235 gregl 2.9 SET(C_RFLT|C_TFLT);
236     if (!CHK(C_XYZE)) {
237     cpcolormat(cvts.cmat, xyz2rgbmat);
238     SET(C_CXFM|C_GAMUT);
239 gregl 2.10 } else if (cvts.comp == COMPRESSION_SGILOG)
240 gregl 2.9 SET(C_GAMUT);
241     if (cvts.pconf != PLANARCONFIG_CONTIG)
242     quiterr("cannot handle separate Luv planes");
243 gregl 2.10 TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
244 gregl 2.12 SGILOGDATAFMT_FLOAT);
245 gregl 2.9 cvts.tf = Luv2Color;
246     break;
247 gregl 2.10 case PHOTOMETRIC_LOGL:
248     SET(C_GRY|C_RFLT|C_TFLT|C_GAMUT);
249     cvts.pconf = PLANARCONFIG_CONTIG;
250     TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
251 gregl 2.12 SGILOGDATAFMT_FLOAT);
252 gregl 2.10 cvts.tf = L2Color;
253     break;
254 gregl 2.11 case PHOTOMETRIC_YCBCR:
255     if (cvts.comp == COMPRESSION_JPEG &&
256     cvts.pconf == PLANARCONFIG_CONTIG) {
257     TIFFSetField(cvts.tif, TIFFTAG_JPEGCOLORMODE,
258     JPEGCOLORMODE_RGB);
259     cvts.phot = PHOTOMETRIC_RGB;
260     } else
261     quiterr("unsupported photometric type");
262     /* fall through */
263 gregl 2.10 case PHOTOMETRIC_RGB:
264 gwlarson 2.18 SET(C_GAMMA);
265 gregl 2.9 setcolrgam(cvts.gamcor);
266     if (CHK(C_XYZE)) {
267 greg 2.20 comprgb2xyzWBmat(cvts.cmat,
268 gregl 2.9 CHK(C_PRIM) ? cvts.prims : stdprims);
269     SET(C_CXFM);
270     }
271     if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) ||
272 gregl 2.10 hi != 3)
273     quiterr("unsupported samples per pixel for RGB");
274 gregl 2.9 if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) ||
275 gwlarson 2.18 hi != 8 & hi != 16)
276 gregl 2.10 quiterr("unsupported bits per sample for RGB");
277 gwlarson 2.18 if (hi == 8)
278     cvts.tf = RGB2Colr;
279     else {
280     cvts.tf = RRGGBB2Color;
281 gwlarson 2.19 SET(C_RFLT|C_TWRD);
282 gwlarson 2.18 }
283 gregl 2.9 break;
284 gregl 2.10 case PHOTOMETRIC_MINISBLACK:
285 gwlarson 2.18 SET(C_GRY|C_GAMMA);
286 gregl 2.15 setcolrgam(cvts.gamcor);
287 gregl 2.10 cvts.pconf = PLANARCONFIG_CONTIG;
288     if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) ||
289     hi != 1)
290     quiterr("unsupported samples per pixel for greyscale");
291     if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) ||
292 gwlarson 2.18 hi != 8 & hi != 16)
293 gregl 2.10 quiterr("unsupported bits per sample for greyscale");
294 gwlarson 2.18 if (hi == 8)
295     cvts.tf = Gry2Colr;
296     else {
297     cvts.tf = GGry2Color;
298 gwlarson 2.19 SET(C_RFLT|C_TWRD);
299 gwlarson 2.18 }
300 gregl 2.10 break;
301     default:
302     quiterr("unsupported photometric type");
303     break;
304 gregl 2.9 }
305    
306     if (!TIFFGetField(cvts.tif, TIFFTAG_IMAGEWIDTH, &cvts.xmax) ||
307     !TIFFGetField(cvts.tif, TIFFTAG_IMAGELENGTH, &cvts.ymax))
308 greg 1.1 quiterr("unknown input image resolution");
309 gregl 2.9
310     if (!TIFFGetField(cvts.tif, TIFFTAG_STONITS, &cvts.stonits))
311     cvts.stonits = 1.;
312     /* add to Radiance header */
313     if (cvts.pixrat < .99 || cvts.pixrat > 1.01)
314     fputaspect(cvts.pixrat, cvts.rfp);
315     if (CHK(C_XYZE)) {
316     fputexpos(pow(2.,(double)cvts.bradj)/cvts.stonits, cvts.rfp);
317     fputformat(CIEFMT, cvts.rfp);
318     } else {
319     if (CHK(C_PRIM))
320     fputprims(cvts.prims, cvts.rfp);
321     fputexpos(WHTEFFICACY*pow(2.,(double)cvts.bradj)/cvts.stonits,
322     cvts.rfp);
323     fputformat(COLRFMT, cvts.rfp);
324     }
325    
326     allocbufs(); /* allocate scanline buffers */
327     }
328    
329    
330     tiff2ra(ac, av) /* convert TIFF image to Radiance picture */
331     int ac;
332     char *av[];
333     {
334     int32 y;
335     /* open TIFF input */
336     if ((cvts.tif = TIFFOpen(av[ac], "r")) == NULL)
337     quiterr("cannot open TIFF input");
338     /* open Radiance output */
339     if (av[ac+1] == NULL || !strcmp(av[ac+1], "-"))
340     cvts.rfp = stdout;
341     else if ((cvts.rfp = fopen(av[ac+1], "w")) == NULL)
342     quiterr("cannot open Radiance output picture");
343     /* start output header */
344     newheader("RADIANCE", cvts.rfp);
345     printargs(ac, av, cvts.rfp);
346    
347     initfromtif(); /* initialize conversion */
348    
349     fputc('\n', cvts.rfp); /* finish Radiance header */
350     fputresolu(pixorder(), (int)cvts.xmax, (int)cvts.ymax, cvts.rfp);
351    
352     for (y = 0; y < cvts.ymax; y++) /* convert image */
353     (*cvts.tf)(y);
354     /* clean up */
355     fclose(cvts.rfp);
356     TIFFClose(cvts.tif);
357     }
358    
359    
360     int
361     headline(s) /* process Radiance input header line */
362     char *s;
363     {
364     char fmt[32];
365    
366     if (formatval(fmt, s)) {
367     if (!strcmp(fmt, COLRFMT))
368     CLR(C_XYZE);
369     else if (!strcmp(fmt, CIEFMT))
370     SET(C_XYZE);
371     else
372     quiterr("unrecognized input picture format");
373 gwlarson 2.17 return(1);
374 gregl 2.9 }
375     if (isexpos(s)) {
376     cvts.stonits /= exposval(s);
377 gwlarson 2.17 return(1);
378 gregl 2.9 }
379     if (isaspect(s)) {
380     cvts.pixrat *= aspectval(s);
381 gwlarson 2.17 return(1);
382 gregl 2.9 }
383     if (isprims(s)) {
384     primsval(cvts.prims, s);
385     SET(C_PRIM);
386 gwlarson 2.17 return(1);
387 gregl 2.9 }
388 gwlarson 2.17 return(0);
389 gregl 2.9 }
390    
391    
392     initfromrad() /* initialize input from a Radiance picture */
393     {
394     int i1, i2, po;
395     /* read Radiance header */
396     CLR(C_RFLT|C_TFLT|C_XYZE|C_PRIM|C_GAMMA|C_CXFM);
397     cvts.stonits = 1.;
398     cvts.pixrat = 1.;
399     cvts.pconf = PLANARCONFIG_CONTIG;
400     getheader(cvts.rfp, headline, NULL);
401     if ((po = fgetresolu(&i1, &i2, cvts.rfp)) < 0)
402     quiterr("bad Radiance picture");
403     cvts.xmax = i1; cvts.ymax = i2;
404     for (i1 = 0; i1 < 8; i1++) /* interpret orientation */
405     if (ortab[i1] == po) {
406     cvts.orient = i1 + 1;
407     break;
408 greg 1.1 }
409 gregl 2.9 if (i1 >= 8)
410     quiterr("internal error 1 in initfromrad");
411     if (!(po & YMAJOR))
412     cvts.pixrat = 1./cvts.pixrat;
413     if (!CHK(C_XYZE))
414     cvts.stonits *= WHTEFFICACY;
415     /* set up conversion */
416     TIFFSetField(cvts.tif, TIFFTAG_COMPRESSION, cvts.comp);
417 gregl 2.10 TIFFSetField(cvts.tif, TIFFTAG_PHOTOMETRIC, cvts.phot);
418 gregl 2.9
419 gregl 2.10 switch (cvts.phot) {
420     case PHOTOMETRIC_LOGLUV:
421 gregl 2.9 SET(C_RFLT|C_TFLT);
422     CLR(C_GRY);
423     if (!CHK(C_XYZE)) {
424 greg 2.20 comprgb2xyzWBmat(cvts.cmat,
425     CHK(C_PRIM) ? cvts.prims : stdprims);
426 gregl 2.9 SET(C_CXFM);
427     }
428 gregl 2.10 if (cvts.comp != COMPRESSION_SGILOG &&
429     cvts.comp != COMPRESSION_SGILOG24)
430     quiterr("internal error 2 in initfromrad");
431     TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
432 gregl 2.12 SGILOGDATAFMT_FLOAT);
433 gregl 2.9 cvts.tf = Color2Luv;
434     break;
435 gregl 2.10 case PHOTOMETRIC_LOGL:
436     SET(C_GRY|C_RFLT|C_TFLT);
437     if (cvts.comp != COMPRESSION_SGILOG)
438     quiterr("internal error 3 in initfromrad");
439     TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
440 gregl 2.12 SGILOGDATAFMT_FLOAT);
441 gregl 2.10 cvts.tf = Color2L;
442     break;
443     case PHOTOMETRIC_RGB:
444 gregl 2.9 SET(C_GAMMA|C_GAMUT);
445 gregl 2.10 CLR(C_GRY);
446 gregl 2.9 setcolrgam(cvts.gamcor);
447     if (CHK(C_XYZE)) {
448 greg 2.20 compxyz2rgbWBmat(cvts.cmat,
449 gregl 2.9 CHK(C_PRIM) ? cvts.prims : stdprims);
450     SET(C_CXFM);
451     }
452     if (CHK(C_PRIM)) {
453     TIFFSetField(cvts.tif, TIFFTAG_PRIMARYCHROMATICITIES,
454     (float *)cvts.prims);
455     TIFFSetField(cvts.tif, TIFFTAG_WHITEPOINT,
456     (float *)cvts.prims[WHT]);
457     }
458 gregl 2.10 cvts.tf = Colr2RGB;
459 gregl 2.9 break;
460 gregl 2.10 case PHOTOMETRIC_MINISBLACK:
461     SET(C_GRY|C_GAMMA|C_GAMUT);
462     setcolrgam(cvts.gamcor);
463     cvts.tf = Colr2Gry;
464     break;
465     default:
466     quiterr("internal error 4 in initfromrad");
467     break;
468 greg 1.1 }
469 gregl 2.9 /* set other TIFF fields */
470     TIFFSetField(cvts.tif, TIFFTAG_IMAGEWIDTH, cvts.xmax);
471     TIFFSetField(cvts.tif, TIFFTAG_IMAGELENGTH, cvts.ymax);
472     TIFFSetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, CHK(C_GRY) ? 1 : 3);
473     TIFFSetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, CHK(C_TFLT) ? 32 : 8);
474     TIFFSetField(cvts.tif, TIFFTAG_XRESOLUTION, 72.);
475     TIFFSetField(cvts.tif, TIFFTAG_YRESOLUTION, 72./cvts.pixrat);
476     TIFFSetField(cvts.tif, TIFFTAG_ORIENTATION, cvts.orient);
477     TIFFSetField(cvts.tif, TIFFTAG_RESOLUTIONUNIT, 2);
478     TIFFSetField(cvts.tif, TIFFTAG_PLANARCONFIG, cvts.pconf);
479     TIFFSetField(cvts.tif, TIFFTAG_STONITS,
480     cvts.stonits/pow(2.,(double)cvts.bradj));
481 gregl 2.10 if (cvts.comp == COMPRESSION_NONE)
482     i1 = TIFFScanlineSize(cvts.tif);
483     else
484     i1 = 3*cvts.xmax; /* conservative guess */
485 gregl 2.9 i2 = 8192/i1; /* compute good strip size */
486     if (i2 < 1) i2 = 1;
487     TIFFSetField(cvts.tif, TIFFTAG_ROWSPERSTRIP, (uint32)i2);
488    
489     allocbufs(); /* allocate scanline buffers */
490     }
491    
492    
493     ra2tiff(ac, av) /* convert Radiance picture to TIFF image */
494     int ac;
495     char *av[];
496     {
497     uint32 y;
498     /* open Radiance file */
499     if (!strcmp(av[ac], "-"))
500     cvts.rfp = stdin;
501     else if ((cvts.rfp = fopen(av[ac], "r")) == NULL)
502     quiterr("cannot open Radiance input picture");
503     /* open TIFF file */
504     if ((cvts.tif = TIFFOpen(av[ac+1], "w")) == NULL)
505     quiterr("cannot open TIFF output");
506    
507     initfromrad(); /* initialize conversion */
508    
509     for (y = 0; y < cvts.ymax; y++) /* convert image */
510     (*cvts.tf)(y);
511 greg 1.1 /* clean up */
512 gregl 2.9 TIFFClose(cvts.tif);
513     fclose(cvts.rfp);
514     }
515    
516    
517     int
518     Luv2Color(y) /* read/convert/write Luv->COLOR scanline */
519     uint32 y;
520     {
521     register int x;
522    
523 gwlarson 2.19 if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT))
524 gregl 2.9 quiterr("internal error 1 in Luv2Color");
525    
526     if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
527     quiterr("error reading TIFF input");
528    
529     for (x = cvts.xmax; x--; ) {
530 gwlarson 2.16 colval(cvts.r.colors[x],CIEX) = cvts.t.fp[3*x];
531     colval(cvts.r.colors[x],CIEY) = cvts.t.fp[3*x + 1];
532     colval(cvts.r.colors[x],CIEZ) = cvts.t.fp[3*x + 2];
533 gregl 2.9 if (CHK(C_CXFM))
534     colortrans(cvts.r.colors[x], cvts.cmat,
535     cvts.r.colors[x]);
536     if (CHK(C_GAMUT))
537     clipgamut(cvts.r.colors[x], cvts.t.fp[3*x + 1],
538     CGAMUT_LOWER, cblack, cwhite);
539     }
540     if (cvts.bradj) {
541     double m = pow(2.,(double)cvts.bradj);
542     for (x = cvts.xmax; x--; )
543     scalecolor(cvts.r.colors[x], m);
544     }
545    
546     if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
547     quiterr("error writing Radiance picture");
548     }
549    
550    
551     int
552 gwlarson 2.18 RRGGBB2Color(y) /* read/convert/write RGB16->COLOR scanline */
553     uint32 y;
554     {
555     int dogamma = cvts.gamcor < 0.99 | cvts.gamcor > 1.01;
556     register double d;
557     register int x;
558    
559 gwlarson 2.19 if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_TWRD|C_RFLT))
560 gwlarson 2.18 quiterr("internal error 1 in RRGGBB2Color");
561    
562     if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
563     quiterr("error reading TIFF input");
564    
565     for (x = cvts.xmax; x--; ) {
566     d = (cvts.t.wp[3*x] + 0.5)*(1./(1L<<16));
567     if (dogamma) d = pow(d, cvts.gamcor);
568     colval(cvts.r.colors[x],RED) = d;
569     d = (cvts.t.wp[3*x + 1] + 0.5)*(1./(1L<<16));
570     if (dogamma) d = pow(d, cvts.gamcor);
571     colval(cvts.r.colors[x],GRN) = d;
572     d = (cvts.t.wp[3*x + 2] + 0.5)*(1./(1L<<16));
573     if (dogamma) d = pow(d, cvts.gamcor);
574     colval(cvts.r.colors[x],BLU) = d;
575     if (CHK(C_CXFM))
576     colortrans(cvts.r.colors[x], cvts.cmat,
577     cvts.r.colors[x]);
578     if (CHK(C_GAMUT))
579     clipgamut(cvts.r.colors[x], cvts.t.fp[3*x + 1],
580     CGAMUT_LOWER, cblack, cwhite);
581     }
582     if (cvts.bradj) {
583     d = pow(2.,(double)cvts.bradj);
584     for (x = cvts.xmax; x--; )
585     scalecolor(cvts.r.colors[x], d);
586     }
587    
588     if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
589     quiterr("error writing Radiance picture");
590     }
591    
592    
593     int
594 gregl 2.9 L2Color(y) /* read/convert/write L16->COLOR scanline */
595     uint32 y;
596     {
597     register int x;
598    
599 gwlarson 2.19 if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
600 gregl 2.9 quiterr("internal error 1 in L2Color");
601    
602     if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
603     quiterr("error reading TIFF input");
604    
605     for (x = cvts.xmax; x--; )
606 gwlarson 2.16 colval(cvts.r.colors[x],RED) =
607     colval(cvts.r.colors[x],GRN) =
608     colval(cvts.r.colors[x],BLU) =
609     cvts.t.fp[x] > 0. ? cvts.t.fp[x] : 0.;
610 gregl 2.9
611     if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
612     quiterr("error writing Radiance picture");
613     }
614    
615    
616     int
617     RGB2Colr(y) /* read/convert/write RGB->COLR scanline */
618     uint32 y;
619     {
620     COLOR ctmp;
621     register int x;
622    
623 gwlarson 2.19 if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY))
624 gregl 2.9 quiterr("internal error 1 in RGB2Colr");
625    
626     if (cvts.pconf == PLANARCONFIG_CONTIG) {
627     if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
628     goto readerr;
629     for (x = cvts.xmax; x--; ) {
630     cvts.r.colrs[x][RED] = cvts.t.bp[3*x];
631     cvts.r.colrs[x][GRN] = cvts.t.bp[3*x + 1];
632     cvts.r.colrs[x][BLU] = cvts.t.bp[3*x + 2];
633     }
634     } else {
635     if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
636     goto readerr;
637     if (TIFFReadScanline(cvts.tif,
638 gregl 2.14 (tdata_t)(cvts.t.bp + cvts.xmax), y, 1) < 0)
639 gregl 2.9 goto readerr;
640     if (TIFFReadScanline(cvts.tif,
641 gregl 2.14 (tdata_t)(cvts.t.bp + 2*cvts.xmax), y, 2) < 0)
642 gregl 2.9 goto readerr;
643     for (x = cvts.xmax; x--; ) {
644     cvts.r.colrs[x][RED] = cvts.t.bp[x];
645     cvts.r.colrs[x][GRN] = cvts.t.bp[cvts.xmax + x];
646     cvts.r.colrs[x][BLU] = cvts.t.bp[2*cvts.xmax + x];
647     }
648     }
649    
650     gambs_colrs(cvts.r.colrs, cvts.xmax);
651     if (CHK(C_CXFM))
652     for (x = cvts.xmax; x--; ) {
653     colr_color(ctmp, cvts.r.colrs[x]);
654     colortrans(ctmp, cvts.cmat, ctmp);
655     if (CHK(C_GAMUT)) /* !CHK(C_XYZE) */
656     clipgamut(ctmp, bright(ctmp), CGAMUT_LOWER,
657     cblack, cwhite);
658     setcolr(cvts.r.colrs[x], colval(ctmp,RED),
659     colval(ctmp,GRN), colval(ctmp,BLU));
660     }
661     if (cvts.bradj)
662     shiftcolrs(cvts.r.colrs, cvts.xmax, cvts.bradj);
663    
664     if (fwritecolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)
665     quiterr("error writing Radiance picture");
666 greg 1.1 return;
667     readerr:
668     quiterr("error reading TIFF input");
669     }
670    
671    
672 gregl 2.9 int
673     Gry2Colr(y) /* read/convert/write G8->COLR scanline */
674     uint32 y;
675 greg 1.1 {
676     register int x;
677 gregl 2.9
678 gwlarson 2.19 if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY)
679 gregl 2.9 quiterr("internal error 1 in Gry2Colr");
680    
681     if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
682     quiterr("error reading TIFF input");
683    
684     for (x = cvts.xmax; x--; )
685     cvts.r.colrs[x][RED] =
686     cvts.r.colrs[x][GRN] =
687     cvts.r.colrs[x][BLU] = cvts.t.bp[x];
688    
689     gambs_colrs(cvts.r.colrs, cvts.xmax);
690     if (cvts.bradj)
691     shiftcolrs(cvts.r.colrs, cvts.xmax, cvts.bradj);
692    
693     if (fwritecolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)
694     quiterr("error writing Radiance picture");
695     }
696    
697    
698     int
699 gwlarson 2.18 GGry2Color(y) /* read/convert/write G16->COLOR scanline */
700     uint32 y;
701     {
702     int dogamma = cvts.gamcor < 0.99 | cvts.gamcor > 1.01;
703     double m;
704     register double d;
705     register int x;
706    
707 gwlarson 2.19 if (CHK(C_TFLT|C_TWRD|C_GRY|C_RFLT) != (C_GRY|C_RFLT|C_TWRD))
708 gwlarson 2.18 quiterr("internal error 1 in GGry2Color");
709    
710     if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
711     quiterr("error reading TIFF input");
712    
713     if (cvts.bradj)
714     m = pow(2., (double)cvts.bradj);
715     for (x = cvts.xmax; x--; ) {
716     d = (cvts.t.wp[x] + 0.5)*(1./(1L<<16));
717     if (dogamma) d = pow(d, cvts.gamcor);
718     if (cvts.bradj) d *= m;
719     colval(cvts.r.colors[x],RED) =
720     colval(cvts.r.colors[x],GRN) =
721     colval(cvts.r.colors[x],BLU) = d;
722     }
723     if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
724     quiterr("error writing Radiance picture");
725     }
726    
727    
728     int
729 gregl 2.9 Color2L(y) /* read/convert/write COLOR->L16 scanline */
730     uint32 y;
731     {
732     double m = pow(2.,(double)cvts.bradj);
733     register int x;
734    
735 gwlarson 2.19 if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
736 gregl 2.9 quiterr("internal error 1 in Color2L");
737    
738     if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
739     quiterr("error reading Radiance picture");
740    
741     for (x = cvts.xmax; x--; )
742     cvts.t.fp[x] = m*( CHK(C_XYZE) ? colval(cvts.r.colors[x],CIEY)
743     : bright(cvts.r.colors[x]) );
744    
745     if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
746     quiterr("error writing TIFF output");
747     }
748    
749    
750     int
751     Color2Luv(y) /* read/convert/write COLOR->Luv scanline */
752     uint32 y;
753     {
754     register int x;
755    
756 gwlarson 2.19 if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT))
757 gregl 2.9 quiterr("internal error 1 in Color2Luv");
758    
759     if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
760     quiterr("error reading Radiance picture");
761    
762     if (CHK(C_CXFM))
763     for (x = cvts.xmax; x--; )
764     colortrans(cvts.r.colors[x], cvts.cmat,
765     cvts.r.colors[x]);
766     if (cvts.bradj) {
767     double m = pow(2.,(double)cvts.bradj);
768     for (x = cvts.xmax; x--; )
769     scalecolor(cvts.r.colors[x], m);
770     }
771    
772     for (x = cvts.xmax; x--; ) {
773 gwlarson 2.16 cvts.t.fp[3*x] = colval(cvts.r.colors[x],CIEX);
774     cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],CIEY);
775     cvts.t.fp[3*x+2] = colval(cvts.r.colors[x],CIEZ);
776 gregl 2.9 }
777    
778     if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
779     quiterr("error writing TIFF output");
780     }
781    
782    
783     int
784     Colr2Gry(y) /* read/convert/write COLR->RGB scanline */
785     uint32 y;
786     {
787     register int x;
788    
789 gwlarson 2.19 if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY)
790 gregl 2.9 quiterr("internal error 1 in Colr2Gry");
791    
792     if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)
793     quiterr("error reading Radiance picture");
794    
795     if (cvts.bradj)
796     shiftcolrs(cvts.r.colrs, cvts.xmax, cvts.bradj);
797     for (x = cvts.xmax; x--; )
798     colval(cvts.r.colrs[x],CIEY) = normbright(cvts.r.colrs[x]);
799     colrs_gambs(cvts.r.colrs, cvts.xmax);
800    
801     for (x = cvts.xmax; x--; )
802     cvts.t.bp[x] = colval(cvts.r.colrs[x],CIEY);
803    
804     if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
805     quiterr("error writing TIFF output");
806     }
807    
808    
809     int
810     Colr2RGB(y) /* read/convert/write COLR->RGB scanline */
811     uint32 y;
812     {
813     COLOR ctmp;
814     register int x;
815    
816 gwlarson 2.19 if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY))
817 gregl 2.9 quiterr("internal error 1 in Colr2RGB");
818    
819     if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)
820     quiterr("error reading Radiance picture");
821    
822     if (cvts.bradj)
823     shiftcolrs(cvts.r.colrs, cvts.xmax, cvts.bradj);
824     if (CHK(C_CXFM))
825     for (x = cvts.xmax; x--; ) {
826     colr_color(ctmp, cvts.r.colrs[x]);
827     colortrans(ctmp, cvts.cmat, ctmp);
828     if (CHK(C_GAMUT))
829     clipgamut(ctmp, bright(ctmp), CGAMUT,
830     cblack, cwhite);
831     setcolr(cvts.r.colrs[x], colval(ctmp,RED),
832     colval(ctmp,GRN), colval(ctmp,BLU));
833 greg 1.1 }
834 gregl 2.9 colrs_gambs(cvts.r.colrs, cvts.xmax);
835    
836     for (x = cvts.xmax; x--; ) {
837     cvts.t.bp[3*x] = cvts.r.colrs[x][RED];
838     cvts.t.bp[3*x+1] = cvts.r.colrs[x][GRN];
839     cvts.t.bp[3*x+2] = cvts.r.colrs[x][BLU];
840 greg 1.1 }
841 gregl 2.9
842     if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
843     quiterr("error writing TIFF output");
844 greg 1.1 }