| 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  "platform.h" | 
| 17 |  | #include  "tiffio.h" | 
| 18 |  | #include  "color.h" | 
| 19 |  | #include  "resolu.h" | 
| 20 |  |  | 
| 21 |  | #define  GAMCOR         2.2             /* default gamma */ | 
| 22 |  |  | 
| 20 | – | #ifndef malloc | 
| 21 | – | extern char  *malloc(); | 
| 22 | – | #endif | 
| 23 |  | /* conversion flags */ | 
| 24 |  | #define C_CXFM          0x1             /* needs color transformation */ | 
| 25 |  | #define C_GAMUT         0x2             /* needs gamut mapping */ | 
| 28 |  | #define C_XYZE          0x10            /* Radiance is XYZE */ | 
| 29 |  | #define C_RFLT          0x20            /* Radiance data is float */ | 
| 30 |  | #define C_TFLT          0x40            /* TIFF data is float */ | 
| 31 | < | #define C_PRIM          0x80            /* has assigned primaries */ | 
| 31 | > | #define C_TWRD          0x80            /* TIFF data is 16-bit */ | 
| 32 | > | #define C_PRIM          0x100           /* has assigned primaries */ | 
| 33 |  |  | 
| 34 | + | typedef void colcvf_t(uint32 y); | 
| 35 | + |  | 
| 36 |  | struct { | 
| 37 |  | uint16  flags;          /* conversion flags (defined above) */ | 
| 38 | + | char    capdate[20];    /* capture date/time */ | 
| 39 | + | char    owner[256];     /* content owner */ | 
| 40 |  | uint16  comp;           /* TIFF compression type */ | 
| 41 |  | uint16  phot;           /* TIFF photometric type */ | 
| 42 |  | uint16  pconf;          /* TIFF planar configuration */ | 
| 57 |  | } r;                    /* Radiance scanline */ | 
| 58 |  | union { | 
| 59 |  | uint8   *bp;            /* byte pointer */ | 
| 60 | + | uint16  *wp;            /* word pointer */ | 
| 61 |  | float   *fp;            /* float pointer */ | 
| 62 |  | char    *p;             /* generic pointer */ | 
| 63 |  | } t;                    /* TIFF scanline */ | 
| 64 | < | int     (*tf)();        /* translation procedure */ | 
| 64 | > | colcvf_t *tf;   /* translation procedure */ | 
| 65 |  | }       cvts = {        /* conversion structure */ | 
| 66 | < | 0, COMPRESSION_NONE, PHOTOMETRIC_RGB, | 
| 66 | > | 0, "", "", COMPRESSION_NONE, PHOTOMETRIC_RGB, | 
| 67 |  | PLANARCONFIG_CONTIG, GAMCOR, 0, 1, 1., 1., | 
| 68 |  | }; | 
| 69 |  |  | 
| 72 |  | #define CLR(f)          (cvts.flags &= ~(f)) | 
| 73 |  | #define TGL(f)          (cvts.flags ^= (f)) | 
| 74 |  |  | 
| 75 | < | int     Luv2Color(), L2Color(), RGB2Colr(), Gry2Colr(); | 
| 76 | < | int     Color2Luv(), Color2L(), Colr2RGB(), Colr2Gry(); | 
| 75 | > | static colcvf_t Luv2Color, L2Color, RGB2Colr, Gry2Colr; | 
| 76 | > | static colcvf_t Color2Luv, Color2L, Colr2RGB, Colr2Gry; | 
| 77 | > | static colcvf_t RRGGBB2Color, GGry2Color, Color2RRGGBB, Color2GGry; | 
| 78 |  |  | 
| 79 | + | static gethfunc headline; | 
| 80 | + | static void quiterr(char *err); | 
| 81 | + | static void allocbufs(void); | 
| 82 | + | static void initfromtif(void); | 
| 83 | + | static void tiff2ra(int  ac, char  *av[]); | 
| 84 | + | static void initfromrad(void); | 
| 85 | + | static void ra2tiff(int  ac, char  *av[]); | 
| 86 | + |  | 
| 87 | + |  | 
| 88 | + |  | 
| 89 | + | #define RfGfBf2Color    Luv2Color | 
| 90 | + | #define Gryf2Color      L2Color | 
| 91 | + | #define Color2Gryf      Color2L | 
| 92 | + | #define Color2RfGfBf    Color2Luv | 
| 93 | + |  | 
| 94 |  | short   ortab[8] = {            /* orientation conversion table */ | 
| 95 |  | YMAJOR|YDECR, | 
| 96 |  | YMAJOR|YDECR|XDECR, | 
| 104 |  |  | 
| 105 |  | #define pixorder()      ortab[cvts.orient-1] | 
| 106 |  |  | 
| 107 | + | extern char     TMSTR[];        /* "CAPDATE=" from header.c */ | 
| 108 | + | char            OWNSTR[] = "OWNER="; | 
| 109 | + |  | 
| 110 |  | char  *progname; | 
| 111 |  |  | 
| 112 |  |  | 
| 113 | < | main(argc, argv) | 
| 114 | < | int  argc; | 
| 90 | < | char  *argv[]; | 
| 113 | > | int | 
| 114 | > | main(int  argc, char  *argv[]) | 
| 115 |  | { | 
| 116 |  | int  reverse = 0; | 
| 117 |  | int  i; | 
| 138 |  | cvts.comp = COMPRESSION_SGILOG24; | 
| 139 |  | cvts.phot = PHOTOMETRIC_LOGLUV; | 
| 140 |  | break; | 
| 141 | + | case 'w':               /* 16-bit/primary output? */ | 
| 142 | + | TGL(C_TWRD); | 
| 143 | + | break; | 
| 144 | + | case 'f':               /* IEEE float output? */ | 
| 145 | + | TGL(C_TFLT); | 
| 146 | + | break; | 
| 147 |  | case 'b':               /* greyscale output? */ | 
| 148 |  | TGL(C_GRY); | 
| 149 |  | break; | 
| 174 |  |  | 
| 175 |  | if (i != argc-2) | 
| 176 |  | goto userr; | 
| 177 | < |  | 
| 178 | < | if (CHK(C_GRY))         /* consistency corrections */ | 
| 177 | > | /* consistency checks */ | 
| 178 | > | if (CHK(C_GRY)) { | 
| 179 |  | if (cvts.phot == PHOTOMETRIC_RGB) | 
| 180 |  | cvts.phot = PHOTOMETRIC_MINISBLACK; | 
| 181 |  | else { | 
| 182 |  | cvts.phot = PHOTOMETRIC_LOGL; | 
| 183 |  | cvts.comp = COMPRESSION_SGILOG; | 
| 184 |  | } | 
| 185 | + | } | 
| 186 | + | if (CHK(C_TWRD|C_TFLT) == (C_TWRD|C_TFLT)) | 
| 187 | + | goto userr; | 
| 188 |  |  | 
| 189 |  | ra2tiff(i, argv); | 
| 190 |  | } | 
| 192 |  | exit(0); | 
| 193 |  | userr: | 
| 194 |  | fprintf(stderr, | 
| 195 | < | "Usage: %s [-z|-L|-l][-b][-e +/-stops][-g gamma] {in.pic|-} out.tif\n", | 
| 195 | > | "Usage: %s [-z|-L|-l|-f|-w][-b][-e +/-stops][-g gamma] {in.hdr|-} out.tif\n", | 
| 196 |  | progname); | 
| 197 |  | fprintf(stderr, | 
| 198 | < | "   Or: %s -r [-x][-e +/-stops][-g gamma] in.tif [out.pic|-]\n", | 
| 198 | > | "   Or: %s -r [-x][-e +/-stops][-g gamma] in.tif [out.hdr|-]\n", | 
| 199 |  | progname); | 
| 200 |  | exit(1); | 
| 201 |  | } | 
| 202 |  |  | 
| 203 |  |  | 
| 204 | < | quiterr(err)            /* print message and exit */ | 
| 205 | < | char  *err; | 
| 204 | > | static void | 
| 205 | > | quiterr(                /* print message and exit */ | 
| 206 | > | char  *err | 
| 207 | > | ) | 
| 208 |  | { | 
| 209 |  | if (err != NULL) { | 
| 210 |  | fprintf(stderr, "%s: %s\n", progname, err); | 
| 214 |  | } | 
| 215 |  |  | 
| 216 |  |  | 
| 217 | < | allocbufs()                     /* allocate scanline buffers */ | 
| 217 | > | static void | 
| 218 | > | allocbufs(void)                 /* allocate scanline buffers */ | 
| 219 |  | { | 
| 220 |  | int     rsiz, tsiz; | 
| 221 |  |  | 
| 222 |  | rsiz = CHK(C_RFLT) ? sizeof(COLOR) : sizeof(COLR); | 
| 223 | < | tsiz = (CHK(C_TFLT) ? sizeof(float) : sizeof(uint8)) * | 
| 223 | > | tsiz = (CHK(C_TFLT) ? sizeof(float) : | 
| 224 | > | CHK(C_TWRD) ? sizeof(uint16) : sizeof(uint8)) * | 
| 225 |  | (CHK(C_GRY) ? 1 : 3); | 
| 226 |  | cvts.r.p = (char *)malloc(rsiz*cvts.xmax); | 
| 227 |  | cvts.t.p = (char *)malloc(tsiz*cvts.xmax); | 
| 228 | < | if (cvts.r.p == NULL | cvts.t.p == NULL) | 
| 228 | > | if ((cvts.r.p == NULL) | (cvts.t.p == NULL)) | 
| 229 |  | quiterr("no memory to allocate scanline buffers"); | 
| 230 |  | } | 
| 231 |  |  | 
| 232 |  |  | 
| 233 | < | initfromtif()           /* initialize conversion from TIFF input */ | 
| 233 | > | static void | 
| 234 | > | initfromtif(void)               /* initialize conversion from TIFF input */ | 
| 235 |  | { | 
| 236 |  | uint16  hi; | 
| 237 | + | char    *cp; | 
| 238 |  | float   *fa, f1, f2; | 
| 239 |  |  | 
| 240 | < | CLR(C_GRY|C_GAMMA|C_PRIM|C_RFLT|C_TFLT|C_CXFM); | 
| 240 | > | CLR(C_GRY|C_GAMMA|C_PRIM|C_RFLT|C_TFLT|C_TWRD|C_CXFM); | 
| 241 |  |  | 
| 242 |  | TIFFGetFieldDefaulted(cvts.tif, TIFFTAG_PLANARCONFIG, &cvts.pconf); | 
| 243 |  |  | 
| 276 |  | cpcolormat(cvts.cmat, xyz2rgbmat); | 
| 277 |  | SET(C_CXFM|C_GAMUT); | 
| 278 |  | } else if (cvts.comp == COMPRESSION_SGILOG) | 
| 279 | < | SET(C_GAMUT); | 
| 279 | > | SET(C_GAMUT);           /* may be outside XYZ gamut */ | 
| 280 |  | if (cvts.pconf != PLANARCONFIG_CONTIG) | 
| 281 |  | quiterr("cannot handle separate Luv planes"); | 
| 282 |  | TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT, | 
| 300 |  | quiterr("unsupported photometric type"); | 
| 301 |  | /* fall through */ | 
| 302 |  | case PHOTOMETRIC_RGB: | 
| 303 | < | SET(C_GAMMA|C_GAMUT); | 
| 303 | > | SET(C_GAMMA); | 
| 304 |  | setcolrgam(cvts.gamcor); | 
| 305 |  | if (CHK(C_XYZE)) { | 
| 306 | < | comprgb2xyzmat(cvts.cmat, | 
| 306 | > | comprgb2xyzWBmat(cvts.cmat, | 
| 307 |  | CHK(C_PRIM) ? cvts.prims : stdprims); | 
| 308 |  | SET(C_CXFM); | 
| 309 |  | } | 
| 310 |  | if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) || | 
| 311 |  | hi != 3) | 
| 312 |  | quiterr("unsupported samples per pixel for RGB"); | 
| 313 | < | if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) || | 
| 314 | < | hi != 8) | 
| 313 | > | if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi)) | 
| 314 | > | hi = -1; | 
| 315 | > | switch (hi) { | 
| 316 | > | case 8: | 
| 317 | > | cvts.tf = RGB2Colr; | 
| 318 | > | break; | 
| 319 | > | case 16: | 
| 320 | > | cvts.tf = RRGGBB2Color; | 
| 321 | > | SET(C_RFLT|C_TWRD); | 
| 322 | > | break; | 
| 323 | > | case 32: | 
| 324 | > | cvts.tf = RfGfBf2Color; | 
| 325 | > | SET(C_RFLT|C_TFLT); | 
| 326 | > | break; | 
| 327 | > | default: | 
| 328 |  | quiterr("unsupported bits per sample for RGB"); | 
| 329 | < | cvts.tf = RGB2Colr; | 
| 329 | > | } | 
| 330 |  | break; | 
| 331 |  | case PHOTOMETRIC_MINISBLACK: | 
| 332 | < | SET(C_GRY|C_GAMMA|C_GAMUT); | 
| 332 | > | SET(C_GRY|C_GAMMA); | 
| 333 | > | setcolrgam(cvts.gamcor); | 
| 334 |  | cvts.pconf = PLANARCONFIG_CONTIG; | 
| 335 |  | if (!TIFFGetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, &hi) || | 
| 336 |  | hi != 1) | 
| 337 |  | quiterr("unsupported samples per pixel for greyscale"); | 
| 338 | < | if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi) || | 
| 339 | < | hi != 8) | 
| 340 | < | quiterr("unsupported bits per sample for greyscale"); | 
| 341 | < | cvts.tf = Gry2Colr; | 
| 338 | > | if (!TIFFGetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, &hi)) | 
| 339 | > | hi = -1; | 
| 340 | > | switch (hi) { | 
| 341 | > | case 8: | 
| 342 | > | cvts.tf = Gry2Colr; | 
| 343 | > | break; | 
| 344 | > | case 16: | 
| 345 | > | cvts.tf = GGry2Color; | 
| 346 | > | SET(C_RFLT|C_TWRD); | 
| 347 | > | break; | 
| 348 | > | case 32: | 
| 349 | > | cvts.tf = Gryf2Color; | 
| 350 | > | SET(C_RFLT|C_TFLT); | 
| 351 | > | break; | 
| 352 | > | default: | 
| 353 | > | quiterr("unsupported bits per sample for Gray"); | 
| 354 | > | } | 
| 355 |  | break; | 
| 356 |  | default: | 
| 357 |  | quiterr("unsupported photometric type"); | 
| 363 |  | quiterr("unknown input image resolution"); | 
| 364 |  |  | 
| 365 |  | if (!TIFFGetField(cvts.tif, TIFFTAG_STONITS, &cvts.stonits)) | 
| 366 | < | cvts.stonits = 1.; | 
| 366 | > | cvts.stonits = -1.; | 
| 367 | > |  | 
| 368 | > | if (!TIFFGetField(cvts.tif, TIFFTAG_DATETIME, &cp)) | 
| 369 | > | cvts.capdate[0] = '\0'; | 
| 370 | > | else { | 
| 371 | > | strncpy(cvts.capdate, cp, 19); | 
| 372 | > | cvts.capdate[19] = '\0'; | 
| 373 | > | } | 
| 374 | > | if (!TIFFGetField(cvts.tif, TIFFTAG_ARTIST, &cp)) | 
| 375 | > | cvts.owner[0] = '\0'; | 
| 376 | > | else { | 
| 377 | > | strncpy(cvts.owner, cp, sizeof(cvts.owner)); | 
| 378 | > | cvts.owner[sizeof(cvts.owner)-1] = '\0'; | 
| 379 | > | } | 
| 380 |  | /* add to Radiance header */ | 
| 381 |  | if (cvts.pixrat < .99 || cvts.pixrat > 1.01) | 
| 382 |  | fputaspect(cvts.pixrat, cvts.rfp); | 
| 383 |  | if (CHK(C_XYZE)) { | 
| 384 | < | fputexpos(pow(2.,(double)cvts.bradj)/cvts.stonits, cvts.rfp); | 
| 384 | > | if (cvts.stonits > .0) | 
| 385 | > | fputexpos(pow(2.,(double)cvts.bradj)/cvts.stonits, cvts.rfp); | 
| 386 |  | fputformat(CIEFMT, cvts.rfp); | 
| 387 |  | } else { | 
| 388 |  | if (CHK(C_PRIM)) | 
| 389 |  | fputprims(cvts.prims, cvts.rfp); | 
| 390 | < | fputexpos(WHTEFFICACY*pow(2.,(double)cvts.bradj)/cvts.stonits, | 
| 391 | < | cvts.rfp); | 
| 390 | > | if (cvts.stonits > .0) | 
| 391 | > | fputexpos(WHTEFFICACY*pow(2.,(double)cvts.bradj)/cvts.stonits, | 
| 392 | > | cvts.rfp); | 
| 393 |  | fputformat(COLRFMT, cvts.rfp); | 
| 394 |  | } | 
| 395 | + | if (cvts.capdate[0]) | 
| 396 | + | fprintf(cvts.rfp, "%s %s\n", TMSTR, cvts.capdate); | 
| 397 | + | if (cvts.owner[0]) | 
| 398 | + | fprintf(cvts.rfp, "%s %s\n", OWNSTR, cvts.owner); | 
| 399 |  |  | 
| 400 |  | allocbufs();                    /* allocate scanline buffers */ | 
| 401 |  | } | 
| 402 |  |  | 
| 403 |  |  | 
| 404 | < | tiff2ra(ac, av)         /* convert TIFF image to Radiance picture */ | 
| 405 | < | int  ac; | 
| 406 | < | char  *av[]; | 
| 404 | > | static void | 
| 405 | > | tiff2ra(                /* convert TIFF image to Radiance picture */ | 
| 406 | > | int  ac, | 
| 407 | > | char  *av[] | 
| 408 | > | ) | 
| 409 |  | { | 
| 410 |  | int32   y; | 
| 411 |  | /* open TIFF input */ | 
| 416 |  | cvts.rfp = stdout; | 
| 417 |  | else if ((cvts.rfp = fopen(av[ac+1], "w")) == NULL) | 
| 418 |  | quiterr("cannot open Radiance output picture"); | 
| 419 | + | SET_FILE_BINARY(cvts.rfp); | 
| 420 |  | /* start output header */ | 
| 421 |  | newheader("RADIANCE", cvts.rfp); | 
| 422 |  | printargs(ac, av, cvts.rfp); | 
| 434 |  | } | 
| 435 |  |  | 
| 436 |  |  | 
| 437 | < | int | 
| 438 | < | headline(s)                     /* process Radiance input header line */ | 
| 439 | < | char    *s; | 
| 437 | > | static int | 
| 438 | > | headline(                       /* process Radiance input header line */ | 
| 439 | > | char    *s, | 
| 440 | > | void    *p | 
| 441 | > | ) | 
| 442 |  | { | 
| 443 | < | char    fmt[32]; | 
| 443 | > | static int      tmstrlen = 0; | 
| 444 | > | static int      ownstrlen = 0; | 
| 445 | > | char    fmt[MAXFMTLEN]; | 
| 446 |  |  | 
| 447 | + | if (!tmstrlen) | 
| 448 | + | tmstrlen = strlen(TMSTR); | 
| 449 | + | if (!ownstrlen) | 
| 450 | + | ownstrlen = strlen(OWNSTR); | 
| 451 |  | if (formatval(fmt, s)) { | 
| 452 |  | if (!strcmp(fmt, COLRFMT)) | 
| 453 |  | CLR(C_XYZE); | 
| 455 |  | SET(C_XYZE); | 
| 456 |  | else | 
| 457 |  | quiterr("unrecognized input picture format"); | 
| 458 | < | return; | 
| 458 | > | return(1); | 
| 459 |  | } | 
| 460 |  | if (isexpos(s)) { | 
| 461 |  | cvts.stonits /= exposval(s); | 
| 462 | < | return; | 
| 462 | > | return(1); | 
| 463 |  | } | 
| 464 |  | if (isaspect(s)) { | 
| 465 |  | cvts.pixrat *= aspectval(s); | 
| 466 | < | return; | 
| 466 | > | return(1); | 
| 467 |  | } | 
| 468 |  | if (isprims(s)) { | 
| 469 |  | primsval(cvts.prims, s); | 
| 470 |  | SET(C_PRIM); | 
| 471 | < | return; | 
| 471 | > | return(1); | 
| 472 |  | } | 
| 473 | + | if (isdate(s)) { | 
| 474 | + | if (s[tmstrlen] == ' ') | 
| 475 | + | strncpy(cvts.capdate, s+tmstrlen+1, 19); | 
| 476 | + | else | 
| 477 | + | strncpy(cvts.capdate, s+tmstrlen, 19); | 
| 478 | + | cvts.capdate[19] = '\0'; | 
| 479 | + | return(1); | 
| 480 | + | } | 
| 481 | + | if (!strncmp(s, OWNSTR, ownstrlen)) { | 
| 482 | + | register char   *cp = s + ownstrlen; | 
| 483 | + |  | 
| 484 | + | while (isspace(*cp)) | 
| 485 | + | ++cp; | 
| 486 | + | strncpy(cvts.owner, cp, sizeof(cvts.owner)); | 
| 487 | + | cvts.owner[sizeof(cvts.owner)-1] = '\0'; | 
| 488 | + | for (cp = cvts.owner; *cp; cp++) | 
| 489 | + | ; | 
| 490 | + | while (cp > cvts.owner && isspace(cp[-1])) | 
| 491 | + | *--cp = '\0'; | 
| 492 | + | return(1); | 
| 493 | + | } | 
| 494 | + | return(0); | 
| 495 |  | } | 
| 496 |  |  | 
| 497 |  |  | 
| 498 | < | initfromrad()                   /* initialize input from a Radiance picture */ | 
| 498 | > | static void | 
| 499 | > | initfromrad(void)                       /* initialize input from a Radiance picture */ | 
| 500 |  | { | 
| 501 |  | int     i1, i2, po; | 
| 502 |  | /* read Radiance header */ | 
| 503 | < | CLR(C_RFLT|C_TFLT|C_XYZE|C_PRIM|C_GAMMA|C_CXFM); | 
| 503 | > | CLR(C_RFLT|C_XYZE|C_PRIM|C_GAMMA|C_CXFM); | 
| 504 | > | cvts.capdate[0] = '\0'; | 
| 505 | > | cvts.owner[0] = '\0'; | 
| 506 |  | cvts.stonits = 1.; | 
| 507 |  | cvts.pixrat = 1.; | 
| 508 |  | cvts.pconf = PLANARCONFIG_CONTIG; | 
| 528 |  | switch (cvts.phot) { | 
| 529 |  | case PHOTOMETRIC_LOGLUV: | 
| 530 |  | SET(C_RFLT|C_TFLT); | 
| 531 | < | CLR(C_GRY); | 
| 531 | > | CLR(C_GRY|C_TWRD); | 
| 532 |  | if (!CHK(C_XYZE)) { | 
| 533 | < | cpcolormat(cvts.cmat, rgb2xyzmat); | 
| 533 | > | comprgb2xyzWBmat(cvts.cmat, | 
| 534 | > | CHK(C_PRIM) ? cvts.prims : stdprims); | 
| 535 |  | SET(C_CXFM); | 
| 536 |  | } | 
| 537 |  | if (cvts.comp != COMPRESSION_SGILOG && | 
| 543 |  | break; | 
| 544 |  | case PHOTOMETRIC_LOGL: | 
| 545 |  | SET(C_GRY|C_RFLT|C_TFLT); | 
| 546 | + | CLR(C_TWRD); | 
| 547 |  | if (cvts.comp != COMPRESSION_SGILOG) | 
| 548 |  | quiterr("internal error 3 in initfromrad"); | 
| 549 |  | TIFFSetField(cvts.tif, TIFFTAG_SGILOGDATAFMT, | 
| 555 |  | CLR(C_GRY); | 
| 556 |  | setcolrgam(cvts.gamcor); | 
| 557 |  | if (CHK(C_XYZE)) { | 
| 558 | < | compxyz2rgbmat(cvts.cmat, | 
| 558 | > | compxyz2rgbWBmat(cvts.cmat, | 
| 559 |  | CHK(C_PRIM) ? cvts.prims : stdprims); | 
| 560 |  | SET(C_CXFM); | 
| 561 |  | } | 
| 565 |  | TIFFSetField(cvts.tif, TIFFTAG_WHITEPOINT, | 
| 566 |  | (float *)cvts.prims[WHT]); | 
| 567 |  | } | 
| 568 | < | cvts.tf = Colr2RGB; | 
| 568 | > | if (CHK(C_TWRD)) { | 
| 569 | > | cvts.tf = Color2RRGGBB; | 
| 570 | > | SET(C_RFLT); | 
| 571 | > | } else if (CHK(C_TFLT)) { | 
| 572 | > | TIFFSetField(cvts.tif, TIFFTAG_SAMPLEFORMAT, | 
| 573 | > | SAMPLEFORMAT_IEEEFP); | 
| 574 | > | cvts.tf = Color2RfGfBf; | 
| 575 | > | SET(C_RFLT); | 
| 576 | > | CLR(C_GAMUT); | 
| 577 | > | } else | 
| 578 | > | cvts.tf = Colr2RGB; | 
| 579 |  | break; | 
| 580 |  | case PHOTOMETRIC_MINISBLACK: | 
| 581 |  | SET(C_GRY|C_GAMMA|C_GAMUT); | 
| 582 |  | setcolrgam(cvts.gamcor); | 
| 583 | < | cvts.tf = Colr2Gry; | 
| 583 | > | if (CHK(C_TWRD)) { | 
| 584 | > | cvts.tf = Color2GGry; | 
| 585 | > | SET(C_RFLT); | 
| 586 | > | } else if (CHK(C_TFLT)) { | 
| 587 | > | TIFFSetField(cvts.tif, TIFFTAG_SAMPLEFORMAT, | 
| 588 | > | SAMPLEFORMAT_IEEEFP); | 
| 589 | > | cvts.tf = Color2Gryf; | 
| 590 | > | SET(C_RFLT); | 
| 591 | > | } else | 
| 592 | > | cvts.tf = Colr2Gry; | 
| 593 |  | break; | 
| 594 |  | default: | 
| 595 |  | quiterr("internal error 4 in initfromrad"); | 
| 599 |  | TIFFSetField(cvts.tif, TIFFTAG_IMAGEWIDTH, cvts.xmax); | 
| 600 |  | TIFFSetField(cvts.tif, TIFFTAG_IMAGELENGTH, cvts.ymax); | 
| 601 |  | TIFFSetField(cvts.tif, TIFFTAG_SAMPLESPERPIXEL, CHK(C_GRY) ? 1 : 3); | 
| 602 | < | TIFFSetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, CHK(C_TFLT) ? 32 : 8); | 
| 602 | > | TIFFSetField(cvts.tif, TIFFTAG_BITSPERSAMPLE, | 
| 603 | > | CHK(C_TFLT) ? 32 : CHK(C_TWRD) ? 16 : 8); | 
| 604 |  | TIFFSetField(cvts.tif, TIFFTAG_XRESOLUTION, 72.); | 
| 605 |  | TIFFSetField(cvts.tif, TIFFTAG_YRESOLUTION, 72./cvts.pixrat); | 
| 606 |  | TIFFSetField(cvts.tif, TIFFTAG_ORIENTATION, cvts.orient); | 
| 608 |  | TIFFSetField(cvts.tif, TIFFTAG_PLANARCONFIG, cvts.pconf); | 
| 609 |  | TIFFSetField(cvts.tif, TIFFTAG_STONITS, | 
| 610 |  | cvts.stonits/pow(2.,(double)cvts.bradj)); | 
| 611 | + | if (cvts.capdate[0]) | 
| 612 | + | TIFFSetField(cvts.tif, TIFFTAG_DATETIME, cvts.capdate); | 
| 613 | + | if (cvts.owner[0]) | 
| 614 | + | TIFFSetField(cvts.tif, TIFFTAG_ARTIST, cvts.owner); | 
| 615 |  | if (cvts.comp == COMPRESSION_NONE) | 
| 616 |  | i1 = TIFFScanlineSize(cvts.tif); | 
| 617 |  | else | 
| 624 |  | } | 
| 625 |  |  | 
| 626 |  |  | 
| 627 | < | ra2tiff(ac, av)         /* convert Radiance picture to TIFF image */ | 
| 628 | < | int  ac; | 
| 629 | < | char  *av[]; | 
| 627 | > | static void | 
| 628 | > | ra2tiff(                /* convert Radiance picture to TIFF image */ | 
| 629 | > | int  ac, | 
| 630 | > | char  *av[] | 
| 631 | > | ) | 
| 632 |  | { | 
| 633 |  | uint32  y; | 
| 634 |  | /* open Radiance file */ | 
| 636 |  | cvts.rfp = stdin; | 
| 637 |  | else if ((cvts.rfp = fopen(av[ac], "r")) == NULL) | 
| 638 |  | quiterr("cannot open Radiance input picture"); | 
| 639 | + | SET_FILE_BINARY(cvts.rfp); | 
| 640 |  | /* open TIFF file */ | 
| 641 |  | if ((cvts.tif = TIFFOpen(av[ac+1], "w")) == NULL) | 
| 642 |  | quiterr("cannot open TIFF output"); | 
| 651 |  | } | 
| 652 |  |  | 
| 653 |  |  | 
| 654 | < | int | 
| 655 | < | Luv2Color(y)                    /* read/convert/write Luv->COLOR scanline */ | 
| 656 | < | uint32  y; | 
| 654 | > | static void | 
| 655 | > | Luv2Color(                      /* read/convert/write Luv->COLOR scanline */ | 
| 656 | > | uint32  y | 
| 657 | > | ) | 
| 658 |  | { | 
| 659 |  | register int    x; | 
| 660 |  |  | 
| 661 | < | if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | CHK(C_GRY)) | 
| 661 | > | if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT)) | 
| 662 |  | quiterr("internal error 1 in Luv2Color"); | 
| 663 |  |  | 
| 664 | + | if (cvts.pconf != PLANARCONFIG_CONTIG) | 
| 665 | + | quiterr("cannot handle separate 32-bit color planes"); | 
| 666 | + |  | 
| 667 |  | if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0) | 
| 668 |  | quiterr("error reading TIFF input"); | 
| 669 | < |  | 
| 669 | > | /* also works for float RGB */ | 
| 670 |  | for (x = cvts.xmax; x--; ) { | 
| 671 | < | cvts.r.colors[x][RED] = cvts.t.fp[3*x]; | 
| 672 | < | cvts.r.colors[x][GRN] = cvts.t.fp[3*x + 1]; | 
| 673 | < | cvts.r.colors[x][BLU] = cvts.t.fp[3*x + 2]; | 
| 671 | > | setcolor(cvts.r.colors[x], | 
| 672 | > | cvts.t.fp[3*x], | 
| 673 | > | cvts.t.fp[3*x + 1], | 
| 674 | > | cvts.t.fp[3*x + 2]); | 
| 675 |  | if (CHK(C_CXFM)) | 
| 676 |  | colortrans(cvts.r.colors[x], cvts.cmat, | 
| 677 |  | cvts.r.colors[x]); | 
| 690 |  | } | 
| 691 |  |  | 
| 692 |  |  | 
| 693 | < | int | 
| 694 | < | L2Color(y)                      /* read/convert/write L16->COLOR scanline */ | 
| 695 | < | uint32  y; | 
| 693 | > | static void | 
| 694 | > | RRGGBB2Color(                   /* read/convert/write RGB16->COLOR scanline */ | 
| 695 | > | uint32  y | 
| 696 | > | ) | 
| 697 |  | { | 
| 698 | + | int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01); | 
| 699 | + | register double d; | 
| 700 |  | register int    x; | 
| 701 |  |  | 
| 702 | < | if (CHK(C_RFLT|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY)) | 
| 703 | < | quiterr("internal error 1 in L2Color"); | 
| 702 | > | if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_TWRD|C_RFLT)) | 
| 703 | > | quiterr("internal error 1 in RRGGBB2Color"); | 
| 704 |  |  | 
| 705 | + | if (cvts.pconf != PLANARCONFIG_CONTIG) | 
| 706 | + | quiterr("cannot handle separate 16-bit color planes"); | 
| 707 | + |  | 
| 708 |  | if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0) | 
| 709 |  | quiterr("error reading TIFF input"); | 
| 710 |  |  | 
| 711 | < | for (x = cvts.xmax; x--; ) | 
| 712 | < | cvts.r.colors[x][RED] = | 
| 713 | < | cvts.r.colors[x][GRN] = | 
| 714 | < | cvts.r.colors[x][BLU] = cvts.t.fp[x] > 0. ? cvts.t.fp[x] : 0.; | 
| 711 | > | for (x = cvts.xmax; x--; ) { | 
| 712 | > | d = (cvts.t.wp[3*x] + 0.5)*(1./(1L<<16)); | 
| 713 | > | if (dogamma) d = pow(d, cvts.gamcor); | 
| 714 | > | colval(cvts.r.colors[x],RED) = d; | 
| 715 | > | d = (cvts.t.wp[3*x + 1] + 0.5)*(1./(1L<<16)); | 
| 716 | > | if (dogamma) d = pow(d, cvts.gamcor); | 
| 717 | > | colval(cvts.r.colors[x],GRN) = d; | 
| 718 | > | d = (cvts.t.wp[3*x + 2] + 0.5)*(1./(1L<<16)); | 
| 719 | > | if (dogamma) d = pow(d, cvts.gamcor); | 
| 720 | > | colval(cvts.r.colors[x],BLU) = d; | 
| 721 | > | if (CHK(C_CXFM)) | 
| 722 | > | colortrans(cvts.r.colors[x], cvts.cmat, | 
| 723 | > | cvts.r.colors[x]); | 
| 724 | > | } | 
| 725 | > | if (cvts.bradj) { | 
| 726 | > | d = pow(2.,(double)cvts.bradj); | 
| 727 | > | for (x = cvts.xmax; x--; ) | 
| 728 | > | scalecolor(cvts.r.colors[x], d); | 
| 729 | > | } | 
| 730 |  |  | 
| 731 |  | if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0) | 
| 732 |  | quiterr("error writing Radiance picture"); | 
| 733 |  | } | 
| 734 |  |  | 
| 735 |  |  | 
| 736 | < | int | 
| 737 | < | RGB2Colr(y)                     /* read/convert/write RGB->COLR scanline */ | 
| 738 | < | uint32  y; | 
| 736 | > | static void | 
| 737 | > | L2Color(                        /* read/convert/write Lfloat->COLOR scanline */ | 
| 738 | > | uint32  y | 
| 739 | > | ) | 
| 740 |  | { | 
| 741 | + | float   m = pow(2., (double)cvts.bradj); | 
| 742 | + | register int    x; | 
| 743 | + |  | 
| 744 | + | if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY)) | 
| 745 | + | quiterr("internal error 1 in L2Color"); | 
| 746 | + |  | 
| 747 | + | if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0) | 
| 748 | + | quiterr("error reading TIFF input"); | 
| 749 | + | /* also works for float greyscale */ | 
| 750 | + | for (x = cvts.xmax; x--; ) { | 
| 751 | + | register float  f = cvts.t.fp[x]; | 
| 752 | + | if (cvts.bradj) f *= m; | 
| 753 | + | setcolor(cvts.r.colors[x], f, f, f); | 
| 754 | + | } | 
| 755 | + | if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0) | 
| 756 | + | quiterr("error writing Radiance picture"); | 
| 757 | + | } | 
| 758 | + |  | 
| 759 | + |  | 
| 760 | + | static void | 
| 761 | + | RGB2Colr(                       /* read/convert/write RGB->COLR scanline */ | 
| 762 | + | uint32  y | 
| 763 | + | ) | 
| 764 | + | { | 
| 765 |  | COLOR   ctmp; | 
| 766 |  | register int    x; | 
| 767 |  |  | 
| 768 | < | if (CHK(C_RFLT|C_TFLT|C_GRY)) | 
| 768 | > | if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY)) | 
| 769 |  | quiterr("internal error 1 in RGB2Colr"); | 
| 770 |  |  | 
| 771 |  | if (cvts.pconf == PLANARCONFIG_CONTIG) { | 
| 780 |  | if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0) | 
| 781 |  | goto readerr; | 
| 782 |  | if (TIFFReadScanline(cvts.tif, | 
| 783 | < | (tidata_t)(cvts.t.bp + cvts.xmax), y, 1) < 0) | 
| 783 | > | (tdata_t)(cvts.t.bp + cvts.xmax), y, 1) < 0) | 
| 784 |  | goto readerr; | 
| 785 |  | if (TIFFReadScanline(cvts.tif, | 
| 786 | < | (tidata_t)(cvts.t.bp + 2*cvts.xmax), y, 2) < 0) | 
| 786 | > | (tdata_t)(cvts.t.bp + 2*cvts.xmax), y, 2) < 0) | 
| 787 |  | goto readerr; | 
| 788 |  | for (x = cvts.xmax; x--; ) { | 
| 789 |  | cvts.r.colrs[x][RED] = cvts.t.bp[x]; | 
| 814 |  | } | 
| 815 |  |  | 
| 816 |  |  | 
| 817 | < | int | 
| 818 | < | Gry2Colr(y)                     /* read/convert/write G8->COLR scanline */ | 
| 819 | < | uint32  y; | 
| 817 | > | static void | 
| 818 | > | Gry2Colr(                       /* read/convert/write G8->COLR scanline */ | 
| 819 | > | uint32  y | 
| 820 | > | ) | 
| 821 |  | { | 
| 822 |  | register int    x; | 
| 823 |  |  | 
| 824 | < | if (CHK(C_RFLT|C_TFLT) | !CHK(C_GRY)) | 
| 824 | > | if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY) | 
| 825 |  | quiterr("internal error 1 in Gry2Colr"); | 
| 826 |  |  | 
| 827 |  | if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0) | 
| 841 |  | } | 
| 842 |  |  | 
| 843 |  |  | 
| 844 | < | int | 
| 845 | < | Color2L(y)                      /* read/convert/write COLOR->L16 scanline */ | 
| 846 | < | uint32  y; | 
| 844 | > | static void | 
| 845 | > | GGry2Color(                     /* read/convert/write G16->COLOR scanline */ | 
| 846 | > | uint32  y | 
| 847 | > | ) | 
| 848 |  | { | 
| 849 | < | double  m = pow(2.,(double)cvts.bradj); | 
| 849 | > | int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01); | 
| 850 | > | double  m; | 
| 851 | > | register double d; | 
| 852 |  | register int    x; | 
| 853 |  |  | 
| 854 | < | if (CHK(C_RFLT|C_TFLT|C_GRY) != (C_RFLT|C_TFLT|C_GRY)) | 
| 854 | > | if (CHK(C_TFLT|C_TWRD|C_GRY|C_RFLT) != (C_GRY|C_RFLT|C_TWRD)) | 
| 855 | > | quiterr("internal error 1 in GGry2Color"); | 
| 856 | > |  | 
| 857 | > | if (TIFFReadScanline(cvts.tif, cvts.t.p, y, 0) < 0) | 
| 858 | > | quiterr("error reading TIFF input"); | 
| 859 | > |  | 
| 860 | > | if (cvts.bradj) | 
| 861 | > | m = pow(2., (double)cvts.bradj); | 
| 862 | > | for (x = cvts.xmax; x--; ) { | 
| 863 | > | d = (cvts.t.wp[x] + 0.5)*(1./(1L<<16)); | 
| 864 | > | if (dogamma) d = pow(d, cvts.gamcor); | 
| 865 | > | if (cvts.bradj) d *= m; | 
| 866 | > | colval(cvts.r.colors[x],RED) = | 
| 867 | > | colval(cvts.r.colors[x],GRN) = | 
| 868 | > | colval(cvts.r.colors[x],BLU) = d; | 
| 869 | > | } | 
| 870 | > | if (fwritescan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0) | 
| 871 | > | quiterr("error writing Radiance picture"); | 
| 872 | > | } | 
| 873 | > |  | 
| 874 | > |  | 
| 875 | > | static void | 
| 876 | > | Color2GGry(                     /* read/convert/write COLOR->G16 scanline */ | 
| 877 | > | uint32  y | 
| 878 | > | ) | 
| 879 | > | { | 
| 880 | > | int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01); | 
| 881 | > | float   m = pow(2.,(double)cvts.bradj); | 
| 882 | > | register int    x; | 
| 883 | > |  | 
| 884 | > | if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TWRD|C_GRY)) | 
| 885 | > | quiterr("internal error 1 in Color2GGry"); | 
| 886 | > |  | 
| 887 | > | if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0) | 
| 888 | > | quiterr("error reading Radiance picture"); | 
| 889 | > |  | 
| 890 | > | for (x = cvts.xmax; x--; ) { | 
| 891 | > | register float  f = m*( CHK(C_XYZE) ? | 
| 892 | > | colval(cvts.r.colors[x],CIEY) | 
| 893 | > | : bright(cvts.r.colors[x]) ); | 
| 894 | > | if (f <= 0) | 
| 895 | > | cvts.t.wp[x] = 0; | 
| 896 | > | else if (f >= 1) | 
| 897 | > | cvts.t.wp[x] = 0xffff; | 
| 898 | > | else if (dogamma) | 
| 899 | > | cvts.t.wp[x] = (int)((float)(1L<<16) * | 
| 900 | > | pow(f, 1./cvts.gamcor)); | 
| 901 | > | else | 
| 902 | > | cvts.t.wp[x] = (int)((float)(1L<<16) * f); | 
| 903 | > | } | 
| 904 | > |  | 
| 905 | > | if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0) | 
| 906 | > | quiterr("error writing TIFF output"); | 
| 907 | > | } | 
| 908 | > |  | 
| 909 | > |  | 
| 910 | > | static void | 
| 911 | > | Color2L(                        /* read/convert/write COLOR->Lfloat scanline */ | 
| 912 | > | uint32  y | 
| 913 | > | ) | 
| 914 | > | { | 
| 915 | > | float   m = pow(2.,(double)cvts.bradj); | 
| 916 | > | register int    x; | 
| 917 | > |  | 
| 918 | > | if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TFLT|C_GRY)) | 
| 919 |  | quiterr("internal error 1 in Color2L"); | 
| 920 |  |  | 
| 921 |  | if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0) | 
| 930 |  | } | 
| 931 |  |  | 
| 932 |  |  | 
| 933 | < | int | 
| 934 | < | Color2Luv(y)                    /* read/convert/write COLOR->Luv scanline */ | 
| 935 | < | uint32  y; | 
| 933 | > | static void | 
| 934 | > | Color2Luv(                      /* read/convert/write COLOR->Luv scanline */ | 
| 935 | > | uint32  y | 
| 936 | > | ) | 
| 937 |  | { | 
| 938 |  | register int    x; | 
| 939 |  |  | 
| 940 | < | if (CHK(C_RFLT|C_TFLT) != (C_RFLT|C_TFLT) | CHK(C_GRY)) | 
| 940 | > | if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != (C_RFLT|C_TFLT)) | 
| 941 |  | quiterr("internal error 1 in Color2Luv"); | 
| 942 |  |  | 
| 943 |  | if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0) | 
| 952 |  | for (x = cvts.xmax; x--; ) | 
| 953 |  | scalecolor(cvts.r.colors[x], m); | 
| 954 |  | } | 
| 955 | + | /* also works for float RGB */ | 
| 956 | + | for (x = cvts.xmax; x--; ) { | 
| 957 | + | cvts.t.fp[3*x] = colval(cvts.r.colors[x],CIEX); | 
| 958 | + | cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],CIEY); | 
| 959 | + | cvts.t.fp[3*x+2] = colval(cvts.r.colors[x],CIEZ); | 
| 960 | + | } | 
| 961 |  |  | 
| 962 | + | if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0) | 
| 963 | + | quiterr("error writing TIFF output"); | 
| 964 | + | } | 
| 965 | + |  | 
| 966 | + |  | 
| 967 | + | static void | 
| 968 | + | Color2RRGGBB(                   /* read/convert/write COLOR->RGB16 scanline */ | 
| 969 | + | uint32  y | 
| 970 | + | ) | 
| 971 | + | { | 
| 972 | + | int     dogamma = (cvts.gamcor < 0.99) | (cvts.gamcor > 1.01); | 
| 973 | + | float   m = pow(2.,(double)cvts.bradj); | 
| 974 | + | register int    x, i; | 
| 975 | + |  | 
| 976 | + | if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY) != (C_RFLT|C_TWRD)) | 
| 977 | + | quiterr("internal error 1 in Color2RRGGBB"); | 
| 978 | + |  | 
| 979 | + | if (freadscan(cvts.r.colors, cvts.xmax, cvts.rfp) < 0) | 
| 980 | + | quiterr("error reading Radiance picture"); | 
| 981 | + |  | 
| 982 |  | for (x = cvts.xmax; x--; ) { | 
| 983 | < | cvts.t.fp[3*x] = colval(cvts.r.colors[x],RED); | 
| 984 | < | cvts.t.fp[3*x+1] = colval(cvts.r.colors[x],GRN); | 
| 985 | < | cvts.t.fp[3*x+2] = colval(cvts.r.colors[x],BLU); | 
| 983 | > | if (CHK(C_CXFM)) { | 
| 984 | > | colortrans(cvts.r.colors[x], cvts.cmat, | 
| 985 | > | cvts.r.colors[x]); | 
| 986 | > | if (CHK(C_GAMUT)) | 
| 987 | > | clipgamut(cvts.r.colors[x], bright(cvts.r.colors[x]), | 
| 988 | > | CGAMUT_LOWER, cblack, cwhite); | 
| 989 | > | } | 
| 990 | > | for (i = 3; i--; ) { | 
| 991 | > | register float  f = m*colval(cvts.r.colors[x],i); | 
| 992 | > | if (f <= 0) | 
| 993 | > | cvts.t.wp[3*x + i] = 0; | 
| 994 | > | else if (f >= 1) | 
| 995 | > | cvts.t.wp[3*x + i] = 0xffff; | 
| 996 | > | else if (dogamma) | 
| 997 | > | cvts.t.wp[3*x + i] = (int)((float)(1L<<16) * | 
| 998 | > | pow(f, 1./cvts.gamcor)); | 
| 999 | > | else | 
| 1000 | > | cvts.t.wp[3*x + i] = (int)((float)(1L<<16)*f); | 
| 1001 | > | } | 
| 1002 |  | } | 
| 1003 |  |  | 
| 1004 |  | if (TIFFWriteScanline(cvts.tif, cvts.t.p, y, 0) < 0) | 
| 1006 |  | } | 
| 1007 |  |  | 
| 1008 |  |  | 
| 1009 | < | int | 
| 1010 | < | Colr2Gry(y)                     /* read/convert/write COLR->RGB scanline */ | 
| 1011 | < | uint32  y; | 
| 1009 | > | static void | 
| 1010 | > | Colr2Gry(                       /* read/convert/write COLR->RGB scanline */ | 
| 1011 | > | uint32  y | 
| 1012 | > | ) | 
| 1013 |  | { | 
| 1014 |  | register int    x; | 
| 1015 |  |  | 
| 1016 | < | if (CHK(C_RFLT|C_TFLT) | !CHK(C_GRY)) | 
| 1016 | > | if (CHK(C_RFLT|C_TWRD|C_TFLT|C_GRY) != C_GRY) | 
| 1017 |  | quiterr("internal error 1 in Colr2Gry"); | 
| 1018 |  |  | 
| 1019 |  | if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0) | 
| 1033 |  | } | 
| 1034 |  |  | 
| 1035 |  |  | 
| 1036 | < | int | 
| 1037 | < | Colr2RGB(y)                     /* read/convert/write COLR->RGB scanline */ | 
| 1038 | < | uint32  y; | 
| 1036 | > | static void | 
| 1037 | > | Colr2RGB(                       /* read/convert/write COLR->RGB scanline */ | 
| 1038 | > | uint32  y | 
| 1039 | > | ) | 
| 1040 |  | { | 
| 1041 |  | COLOR   ctmp; | 
| 1042 |  | register int    x; | 
| 1043 |  |  | 
| 1044 | < | if (CHK(C_RFLT|C_TFLT|C_GRY)) | 
| 1044 | > | if (CHK(C_RFLT|C_TFLT|C_TWRD|C_GRY)) | 
| 1045 |  | quiterr("internal error 1 in Colr2RGB"); | 
| 1046 |  |  | 
| 1047 |  | if (freadcolrs(cvts.r.colrs, cvts.xmax, cvts.rfp) < 0) |