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.20 by greg, Sat Feb 22 02:07:28 2003 UTC vs.
Revision 2.24 by greg, Wed Jul 16 01:32:53 2003 UTC

# Line 9 | Line 9 | static const char      RCSid[] = "$Id$";
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"
# Line 29 | Line 30 | static const char      RCSid[] = "$Id$";
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 53 | Line 56 | struct {
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 64 | 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();
72 < int     RRGGBB2Color(), GGry2Color();
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 81 | 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 113 | 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 143 | 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 158 | 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 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 271 | Line 291 | initfromtif()          /* initialize conversion from TIFF inpu
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 & hi != 16)
296 <                        quiterr("unsupported bits per sample for RGB");
297 <                if (hi == 8)
294 >                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi))
295 >                        hi = -1;
296 >                switch (hi) {
297 >                case 8:
298                          cvts.tf = RGB2Colr;
299 <                else {
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                  }
311                  break;
312          case PHOTOMETRIC_MINISBLACK:
# Line 288 | Line 316 | initfromtif()          /* initialize conversion from TIFF inpu
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 & hi != 16)
321 <                        quiterr("unsupported bits per sample for greyscale");
322 <                if (hi == 8)
319 >                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi))
320 >                        hi = -1;
321 >                switch (hi) {
322 >                case 8:
323                          cvts.tf = Gry2Colr;
324 <                else {
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:
# Line 309 | 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 322 | 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 361 | 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 385 | Line 444 | char   *s;
444                  SET(C_PRIM);
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  
# Line 393 | 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 419 | 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                          comprgb2xyzWBmat(cvts.cmat,
507                                          CHK(C_PRIM) ? cvts.prims : stdprims);
# Line 434 | 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 455 | 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 470 | 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 478 | 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 514 | Line 620 | char  *av[];
620   }
621  
622  
623 < int
623 > void
624   Luv2Color(y)                    /* read/convert/write Luv->COLOR scanline */
625   uint32  y;
626   {
# Line 525 | Line 631 | uint32 y;
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 <                colval(cvts.r.colors[x],CIEX) = cvts.t.fp[3*x];
637 <                colval(cvts.r.colors[x],CIEY) = cvts.t.fp[3*x + 1];
638 <                colval(cvts.r.colors[x],CIEZ) = 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 548 | Line 655 | uint32 y;
655   }
656  
657  
658 < int
658 > void
659   RRGGBB2Color(y)                 /* read/convert/write RGB16->COLOR scanline */
660   uint32  y;
661   {
# Line 590 | Line 697 | uint32 y;
697   }
698  
699  
700 < int
701 < L2Color(y)                      /* read/convert/write L16->COLOR scanline */
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))
# Line 601 | Line 709 | uint32 y;
709  
710          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
711                  quiterr("error reading TIFF input");
712 <        
713 <        for (x = cvts.xmax; x--; )
714 <                colval(cvts.r.colors[x],RED) =
715 <                colval(cvts.r.colors[x],GRN) =
716 <                colval(cvts.r.colors[x],BLU) =
717 <                                cvts.t.fp[x] > 0. ? cvts.t.fp[x] : 0.;
610 <
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 < int
723 > void
724   RGB2Colr(y)                     /* read/convert/write RGB->COLR scanline */
725   uint32  y;
726   {
# Line 669 | Line 776 | readerr:
776   }
777  
778  
779 < int
779 > void
780   Gry2Colr(y)                     /* read/convert/write G8->COLR scanline */
781   uint32  y;
782   {
# Line 695 | Line 802 | uint32 y;
802   }
803  
804  
805 < int
805 > void
806   GGry2Color(y)                   /* read/convert/write G16->COLOR scanline */
807   uint32  y;
808   {
# Line 725 | Line 832 | uint32 y;
832   }
833  
834  
835 < int
836 < Color2L(y)                      /* read/convert/write COLOR->L16 scanline */
835 > void
836 > Color2GGry(y)                   /* read/convert/write COLOR->G16 scanline */
837   uint32  y;
838   {
839 <        double  m = pow(2.,(double)cvts.bradj);
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  
# Line 747 | Line 888 | uint32 y;
888   }
889  
890  
891 < int
891 > void
892   Color2Luv(y)                    /* read/convert/write COLOR->Luv scanline */
893   uint32  y;
894   {
# Line 768 | 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],CIEX);
915                  cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],CIEY);
# Line 780 | 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   {
# Line 806 | Line 980 | uint32 y;
980   }
981  
982  
983 < int
983 > void
984   Colr2RGB(y)                     /* read/convert/write COLR->RGB scanline */
985   uint32  y;
986   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines