Back to index

radiance  4R0+20100331
ra_xyze.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: ra_xyze.c,v 2.10 2006/08/22 21:38:22 greg Exp $";
00003 #endif
00004 /*
00005  *  Program to convert between RADIANCE RGBE and XYZE formats
00006  *  Added white-balance adjustment 10/01 (GW).
00007  */
00008 
00009 #include  <stdio.h>
00010 #include  <string.h>
00011 #include  <math.h>
00012 #include  <time.h>
00013 
00014 #include  "platform.h"
00015 #include  "color.h"
00016 #include  "resolu.h"
00017 
00018 int  rgbinp = -1;                  /* input is RGBE? */
00019 int  rgbout = 0;                   /* output should be RGBE? */
00020 RGBPRIMS  inprims = STDPRIMS;             /* input primaries */
00021 RGBPRIMS  outprims = STDPRIMS;            /* output primaries */
00022 double expcomp = 1.0;                     /* exposure compensation */
00023 int  doflat = -1;                  /* produce flat file? */
00024 double  origexp = -1.0;                   /* original exposure */
00025 char  *progname;
00026 
00027 static gethfunc headline;
00028 static void quiterr(char *err);
00029 static void convert(void);
00030 
00031 
00032 
00033 static int
00034 headline(                          /* process header line */
00035        char   *s,
00036        void   *p
00037 )
00038 {
00039        char   fmt[32];
00040 
00041        if (formatval(fmt, s)) {    /* check if format string */
00042               if (!strcmp(fmt,COLRFMT))
00043                      rgbinp = 1;
00044               else if (!strcmp(fmt,CIEFMT))
00045                      rgbinp = 0;
00046               else
00047                      rgbinp = -2;
00048               return(0);           /* don't echo */
00049        }
00050        if (origexp > 0.0 && isexpos(s)) {
00051               origexp *= exposval(s);
00052               return(0);           /* don't echo */
00053        }
00054        if (isprims(s)) {           /* get input primaries */
00055               primsval(inprims, s);
00056               return(0);           /* don't echo */
00057        }
00058                                    /* should I grok colcorr also? */
00059        return(fputs(s, stdout));
00060 }
00061 
00062 
00063 int
00064 main(int  argc, char  *argv[])
00065 {
00066        int  i;
00067        SET_DEFAULT_BINARY();
00068        SET_FILE_BINARY(stdin);
00069        SET_FILE_BINARY(stdout);
00070        progname = argv[0];
00071 
00072        for (i = 1; i < argc; i++)
00073               if (argv[i][0] == '-')
00074                      switch (argv[i][1]) {
00075                      case 'c':            /* rle-compressed output */
00076                             doflat = 0;
00077                             break;
00078                      case 'u':            /* flat output */
00079                             doflat = 1;
00080                             break;
00081                      case 'r':            /* RGBE output */
00082                             rgbout = 1;
00083                             break;
00084                      case 'p':            /* RGB primaries */
00085                             if (i+8 >= argc)
00086                                    goto userr;
00087                             outprims[RED][CIEX] = atof(argv[++i]);
00088                             outprims[RED][CIEY] = atof(argv[++i]);
00089                             outprims[GRN][CIEX] = atof(argv[++i]);
00090                             outprims[GRN][CIEY] = atof(argv[++i]);
00091                             outprims[BLU][CIEX] = atof(argv[++i]);
00092                             outprims[BLU][CIEY] = atof(argv[++i]);
00093                             outprims[WHT][CIEX] = atof(argv[++i]);
00094                             outprims[WHT][CIEY] = atof(argv[++i]);
00095                             break;
00096                      case 'o':            /* original exposure */
00097                             origexp = 1.0;
00098                             break;
00099                      case 'e':            /* exposure compensation */
00100                             expcomp = atof(argv[++i]);
00101                             if (argv[i][0] == '+' || argv[i][0] == '-')
00102                                    expcomp = pow(2., expcomp);
00103                             break;
00104                      default:
00105                             goto userr;
00106                      }
00107               else
00108                      break;
00109 
00110        if (doflat < 0)
00111               doflat = !rgbout;
00112        if (i < argc-2)
00113               goto userr;
00114        if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
00115               fprintf(stderr, "%s: can't open input \"%s\"\n",
00116                             progname, argv[i]);
00117               exit(1);
00118        }
00119        if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
00120               fprintf(stderr, "%s: can't open output \"%s\"\n",
00121                             progname, argv[i+1]);
00122               exit(1);
00123        }
00124        getheader(stdin, headline, NULL);
00125        if (rgbinp == -2)
00126               quiterr("unrecognized input file format");
00127        if (rgbinp == -1)
00128               rgbinp = !rgbout;
00129        printargs(argc, argv, stdout);            /* add to header */
00130        convert();                         /* convert picture */
00131        exit(0);
00132 userr:
00133        fprintf(stderr, "Usage: %s [-r][-o][-e exp][-c|-u]", progname);
00134        fprintf(stderr, "[-p rx ry gx gy bx by wx wy] [input [output]]\n");
00135        exit(1);
00136 }
00137 
00138 
00139 static void
00140 quiterr(             /* print message and exit */
00141        char  *err
00142 )
00143 {
00144        if (err != NULL) {
00145               fprintf(stderr, "%s: %s\n", progname, err);
00146               exit(1);
00147        }
00148        exit(0);
00149 }
00150 
00151 
00152 static void
00153 convert(void)                      /* convert to XYZE or RGBE picture */
00154 {
00155        int    order;
00156        int    xmax, ymax;
00157        COLORMAT      xfm;
00158        register COLOR       *scanin;
00159        register COLR *scanout;
00160        double exp2do = expcomp;
00161        double exp2report = expcomp;
00162        int    y;
00163        register int  x;
00164                                           /* recover original? */
00165        if (origexp > 0.0)
00166               exp2do /= origexp;
00167                                           /* compute transform */
00168        if (rgbout) {
00169               if (rgbinp) {               /* RGBE -> RGBE */
00170                      comprgb2rgbWBmat(xfm, inprims, outprims);
00171               } else {                    /* XYZE -> RGBE */
00172                      compxyz2rgbWBmat(xfm, outprims);
00173                      if (origexp > 0.0)
00174                             exp2do /= WHTEFFICACY;
00175                      else
00176                             exp2report *= WHTEFFICACY;
00177               }
00178        } else {
00179               if (rgbinp) {               /* RGBE -> XYZE */
00180                      comprgb2xyzWBmat(xfm, inprims);
00181                      if (origexp > 0.0)
00182                             exp2do *= WHTEFFICACY;
00183                      else
00184                             exp2report /= WHTEFFICACY;
00185               } else {                    /* XYZE -> XYZE */
00186                      for (y = 0; y < 3; y++)
00187                             for (x = 0; x < 3; x++)
00188                                    xfm[y][x] = x==y ? 1. : 0.;
00189               }
00190        }
00191        for (y = 0; y < 3; y++)
00192               for (x = 0; x < 3; x++)
00193                      xfm[y][x] *= exp2do;
00194                                           /* get input resolution */
00195        if ((order = fgetresolu(&xmax, &ymax, stdin)) < 0)
00196               quiterr("bad picture format");
00197                                           /* complete output header */
00198        if ((exp2report < 0.99) | (exp2report > 1.01))
00199               fputexpos(exp2report, stdout);
00200        if (rgbout) {
00201               fputprims(outprims, stdout);
00202               fputformat(COLRFMT, stdout);
00203        } else
00204               fputformat(CIEFMT, stdout);
00205        putc('\n', stdout);
00206        fputresolu(order, xmax, ymax, stdout);
00207                                           /* allocate scanline */
00208        scanin = (COLOR *)malloc(xmax*sizeof(COLOR));
00209        if (scanin == NULL)
00210               quiterr("out of memory in convert");
00211        scanout = doflat ? (COLR *)malloc(xmax*sizeof(COLR)) : NULL;
00212                                           /* convert image */
00213        for (y = 0; y < ymax; y++) {
00214               if (freadscan(scanin, xmax, stdin) < 0)
00215                      quiterr("error reading input picture");
00216               for (x = 0; x < xmax; x++) {
00217                      colortrans(scanin[x], xfm, scanin[x]);
00218                      if (rgbout)
00219                             clipgamut(scanin[x], bright(scanin[x]),
00220                                           CGAMUT_LOWER, cblack, cwhite);
00221               }
00222               if (scanout != NULL) {
00223                      for (x = 0; x < xmax; x++)
00224                             setcolr(scanout[x], colval(scanin[x],RED),
00225                                           colval(scanin[x],GRN),
00226                                           colval(scanin[x],BLU));
00227                      fwrite((char *)scanout, sizeof(COLR), xmax, stdout);
00228               } else
00229                      fwritescan(scanin, xmax, stdout);
00230               if (ferror(stdout))
00231                      quiterr("error writing output picture");
00232        }
00233                                           /* free scanline */
00234        free((void *)scanin);
00235        if (scanout != NULL)
00236               free((void *)scanout);
00237 }