| 1 | – | /* Copyright (c) 1997 Regents of the University of California */ | 
| 2 | – |  | 
| 1 |  | #ifndef lint | 
| 2 | < | static char SCCSid[] = "$SunId$ LBL"; | 
| 2 | > | static const char       RCSid[] = "$Id$"; | 
| 3 |  | #endif | 
| 6 | – |  | 
| 4 |  | /* | 
| 5 |  | *  Program to convert between RADIANCE RGBE and XYZE formats | 
| 6 | + | *  Added white-balance adjustment 10/01 (GW). | 
| 7 |  | */ | 
| 8 |  |  | 
| 9 |  | #include  <stdio.h> | 
| 10 | + | #include  <string.h> | 
| 11 |  | #include  <math.h> | 
| 12 | + | #include  <time.h> | 
| 13 | + |  | 
| 14 | + | #include  "platform.h" | 
| 15 |  | #include  "color.h" | 
| 16 |  | #include  "resolu.h" | 
| 17 |  |  | 
| 16 | – | #ifdef MSDOS | 
| 17 | – | #include  <fcntl.h> | 
| 18 | – | #endif | 
| 19 | – |  | 
| 20 | – | extern char  *malloc(), *strcpy(); | 
| 21 | – |  | 
| 18 |  | int  rgbinp = -1;                       /* input is RGBE? */ | 
| 23 | – |  | 
| 19 |  | int  rgbout = 0;                        /* output should be RGBE? */ | 
| 25 | – |  | 
| 20 |  | RGBPRIMS  inprims = STDPRIMS;           /* input primaries */ | 
| 27 | – |  | 
| 21 |  | RGBPRIMS  outprims = STDPRIMS;          /* output primaries */ | 
| 29 | – |  | 
| 22 |  | double  expcomp = 1.0;                  /* exposure compensation */ | 
| 31 | – |  | 
| 23 |  | int  doflat = -1;                       /* produce flat file? */ | 
| 24 | < |  | 
| 24 | > | double  origexp = -1.0;                 /* original exposure */ | 
| 25 |  | char  *progname; | 
| 26 |  |  | 
| 27 | + | static gethfunc headline; | 
| 28 | + | static void quiterr(char *err); | 
| 29 | + | static void convert(void); | 
| 30 |  |  | 
| 31 | < | headline(s)                             /* process header line */ | 
| 32 | < | char    *s; | 
| 31 | > |  | 
| 32 | > |  | 
| 33 | > | static int | 
| 34 | > | headline(                               /* process header line */ | 
| 35 | > | char    *s, | 
| 36 | > | void    *p | 
| 37 | > | ) | 
| 38 |  | { | 
| 39 |  | char    fmt[32]; | 
| 40 |  |  | 
| 45 |  | rgbinp = 0; | 
| 46 |  | else | 
| 47 |  | rgbinp = -2; | 
| 48 | < | return;                 /* don't echo */ | 
| 48 | > | return(0);              /* don't echo */ | 
| 49 |  | } | 
| 50 | + | if (origexp > 0.0 && isexpos(s)) { | 
| 51 | + | origexp *= exposval(s); | 
| 52 | + | return(0);              /* don't echo */ | 
| 53 | + | } | 
| 54 |  | if (isprims(s)) {               /* get input primaries */ | 
| 55 |  | primsval(inprims, s); | 
| 56 | < | return;                 /* don't echo */ | 
| 56 | > | return(0);              /* don't echo */ | 
| 57 |  | } | 
| 58 |  | /* should I grok colcorr also? */ | 
| 59 | < | fputs(s, stdout); | 
| 59 | > | return(fputs(s, stdout)); | 
| 60 |  | } | 
| 61 |  |  | 
| 62 |  |  | 
| 63 | < | main(argc, argv) | 
| 64 | < | int  argc; | 
| 62 | < | char  *argv[]; | 
| 63 | > | int | 
| 64 | > | main(int  argc, char  *argv[]) | 
| 65 |  | { | 
| 66 |  | int  i; | 
| 67 | < | #ifdef MSDOS | 
| 68 | < | extern int  _fmode; | 
| 69 | < | _fmode = O_BINARY; | 
| 68 | < | setmode(fileno(stdin), O_BINARY); | 
| 69 | < | setmode(fileno(stdout), O_BINARY); | 
| 70 | < | #endif | 
| 67 | > | SET_DEFAULT_BINARY(); | 
| 68 | > | SET_FILE_BINARY(stdin); | 
| 69 | > | SET_FILE_BINARY(stdout); | 
| 70 |  | progname = argv[0]; | 
| 71 |  |  | 
| 72 |  | for (i = 1; i < argc; i++) | 
| 93 |  | outprims[WHT][CIEX] = atof(argv[++i]); | 
| 94 |  | outprims[WHT][CIEY] = atof(argv[++i]); | 
| 95 |  | break; | 
| 96 | + | case 'o':               /* original exposure */ | 
| 97 | + | origexp = 1.0; | 
| 98 | + | break; | 
| 99 |  | case 'e':               /* exposure compensation */ | 
| 100 |  | expcomp = atof(argv[++i]); | 
| 101 |  | if (argv[i][0] == '+' || argv[i][0] == '-') | 
| 127 |  | if (rgbinp == -1) | 
| 128 |  | rgbinp = !rgbout; | 
| 129 |  | printargs(argc, argv, stdout);          /* add to header */ | 
| 128 | – | if (expcomp < 0.99 || expcomp > 1.01) | 
| 129 | – | fputexpos(expcomp, stdout); | 
| 130 |  | convert();                              /* convert picture */ | 
| 131 |  | exit(0); | 
| 132 |  | userr: | 
| 133 | < | fprintf(stderr, "Usage: %s [-r][-e exp][-c|-u]", progname); | 
| 133 | > | fprintf(stderr, "Usage: %s [-r][-o][-e exp][-c|-u]", progname); | 
| 134 |  | fprintf(stderr, "[-p rx ry gx gy bx by wx wy] [input [output]]\n"); | 
| 135 |  | exit(1); | 
| 136 |  | } | 
| 137 |  |  | 
| 138 |  |  | 
| 139 | < | quiterr(err)            /* print message and exit */ | 
| 140 | < | char  *err; | 
| 139 | > | static void | 
| 140 | > | quiterr(                /* print message and exit */ | 
| 141 | > | char  *err | 
| 142 | > | ) | 
| 143 |  | { | 
| 144 |  | if (err != NULL) { | 
| 145 |  | fprintf(stderr, "%s: %s\n", progname, err); | 
| 149 |  | } | 
| 150 |  |  | 
| 151 |  |  | 
| 152 | < | convert()                               /* convert to XYZE or RGBE picture */ | 
| 152 | > | static void | 
| 153 | > | convert(void)                           /* convert to XYZE or RGBE picture */ | 
| 154 |  | { | 
| 155 |  | int     order; | 
| 156 |  | int     xmax, ymax; | 
| 157 |  | COLORMAT        xfm; | 
| 158 |  | register COLOR  *scanin; | 
| 159 |  | register COLR   *scanout; | 
| 160 | + | double  exp2do = expcomp; | 
| 161 | + | double  exp2report = expcomp; | 
| 162 |  | int     y; | 
| 163 |  | register int    x; | 
| 164 | + | /* recover original? */ | 
| 165 | + | if (origexp > 0.0) | 
| 166 | + | exp2do /= origexp; | 
| 167 |  | /* compute transform */ | 
| 168 |  | if (rgbout) { | 
| 161 | – | double  mult; | 
| 169 |  | if (rgbinp) {                   /* RGBE -> RGBE */ | 
| 170 | < | comprgb2rgbmat(xfm, inprims, outprims); | 
| 164 | < | mult = expcomp; | 
| 170 | > | comprgb2rgbWBmat(xfm, inprims, outprims); | 
| 171 |  | } else {                        /* XYZE -> RGBE */ | 
| 172 | < | compxyz2rgbmat(xfm, outprims); | 
| 173 | < | mult = expcomp/WHTEFFICACY; | 
| 172 | > | compxyz2rgbWBmat(xfm, outprims); | 
| 173 | > | if (origexp > 0.0) | 
| 174 | > | exp2do /= WHTEFFICACY; | 
| 175 | > | else | 
| 176 | > | exp2report *= WHTEFFICACY; | 
| 177 |  | } | 
| 169 | – | for (y = 0; y < 3; y++) | 
| 170 | – | for (x = 0; x < 3; x++) | 
| 171 | – | xfm[y][x] *= mult; | 
| 178 |  | } else { | 
| 179 |  | if (rgbinp) {                   /* RGBE -> XYZE */ | 
| 180 | < | comprgb2xyzmat(xfm, inprims); | 
| 181 | < | for (y = 0; y < 3; y++) | 
| 182 | < | for (x = 0; x < 3; x++) | 
| 183 | < | xfm[y][x] *= WHTEFFICACY*expcomp; | 
| 180 | > | comprgb2xyzWBmat(xfm, inprims); | 
| 181 | > | if (origexp > 0.0) | 
| 182 | > | exp2do *= WHTEFFICACY; | 
| 183 | > | else | 
| 184 | > | exp2report /= WHTEFFICACY; | 
| 185 |  | } else {                        /* XYZE -> XYZE */ | 
| 186 |  | for (y = 0; y < 3; y++) | 
| 187 |  | for (x = 0; x < 3; x++) | 
| 188 | < | xfm[y][x] = x==y ? expcomp : 0.; | 
| 188 | > | xfm[y][x] = x==y ? 1. : 0.; | 
| 189 |  | } | 
| 190 |  | } | 
| 191 | + | for (y = 0; y < 3; y++) | 
| 192 | + | for (x = 0; x < 3; x++) | 
| 193 | + | xfm[y][x] *= exp2do; | 
| 194 |  | /* get input resolution */ | 
| 195 |  | if ((order = fgetresolu(&xmax, &ymax, stdin)) < 0) | 
| 196 |  | quiterr("bad picture format"); | 
| 197 |  | /* complete output header */ | 
| 198 | + | if ((exp2report < 0.99) | (exp2report > 1.01)) | 
| 199 | + | fputexpos(exp2report, stdout); | 
| 200 |  | if (rgbout) { | 
| 201 |  | fputprims(outprims, stdout); | 
| 202 |  | fputformat(COLRFMT, stdout); | 
| 231 |  | quiterr("error writing output picture"); | 
| 232 |  | } | 
| 233 |  | /* free scanline */ | 
| 234 | < | free((char *)scanin); | 
| 234 | > | free((void *)scanin); | 
| 235 |  | if (scanout != NULL) | 
| 236 | < | free((char *)scanout); | 
| 236 | > | free((void *)scanout); | 
| 237 |  | } |