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.10 by gregl, Thu Jul 31 21:26:45 1997 UTC vs.
Revision 2.26 by schorsch, Sun Jul 27 22:12:03 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 */
38          float   gamcor;         /* gamma correction value */
39          short   bradj;          /* Radiance exposure adjustment (stops) */
40          uint16  orient;         /* visual orientation (TIFF spec.) */
41 <        float   stonits;        /* input conversion to nits */
41 >        double  stonits;        /* input conversion to nits */
42          float   pixrat;         /* pixel aspect ratio */
43          FILE    *rfp;           /* Radiance stream pointer */
44          TIFF    *tif;           /* TIFF pointer */
# 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 +                }
172 +                if (CHK(C_TWRD|C_TFLT) == (C_TWRD|C_TFLT))
173 +                        goto userr;
174  
175                  ra2tiff(i, argv);
176          }
# Line 159 | Line 178 | doneopts:
178          exit(0);
179   userr:
180          fprintf(stderr,
181 <        "Usage: %s [-z|-L|-l][-b][-e +/-stops][-g gamma] {in.pic|-} out.tif\n",
181 >        "Usage: %s [-z|-L|-l|-f|-w][-b][-e +/-stops][-g gamma] {in.pic|-} out.tif\n",
182                          progname);
183          fprintf(stderr,
184          "   Or: %s -r [-x][-e +/-stops][-g gamma] in.tif [out.pic|-]\n",
# Line 184 | Line 203 | allocbufs()                    /* allocate scanline buffers */
203          int     rsiz, tsiz;
204  
205          rsiz = CHK(C_RFLT) ? sizeof(COLOR) : sizeof(COLR);
206 <        tsiz = (CHK(C_TFLT) ? sizeof(float) : sizeof(uint8)) *
206 >        tsiz = (CHK(C_TFLT) ? sizeof(float) :
207 >                        CHK(C_TWRD) ? sizeof(uint16) : sizeof(uint8)) *
208                          (CHK(C_GRY) ? 1 : 3);
209          cvts.r.p = (char *)malloc(rsiz*cvts.xmax);
210          cvts.t.p = (char *)malloc(tsiz*cvts.xmax);
211 <        if (cvts.r.p == NULL | cvts.t.p == NULL)
211 >        if ((cvts.r.p == NULL) | (cvts.t.p == NULL))
212                  quiterr("no memory to allocate scanline buffers");
213   }
214  
# Line 196 | Line 216 | allocbufs()                    /* allocate scanline buffers */
216   initfromtif()           /* initialize conversion from TIFF input */
217   {
218          uint16  hi;
219 +        char    *cp;
220          float   *fa, f1, f2;
221  
222 <        CLR(C_GRY|C_GAMMA|C_PRIM|C_RFLT|C_TFLT|C_CXFM);
222 >        CLR(C_GRY|C_GAMMA|C_PRIM|C_RFLT|C_TFLT|C_TWRD|C_CXFM);
223  
224          TIFFGetFieldDefaulted(cvts.tif, TIFFTAG_PLANARCONFIG, &cvts.pconf);
225  
# Line 241 | Line 262 | initfromtif()          /* initialize conversion from TIFF inpu
262                  if (cvts.pconf != PLANARCONFIG_CONTIG)
263                          quiterr("cannot handle separate Luv planes");
264                  TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
265 <                                SGILOGDATAFMT_FLTXYZ);
265 >                                SGILOGDATAFMT_FLOAT);
266                  cvts.tf = Luv2Color;
267                  break;
268          case PHOTOMETRIC_LOGL:
269                  SET(C_GRY|C_RFLT|C_TFLT|C_GAMUT);
270                  cvts.pconf = PLANARCONFIG_CONTIG;
271                  TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
272 <                                SGILOGDATAFMT_FLTY);
272 >                                SGILOGDATAFMT_FLOAT);
273                  cvts.tf = L2Color;
274                  break;
275 +        case PHOTOMETRIC_YCBCR:
276 +                if (cvts.comp == COMPRESSION_JPEG &&
277 +                                cvts.pconf == PLANARCONFIG_CONTIG) {
278 +                        TIFFSetField(cvts.tif, TIFFTAG_JPEGCOLORMODE,
279 +                                        JPEGCOLORMODE_RGB);
280 +                        cvts.phot = PHOTOMETRIC_RGB;
281 +                } else
282 +                        quiterr("unsupported photometric type");
283 +                /* fall through */
284          case PHOTOMETRIC_RGB:
285 <                SET(C_GAMMA|C_GAMUT);
285 >                SET(C_GAMMA);
286                  setcolrgam(cvts.gamcor);
287                  if (CHK(C_XYZE)) {
288 <                        comprgb2xyzmat(cvts.cmat,
288 >                        comprgb2xyzWBmat(cvts.cmat,
289                                          CHK(C_PRIM) ? cvts.prims : stdprims);
290                          SET(C_CXFM);
291                  }
292                  if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) ||
293                                  hi != 3)
294                          quiterr("unsupported samples per pixel for RGB");
295 <                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) ||
296 <                                hi != 8)
295 >                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi))
296 >                        hi = -1;
297 >                switch (hi) {
298 >                case 8:
299 >                        cvts.tf = RGB2Colr;
300 >                        break;
301 >                case 16:
302 >                        cvts.tf = RRGGBB2Color;
303 >                        SET(C_RFLT|C_TWRD);
304 >                        break;
305 >                case 32:
306 >                        cvts.tf = RfGfBf2Color;
307 >                        SET(C_RFLT|C_TFLT);
308 >                        break;
309 >                default:
310                          quiterr("unsupported bits per sample for RGB");
311 <                cvts.tf = RGB2Colr;
311 >                }
312                  break;
313          case PHOTOMETRIC_MINISBLACK:
314 <                SET(C_GRY|C_GAMMA|C_GAMUT);
314 >                SET(C_GRY|C_GAMMA);
315 >                setcolrgam(cvts.gamcor);
316                  cvts.pconf = PLANARCONFIG_CONTIG;
317                  if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) ||
318                                  hi != 1)
319                          quiterr("unsupported samples per pixel for greyscale");
320 <                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) ||
321 <                                hi != 8)
322 <                        quiterr("unsupported bits per sample for greyscale");
323 <                cvts.tf = Gry2Colr;
320 >                if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi))
321 >                        hi = -1;
322 >                switch (hi) {
323 >                case 8:
324 >                        cvts.tf = Gry2Colr;
325 >                        break;
326 >                case 16:
327 >                        cvts.tf = GGry2Color;
328 >                        SET(C_RFLT|C_TWRD);
329 >                        break;
330 >                case 32:
331 >                        cvts.tf = Gryf2Color;
332 >                        SET(C_RFLT|C_TFLT);
333 >                        break;
334 >                default:
335 >                        quiterr("unsupported bits per sample for Gray");
336 >                }
337                  break;
338          default:
339                  quiterr("unsupported photometric type");
# Line 289 | Line 346 | initfromtif()          /* initialize conversion from TIFF inpu
346  
347          if (!TIFFGetField(cvts.tif, TIFFTAG_STONITS, &cvts.stonits))
348                  cvts.stonits = 1.;
349 +
350 +        if (!TIFFGetField(cvts.tif, TIFFTAG_DATETIME, &cp))
351 +                cvts.capdate[0] = '\0';
352 +        else {
353 +                strncpy(cvts.capdate, cp, 19);
354 +                cvts.capdate[19] = '\0';
355 +        }
356 +        if (!TIFFGetField(cvts.tif, TIFFTAG_ARTIST, &cp))
357 +                cvts.owner[0] = '\0';
358 +        else {
359 +                strncpy(cvts.owner, cp, sizeof(cvts.owner));
360 +                cvts.owner[sizeof(cvts.owner)-1] = '\0';
361 +        }
362                                          /* add to Radiance header */
363          if (cvts.pixrat < .99 || cvts.pixrat > 1.01)
364                  fputaspect(cvts.pixrat, cvts.rfp);
# Line 302 | Line 372 | initfromtif()          /* initialize conversion from TIFF inpu
372                                  cvts.rfp);
373                  fputformat(COLRFMT, cvts.rfp);
374          }
375 +        if (cvts.capdate[0])
376 +                fprintf(cvts.rfp, "%s %s\n", TMSTR, cvts.capdate);
377 +        if (cvts.owner[0])
378 +                fprintf(cvts.rfp, "%s %s\n", OWNSTR, cvts.owner);
379  
380          allocbufs();                    /* allocate scanline buffers */
381   }
# Line 341 | Line 415 | int
415   headline(s)                     /* process Radiance input header line */
416   char    *s;
417   {
418 +        static int      tmstrlen = 0;
419 +        static int      ownstrlen = 0;
420          char    fmt[32];
421  
422 +        if (!tmstrlen)
423 +                tmstrlen = strlen(TMSTR);
424 +        if (!ownstrlen)
425 +                ownstrlen = strlen(OWNSTR);
426          if (formatval(fmt, s)) {
427                  if (!strcmp(fmt, COLRFMT))
428                          CLR(C_XYZE);
# Line 350 | Line 430 | char   *s;
430                          SET(C_XYZE);
431                  else
432                          quiterr("unrecognized input picture format");
433 <                return;
433 >                return(1);
434          }
435          if (isexpos(s)) {
436                  cvts.stonits /= exposval(s);
437 <                return;
437 >                return(1);
438          }
439          if (isaspect(s)) {
440                  cvts.pixrat *= aspectval(s);
441 <                return;
441 >                return(1);
442          }
443          if (isprims(s)) {
444                  primsval(cvts.prims, s);
445                  SET(C_PRIM);
446 <                return;
446 >                return(1);
447          }
448 +        if (isdate(s)) {
449 +                if (s[tmstrlen] == ' ')
450 +                        strncpy(cvts.capdate, s+tmstrlen+1, 19);
451 +                else
452 +                        strncpy(cvts.capdate, s+tmstrlen, 19);
453 +                cvts.capdate[19] = '\0';
454 +                return(1);
455 +        }
456 +        if (!strncmp(s, OWNSTR, ownstrlen)) {
457 +                register char   *cp = s + ownstrlen;
458 +
459 +                while (isspace(*cp))
460 +                        ++cp;
461 +                strncpy(cvts.owner, cp, sizeof(cvts.owner));
462 +                cvts.owner[sizeof(cvts.owner)-1] = '\0';
463 +                for (cp = cvts.owner; *cp; cp++)
464 +                        ;
465 +                while (cp > cvts.owner && isspace(cp[-1]))
466 +                        *--cp = '\0';
467 +                return(1);
468 +        }
469 +        return(0);
470   }
471  
472  
# Line 372 | Line 474 | initfromrad()                  /* initialize input from a Radiance pi
474   {
475          int     i1, i2, po;
476                                                  /* read Radiance header */
477 <        CLR(C_RFLT|C_TFLT|C_XYZE|C_PRIM|C_GAMMA|C_CXFM);
477 >        CLR(C_RFLT|C_XYZE|C_PRIM|C_GAMMA|C_CXFM);
478 >        cvts.capdate[0] = '\0';
479 >        cvts.owner[0] = '\0';
480          cvts.stonits = 1.;
481          cvts.pixrat = 1.;
482          cvts.pconf = PLANARCONFIG_CONTIG;
# Line 398 | Line 502 | initfromrad()                  /* initialize input from a Radiance pi
502          switch (cvts.phot) {
503          case PHOTOMETRIC_LOGLUV:
504                  SET(C_RFLT|C_TFLT);
505 <                CLR(C_GRY);
505 >                CLR(C_GRY|C_TWRD);
506                  if (!CHK(C_XYZE)) {
507 <                        cpcolormat(cvts.cmat, rgb2xyzmat);
507 >                        comprgb2xyzWBmat(cvts.cmat,
508 >                                        CHK(C_PRIM) ? cvts.prims : stdprims);
509                          SET(C_CXFM);
510                  }
511                  if (cvts.comp != COMPRESSION_SGILOG &&
512                                  cvts.comp != COMPRESSION_SGILOG24)
513                          quiterr("internal error 2 in initfromrad");
514                  TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
515 <                                SGILOGDATAFMT_FLTXYZ);
515 >                                SGILOGDATAFMT_FLOAT);
516                  cvts.tf = Color2Luv;
517                  break;
518          case PHOTOMETRIC_LOGL:
519                  SET(C_GRY|C_RFLT|C_TFLT);
520 +                CLR(C_TWRD);
521                  if (cvts.comp != COMPRESSION_SGILOG)    
522                          quiterr("internal error 3 in initfromrad");
523                  TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT,
524 <                                SGILOGDATAFMT_FLTY);
524 >                                SGILOGDATAFMT_FLOAT);
525                  cvts.tf = Color2L;
526                  break;
527          case PHOTOMETRIC_RGB:
# Line 423 | Line 529 | initfromrad()                  /* initialize input from a Radiance pi
529                  CLR(C_GRY);
530                  setcolrgam(cvts.gamcor);
531                  if (CHK(C_XYZE)) {
532 <                        compxyz2rgbmat(cvts.cmat,
532 >                        compxyz2rgbWBmat(cvts.cmat,
533                                          CHK(C_PRIM) ? cvts.prims : stdprims);
534                          SET(C_CXFM);
535                  }
# Line 433 | Line 539 | initfromrad()                  /* initialize input from a Radiance pi
539                          TIFFSetField(cvts.tif, TIFFTAG_WHITEPOINT,
540                                          (float *)cvts.prims[WHT]);
541                  }
542 <                cvts.tf = Colr2RGB;
542 >                if (CHK(C_TWRD)) {
543 >                        cvts.tf = Color2RRGGBB;
544 >                        SET(C_RFLT);
545 >                } else if (CHK(C_TFLT)) {
546 >                        TIFFSetField(cvts.tif, TIFFTAG_SAMPLEFORMAT,
547 >                                        SAMPLEFORMAT_IEEEFP);
548 >                        cvts.tf = Color2RfGfBf;
549 >                        SET(C_RFLT);
550 >                } else
551 >                        cvts.tf = Colr2RGB;
552                  break;
553          case PHOTOMETRIC_MINISBLACK:
554                  SET(C_GRY|C_GAMMA|C_GAMUT);
555                  setcolrgam(cvts.gamcor);
556 <                cvts.tf = Colr2Gry;
556 >                if (CHK(C_TWRD)) {
557 >                        cvts.tf = Color2GGry;
558 >                        SET(C_RFLT);
559 >                } else if (CHK(C_TFLT)) {
560 >                        TIFFSetField(cvts.tif, TIFFTAG_SAMPLEFORMAT,
561 >                                        SAMPLEFORMAT_IEEEFP);
562 >                        cvts.tf = Color2Gryf;
563 >                        SET(C_RFLT);
564 >                } else
565 >                        cvts.tf = Colr2Gry;
566                  break;
567          default:
568                  quiterr("internal error 4 in initfromrad");
# Line 448 | Line 572 | initfromrad()                  /* initialize input from a Radiance pi
572          TIFFSetField(cvts.tif, TIFFTAG_IMAGEWIDTH, cvts.xmax);
573          TIFFSetField(cvts.tif, TIFFTAG_IMAGELENGTH, cvts.ymax);
574          TIFFSetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, CHK(C_GRY) ? 1 : 3);
575 <        TIFFSetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, CHK(C_TFLT) ? 32 : 8);
575 >        TIFFSetField(cvts.tif, TIFFTAG_BITSPERSAMPLE,
576 >                        CHK(C_TFLT) ? 32 : CHK(C_TWRD) ? 16 : 8);
577          TIFFSetField(cvts.tif, TIFFTAG_XRESOLUTION, 72.);
578          TIFFSetField(cvts.tif, TIFFTAG_YRESOLUTION, 72./cvts.pixrat);
579          TIFFSetField(cvts.tif, TIFFTAG_ORIENTATION, cvts.orient);
# Line 456 | Line 581 | initfromrad()                  /* initialize input from a Radiance pi
581          TIFFSetField(cvts.tif, TIFFTAG_PLANARCONFIG, cvts.pconf);
582          TIFFSetField(cvts.tif, TIFFTAG_STONITS,
583                          cvts.stonits/pow(2.,(double)cvts.bradj));
584 +        if (cvts.capdate[0])
585 +                TIFFSetField(cvts.tif, TIFFTAG_DATETIME, cvts.capdate);
586 +        if (cvts.owner[0])
587 +                TIFFSetField(cvts.tif, TIFFTAG_ARTIST, cvts.owner);
588          if (cvts.comp == COMPRESSION_NONE)
589                  i1 = TIFFScanlineSize(cvts.tif);
590          else
# Line 492 | Line 621 | char  *av[];
621   }
622  
623  
624 < int
624 > void
625   Luv2Color(y)                    /* read/convert/write Luv->COLOR scanline */
626   uint32  y;
627   {
628          register int    x;
629  
630 <        if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | CHK(C_GRY))
630 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT))
631                  quiterr("internal error 1 in Luv2Color");
632  
633          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
634                  quiterr("error reading TIFF input");
635 <        
635 >                                        /* also works for float RGB */
636          for (x = cvts.xmax; x--; ) {
637 <                cvts.r.colors[x][RED] = cvts.t.fp[3*x];
638 <                cvts.r.colors[x][GRN] = cvts.t.fp[3*x + 1];
639 <                cvts.r.colors[x][BLU] = cvts.t.fp[3*x + 2];
637 >                setcolor(cvts.r.colors[x],
638 >                                cvts.t.fp[3*x],
639 >                                cvts.t.fp[3*x + 1],
640 >                                cvts.t.fp[3*x + 2]);
641                  if (CHK(C_CXFM))
642                          colortrans(cvts.r.colors[x], cvts.cmat,
643                                          cvts.r.colors[x]);
# Line 526 | Line 656 | uint32 y;
656   }
657  
658  
659 < int
660 < L2Color(y)                      /* read/convert/write L16->COLOR scanline */
659 > void
660 > RRGGBB2Color(y)                 /* read/convert/write RGB16->COLOR scanline */
661   uint32  y;
662   {
663 +        int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01);
664 +        register double d;
665          register int    x;
666  
667 <        if (CHK(C_RFLT|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
668 <                quiterr("internal error 1 in L2Color");
667 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_TWRD|C_RFLT))
668 >                quiterr("internal error 1 in RRGGBB2Color");
669  
670          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
671                  quiterr("error reading TIFF input");
672          
673 <        for (x = cvts.xmax; x--; )
674 <                cvts.r.colors[x][RED] =
675 <                cvts.r.colors[x][GRN] =
676 <                cvts.r.colors[x][BLU] = cvts.t.fp[x] > 0. ? cvts.t.fp[x] : 0.;
673 >        for (x = cvts.xmax; x--; ) {
674 >                d = (cvts.t.wp[3*x] + 0.5)*(1./(1L<<16));
675 >                if (dogamma) d = pow(d, cvts.gamcor);
676 >                colval(cvts.r.colors[x],RED) = d;
677 >                d = (cvts.t.wp[3*x + 1] + 0.5)*(1./(1L<<16));
678 >                if (dogamma) d = pow(d, cvts.gamcor);
679 >                colval(cvts.r.colors[x],GRN) = d;
680 >                d = (cvts.t.wp[3*x + 2] + 0.5)*(1./(1L<<16));
681 >                if (dogamma) d = pow(d, cvts.gamcor);
682 >                colval(cvts.r.colors[x],BLU) = d;
683 >                if (CHK(C_CXFM))
684 >                        colortrans(cvts.r.colors[x], cvts.cmat,
685 >                                        cvts.r.colors[x]);
686 >                if (CHK(C_GAMUT))
687 >                        clipgamut(cvts.r.colors[x], cvts.t.fp[3*x + 1],
688 >                                        CGAMUT_LOWER, cblack, cwhite);
689 >        }
690 >        if (cvts.bradj) {
691 >                d = pow(2.,(double)cvts.bradj);
692 >                for (x = cvts.xmax; x--; )
693 >                        scalecolor(cvts.r.colors[x], d);
694 >        }
695  
696          if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
697                  quiterr("error writing Radiance picture");
698   }
699  
700  
701 < int
701 > void
702 > L2Color(y)                      /* read/convert/write Lfloat->COLOR scanline */
703 > uint32  y;
704 > {
705 >        float   m = pow(2., (double)cvts.bradj);
706 >        register int    x;
707 >
708 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
709 >                quiterr("internal error 1 in L2Color");
710 >
711 >        if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
712 >                quiterr("error reading TIFF input");
713 >                                        /* also works for float greyscale */
714 >        for (x = cvts.xmax; x--; ) {
715 >                register float  f = cvts.t.fp[x];
716 >                if (cvts.bradj) f *= m;
717 >                setcolor(cvts.r.colors[x], f, f, f);
718 >        }
719 >        if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
720 >                quiterr("error writing Radiance picture");
721 > }
722 >
723 >
724 > void
725   RGB2Colr(y)                     /* read/convert/write RGB->COLR scanline */
726   uint32  y;
727   {
728          COLOR   ctmp;
729          register int    x;
730  
731 <        if (CHK(C_RFLT|C_TFLT|C_GRY))
731 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY))
732                  quiterr("internal error 1 in RGB2Colr");
733  
734          if (cvts.pconf == PLANARCONFIG_CONTIG) {
# Line 570 | Line 743 | uint32 y;
743                  if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
744                          goto readerr;
745                  if (TIFFReadScanline(cvts.tif,
746 <                                (tidata_t)(cvts.t.bp + cvts.xmax), y, 1) < 0)
746 >                                (tdata_t)(cvts.t.bp + cvts.xmax), y, 1) < 0)
747                          goto readerr;
748                  if (TIFFReadScanline(cvts.tif,
749 <                                (tidata_t)(cvts.t.bp + 2*cvts.xmax), y, 2) < 0)
749 >                                (tdata_t)(cvts.t.bp + 2*cvts.xmax), y, 2) < 0)
750                          goto readerr;
751                  for (x = cvts.xmax; x--; ) {
752                          cvts.r.colrs[x][RED] = cvts.t.bp[x];
# Line 604 | Line 777 | readerr:
777   }
778  
779  
780 < int
780 > void
781   Gry2Colr(y)                     /* read/convert/write G8->COLR scanline */
782   uint32  y;
783   {
784          register int    x;
785  
786 <        if (CHK(C_RFLT|C_TFLT) | !CHK(C_GRY))
786 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY)
787                  quiterr("internal error 1 in Gry2Colr");
788  
789          if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
# Line 630 | Line 803 | uint32 y;
803   }
804  
805  
806 < int
807 < Color2L(y)                      /* read/convert/write COLOR->L16 scanline */
806 > void
807 > GGry2Color(y)                   /* read/convert/write G16->COLOR scanline */
808   uint32  y;
809   {
810 <        double  m = pow(2.,(double)cvts.bradj);
810 >        int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01);
811 >        double  m;
812 >        register double d;
813          register int    x;
814  
815 <        if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | !CHK(C_GRY))
815 >        if (CHK(C_TFLT|C_TWRD|C_GRY|C_RFLT) != (C_GRY|C_RFLT|C_TWRD))
816 >                quiterr("internal error 1 in GGry2Color");
817 >
818 >        if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0)
819 >                quiterr("error reading TIFF input");
820 >
821 >        if (cvts.bradj)
822 >                m = pow(2., (double)cvts.bradj);
823 >        for (x = cvts.xmax; x--; ) {
824 >                d = (cvts.t.wp[x] + 0.5)*(1./(1L<<16));
825 >                if (dogamma) d = pow(d, cvts.gamcor);
826 >                if (cvts.bradj) d *= m;
827 >                colval(cvts.r.colors[x],RED) =
828 >                colval(cvts.r.colors[x],GRN) =
829 >                colval(cvts.r.colors[x],BLU) = d;
830 >        }
831 >        if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
832 >                quiterr("error writing Radiance picture");
833 > }
834 >
835 >
836 > void
837 > Color2GGry(y)                   /* read/convert/write COLOR->G16 scanline */
838 > uint32  y;
839 > {
840 >        int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01);
841 >        float   m = pow(2.,(double)cvts.bradj);
842 >        register int    x;
843 >
844 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TWRD|C_GRY))
845 >                quiterr("internal error 1 in Color2GGry");
846 >
847 >        if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
848 >                quiterr("error reading Radiance picture");
849 >
850 >        for (x = cvts.xmax; x--; ) {
851 >                register float  f = m*( CHK(C_XYZE) ?
852 >                                                colval(cvts.r.colors[x],CIEY)
853 >                                                : bright(cvts.r.colors[x]) );
854 >                if (f <= 0)
855 >                        cvts.t.wp[x] = 0;
856 >                else if (f >= 1)
857 >                        cvts.t.wp[x] = 0xffff;
858 >                else if (dogamma)
859 >                        cvts.t.wp[x] = (int)((float)(1L<<16) *
860 >                                                pow(f, 1./cvts.gamcor));
861 >                else
862 >                        cvts.t.wp[x] = (int)((float)(1L<<16) * f);
863 >        }
864 >
865 >        if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
866 >                quiterr("error writing TIFF output");
867 > }
868 >
869 >
870 > void
871 > Color2L(y)                      /* read/convert/write COLOR->Lfloat scanline */
872 > uint32  y;
873 > {
874 >        float   m = pow(2.,(double)cvts.bradj);
875 >        register int    x;
876 >
877 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TFLT|C_GRY))
878                  quiterr("internal error 1 in Color2L");
879  
880          if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
# Line 652 | Line 889 | uint32 y;
889   }
890  
891  
892 < int
892 > void
893   Color2Luv(y)                    /* read/convert/write COLOR->Luv scanline */
894   uint32  y;
895   {
896          register int    x;
897  
898 <        if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | CHK(C_GRY))
898 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT))
899                  quiterr("internal error 1 in Color2Luv");
900  
901          if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
# Line 673 | Line 910 | uint32 y;
910                  for (x = cvts.xmax; x--; )
911                          scalecolor(cvts.r.colors[x], m);
912          }
913 <
913 >                                        /* also works for float RGB */
914          for (x = cvts.xmax; x--; ) {
915 <                cvts.t.fp[3*x] = colval(cvts.r.colors[x],RED);
916 <                cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],GRN);
917 <                cvts.t.fp[3*x+2] = colval(cvts.r.colors[x],BLU);
915 >                cvts.t.fp[3*x] = colval(cvts.r.colors[x],CIEX);
916 >                cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],CIEY);
917 >                cvts.t.fp[3*x+2] = colval(cvts.r.colors[x],CIEZ);
918          }
919  
920          if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
# Line 685 | Line 922 | uint32 y;
922   }
923  
924  
925 < int
925 > void
926 > Color2RRGGBB(y)                 /* read/convert/write COLOR->RGB16 scanline */
927 > uint32  y;
928 > {
929 >        int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01);
930 >        float   m = pow(2.,(double)cvts.bradj);
931 >        register int    x, i;
932 >
933 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TWRD))
934 >                quiterr("internal error 1 in Color2RRGGBB");
935 >
936 >        if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0)
937 >                quiterr("error reading Radiance picture");
938 >
939 >        for (x = cvts.xmax; x--; )
940 >            for (i = 3; i--; ) {
941 >                register float  f = m*colval(cvts.r.colors[x],i);
942 >                if (f <= 0)
943 >                        cvts.t.wp[3*x + i] = 0;
944 >                else if (f >= 1)
945 >                        cvts.t.wp[3*x + i] = 0xffff;
946 >                else if (dogamma)
947 >                        cvts.t.wp[3*x + i] = (int)((float)(1L<<16) *
948 >                                                pow(f, 1./cvts.gamcor));
949 >                else
950 >                        cvts.t.wp[3*x + i] = (int)((float)(1L<<16)*f);
951 >            }
952 >
953 >        if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0)
954 >                quiterr("error writing TIFF output");
955 > }
956 >
957 >
958 > void
959   Colr2Gry(y)                     /* read/convert/write COLR->RGB scanline */
960   uint32  y;
961   {
962          register int    x;
963  
964 <        if (CHK(C_RFLT|C_TFLT) | !CHK(C_GRY))
964 >        if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY)
965                  quiterr("internal error 1 in Colr2Gry");
966  
967          if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)
# Line 711 | Line 981 | uint32 y;
981   }
982  
983  
984 < int
984 > void
985   Colr2RGB(y)                     /* read/convert/write COLR->RGB scanline */
986   uint32  y;
987   {
988          COLOR   ctmp;
989          register int    x;
990  
991 <        if (CHK(C_RFLT|C_TFLT|C_GRY))
991 >        if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY))
992                  quiterr("internal error 1 in Colr2RGB");
993  
994          if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines