ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_tiff.c
Revision: 2.18
Committed: Sun May 30 17:35:08 1999 UTC (24 years, 11 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 2.17: +94 -10 lines
Log Message:
added ability to read 16-bit/channel TIFFs

File Contents

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