ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_xyze.c
Revision: 2.12
Committed: Thu Aug 2 18:33:48 2018 UTC (5 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2
Changes since 2.11: +2 -2 lines
Log Message:
Created MAXFMTLEN to guard against buffer overrun attacks in header input

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.12 static const char RCSid[] = "$Id: ra_xyze.c,v 2.11 2016/08/18 00:52:48 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Program to convert between RADIANCE RGBE and XYZE formats
6 greg 2.6 * Added white-balance adjustment 10/01 (GW).
7 greg 2.1 */
8    
9     #include <stdio.h>
10 greg 2.6 #include <string.h>
11 greg 2.1 #include <math.h>
12 greg 2.6 #include <time.h>
13 schorsch 2.7
14     #include "platform.h"
15 greg 2.1 #include "color.h"
16     #include "resolu.h"
17 greg 2.11 #include "rtio.h"
18 greg 2.1
19     int rgbinp = -1; /* input is RGBE? */
20     int rgbout = 0; /* output should be RGBE? */
21     RGBPRIMS inprims = STDPRIMS; /* input primaries */
22     RGBPRIMS outprims = STDPRIMS; /* output primaries */
23     double expcomp = 1.0; /* exposure compensation */
24     int doflat = -1; /* produce flat file? */
25 greg 2.10 double origexp = -1.0; /* original exposure */
26 greg 2.1 char *progname;
27    
28 schorsch 2.8 static gethfunc headline;
29 schorsch 2.9 static void quiterr(char *err);
30     static void convert(void);
31    
32 greg 2.1
33 schorsch 2.8
34     static int
35     headline( /* process header line */
36     char *s,
37     void *p
38     )
39 greg 2.1 {
40 greg 2.12 char fmt[MAXFMTLEN];
41 greg 2.1
42     if (formatval(fmt, s)) { /* check if format string */
43     if (!strcmp(fmt,COLRFMT))
44     rgbinp = 1;
45     else if (!strcmp(fmt,CIEFMT))
46     rgbinp = 0;
47     else
48     rgbinp = -2;
49 gwlarson 2.5 return(0); /* don't echo */
50 greg 2.1 }
51 greg 2.10 if (origexp > 0.0 && isexpos(s)) {
52     origexp *= exposval(s);
53     return(0); /* don't echo */
54     }
55 greg 2.1 if (isprims(s)) { /* get input primaries */
56     primsval(inprims, s);
57 gwlarson 2.5 return(0); /* don't echo */
58 greg 2.1 }
59     /* should I grok colcorr also? */
60 gwlarson 2.5 return(fputs(s, stdout));
61 greg 2.1 }
62    
63    
64 schorsch 2.9 int
65     main(int argc, char *argv[])
66 greg 2.1 {
67     int i;
68 schorsch 2.7 SET_DEFAULT_BINARY();
69     SET_FILE_BINARY(stdin);
70     SET_FILE_BINARY(stdout);
71 greg 2.1 progname = argv[0];
72    
73     for (i = 1; i < argc; i++)
74     if (argv[i][0] == '-')
75     switch (argv[i][1]) {
76     case 'c': /* rle-compressed output */
77     doflat = 0;
78     break;
79     case 'u': /* flat output */
80     doflat = 1;
81     break;
82     case 'r': /* RGBE output */
83     rgbout = 1;
84     break;
85     case 'p': /* RGB primaries */
86 greg 2.2 if (i+8 >= argc)
87 greg 2.1 goto userr;
88     outprims[RED][CIEX] = atof(argv[++i]);
89     outprims[RED][CIEY] = atof(argv[++i]);
90     outprims[GRN][CIEX] = atof(argv[++i]);
91     outprims[GRN][CIEY] = atof(argv[++i]);
92     outprims[BLU][CIEX] = atof(argv[++i]);
93     outprims[BLU][CIEY] = atof(argv[++i]);
94     outprims[WHT][CIEX] = atof(argv[++i]);
95     outprims[WHT][CIEY] = atof(argv[++i]);
96     break;
97 greg 2.10 case 'o': /* original exposure */
98     origexp = 1.0;
99     break;
100 greg 2.1 case 'e': /* exposure compensation */
101     expcomp = atof(argv[++i]);
102     if (argv[i][0] == '+' || argv[i][0] == '-')
103     expcomp = pow(2., expcomp);
104     break;
105     default:
106     goto userr;
107     }
108     else
109     break;
110    
111     if (doflat < 0)
112     doflat = !rgbout;
113     if (i < argc-2)
114     goto userr;
115     if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
116     fprintf(stderr, "%s: can't open input \"%s\"\n",
117     progname, argv[i]);
118     exit(1);
119     }
120     if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
121     fprintf(stderr, "%s: can't open output \"%s\"\n",
122     progname, argv[i+1]);
123     exit(1);
124     }
125     getheader(stdin, headline, NULL);
126     if (rgbinp == -2)
127     quiterr("unrecognized input file format");
128     if (rgbinp == -1)
129     rgbinp = !rgbout;
130     printargs(argc, argv, stdout); /* add to header */
131     convert(); /* convert picture */
132     exit(0);
133     userr:
134 greg 2.10 fprintf(stderr, "Usage: %s [-r][-o][-e exp][-c|-u]", progname);
135 greg 2.1 fprintf(stderr, "[-p rx ry gx gy bx by wx wy] [input [output]]\n");
136     exit(1);
137     }
138    
139    
140 schorsch 2.9 static void
141     quiterr( /* print message and exit */
142     char *err
143     )
144 greg 2.1 {
145     if (err != NULL) {
146     fprintf(stderr, "%s: %s\n", progname, err);
147     exit(1);
148     }
149     exit(0);
150     }
151    
152    
153 schorsch 2.9 static void
154     convert(void) /* convert to XYZE or RGBE picture */
155 greg 2.1 {
156     int order;
157     int xmax, ymax;
158     COLORMAT xfm;
159     register COLOR *scanin;
160     register COLR *scanout;
161 greg 2.10 double exp2do = expcomp;
162     double exp2report = expcomp;
163 greg 2.1 int y;
164     register int x;
165 greg 2.10 /* recover original? */
166     if (origexp > 0.0)
167     exp2do /= origexp;
168 greg 2.1 /* compute transform */
169     if (rgbout) {
170     if (rgbinp) { /* RGBE -> RGBE */
171 greg 2.6 comprgb2rgbWBmat(xfm, inprims, outprims);
172 greg 2.1 } else { /* XYZE -> RGBE */
173 greg 2.6 compxyz2rgbWBmat(xfm, outprims);
174 greg 2.10 if (origexp > 0.0)
175     exp2do /= WHTEFFICACY;
176     else
177     exp2report *= WHTEFFICACY;
178 greg 2.1 }
179     } else {
180     if (rgbinp) { /* RGBE -> XYZE */
181 greg 2.6 comprgb2xyzWBmat(xfm, inprims);
182 greg 2.10 if (origexp > 0.0)
183     exp2do *= WHTEFFICACY;
184     else
185     exp2report /= WHTEFFICACY;
186 greg 2.1 } else { /* XYZE -> XYZE */
187     for (y = 0; y < 3; y++)
188     for (x = 0; x < 3; x++)
189 gregl 2.4 xfm[y][x] = x==y ? 1. : 0.;
190 greg 2.1 }
191     }
192 gregl 2.4 for (y = 0; y < 3; y++)
193     for (x = 0; x < 3; x++)
194 greg 2.10 xfm[y][x] *= exp2do;
195 greg 2.1 /* get input resolution */
196     if ((order = fgetresolu(&xmax, &ymax, stdin)) < 0)
197     quiterr("bad picture format");
198     /* complete output header */
199 greg 2.10 if ((exp2report < 0.99) | (exp2report > 1.01))
200     fputexpos(exp2report, stdout);
201 greg 2.1 if (rgbout) {
202     fputprims(outprims, stdout);
203     fputformat(COLRFMT, stdout);
204     } else
205     fputformat(CIEFMT, stdout);
206     putc('\n', stdout);
207     fputresolu(order, xmax, ymax, stdout);
208     /* allocate scanline */
209     scanin = (COLOR *)malloc(xmax*sizeof(COLOR));
210     if (scanin == NULL)
211     quiterr("out of memory in convert");
212     scanout = doflat ? (COLR *)malloc(xmax*sizeof(COLR)) : NULL;
213     /* convert image */
214     for (y = 0; y < ymax; y++) {
215     if (freadscan(scanin, xmax, stdin) < 0)
216     quiterr("error reading input picture");
217 greg 2.3 for (x = 0; x < xmax; x++) {
218 greg 2.1 colortrans(scanin[x], xfm, scanin[x]);
219 greg 2.3 if (rgbout)
220     clipgamut(scanin[x], bright(scanin[x]),
221     CGAMUT_LOWER, cblack, cwhite);
222     }
223 greg 2.1 if (scanout != NULL) {
224     for (x = 0; x < xmax; x++)
225     setcolr(scanout[x], colval(scanin[x],RED),
226     colval(scanin[x],GRN),
227     colval(scanin[x],BLU));
228 greg 2.11 putbinary((char *)scanout, sizeof(COLR), xmax, stdout);
229 greg 2.1 } else
230     fwritescan(scanin, xmax, stdout);
231     if (ferror(stdout))
232     quiterr("error writing output picture");
233     }
234     /* free scanline */
235 greg 2.6 free((void *)scanin);
236 greg 2.1 if (scanout != NULL)
237 greg 2.6 free((void *)scanout);
238 greg 2.1 }