ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_xyze.c
(Generate patch)

Comparing ray/src/px/ra_xyze.c (file contents):
Revision 2.1 by greg, Sun Oct 15 14:07:12 1995 UTC vs.
Revision 2.17 by greg, Sat Jun 7 05:09:46 2025 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1995 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  
11 #include  <stdio.h>
9   #include  <math.h>
10 + #include  "platform.h"
11   #include  "color.h"
12   #include  "resolu.h"
13 + #include  "rtio.h"
14  
15 < #ifdef MSDOS
16 < #include  <fcntl.h>
18 < #endif
19 <
20 < extern char  *malloc(), *strcpy();
21 <
22 < int  rgbinp = -1;                       /* input is RGBE? */
23 <
15 > enum {InpUNK, InpRGB, InpXYZ, InpSPEC}; /* input format */
16 > int  infmt = InpUNK;
17   int  rgbout = 0;                        /* output should be RGBE? */
25
18   RGBPRIMS  inprims = STDPRIMS;           /* input primaries */
27
19   RGBPRIMS  outprims = STDPRIMS;          /* output primaries */
29
20   double  expcomp = 1.0;                  /* exposure compensation */
31
21   int  doflat = -1;                       /* produce flat file? */
22 + double  origexp = -1.0;                 /* original exposure */
23  
24 < char  *progname;
24 > static gethfunc headline;
25 > static void quiterr(char *err);
26 > static void myreadscan(COLOR *scn, int len);
27 > static void convert(void);
28  
29  
30 < headline(s)                             /* process header line */
31 < char    *s;
30 >
31 > static int
32 > headline(                               /* process header line */
33 >        char    *s,
34 >        void    *p
35 > )
36   {
37 <        char    fmt[32];
37 >        char    fmt[MAXFMTLEN];
38  
39          if (formatval(fmt, s)) {        /* check if format string */
40                  if (!strcmp(fmt,COLRFMT))
41 <                        rgbinp = 1;
41 >                        infmt = InpRGB;
42                  else if (!strcmp(fmt,CIEFMT))
43 <                        rgbinp = 0;
43 >                        infmt = InpXYZ;
44 >                else if (!strcmp(fmt,SPECFMT))
45 >                        infmt = InpSPEC;
46                  else
47 <                        rgbinp = -2;
48 <                return;                 /* don't echo */
47 >                        infmt = InpUNK;
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 +        if (iswlsplit(s)) {             /* get wavelength limits */
59 +                wlsplitval(WLPART, s);
60 +                return(0);              /* don't echo */
61 +        }
62 +        if (isncomp(s)) {               /* number of color samples */
63 +                NCSAMP = ncompval(s);
64 +                return(0);              /* don't echo */
65 +        }
66                                          /* should I grok colcorr also? */
67 <        fputs(s, stdout);
67 >        return(fputs(s, stdout));
68   }
69  
70  
71 < main(argc, argv)
72 < int  argc;
62 < char  *argv[];
71 > int
72 > main(int  argc, char  *argv[])
73   {
74          int  i;
65 #ifdef MSDOS
66        extern int  _fmode;
67        _fmode = O_BINARY;
68        setmode(fileno(stdin), O_BINARY);
69        setmode(fileno(stdout), O_BINARY);
70 #endif
71        progname = argv[0];
75  
76 +        SET_DEFAULT_BINARY();
77 +        SET_FILE_BINARY(stdin);
78 +        SET_FILE_BINARY(stdout);
79 +        fixargv0(argv[0]);
80 +
81          for (i = 1; i < argc; i++)
82                  if (argv[i][0] == '-')
83                          switch (argv[i][1]) {
# Line 83 | Line 91 | char  *argv[];
91                                  rgbout = 1;
92                                  break;
93                          case 'p':               /* RGB primaries */
94 <                                if (i+9 >= argc)
94 >                                if (i+8 >= argc)
95                                          goto userr;
96                                  outprims[RED][CIEX] = atof(argv[++i]);
97                                  outprims[RED][CIEY] = atof(argv[++i]);
# Line 94 | Line 102 | char  *argv[];
102                                  outprims[WHT][CIEX] = atof(argv[++i]);
103                                  outprims[WHT][CIEY] = atof(argv[++i]);
104                                  break;
105 +                        case 'o':               /* original exposure */
106 +                                origexp = 1.0;
107 +                                break;
108                          case 'e':               /* exposure compensation */
109                                  expcomp = atof(argv[++i]);
110                                  if (argv[i][0] == '+' || argv[i][0] == '-')
# Line 120 | Line 131 | char  *argv[];
131                  exit(1);
132          }
133          getheader(stdin, headline, NULL);
134 <        if (rgbinp == -2)
135 <                quiterr("unrecognized input file format");
136 <        if (rgbinp == -1)
137 <                rgbinp = !rgbout;
134 >        if (infmt == InpUNK)
135 >                quiterr("unrecognized/missing input file format");
136 >        if (infmt == InpSPEC ? (NCSAMP <= 3) | (NCSAMP > MAXCSAMP) :
137 >                        NCSAMP != 3)
138 >                quiterr("bad number of color components");
139          printargs(argc, argv, stdout);          /* add to header */
128        if (expcomp < 0.99 || expcomp > 1.01)
129                fputexpos(expcomp, stdout);
140          convert();                              /* convert picture */
141          exit(0);
142   userr:
143 <        fprintf(stderr, "Usage: %s [-r][-e exp][-c|-u]", progname);
143 >        fprintf(stderr, "Usage: %s [-r][-o][-e exp][-c|-u]", progname);
144          fprintf(stderr, "[-p rx ry gx gy bx by wx wy] [input [output]]\n");
145          exit(1);
146   }
147  
148  
149 < quiterr(err)            /* print message and exit */
150 < char  *err;
149 > static void
150 > quiterr(                /* print message and exit */
151 >        char  *err
152 > )
153   {
154          if (err != NULL) {
155                  fprintf(stderr, "%s: %s\n", progname, err);
# Line 147 | Line 159 | char  *err;
159   }
160  
161  
162 < convert()                               /* convert to XYZE or RGBE picture */
162 > static void
163 > myreadscan(COLOR *scn, int len)
164   {
165 +        if (infmt == InpSPEC) {         /* read & convert to XYZ */
166 +                static COLOR    *scomp = NULL;
167 +                SCOLR           sclr;
168 +                SCOLOR          scol;
169 +                COLOR           xyz;
170 +                int             n;
171 +                if (scomp == NULL) {    /* initialize conversion */
172 +                        scomp = (COLOR *)malloc(sizeof(COLOR)*NCSAMP);
173 +                        if (scomp == NULL)
174 +                                quiterr("out of memory in myreadscan");
175 +                        for (n = NCSAMP; n--; )
176 +                                spec_cie(scomp[n],
177 +                                        WLPART[0] + (WLPART[3] - WLPART[0])*(n+1)/NCSAMP,
178 +                                        WLPART[0] + (WLPART[3] - WLPART[0])*n/NCSAMP);
179 +                }
180 +                while (len-- > 0) {
181 +                        if (getbinary(sclr, LSCOLR, 1, stdin) != 1)
182 +                                goto readerr;
183 +                        scolr_scolor(scol, sclr);
184 +                        setcolor(*scn, 0, 0, 0);
185 +                        for (n = NCSAMP; n--; ) {
186 +                                copycolor(xyz, scomp[n]);
187 +                                scalecolor(xyz, scol[n]);
188 +                                addcolor(*scn, xyz);
189 +                        }
190 +                        scn++;
191 +                }
192 +                return;
193 +        }                               /* else read as RGBE/XYZE */
194 +        if (freadscan(scn, len, stdin) >= 0)
195 +                return;
196 + readerr:
197 +        quiterr("error reading input picture");
198 + }
199 +
200 +
201 + static void
202 + convert(void)                           /* convert to XYZE or RGBE picture */
203 + {
204          int     order;
205          int     xmax, ymax;
206          COLORMAT        xfm;
207 <        register COLOR  *scanin;
208 <        register COLR   *scanout;
207 >        COLOR   *scanin;
208 >        COLR    *scanout;
209 >        double  exp2do = expcomp;
210 >        double  exp2report = expcomp;
211          int     y;
212 <        register int    x;
212 >        int     x;
213 >                                                /* recover original? */
214 >        if (origexp > 0.0)
215 >                exp2do /= origexp;
216                                                  /* compute transform */
217          if (rgbout) {
218 <                double  mult;
219 <                if (rgbinp) {                   /* RGBE -> RGBE */
220 <                        comprgb2rgbmat(xfm, inprims, outprims);
221 <                        mult = expcomp;
165 <                } else {                        /* XYZE -> RGBE */
166 <                        compxyz2rgbmat(xfm, outprims);
167 <                        mult = expcomp/WHTEFFICACY;
218 >                if (infmt == InpRGB) {          /* RGBE -> RGBE */
219 >                        comprgb2rgbWBmat(xfm, inprims, outprims);
220 >                } else {                        /* XYZE/Spectral -> RGBE */
221 >                        compxyz2rgbWBmat(xfm, outprims);
222                  }
223 <                for (y = 0; y < 3; y++)
224 <                        for (x = 0; x < 3; x++)
225 <                                xfm[y][x] *= mult;
223 >                if (infmt == InpXYZ) {
224 >                        if (origexp > 0.0)
225 >                                exp2do /= WHTEFFICACY;
226 >                        else
227 >                                exp2report *= WHTEFFICACY;
228 >                }
229          } else {
230 <                if (rgbinp) {                   /* RGBE -> XYZE */
231 <                        comprgb2xyzmat(xfm, inprims);
232 <                        for (y = 0; y < 3; y++)
233 <                                for (x = 0; x < 3; x++)
234 <                                        xfm[y][x] *= WHTEFFICACY*expcomp;
235 <                } else {                        /* XYZE -> XYZE */
179 <                        for (y = 0; y < 3; y++)
180 <                                for (x = 0; x < 3; x++)
181 <                                        xfm[y][x] = x==y ? expcomp : 0.;
230 >                if (infmt == InpRGB) {          /* RGBE -> XYZE */
231 >                        comprgb2xyzWBmat(xfm, inprims);
232 >                } else {                        /* XYZE/Spectral -> XYZE */
233 >                        memset(xfm, 0, sizeof(xfm));
234 >                        for (x = 3; x--; )
235 >                                xfm[x][x] = 1.;
236                  }
237 +                if (infmt != InpXYZ) {
238 +                        if (origexp > 0)
239 +                                exp2do *= WHTEFFICACY;
240 +                        else
241 +                                exp2report /= WHTEFFICACY;
242 +                }
243          }
244 +        for (y = 0; y < 3; y++)
245 +                for (x = 0; x < 3; x++)
246 +                        xfm[y][x] *= exp2do;
247                                                  /* get input resolution */
248          if ((order = fgetresolu(&xmax, &ymax, stdin)) < 0)
249                  quiterr("bad picture format");
250                                                  /* complete output header */
251 +        if ((exp2report < 0.99) | (exp2report > 1.01))
252 +                fputexpos(exp2report, stdout);
253          if (rgbout) {
254                  fputprims(outprims, stdout);
255                  fputformat(COLRFMT, stdout);
# Line 196 | Line 261 | convert()                              /* convert to XYZE or RGBE picture */
261          scanin = (COLOR *)malloc(xmax*sizeof(COLOR));
262          if (scanin == NULL)
263                  quiterr("out of memory in convert");
264 <        scanout = doflat ? (COLR *)malloc(xmax*sizeof(COLR)) : NULL;
264 >        scanout = doflat ? (COLR *)malloc(xmax*sizeof(COLR)) : (COLR *)NULL;
265                                                  /* convert image */
266          for (y = 0; y < ymax; y++) {
267 <                if (freadscan(scanin, xmax, stdin) < 0)
268 <                        quiterr("error reading input picture");
204 <                for (x = 0; x < xmax; x++)
267 >                myreadscan(scanin, xmax);
268 >                for (x = 0; x < xmax; x++) {
269                          colortrans(scanin[x], xfm, scanin[x]);
270 +                        if (rgbout)
271 +                                clipgamut(scanin[x], bright(scanin[x]),
272 +                                                CGAMUT_LOWER, cblack, cwhite);
273 +                }
274                  if (scanout != NULL) {
275                          for (x = 0; x < xmax; x++)
276                                  setcolr(scanout[x], colval(scanin[x],RED),
277                                                  colval(scanin[x],GRN),
278                                                  colval(scanin[x],BLU));
279 <                        fwrite((char *)scanout, sizeof(COLR), xmax, stdout);
279 >                        putbinary(scanout, sizeof(COLR), xmax, stdout);
280                  } else
281                          fwritescan(scanin, xmax, stdout);
282                  if (ferror(stdout))
283                          quiterr("error writing output picture");
284          }
285                                                  /* free scanline */
286 <        free((char *)scanin);
286 >        free(scanin);
287          if (scanout != NULL)
288 <                free((char *)scanout);
288 >                free(scanout);
289   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines