--- ray/src/px/ra_xyze.c 1995/10/15 14:07:12 2.1 +++ ray/src/px/ra_xyze.c 2006/08/22 21:38:22 2.10 @@ -1,41 +1,40 @@ -/* Copyright (c) 1995 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: ra_xyze.c,v 2.10 2006/08/22 21:38:22 greg Exp $"; #endif - /* * Program to convert between RADIANCE RGBE and XYZE formats + * Added white-balance adjustment 10/01 (GW). */ #include +#include #include +#include + +#include "platform.h" #include "color.h" #include "resolu.h" -#ifdef MSDOS -#include -#endif - -extern char *malloc(), *strcpy(); - int rgbinp = -1; /* input is RGBE? */ - int rgbout = 0; /* output should be RGBE? */ - RGBPRIMS inprims = STDPRIMS; /* input primaries */ - RGBPRIMS outprims = STDPRIMS; /* output primaries */ - double expcomp = 1.0; /* exposure compensation */ - int doflat = -1; /* produce flat file? */ - +double origexp = -1.0; /* original exposure */ char *progname; +static gethfunc headline; +static void quiterr(char *err); +static void convert(void); -headline(s) /* process header line */ -char *s; + + +static int +headline( /* process header line */ + char *s, + void *p +) { char fmt[32]; @@ -46,28 +45,28 @@ char *s; rgbinp = 0; else rgbinp = -2; - return; /* don't echo */ + return(0); /* don't echo */ } + if (origexp > 0.0 && isexpos(s)) { + origexp *= exposval(s); + return(0); /* don't echo */ + } if (isprims(s)) { /* get input primaries */ primsval(inprims, s); - return; /* don't echo */ + return(0); /* don't echo */ } /* should I grok colcorr also? */ - fputs(s, stdout); + return(fputs(s, stdout)); } -main(argc, argv) -int argc; -char *argv[]; +int +main(int argc, char *argv[]) { int i; -#ifdef MSDOS - extern int _fmode; - _fmode = O_BINARY; - setmode(fileno(stdin), O_BINARY); - setmode(fileno(stdout), O_BINARY); -#endif + SET_DEFAULT_BINARY(); + SET_FILE_BINARY(stdin); + SET_FILE_BINARY(stdout); progname = argv[0]; for (i = 1; i < argc; i++) @@ -83,7 +82,7 @@ char *argv[]; rgbout = 1; break; case 'p': /* RGB primaries */ - if (i+9 >= argc) + if (i+8 >= argc) goto userr; outprims[RED][CIEX] = atof(argv[++i]); outprims[RED][CIEY] = atof(argv[++i]); @@ -94,6 +93,9 @@ char *argv[]; outprims[WHT][CIEX] = atof(argv[++i]); outprims[WHT][CIEY] = atof(argv[++i]); break; + case 'o': /* original exposure */ + origexp = 1.0; + break; case 'e': /* exposure compensation */ expcomp = atof(argv[++i]); if (argv[i][0] == '+' || argv[i][0] == '-') @@ -125,19 +127,19 @@ char *argv[]; if (rgbinp == -1) rgbinp = !rgbout; printargs(argc, argv, stdout); /* add to header */ - if (expcomp < 0.99 || expcomp > 1.01) - fputexpos(expcomp, stdout); convert(); /* convert picture */ exit(0); userr: - fprintf(stderr, "Usage: %s [-r][-e exp][-c|-u]", progname); + fprintf(stderr, "Usage: %s [-r][-o][-e exp][-c|-u]", progname); fprintf(stderr, "[-p rx ry gx gy bx by wx wy] [input [output]]\n"); exit(1); } -quiterr(err) /* print message and exit */ -char *err; +static void +quiterr( /* print message and exit */ + char *err +) { if (err != NULL) { fprintf(stderr, "%s: %s\n", progname, err); @@ -147,44 +149,54 @@ char *err; } -convert() /* convert to XYZE or RGBE picture */ +static void +convert(void) /* convert to XYZE or RGBE picture */ { int order; int xmax, ymax; COLORMAT xfm; register COLOR *scanin; register COLR *scanout; + double exp2do = expcomp; + double exp2report = expcomp; int y; register int x; + /* recover original? */ + if (origexp > 0.0) + exp2do /= origexp; /* compute transform */ if (rgbout) { - double mult; if (rgbinp) { /* RGBE -> RGBE */ - comprgb2rgbmat(xfm, inprims, outprims); - mult = expcomp; + comprgb2rgbWBmat(xfm, inprims, outprims); } else { /* XYZE -> RGBE */ - compxyz2rgbmat(xfm, outprims); - mult = expcomp/WHTEFFICACY; + compxyz2rgbWBmat(xfm, outprims); + if (origexp > 0.0) + exp2do /= WHTEFFICACY; + else + exp2report *= WHTEFFICACY; } - for (y = 0; y < 3; y++) - for (x = 0; x < 3; x++) - xfm[y][x] *= mult; } else { if (rgbinp) { /* RGBE -> XYZE */ - comprgb2xyzmat(xfm, inprims); - for (y = 0; y < 3; y++) - for (x = 0; x < 3; x++) - xfm[y][x] *= WHTEFFICACY*expcomp; + comprgb2xyzWBmat(xfm, inprims); + if (origexp > 0.0) + exp2do *= WHTEFFICACY; + else + exp2report /= WHTEFFICACY; } else { /* XYZE -> XYZE */ for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - xfm[y][x] = x==y ? expcomp : 0.; + xfm[y][x] = x==y ? 1. : 0.; } } + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) + xfm[y][x] *= exp2do; /* get input resolution */ if ((order = fgetresolu(&xmax, &ymax, stdin)) < 0) quiterr("bad picture format"); /* complete output header */ + if ((exp2report < 0.99) | (exp2report > 1.01)) + fputexpos(exp2report, stdout); if (rgbout) { fputprims(outprims, stdout); fputformat(COLRFMT, stdout); @@ -201,8 +213,12 @@ convert() /* convert to XYZE or RGBE picture */ for (y = 0; y < ymax; y++) { if (freadscan(scanin, xmax, stdin) < 0) quiterr("error reading input picture"); - for (x = 0; x < xmax; x++) + for (x = 0; x < xmax; x++) { colortrans(scanin[x], xfm, scanin[x]); + if (rgbout) + clipgamut(scanin[x], bright(scanin[x]), + CGAMUT_LOWER, cblack, cwhite); + } if (scanout != NULL) { for (x = 0; x < xmax; x++) setcolr(scanout[x], colval(scanin[x],RED), @@ -215,7 +231,7 @@ convert() /* convert to XYZE or RGBE picture */ quiterr("error writing output picture"); } /* free scanline */ - free((char *)scanin); + free((void *)scanin); if (scanout != NULL) - free((char *)scanout); + free((void *)scanout); }