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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines