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.13 by gregl, Wed Aug 27 11:10:45 1997 UTC vs.
Revision 2.27 by schorsch, Fri Jan 2 12:47:01 2004 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  <time.h>
14 + #include  <string.h>
15 +
16   #include  "tiffio.h"
17   #include  "color.h"
18   #include  "resolu.h"
19  
20   #define  GAMCOR         2.2             /* default gamma */
21  
20 #ifndef malloc
21 extern char  *malloc();
22 #endif
22                                  /* conversion flags */
23   #define C_CXFM          0x1             /* needs color transformation */
24   #define C_GAMUT         0x2             /* needs gamut mapping */
# Line 28 | Line 27 | extern char  *malloc();
27   #define C_XYZE          0x10            /* Radiance is XYZE */
28   #define C_RFLT          0x20            /* Radiance data is float */
29   #define C_TFLT          0x40            /* TIFF data is float */
30 < #define C_PRIM          0x80            /* has assigned primaries */
30 > #define C_TWRD          0x80            /* TIFF data is 16-bit */
31 > #define C_PRIM          0x100           /* has assigned primaries */
32  
33   struct {
34          uint16  flags;          /* conversion flags (defined above) */
35 +        char    capdate[20];    /* capture date/time */
36 +        char    owner[256];     /* content owner */
37          uint16  comp;           /* TIFF compression type */
38          uint16  phot;           /* TIFF photometric type */
39          uint16  pconf;          /* TIFF planar configuration */
# Line 52 | Line 54 | struct {
54          } r;                    /* Radiance scanline */
55          union {
56                  uint8   *bp;            /* byte pointer */
57 +                uint16  *wp;            /* word pointer */
58                  float   *fp;            /* float pointer */
59                  char    *p;             /* generic pointer */
60          } t;                    /* TIFF scanline */
61 <        int     (*tf)();        /* translation procedure */
61 >        void    (*tf)();        /* translation procedure */
62   }       cvts = {        /* conversion structure */
63 <        0, COMPRESSION_NONE, PHOTOMETRIC_RGB,
63 >        0, "", "", COMPRESSION_NONE, PHOTOMETRIC_RGB,
64          PLANARCONFIG_CONTIG, GAMCOR, 0, 1, 1., 1.,
65   };
66  
# Line 66 | Line 69 | struct {
69   #define CLR(f)          (cvts.flags &= ~(f))
70   #define TGL(f)          (cvts.flags ^= (f))
71  
72 < int     Luv2Color(), L2Color(), RGB2Colr(), Gry2Colr();
73 < int     Color2Luv(), Color2L(), Colr2RGB(), Colr2Gry();
72 > void    Luv2Color(), L2Color(), RGB2Colr(), Gry2Colr();
73 > void    Color2Luv(), Color2L(), Colr2RGB(), Colr2Gry();
74 > void    RRGGBB2Color(), GGry2Color(), Color2RRGGBB(), Color2GGry();
75  
76 + #define RfGfBf2Color    Luv2Color
77 + #define Gryf2Color      L2Color
78 + #define Color2Gryf      Color2L
79 + #define Color2RfGfBf    Color2Luv
80 +
81   short   ortab[8] = {            /* orientation conversion table */
82          YMAJOR|YDECR,
83          YMAJOR|YDECR|XDECR,
# Line 82 | Line 91 | short  ortab[8] = {            /* orientation conversion table */
91  
92   #define pixorder()      ortab[cvts.orient-1]
93  
94 + extern char     TMSTR[];        /* "CAPDATE=" from header.c */
95 + char            OWNSTR[] = "OWNER=";
96 +
97   char  *progname;
98  
99 + static gethfunc headline;
100  
101 +
102   main(argc, argv)
103   int  argc;
104   char  *argv[];
# Line 114 | Line 128 | char  *argv[];
128                                  cvts.comp = COMPRESSION_SGILOG24;
129                                  cvts.phot = PHOTOMETRIC_LOGLUV;
130                                  break;
131 +                        case 'w':               /* 16-bit/primary output? */
132 +                                TGL(C_TWRD);
133 +                                break;
134 +                        case 'f':               /* IEEE float output? */
135 +                                TGL(C_TFLT);
136 +                                break;
137                          case 'b':               /* greyscale output? */
138                                  TGL(C_GRY);
139                                  break;
# Line 144 | Line 164 | doneopts:
164  
165                  if (i != argc-2)
166                          goto userr;
167 <
168 <                if (CHK(C_GRY))         /* consistency corrections */
167 >                                                /* consistency checks */
168 >                if (CHK(C_GRY)) {
169                          if (cvts.phot == PHOTOMETRIC_RGB)
170                                  cvts.phot = PHOTOMETRIC_MINISBLACK;
171                          else {
172                                  cvts.phot = PHOTOMETRIC_LOGL;
173                                  cvts.comp = COMPRESSION_SGILOG;
174                          }
175 +                }
176 +                if (CHK(C_TWRD|C_TFLT) == (C_TWRD|C_TFLT))
177 +                        goto userr;
178  
179                  ra2tiff(i, argv);
180          }
# Line 159 | Line 182 | doneopts:
182          exit(0);
183   userr:
184          fprintf(stderr,
185 <        "Usage: %s [-z|-L|-l][-b][-e +/-stops][-g gamma] {in.pic|-} out.tif\n",
185 >        "Usage: %s [-z|-L|-l|-f|-w][-b][-e +/-stops][-g gamma] {in.pic|-} out.tif\n",
186                          progname);
187          fprintf(stderr,
188          "   Or: %s -r [-x][-e +/-stops][-g gamma] in.tif [out.pic|-]\n",
# Line 184 | Line 207 | allocbufs()                    /* allocate scanline buffers */
207          int     rsiz, tsiz;
208  
209          rsiz = CHK(C_RFLT) ? sizeof(COLOR) : sizeof(COLR);
210 <        tsiz = (CHK(C_TFLT) ? sizeof(float) : sizeof(uint8)) *
210 >        tsiz = (CHK(C_TFLT) ? sizeof(float) :
211 >                        CHK(C_TWRD) ? sizeof(uint16) : sizeof(uint8)) *
212                          (CHK(C_GRY) ? 1 : 3);
213          cvts.r.p = (char *)malloc(rsiz*cvts.xmax);
214          cvts.t.p = (char *)malloc(tsiz*cvts.xmax);
215 <        if (cvts.r.p == NULL | cvts.t.p == NULL)
215 >        if ((cvts.r.p == NULL) | (cvts.t.p == NULL))
216                  quiterr("no memory to allocate scanline buffers");
217   }
218  
# Line 196 | Line 220 | allocbufs()                    /* allocate scanline buffers */
220   initfromtif()           /* initialize conversion from TIFF input */
221   {
222          uint16  hi;
223 +        char    *cp;
224          float   *fa, f1, f2;
225  
226 <        CLR(C_GRY|C_GAMMA|C_PRIM|C_RFLT|C_TFLT|C_CXFM);
226 >        CLR(C_GRY|C_GAMMA|C_PRIM|C_RFLT|C_TFLT|C_TWRD|C_CXFM);
227  
228          TIFFGetFieldDefaulted(cvts.tif, TIFFTAG_PLANARCONFIG, &cvts.pconf);
229  
# Line 261 | Line 286 | initfromtif()          /* initialize conversion from TIFF inpu
286                          quiterr("unsupported photometric type");
287                  /* fall through */
288          case PHOTOMETRIC_RGB:
289 <                SET(C_GAMMA|C_GAMUT);
289 >                SET(C_GAMMA);
290                  setcolrgam(cvts.gamcor);
291                  if (CHK(C_XYZE)) {
292 <                        comprgb2xyzmat(cvts.cmat,
292 >                        comprgb2xyzWBmat(cvts.cmat,
293                                          CHK(C_PRIM) ? cvts.prims : stdprims);
294                          SET(C_CXFM);
295                  }
296                  if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) ||
297                                  hi != 3)
298                          quiterr("unsupported samples per pixel for RGB");
299 <                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) ||
300 <                                hi != 8)
299 >                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi))
300 >                        hi = -1;
301 >                switch (hi) {
302 >                case 8:
303 >                        cvts.tf = RGB2Colr;
304 >                        break;
305 >                case 16:
306 >                        cvts.tf = RRGGBB2Color;
307 >                        SET(C_RFLT|C_TWRD);
308 >                        break;
309 >                case 32:
310 >                        cvts.tf = RfGfBf2Color;
311 >                        SET(C_RFLT|C_TFLT);
312 >                        break;
313 >                default:
314                          quiterr("unsupported bits per sample for RGB");
315 <                cvts.tf = RGB2Colr;
315 >                }
316                  break;
317          case PHOTOMETRIC_MINISBLACK:
318 <                SET(C_GRY|C_GAMMA|C_GAMUT);
318 >                SET(C_GRY|C_GAMMA);
319 >                setcolrgam(cvts.gamcor);
320                  cvts.pconf = PLANARCONFIG_CONTIG;
321                  if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) ||
322                                  hi != 1)
323                          quiterr("unsupported samples per pixel for greyscale");
324 <                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) ||
325 <                                hi != 8)
326 <                        quiterr("unsupported bits per sample for greyscale");
327 <                cvts.tf = Gry2Colr;
324 >                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi))
325 >                        hi = -1;
326 >                switch (hi) {
327 >                case 8:
328 >                        cvts.tf = Gry2Colr;
329 >                        break;
330 >                case 16:
331 >                        cvts.tf = GGry2Color;
332 >                        SET(C_RFLT|C_TWRD);
333 >                        break;
334 >                case 32:
335 >                        cvts.tf = Gryf2Color;
336 >                        SET(C_RFLT|C_TFLT);
337 >                        break;
338 >                default:
339 >                        quiterr("unsupported bits per sample for Gray");
340 >                }
341                  break;
342          default:
343                  quiterr("unsupported photometric type");
# Line 298 | Line 350 | initfromtif()          /* initialize conversion from TIFF inpu
350  
351          if (!TIFFGetField(cvts.tif, TIFFTAG_STONITS, &cvts.stonits))
352                  cvts.stonits = 1.;
353 +
354 +        if (!TIFFGetField(cvts.tif, TIFFTAG_DATETIME, &cp))
355 +                cvts.capdate[0] = '\0';
356 +        else {
357 +                strncpy(cvts.capdate, cp, 19);
358 +                cvts.capdate[19] = '\0';
359 +        }
360 +        if (!TIFFGetField(cvts.tif, TIFFTAG_ARTIST, &cp))
361 +                cvts.owner[0] = '\0';
362 +        else {
363 +                strncpy(cvts.owner, cp, sizeof(cvts.owner));
364 +                cvts.owner[sizeof(cvts.owner)-1] = '\0';
365 +        }
366                                          /* add to Radiance header */
367          if (cvts.pixrat < .99 || cvts.pixrat > 1.01)
368                  fputaspect(cvts.pixrat, cvts.rfp);
# Line 311 | Line 376 | initfromtif()          /* initialize conversion from TIFF inpu
376                                  cvts.rfp);
377                  fputformat(COLRFMT, cvts.rfp);
378          }
379 +        if (cvts.capdate[0])
380 +                fprintf(cvts.rfp, "%s %s\n", TMSTR, cvts.capdate);
381 +        if (cvts.owner[0])
382 +                fprintf(cvts.rfp, "%s %s\n", OWNSTR, cvts.owner);
383  
384          allocbufs();                    /* allocate scanline buffers */
385   }
# Line 346 | Line 415 | char  *av[];
415   }
416  
417  
418 < int
419 < headline(s)                     /* process Radiance input header line */
420 < char    *s;
418 > static int
419 > headline(                       /* process Radiance input header line */
420 >        char    *s,
421 >        void    *p
422 > )
423   {
424 +        static int      tmstrlen = 0;
425 +        static int      ownstrlen = 0;
426          char    fmt[32];
427  
428 +        if (!tmstrlen)
429 +                tmstrlen = strlen(TMSTR);
430 +        if (!ownstrlen)
431 +                ownstrlen = strlen(OWNSTR);
432          if (formatval(fmt, s)) {
433                  if (!strcmp(fmt, COLRFMT))
434                          CLR(C_XYZE);
# Line 359 | Line 436 | char   *s;
436                          SET(C_XYZE);
437                  else
438                          quiterr("unrecognized input picture format");
439 <                return;
439 >                return(1);
440          }
441          if (isexpos(s)) {
442                  cvts.stonits /= exposval(s);
443 <                return;
443 >                return(1);
444          }
445          if (isaspect(s)) {
446                  cvts.pixrat *= aspectval(s);
447 <                return;
447 >                return(1);
448          }
449          if (isprims(s)) {
450                  primsval(cvts.prims, s);
451                  SET(C_PRIM);
452 <                return;
452 >                return(1);
453          }
454 +        if (isdate(s)) {
455 +                if (s[tmstrlen] == ' ')
456 +                        strncpy(cvts.capdate, s+tmstrlen+1, 19);
457 +                else
458 +                        strncpy(cvts.capdate, s+tmstrlen, 19);
459 +                cvts.capdate[19] = '\0';
460 +                return(1);
461 +        }
462 +        if (!strncmp(s, OWNSTR, ownstrlen)) {
463 +                register char   *cp = s + ownstrlen;
464 +
465 +                while (isspace(*cp))
466 +                        ++cp;
467 +                strncpy(cvts.owner, cp, sizeof(cvts.owner));
468 +                cvts.owner[sizeof(cvts.owner)-1] = '\0';
469 +                for (cp = cvts.owner; *cp; cp++)
470 +                        ;
471 +                while (cp > cvts.owner && isspace(cp[-1]))
472 +                        *--cp = '\0';
473 +                return(1);
474 +        }
475 +        return(0);
476   }
477  
478  
# Line 381 | Line 480 | initfromrad()                  /* initialize input from a Radiance pi
480   {
481          int     i1, i2, po;
482                                                  /* read Radiance header */
483 <        CLR(C_RFLT|C_TFLT|C_XYZE|C_PRIM|C_GAMMA|C_CXFM);
483 >        CLR(C_RFLT|C_XYZE|C_PRIM|C_GAMMA|C_CXFM);
484 >        cvts.capdate[0] = '\0';
485 >        cvts.owner[0] = '\0';
486          cvts.stonits = 1.;
487          cvts.pixrat = 1.;
488          cvts.pconf = PLANARCONFIG_CONTIG;
# Line 407 | Line 508 | initfromrad()                  /* initialize input from a Radiance pi
508          switch (cvts.phot) {
509          case PHOTOMETRIC_LOGLUV:
510                  SET(C_RFLT|C_TFLT);
511 <                CLR(C_GRY);
511 >                CLR(C_GRY|C_TWRD);
512                  if (!CHK(C_XYZE)) {
513 <                        cpcolormat(cvts.cmat, rgb2xyzmat);
513 >                        comprgb2xyzWBmat(cvts.cmat,
514 >                                        CHK(C_PRIM) ? cvts.prims : stdprims);
515                          SET(C_CXFM);
516                  }
517                  if (cvts.comp != COMPRESSION_SGILOG &&
# Line 421 | Line 523 | initfromrad()                  /* initialize input from a Radiance pi
523                  break;
524          case PHOTOMETRIC_LOGL:
525                  SET(C_GRY|C_RFLT|C_TFLT);
526 +                CLR(C_TWRD);
527                  if (cvts.comp != COMPRESSION_SGILOG)    
528                          quiterr("internal error 3 in initfromrad");
529                  TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
# Line 432 | Line 535 | initfromrad()                  /* initialize input from a Radiance pi
535                  CLR(C_GRY);
536                  setcolrgam(cvts.gamcor);
537                  if (CHK(C_XYZE)) {
538 <                        compxyz2rgbmat(cvts.cmat,
538 >                        compxyz2rgbWBmat(cvts.cmat,
539                                          CHK(C_PRIM) ? cvts.prims : stdprims);
540                          SET(C_CXFM);
541                  }
# Line 442 | Line 545 | initfromrad()                  /* initialize input from a Radiance pi
545                          TIFFSetField(cvts.tif, TIFFTAG_WHITEPOINT,
546                                          (float *)cvts.prims[WHT]);
547                  }
548 <                cvts.tf = Colr2RGB;
548 >                if (CHK(C_TWRD)) {
549 >                        cvts.tf = Color2RRGGBB;
550 >                        SET(C_RFLT);
551 >                } else if (CHK(C_TFLT)) {
552 >                        TIFFSetField(cvts.tif, TIFFTAG_SAMPLEFORMAT,
553 >                                        SAMPLEFORMAT_IEEEFP);
554 >                        cvts.tf = Color2RfGfBf;
555 >                        SET(C_RFLT);
556 >                } else
557 >                        cvts.tf = Colr2RGB;
558                  break;
559          case PHOTOMETRIC_MINISBLACK:
560                  SET(C_GRY|C_GAMMA|C_GAMUT);
561                  setcolrgam(cvts.gamcor);
562 <                cvts.tf = Colr2Gry;
562 >                if (CHK(C_TWRD)) {
563 >                        cvts.tf = Color2GGry;
564 >                        SET(C_RFLT);
565 >                } else if (CHK(C_TFLT)) {
566 >                        TIFFSetField(cvts.tif, TIFFTAG_SAMPLEFORMAT,
567 >                                        SAMPLEFORMAT_IEEEFP);
568 >                        cvts.tf = Color2Gryf;
569 >                        SET(C_RFLT);
570 >                } else
571 >                        cvts.tf = Colr2Gry;
572                  break;
573          default:
574                  quiterr("internal error 4 in initfromrad");
# Line 457 | Line 578 | initfromrad()                  /* initialize input from a Radiance pi
578          TIFFSetField(cvts.tif, TIFFTAG_IMAGEWIDTH, cvts.xmax);
579          TIFFSetField(cvts.tif, TIFFTAG_IMAGELENGTH, cvts.ymax);
580          TIFFSetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, CHK(C_GRY) ? 1 : 3);
581 <        TIFFSetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, CHK(C_TFLT) ? 32 : 8);
581 >        TIFFSetField(cvts.tif, TIFFTAG_BITSPERSAMPLE,
582 >                        CHK(C_TFLT) ? 32 : CHK(C_TWRD) ? 16 : 8);
583          TIFFSetField(cvts.tif, TIFFTAG_XRESOLUTION, 72.);
584          TIFFSetField(cvts.tif, TIFFTAG_YRESOLUTION, 72./cvts.pixrat);
585          TIFFSetField(cvts.tif, TIFFTAG_ORIENTATION, cvts.orient);
# Line 465 | Line 587 | initfromrad()                  /* initialize input from a Radiance pi
587          TIFFSetField(cvts.tif, TIFFTAG_PLANARCONFIG, cvts.pconf);
588          TIFFSetField(cvts.tif, TIFFTAG_STONITS,
589                          cvts.stonits/pow(2.,(double)cvts.bradj));
590 +        if (cvts.capdate[0])
591 +                TIFFSetField(cvts.tif, TIFFTAG_DATETIME, cvts.capdate);
592 +        if (cvts.owner[0])
593 +                TIFFSetField(cvts.tif, TIFFTAG_ARTIST, cvts.owner);
594          if (cvts.comp == COMPRESSION_NONE)
595                  i1 = TIFFScanlineSize(cvts.tif);
596          else
# Line 501 | Line 627 | char  *av[];
627   }
628  
629  
630 < int
630 > void
631   Luv2Color(y)                    /* read/convert/write Luv->COLOR scanline */
632   uint32  y;
633   {
634          register int    x;
635  
636 <        if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | CHK(C_GRY))
636 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT))
637                  quiterr("internal error 1 in Luv2Color");
638  
639          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
640                  quiterr("error reading TIFF input");
641 <        
641 >                                        /* also works for float RGB */
642          for (x = cvts.xmax; x--; ) {
643 <                cvts.r.colors[x][RED] = cvts.t.fp[3*x];
644 <                cvts.r.colors[x][GRN] = cvts.t.fp[3*x + 1];
645 <                cvts.r.colors[x][BLU] = cvts.t.fp[3*x + 2];
643 >                setcolor(cvts.r.colors[x],
644 >                                cvts.t.fp[3*x],
645 >                                cvts.t.fp[3*x + 1],
646 >                                cvts.t.fp[3*x + 2]);
647                  if (CHK(C_CXFM))
648                          colortrans(cvts.r.colors[x], cvts.cmat,
649                                          cvts.r.colors[x]);
# Line 535 | Line 662 | uint32 y;
662   }
663  
664  
665 < int
666 < L2Color(y)                      /* read/convert/write L16->COLOR scanline */
665 > void
666 > RRGGBB2Color(y)                 /* read/convert/write RGB16->COLOR scanline */
667   uint32  y;
668   {
669 +        int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01);
670 +        register double d;
671          register int    x;
672  
673 <        if (CHK(C_RFLT|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
674 <                quiterr("internal error 1 in L2Color");
673 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_TWRD|C_RFLT))
674 >                quiterr("internal error 1 in RRGGBB2Color");
675  
676          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
677                  quiterr("error reading TIFF input");
678          
679 <        for (x = cvts.xmax; x--; )
680 <                cvts.r.colors[x][RED] =
681 <                cvts.r.colors[x][GRN] =
682 <                cvts.r.colors[x][BLU] = cvts.t.fp[x] > 0. ? cvts.t.fp[x] : 0.;
679 >        for (x = cvts.xmax; x--; ) {
680 >                d = (cvts.t.wp[3*x] + 0.5)*(1./(1L<<16));
681 >                if (dogamma) d = pow(d, cvts.gamcor);
682 >                colval(cvts.r.colors[x],RED) = d;
683 >                d = (cvts.t.wp[3*x + 1] + 0.5)*(1./(1L<<16));
684 >                if (dogamma) d = pow(d, cvts.gamcor);
685 >                colval(cvts.r.colors[x],GRN) = d;
686 >                d = (cvts.t.wp[3*x + 2] + 0.5)*(1./(1L<<16));
687 >                if (dogamma) d = pow(d, cvts.gamcor);
688 >                colval(cvts.r.colors[x],BLU) = d;
689 >                if (CHK(C_CXFM))
690 >                        colortrans(cvts.r.colors[x], cvts.cmat,
691 >                                        cvts.r.colors[x]);
692 >                if (CHK(C_GAMUT))
693 >                        clipgamut(cvts.r.colors[x], cvts.t.fp[3*x + 1],
694 >                                        CGAMUT_LOWER, cblack, cwhite);
695 >        }
696 >        if (cvts.bradj) {
697 >                d = pow(2.,(double)cvts.bradj);
698 >                for (x = cvts.xmax; x--; )
699 >                        scalecolor(cvts.r.colors[x], d);
700 >        }
701  
702          if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
703                  quiterr("error writing Radiance picture");
704   }
705  
706  
707 < int
707 > void
708 > L2Color(y)                      /* read/convert/write Lfloat->COLOR scanline */
709 > uint32  y;
710 > {
711 >        float   m = pow(2., (double)cvts.bradj);
712 >        register int    x;
713 >
714 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
715 >                quiterr("internal error 1 in L2Color");
716 >
717 >        if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
718 >                quiterr("error reading TIFF input");
719 >                                        /* also works for float greyscale */
720 >        for (x = cvts.xmax; x--; ) {
721 >                register float  f = cvts.t.fp[x];
722 >                if (cvts.bradj) f *= m;
723 >                setcolor(cvts.r.colors[x], f, f, f);
724 >        }
725 >        if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
726 >                quiterr("error writing Radiance picture");
727 > }
728 >
729 >
730 > void
731   RGB2Colr(y)                     /* read/convert/write RGB->COLR scanline */
732   uint32  y;
733   {
734          COLOR   ctmp;
735          register int    x;
736  
737 <        if (CHK(C_RFLT|C_TFLT|C_GRY))
737 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY))
738                  quiterr("internal error 1 in RGB2Colr");
739  
740          if (cvts.pconf == PLANARCONFIG_CONTIG) {
# Line 579 | Line 749 | uint32 y;
749                  if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
750                          goto readerr;
751                  if (TIFFReadScanline(cvts.tif,
752 <                                (tidata_t)(cvts.t.bp + cvts.xmax), y, 1) < 0)
752 >                                (tdata_t)(cvts.t.bp + cvts.xmax), y, 1) < 0)
753                          goto readerr;
754                  if (TIFFReadScanline(cvts.tif,
755 <                                (tidata_t)(cvts.t.bp + 2*cvts.xmax), y, 2) < 0)
755 >                                (tdata_t)(cvts.t.bp + 2*cvts.xmax), y, 2) < 0)
756                          goto readerr;
757                  for (x = cvts.xmax; x--; ) {
758                          cvts.r.colrs[x][RED] = cvts.t.bp[x];
# Line 613 | Line 783 | readerr:
783   }
784  
785  
786 < int
786 > void
787   Gry2Colr(y)                     /* read/convert/write G8->COLR scanline */
788   uint32  y;
789   {
790          register int    x;
791  
792 <        if (CHK(C_RFLT|C_TFLT) | !CHK(C_GRY))
792 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY)
793                  quiterr("internal error 1 in Gry2Colr");
794  
795          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
# Line 639 | Line 809 | uint32 y;
809   }
810  
811  
812 < int
813 < Color2L(y)                      /* read/convert/write COLOR->L16 scanline */
812 > void
813 > GGry2Color(y)                   /* read/convert/write G16->COLOR scanline */
814   uint32  y;
815   {
816 <        double  m = pow(2.,(double)cvts.bradj);
816 >        int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01);
817 >        double  m;
818 >        register double d;
819          register int    x;
820  
821 <        if (CHK(C_RFLT|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
821 >        if (CHK(C_TFLT|C_TWRD|C_GRY|C_RFLT) != (C_GRY|C_RFLT|C_TWRD))
822 >                quiterr("internal error 1 in GGry2Color");
823 >
824 >        if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
825 >                quiterr("error reading TIFF input");
826 >
827 >        if (cvts.bradj)
828 >                m = pow(2., (double)cvts.bradj);
829 >        for (x = cvts.xmax; x--; ) {
830 >                d = (cvts.t.wp[x] + 0.5)*(1./(1L<<16));
831 >                if (dogamma) d = pow(d, cvts.gamcor);
832 >                if (cvts.bradj) d *= m;
833 >                colval(cvts.r.colors[x],RED) =
834 >                colval(cvts.r.colors[x],GRN) =
835 >                colval(cvts.r.colors[x],BLU) = d;
836 >        }
837 >        if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
838 >                quiterr("error writing Radiance picture");
839 > }
840 >
841 >
842 > void
843 > Color2GGry(y)                   /* read/convert/write COLOR->G16 scanline */
844 > uint32  y;
845 > {
846 >        int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01);
847 >        float   m = pow(2.,(double)cvts.bradj);
848 >        register int    x;
849 >
850 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TWRD|C_GRY))
851 >                quiterr("internal error 1 in Color2GGry");
852 >
853 >        if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
854 >                quiterr("error reading Radiance picture");
855 >
856 >        for (x = cvts.xmax; x--; ) {
857 >                register float  f = m*( CHK(C_XYZE) ?
858 >                                                colval(cvts.r.colors[x],CIEY)
859 >                                                : bright(cvts.r.colors[x]) );
860 >                if (f <= 0)
861 >                        cvts.t.wp[x] = 0;
862 >                else if (f >= 1)
863 >                        cvts.t.wp[x] = 0xffff;
864 >                else if (dogamma)
865 >                        cvts.t.wp[x] = (int)((float)(1L<<16) *
866 >                                                pow(f, 1./cvts.gamcor));
867 >                else
868 >                        cvts.t.wp[x] = (int)((float)(1L<<16) * f);
869 >        }
870 >
871 >        if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
872 >                quiterr("error writing TIFF output");
873 > }
874 >
875 >
876 > void
877 > Color2L(y)                      /* read/convert/write COLOR->Lfloat scanline */
878 > uint32  y;
879 > {
880 >        float   m = pow(2.,(double)cvts.bradj);
881 >        register int    x;
882 >
883 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
884                  quiterr("internal error 1 in Color2L");
885  
886          if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
# Line 661 | Line 895 | uint32 y;
895   }
896  
897  
898 < int
898 > void
899   Color2Luv(y)                    /* read/convert/write COLOR->Luv scanline */
900   uint32  y;
901   {
902          register int    x;
903  
904 <        if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | CHK(C_GRY))
904 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT))
905                  quiterr("internal error 1 in Color2Luv");
906  
907          if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
# Line 682 | Line 916 | uint32 y;
916                  for (x = cvts.xmax; x--; )
917                          scalecolor(cvts.r.colors[x], m);
918          }
919 <
919 >                                        /* also works for float RGB */
920          for (x = cvts.xmax; x--; ) {
921 <                cvts.t.fp[3*x] = colval(cvts.r.colors[x],RED);
922 <                cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],GRN);
923 <                cvts.t.fp[3*x+2] = colval(cvts.r.colors[x],BLU);
921 >                cvts.t.fp[3*x] = colval(cvts.r.colors[x],CIEX);
922 >                cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],CIEY);
923 >                cvts.t.fp[3*x+2] = colval(cvts.r.colors[x],CIEZ);
924          }
925  
926          if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
# Line 694 | Line 928 | uint32 y;
928   }
929  
930  
931 < int
931 > void
932 > Color2RRGGBB(y)                 /* read/convert/write COLOR->RGB16 scanline */
933 > uint32  y;
934 > {
935 >        int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01);
936 >        float   m = pow(2.,(double)cvts.bradj);
937 >        register int    x, i;
938 >
939 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TWRD))
940 >                quiterr("internal error 1 in Color2RRGGBB");
941 >
942 >        if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
943 >                quiterr("error reading Radiance picture");
944 >
945 >        for (x = cvts.xmax; x--; )
946 >            for (i = 3; i--; ) {
947 >                register float  f = m*colval(cvts.r.colors[x],i);
948 >                if (f <= 0)
949 >                        cvts.t.wp[3*x + i] = 0;
950 >                else if (f >= 1)
951 >                        cvts.t.wp[3*x + i] = 0xffff;
952 >                else if (dogamma)
953 >                        cvts.t.wp[3*x + i] = (int)((float)(1L<<16) *
954 >                                                pow(f, 1./cvts.gamcor));
955 >                else
956 >                        cvts.t.wp[3*x + i] = (int)((float)(1L<<16)*f);
957 >            }
958 >
959 >        if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
960 >                quiterr("error writing TIFF output");
961 > }
962 >
963 >
964 > void
965   Colr2Gry(y)                     /* read/convert/write COLR->RGB scanline */
966   uint32  y;
967   {
968          register int    x;
969  
970 <        if (CHK(C_RFLT|C_TFLT) | !CHK(C_GRY))
970 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY)
971                  quiterr("internal error 1 in Colr2Gry");
972  
973          if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)
# Line 720 | Line 987 | uint32 y;
987   }
988  
989  
990 < int
990 > void
991   Colr2RGB(y)                     /* read/convert/write COLR->RGB scanline */
992   uint32  y;
993   {
994          COLOR   ctmp;
995          register int    x;
996  
997 <        if (CHK(C_RFLT|C_TFLT|C_GRY))
997 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY))
998                  quiterr("internal error 1 in Colr2RGB");
999  
1000          if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines