ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_tiff.c
(Generate patch)

Comparing ray/src/px/ra_tiff.c (file contents):
Revision 2.11 by gregl, Fri Aug 15 18:30:14 1997 UTC vs.
Revision 2.23 by greg, Mon Jul 14 04:56:54 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1997 Silicon Graphics, Inc. */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ SGI";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  Program to convert between RADIANCE and TIFF files.
6 < *  Added experimental LogLuv encodings 7/97 (GWL).
6 > *  Added LogLuv encodings 7/97 (GWL).
7 > *  Added white-balance adjustment 10/01 (GW).
8   */
9  
10   #include  <stdio.h>
11   #include  <math.h>
12 + #include  <ctype.h>
13   #include  "tiffio.h"
14   #include  "color.h"
15   #include  "resolu.h"
16  
17   #define  GAMCOR         2.2             /* default gamma */
18  
20 #ifndef malloc
21 extern char  *malloc();
22 #endif
19                                  /* conversion flags */
20   #define C_CXFM          0x1             /* needs color transformation */
21   #define C_GAMUT         0x2             /* needs gamut mapping */
# Line 28 | Line 24 | extern char  *malloc();
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 < #define C_PRIM          0x80            /* has assigned primaries */
27 > #define C_TWRD          0x80            /* TIFF data is 16-bit */
28 > #define C_PRIM          0x100           /* has assigned primaries */
29  
30   struct {
31          uint16  flags;          /* conversion flags (defined above) */
32 +        char    capdate[20];    /* capture date/time */
33 +        char    owner[256];     /* content owner */
34          uint16  comp;           /* TIFF compression type */
35          uint16  phot;           /* TIFF photometric type */
36          uint16  pconf;          /* TIFF planar configuration */
# Line 52 | Line 51 | struct {
51          } r;                    /* Radiance scanline */
52          union {
53                  uint8   *bp;            /* byte pointer */
54 +                uint16  *wp;            /* word pointer */
55                  float   *fp;            /* float pointer */
56                  char    *p;             /* generic pointer */
57          } t;                    /* TIFF scanline */
58 <        int     (*tf)();        /* translation procedure */
58 >        void    (*tf)();        /* translation procedure */
59   }       cvts = {        /* conversion structure */
60 <        0, COMPRESSION_NONE, PHOTOMETRIC_RGB,
60 >        0, "", "", COMPRESSION_NONE, PHOTOMETRIC_RGB,
61          PLANARCONFIG_CONTIG, GAMCOR, 0, 1, 1., 1.,
62   };
63  
# Line 66 | Line 66 | struct {
66   #define CLR(f)          (cvts.flags &= ~(f))
67   #define TGL(f)          (cvts.flags ^= (f))
68  
69 < int     Luv2Color(), L2Color(), RGB2Colr(), Gry2Colr();
70 < int     Color2Luv(), Color2L(), Colr2RGB(), Colr2Gry();
69 > void    Luv2Color(), L2Color(), RGB2Colr(), Gry2Colr();
70 > void    Color2Luv(), Color2L(), Colr2RGB(), Colr2Gry();
71 > void    RRGGBB2Color(), GGry2Color(), Color2RRGGBB(), Color2GGry();
72  
73 + #define RfGfBf2Color    Luv2Color
74 + #define Gryf2Color      L2Color
75 + #define Color2Gryf      Color2L
76 + #define Color2RfGfBf    Color2Luv
77 +
78   short   ortab[8] = {            /* orientation conversion table */
79          YMAJOR|YDECR,
80          YMAJOR|YDECR|XDECR,
# Line 82 | Line 88 | short  ortab[8] = {            /* orientation conversion table */
88  
89   #define pixorder()      ortab[cvts.orient-1]
90  
91 + extern char     TMSTR[];        /* "CAPDATE=" from header.c */
92 + char            OWNSTR[] = "OWNER=";
93 +
94   char  *progname;
95  
96  
# Line 114 | Line 123 | char  *argv[];
123                                  cvts.comp = COMPRESSION_SGILOG24;
124                                  cvts.phot = PHOTOMETRIC_LOGLUV;
125                                  break;
126 +                        case 'w':               /* 16-bit/primary output? */
127 +                                TGL(C_TWRD);
128 +                                break;
129 +                        case 'f':               /* IEEE float output? */
130 +                                TGL(C_TFLT);
131 +                                break;
132                          case 'b':               /* greyscale output? */
133                                  TGL(C_GRY);
134                                  break;
# Line 144 | Line 159 | doneopts:
159  
160                  if (i != argc-2)
161                          goto userr;
162 <
163 <                if (CHK(C_GRY))         /* consistency corrections */
162 >                                                /* consistency checks */
163 >                if (CHK(C_GRY))
164                          if (cvts.phot == PHOTOMETRIC_RGB)
165                                  cvts.phot = PHOTOMETRIC_MINISBLACK;
166                          else {
167                                  cvts.phot = PHOTOMETRIC_LOGL;
168                                  cvts.comp = COMPRESSION_SGILOG;
169                          }
170 +                if (CHK(C_TWRD|C_TFLT) == (C_TWRD|C_TFLT))
171 +                        goto userr;
172  
173                  ra2tiff(i, argv);
174          }
# Line 159 | Line 176 | doneopts:
176          exit(0);
177   userr:
178          fprintf(stderr,
179 <        "Usage: %s [-z|-L|-l][-b][-e +/-stops][-g gamma] {in.pic|-} out.tif\n",
179 >        "Usage: %s [-z|-L|-l|-f|-w][-b][-e +/-stops][-g gamma] {in.pic|-} out.tif\n",
180                          progname);
181          fprintf(stderr,
182          "   Or: %s -r [-x][-e +/-stops][-g gamma] in.tif [out.pic|-]\n",
# Line 184 | Line 201 | allocbufs()                    /* allocate scanline buffers */
201          int     rsiz, tsiz;
202  
203          rsiz = CHK(C_RFLT) ? sizeof(COLOR) : sizeof(COLR);
204 <        tsiz = (CHK(C_TFLT) ? sizeof(float) : sizeof(uint8)) *
204 >        tsiz = (CHK(C_TFLT) ? sizeof(float) :
205 >                        CHK(C_TWRD) ? sizeof(uint16) : sizeof(uint8)) *
206                          (CHK(C_GRY) ? 1 : 3);
207          cvts.r.p = (char *)malloc(rsiz*cvts.xmax);
208          cvts.t.p = (char *)malloc(tsiz*cvts.xmax);
# Line 196 | Line 214 | allocbufs()                    /* allocate scanline buffers */
214   initfromtif()           /* initialize conversion from TIFF input */
215   {
216          uint16  hi;
217 +        char    *cp;
218          float   *fa, f1, f2;
219  
220 <        CLR(C_GRY|C_GAMMA|C_PRIM|C_RFLT|C_TFLT|C_CXFM);
220 >        CLR(C_GRY|C_GAMMA|C_PRIM|C_RFLT|C_TFLT|C_TWRD|C_CXFM);
221  
222          TIFFGetFieldDefaulted(cvts.tif, TIFFTAG_PLANARCONFIG, &cvts.pconf);
223  
# Line 241 | Line 260 | initfromtif()          /* initialize conversion from TIFF inpu
260                  if (cvts.pconf != PLANARCONFIG_CONTIG)
261                          quiterr("cannot handle separate Luv planes");
262                  TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
263 <                                SGILOGDATAFMT_FLTXYZ);
263 >                                SGILOGDATAFMT_FLOAT);
264                  cvts.tf = Luv2Color;
265                  break;
266          case PHOTOMETRIC_LOGL:
267                  SET(C_GRY|C_RFLT|C_TFLT|C_GAMUT);
268                  cvts.pconf = PLANARCONFIG_CONTIG;
269                  TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
270 <                                SGILOGDATAFMT_FLTY);
270 >                                SGILOGDATAFMT_FLOAT);
271                  cvts.tf = L2Color;
272                  break;
273          case PHOTOMETRIC_YCBCR:
# Line 261 | Line 280 | initfromtif()          /* initialize conversion from TIFF inpu
280                          quiterr("unsupported photometric type");
281                  /* fall through */
282          case PHOTOMETRIC_RGB:
283 <                SET(C_GAMMA|C_GAMUT);
283 >                SET(C_GAMMA);
284                  setcolrgam(cvts.gamcor);
285                  if (CHK(C_XYZE)) {
286 <                        comprgb2xyzmat(cvts.cmat,
286 >                        comprgb2xyzWBmat(cvts.cmat,
287                                          CHK(C_PRIM) ? cvts.prims : stdprims);
288                          SET(C_CXFM);
289                  }
290                  if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) ||
291                                  hi != 3)
292                          quiterr("unsupported samples per pixel for RGB");
293 <                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) ||
294 <                                hi != 8)
293 >                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi))
294 >                        hi = -1;
295 >                switch (hi) {
296 >                case 8:
297 >                        cvts.tf = RGB2Colr;
298 >                        break;
299 >                case 16:
300 >                        cvts.tf = RRGGBB2Color;
301 >                        SET(C_RFLT|C_TWRD);
302 >                        break;
303 >                case 32:
304 >                        cvts.tf = RfGfBf2Color;
305 >                        SET(C_RFLT|C_TFLT);
306 >                        break;
307 >                default:
308                          quiterr("unsupported bits per sample for RGB");
309 <                cvts.tf = RGB2Colr;
309 >                }
310                  break;
311          case PHOTOMETRIC_MINISBLACK:
312 <                SET(C_GRY|C_GAMMA|C_GAMUT);
312 >                SET(C_GRY|C_GAMMA);
313 >                setcolrgam(cvts.gamcor);
314                  cvts.pconf = PLANARCONFIG_CONTIG;
315                  if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) ||
316                                  hi != 1)
317                          quiterr("unsupported samples per pixel for greyscale");
318 <                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) ||
319 <                                hi != 8)
320 <                        quiterr("unsupported bits per sample for greyscale");
321 <                cvts.tf = Gry2Colr;
318 >                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi))
319 >                        hi = -1;
320 >                switch (hi) {
321 >                case 8:
322 >                        cvts.tf = Gry2Colr;
323 >                        break;
324 >                case 16:
325 >                        cvts.tf = GGry2Color;
326 >                        SET(C_RFLT|C_TWRD);
327 >                        break;
328 >                case 32:
329 >                        cvts.tf = Gryf2Color;
330 >                        SET(C_RFLT|C_TFLT);
331 >                        break;
332 >                default:
333 >                        quiterr("unsupported bits per sample for Gray");
334 >                }
335                  break;
336          default:
337                  quiterr("unsupported photometric type");
# Line 298 | Line 344 | initfromtif()          /* initialize conversion from TIFF inpu
344  
345          if (!TIFFGetField(cvts.tif, TIFFTAG_STONITS, &cvts.stonits))
346                  cvts.stonits = 1.;
347 +
348 +        if (!TIFFGetField(cvts.tif, TIFFTAG_DATETIME, &cp))
349 +                cvts.capdate[0] = '\0';
350 +        else {
351 +                strncpy(cvts.capdate, cp, 19);
352 +                cvts.capdate[19] = '\0';
353 +        }
354 +        if (!TIFFGetField(cvts.tif, TIFFTAG_ARTIST, &cp))
355 +                cvts.owner[0] = '\0';
356 +        else {
357 +                strncpy(cvts.owner, cp, sizeof(cvts.owner));
358 +                cvts.owner[sizeof(cvts.owner)-1] = '\0';
359 +        }
360                                          /* add to Radiance header */
361          if (cvts.pixrat < .99 || cvts.pixrat > 1.01)
362                  fputaspect(cvts.pixrat, cvts.rfp);
# Line 311 | Line 370 | initfromtif()          /* initialize conversion from TIFF inpu
370                                  cvts.rfp);
371                  fputformat(COLRFMT, cvts.rfp);
372          }
373 +        if (cvts.capdate[0])
374 +                fprintf(cvts.rfp, "%s %s\n", TMSTR, cvts.capdate);
375 +        if (cvts.owner[0])
376 +                fprintf(cvts.rfp, "%s %s\n", OWNSTR, cvts.owner);
377  
378          allocbufs();                    /* allocate scanline buffers */
379   }
# Line 350 | Line 413 | int
413   headline(s)                     /* process Radiance input header line */
414   char    *s;
415   {
416 +        static int      tmstrlen = 0;
417 +        static int      ownstrlen = 0;
418          char    fmt[32];
419  
420 +        if (!tmstrlen)
421 +                tmstrlen = strlen(TMSTR);
422 +        if (!ownstrlen)
423 +                ownstrlen = strlen(OWNSTR);
424          if (formatval(fmt, s)) {
425                  if (!strcmp(fmt, COLRFMT))
426                          CLR(C_XYZE);
# Line 359 | Line 428 | char   *s;
428                          SET(C_XYZE);
429                  else
430                          quiterr("unrecognized input picture format");
431 <                return;
431 >                return(1);
432          }
433          if (isexpos(s)) {
434                  cvts.stonits /= exposval(s);
435 <                return;
435 >                return(1);
436          }
437          if (isaspect(s)) {
438                  cvts.pixrat *= aspectval(s);
439 <                return;
439 >                return(1);
440          }
441          if (isprims(s)) {
442                  primsval(cvts.prims, s);
443                  SET(C_PRIM);
444 <                return;
444 >                return(1);
445          }
446 +        if (isdate(s)) {
447 +                if (s[tmstrlen] == ' ')
448 +                        strncpy(cvts.capdate, s+tmstrlen+1, 19);
449 +                else
450 +                        strncpy(cvts.capdate, s+tmstrlen, 19);
451 +                cvts.capdate[19] = '\0';
452 +                return(1);
453 +        }
454 +        if (!strncmp(s, OWNSTR, ownstrlen)) {
455 +                register char   *cp = s + ownstrlen;
456 +
457 +                while (isspace(*cp))
458 +                        ++cp;
459 +                strncpy(cvts.owner, cp, sizeof(cvts.owner));
460 +                cvts.owner[sizeof(cvts.owner)-1] = '\0';
461 +                for (cp = cvts.owner; *cp; cp++)
462 +                        ;
463 +                while (cp > cvts.owner && isspace(cp[-1]))
464 +                        *--cp = '\0';
465 +                return(1);
466 +        }
467 +        return(0);
468   }
469  
470  
# Line 381 | Line 472 | initfromrad()                  /* initialize input from a Radiance pi
472   {
473          int     i1, i2, po;
474                                                  /* read Radiance header */
475 <        CLR(C_RFLT|C_TFLT|C_XYZE|C_PRIM|C_GAMMA|C_CXFM);
475 >        CLR(C_RFLT|C_XYZE|C_PRIM|C_GAMMA|C_CXFM);
476 >        cvts.capdate[0] = '\0';
477 >        cvts.owner[0] = '\0';
478          cvts.stonits = 1.;
479          cvts.pixrat = 1.;
480          cvts.pconf = PLANARCONFIG_CONTIG;
# Line 407 | Line 500 | initfromrad()                  /* initialize input from a Radiance pi
500          switch (cvts.phot) {
501          case PHOTOMETRIC_LOGLUV:
502                  SET(C_RFLT|C_TFLT);
503 <                CLR(C_GRY);
503 >                CLR(C_GRY|C_TWRD);
504                  if (!CHK(C_XYZE)) {
505 <                        cpcolormat(cvts.cmat, rgb2xyzmat);
505 >                        comprgb2xyzWBmat(cvts.cmat,
506 >                                        CHK(C_PRIM) ? cvts.prims : stdprims);
507                          SET(C_CXFM);
508                  }
509                  if (cvts.comp != COMPRESSION_SGILOG &&
510                                  cvts.comp != COMPRESSION_SGILOG24)
511                          quiterr("internal error 2 in initfromrad");
512                  TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
513 <                                SGILOGDATAFMT_FLTXYZ);
513 >                                SGILOGDATAFMT_FLOAT);
514                  cvts.tf = Color2Luv;
515                  break;
516          case PHOTOMETRIC_LOGL:
517                  SET(C_GRY|C_RFLT|C_TFLT);
518 +                CLR(C_TWRD);
519                  if (cvts.comp != COMPRESSION_SGILOG)    
520                          quiterr("internal error 3 in initfromrad");
521                  TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
522 <                                SGILOGDATAFMT_FLTY);
522 >                                SGILOGDATAFMT_FLOAT);
523                  cvts.tf = Color2L;
524                  break;
525          case PHOTOMETRIC_RGB:
# Line 432 | Line 527 | initfromrad()                  /* initialize input from a Radiance pi
527                  CLR(C_GRY);
528                  setcolrgam(cvts.gamcor);
529                  if (CHK(C_XYZE)) {
530 <                        compxyz2rgbmat(cvts.cmat,
530 >                        compxyz2rgbWBmat(cvts.cmat,
531                                          CHK(C_PRIM) ? cvts.prims : stdprims);
532                          SET(C_CXFM);
533                  }
# Line 442 | Line 537 | initfromrad()                  /* initialize input from a Radiance pi
537                          TIFFSetField(cvts.tif, TIFFTAG_WHITEPOINT,
538                                          (float *)cvts.prims[WHT]);
539                  }
540 <                cvts.tf = Colr2RGB;
540 >                if (CHK(C_TWRD)) {
541 >                        cvts.tf = Color2RRGGBB;
542 >                        SET(C_RFLT);
543 >                } else if (CHK(C_TFLT)) {
544 >                        TIFFSetField(cvts.tif, TIFFTAG_SAMPLEFORMAT,
545 >                                        SAMPLEFORMAT_IEEEFP);
546 >                        cvts.tf = Color2RfGfBf;
547 >                        SET(C_RFLT);
548 >                } else
549 >                        cvts.tf = Colr2RGB;
550                  break;
551          case PHOTOMETRIC_MINISBLACK:
552                  SET(C_GRY|C_GAMMA|C_GAMUT);
553                  setcolrgam(cvts.gamcor);
554 <                cvts.tf = Colr2Gry;
554 >                if (CHK(C_TWRD)) {
555 >                        cvts.tf = Color2GGry;
556 >                        SET(C_RFLT);
557 >                } else if (CHK(C_TFLT)) {
558 >                        TIFFSetField(cvts.tif, TIFFTAG_SAMPLEFORMAT,
559 >                                        SAMPLEFORMAT_IEEEFP);
560 >                        cvts.tf = Color2Gryf;
561 >                        SET(C_RFLT);
562 >                } else
563 >                        cvts.tf = Colr2Gry;
564                  break;
565          default:
566                  quiterr("internal error 4 in initfromrad");
# Line 457 | Line 570 | initfromrad()                  /* initialize input from a Radiance pi
570          TIFFSetField(cvts.tif, TIFFTAG_IMAGEWIDTH, cvts.xmax);
571          TIFFSetField(cvts.tif, TIFFTAG_IMAGELENGTH, cvts.ymax);
572          TIFFSetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, CHK(C_GRY) ? 1 : 3);
573 <        TIFFSetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, CHK(C_TFLT) ? 32 : 8);
573 >        TIFFSetField(cvts.tif, TIFFTAG_BITSPERSAMPLE,
574 >                        CHK(C_TFLT) ? 32 : CHK(C_TWRD) ? 16 : 8);
575          TIFFSetField(cvts.tif, TIFFTAG_XRESOLUTION, 72.);
576          TIFFSetField(cvts.tif, TIFFTAG_YRESOLUTION, 72./cvts.pixrat);
577          TIFFSetField(cvts.tif, TIFFTAG_ORIENTATION, cvts.orient);
# Line 465 | Line 579 | initfromrad()                  /* initialize input from a Radiance pi
579          TIFFSetField(cvts.tif, TIFFTAG_PLANARCONFIG, cvts.pconf);
580          TIFFSetField(cvts.tif, TIFFTAG_STONITS,
581                          cvts.stonits/pow(2.,(double)cvts.bradj));
582 +        if (cvts.capdate[0])
583 +                TIFFSetField(cvts.tif, TIFFTAG_DATETIME, cvts.capdate);
584 +        if (cvts.owner[0])
585 +                TIFFSetField(cvts.tif, TIFFTAG_ARTIST, cvts.owner);
586          if (cvts.comp == COMPRESSION_NONE)
587                  i1 = TIFFScanlineSize(cvts.tif);
588          else
# Line 501 | Line 619 | char  *av[];
619   }
620  
621  
622 < int
622 > void
623   Luv2Color(y)                    /* read/convert/write Luv->COLOR scanline */
624   uint32  y;
625   {
626          register int    x;
627  
628 <        if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | CHK(C_GRY))
628 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT))
629                  quiterr("internal error 1 in Luv2Color");
630  
631          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
632                  quiterr("error reading TIFF input");
633 <        
633 >                                        /* also works for float RGB */
634          for (x = cvts.xmax; x--; ) {
635 <                cvts.r.colors[x][RED] = cvts.t.fp[3*x];
636 <                cvts.r.colors[x][GRN] = cvts.t.fp[3*x + 1];
637 <                cvts.r.colors[x][BLU] = cvts.t.fp[3*x + 2];
635 >                setcolor(cvts.r.colors[x],
636 >                                cvts.t.fp[3*x],
637 >                                cvts.t.fp[3*x + 1],
638 >                                cvts.t.fp[3*x + 2]);
639                  if (CHK(C_CXFM))
640                          colortrans(cvts.r.colors[x], cvts.cmat,
641                                          cvts.r.colors[x]);
# Line 535 | Line 654 | uint32 y;
654   }
655  
656  
657 < int
658 < L2Color(y)                      /* read/convert/write L16->COLOR scanline */
657 > void
658 > RRGGBB2Color(y)                 /* read/convert/write RGB16->COLOR scanline */
659   uint32  y;
660   {
661 +        int     dogamma = cvts.gamcor < 0.99 | cvts.gamcor > 1.01;
662 +        register double d;
663          register int    x;
664  
665 <        if (CHK(C_RFLT|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
666 <                quiterr("internal error 1 in L2Color");
665 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_TWRD|C_RFLT))
666 >                quiterr("internal error 1 in RRGGBB2Color");
667  
668          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
669                  quiterr("error reading TIFF input");
670          
671 <        for (x = cvts.xmax; x--; )
672 <                cvts.r.colors[x][RED] =
673 <                cvts.r.colors[x][GRN] =
674 <                cvts.r.colors[x][BLU] = cvts.t.fp[x] > 0. ? cvts.t.fp[x] : 0.;
671 >        for (x = cvts.xmax; x--; ) {
672 >                d = (cvts.t.wp[3*x] + 0.5)*(1./(1L<<16));
673 >                if (dogamma) d = pow(d, cvts.gamcor);
674 >                colval(cvts.r.colors[x],RED) = d;
675 >                d = (cvts.t.wp[3*x + 1] + 0.5)*(1./(1L<<16));
676 >                if (dogamma) d = pow(d, cvts.gamcor);
677 >                colval(cvts.r.colors[x],GRN) = d;
678 >                d = (cvts.t.wp[3*x + 2] + 0.5)*(1./(1L<<16));
679 >                if (dogamma) d = pow(d, cvts.gamcor);
680 >                colval(cvts.r.colors[x],BLU) = d;
681 >                if (CHK(C_CXFM))
682 >                        colortrans(cvts.r.colors[x], cvts.cmat,
683 >                                        cvts.r.colors[x]);
684 >                if (CHK(C_GAMUT))
685 >                        clipgamut(cvts.r.colors[x], cvts.t.fp[3*x + 1],
686 >                                        CGAMUT_LOWER, cblack, cwhite);
687 >        }
688 >        if (cvts.bradj) {
689 >                d = pow(2.,(double)cvts.bradj);
690 >                for (x = cvts.xmax; x--; )
691 >                        scalecolor(cvts.r.colors[x], d);
692 >        }
693  
694          if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
695                  quiterr("error writing Radiance picture");
696   }
697  
698  
699 < int
699 > void
700 > L2Color(y)                      /* read/convert/write Lfloat->COLOR scanline */
701 > uint32  y;
702 > {
703 >        float   m = pow(2., (double)cvts.bradj);
704 >        register int    x;
705 >
706 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
707 >                quiterr("internal error 1 in L2Color");
708 >
709 >        if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
710 >                quiterr("error reading TIFF input");
711 >                                        /* also works for float greyscale */
712 >        for (x = cvts.xmax; x--; ) {
713 >                register float  f = cvts.t.fp[x];
714 >                if (cvts.bradj) f *= m;
715 >                setcolor(cvts.r.colors[x], f, f, f);
716 >        }
717 >        if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
718 >                quiterr("error writing Radiance picture");
719 > }
720 >
721 >
722 > void
723   RGB2Colr(y)                     /* read/convert/write RGB->COLR scanline */
724   uint32  y;
725   {
726          COLOR   ctmp;
727          register int    x;
728  
729 <        if (CHK(C_RFLT|C_TFLT|C_GRY))
729 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY))
730                  quiterr("internal error 1 in RGB2Colr");
731  
732          if (cvts.pconf == PLANARCONFIG_CONTIG) {
# Line 579 | Line 741 | uint32 y;
741                  if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
742                          goto readerr;
743                  if (TIFFReadScanline(cvts.tif,
744 <                                (tidata_t)(cvts.t.bp + cvts.xmax), y, 1) < 0)
744 >                                (tdata_t)(cvts.t.bp + cvts.xmax), y, 1) < 0)
745                          goto readerr;
746                  if (TIFFReadScanline(cvts.tif,
747 <                                (tidata_t)(cvts.t.bp + 2*cvts.xmax), y, 2) < 0)
747 >                                (tdata_t)(cvts.t.bp + 2*cvts.xmax), y, 2) < 0)
748                          goto readerr;
749                  for (x = cvts.xmax; x--; ) {
750                          cvts.r.colrs[x][RED] = cvts.t.bp[x];
# Line 613 | Line 775 | readerr:
775   }
776  
777  
778 < int
778 > void
779   Gry2Colr(y)                     /* read/convert/write G8->COLR scanline */
780   uint32  y;
781   {
782          register int    x;
783  
784 <        if (CHK(C_RFLT|C_TFLT) | !CHK(C_GRY))
784 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY)
785                  quiterr("internal error 1 in Gry2Colr");
786  
787          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
# Line 639 | Line 801 | uint32 y;
801   }
802  
803  
804 < int
805 < Color2L(y)                      /* read/convert/write COLOR->L16 scanline */
804 > void
805 > GGry2Color(y)                   /* read/convert/write G16->COLOR scanline */
806   uint32  y;
807   {
808 <        double  m = pow(2.,(double)cvts.bradj);
808 >        int     dogamma = cvts.gamcor < 0.99 | cvts.gamcor > 1.01;
809 >        double  m;
810 >        register double d;
811          register int    x;
812  
813 <        if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | !CHK(C_GRY))
813 >        if (CHK(C_TFLT|C_TWRD|C_GRY|C_RFLT) != (C_GRY|C_RFLT|C_TWRD))
814 >                quiterr("internal error 1 in GGry2Color");
815 >
816 >        if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
817 >                quiterr("error reading TIFF input");
818 >
819 >        if (cvts.bradj)
820 >                m = pow(2., (double)cvts.bradj);
821 >        for (x = cvts.xmax; x--; ) {
822 >                d = (cvts.t.wp[x] + 0.5)*(1./(1L<<16));
823 >                if (dogamma) d = pow(d, cvts.gamcor);
824 >                if (cvts.bradj) d *= m;
825 >                colval(cvts.r.colors[x],RED) =
826 >                colval(cvts.r.colors[x],GRN) =
827 >                colval(cvts.r.colors[x],BLU) = d;
828 >        }
829 >        if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
830 >                quiterr("error writing Radiance picture");
831 > }
832 >
833 >
834 > void
835 > Color2GGry(y)                   /* read/convert/write COLOR->G16 scanline */
836 > uint32  y;
837 > {
838 >        int     dogamma = cvts.gamcor < 0.99 | cvts.gamcor > 1.01;
839 >        float   m = pow(2.,(double)cvts.bradj);
840 >        register int    x;
841 >
842 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TWRD|C_GRY))
843 >                quiterr("internal error 1 in Color2GGry");
844 >
845 >        if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
846 >                quiterr("error reading Radiance picture");
847 >
848 >        for (x = cvts.xmax; x--; ) {
849 >                register float  f = m*( CHK(C_XYZE) ?
850 >                                                colval(cvts.r.colors[x],CIEY)
851 >                                                : bright(cvts.r.colors[x]) );
852 >                if (f <= 0)
853 >                        cvts.t.wp[x] = 0;
854 >                else if (f >= 1)
855 >                        cvts.t.wp[x] = 0xffff;
856 >                else if (dogamma)
857 >                        cvts.t.wp[x] = (int)((float)(1L<<16) *
858 >                                                pow(f, 1./cvts.gamcor));
859 >                else
860 >                        cvts.t.wp[x] = (int)((float)(1L<<16) * f);
861 >        }
862 >
863 >        if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
864 >                quiterr("error writing TIFF output");
865 > }
866 >
867 >
868 > void
869 > Color2L(y)                      /* read/convert/write COLOR->Lfloat scanline */
870 > uint32  y;
871 > {
872 >        float   m = pow(2.,(double)cvts.bradj);
873 >        register int    x;
874 >
875 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
876                  quiterr("internal error 1 in Color2L");
877  
878          if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
# Line 661 | Line 887 | uint32 y;
887   }
888  
889  
890 < int
890 > void
891   Color2Luv(y)                    /* read/convert/write COLOR->Luv scanline */
892   uint32  y;
893   {
894          register int    x;
895  
896 <        if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | CHK(C_GRY))
896 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT))
897                  quiterr("internal error 1 in Color2Luv");
898  
899          if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
# Line 682 | Line 908 | uint32 y;
908                  for (x = cvts.xmax; x--; )
909                          scalecolor(cvts.r.colors[x], m);
910          }
911 <
911 >                                        /* also works for float RGB */
912          for (x = cvts.xmax; x--; ) {
913 <                cvts.t.fp[3*x] = colval(cvts.r.colors[x],RED);
914 <                cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],GRN);
915 <                cvts.t.fp[3*x+2] = colval(cvts.r.colors[x],BLU);
913 >                cvts.t.fp[3*x] = colval(cvts.r.colors[x],CIEX);
914 >                cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],CIEY);
915 >                cvts.t.fp[3*x+2] = colval(cvts.r.colors[x],CIEZ);
916          }
917  
918          if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
# Line 694 | Line 920 | uint32 y;
920   }
921  
922  
923 < int
923 > void
924 > Color2RRGGBB(y)                 /* read/convert/write COLOR->RGB16 scanline */
925 > uint32  y;
926 > {
927 >        int     dogamma = cvts.gamcor < 0.99 | cvts.gamcor > 1.01;
928 >        float   m = pow(2.,(double)cvts.bradj);
929 >        register int    x, i;
930 >
931 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TWRD))
932 >                quiterr("internal error 1 in Color2RRGGBB");
933 >
934 >        if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
935 >                quiterr("error reading Radiance picture");
936 >
937 >        for (x = cvts.xmax; x--; )
938 >            for (i = 3; i--; ) {
939 >                register float  f = m*colval(cvts.r.colors[x],i);
940 >                if (f <= 0)
941 >                        cvts.t.wp[3*x + i] = 0;
942 >                else if (f >= 1)
943 >                        cvts.t.wp[3*x + i] = 0xffff;
944 >                else if (dogamma)
945 >                        cvts.t.wp[3*x + i] = (int)((float)(1L<<16) *
946 >                                                pow(f, 1./cvts.gamcor));
947 >                else
948 >                        cvts.t.wp[3*x + i] = (int)((float)(1L<<16)*f);
949 >            }
950 >
951 >        if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
952 >                quiterr("error writing TIFF output");
953 > }
954 >
955 >
956 > void
957   Colr2Gry(y)                     /* read/convert/write COLR->RGB scanline */
958   uint32  y;
959   {
960          register int    x;
961  
962 <        if (CHK(C_RFLT|C_TFLT) | !CHK(C_GRY))
962 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY)
963                  quiterr("internal error 1 in Colr2Gry");
964  
965          if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)
# Line 720 | Line 979 | uint32 y;
979   }
980  
981  
982 < int
982 > void
983   Colr2RGB(y)                     /* read/convert/write COLR->RGB scanline */
984   uint32  y;
985   {
986          COLOR   ctmp;
987          register int    x;
988  
989 <        if (CHK(C_RFLT|C_TFLT|C_GRY))
989 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY))
990                  quiterr("internal error 1 in Colr2RGB");
991  
992          if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines