ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_xyze.c
Revision: 2.17
Committed: Sat Jun 7 05:09:46 2025 UTC (2 weeks, 4 days ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.16: +1 -2 lines
Log Message:
refactor: Put some declarations into "paths.h" and included in "platform.h"

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.17 static const char RCSid[] = "$Id: ra_xyze.c,v 2.16 2025/06/06 19:11:21 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 <math.h>
10 schorsch 2.7 #include "platform.h"
11 greg 2.1 #include "color.h"
12     #include "resolu.h"
13 greg 2.11 #include "rtio.h"
14 greg 2.1
15 greg 2.14 enum {InpUNK, InpRGB, InpXYZ, InpSPEC}; /* input format */
16     int infmt = InpUNK;
17 greg 2.1 int rgbout = 0; /* output should be RGBE? */
18     RGBPRIMS inprims = STDPRIMS; /* input primaries */
19     RGBPRIMS outprims = STDPRIMS; /* output primaries */
20     double expcomp = 1.0; /* exposure compensation */
21     int doflat = -1; /* produce flat file? */
22 greg 2.10 double origexp = -1.0; /* original exposure */
23 greg 2.1
24 schorsch 2.8 static gethfunc headline;
25 schorsch 2.9 static void quiterr(char *err);
26 greg 2.14 static void myreadscan(COLOR *scn, int len);
27 schorsch 2.9 static void convert(void);
28    
29 greg 2.1
30 schorsch 2.8
31     static int
32     headline( /* process header line */
33     char *s,
34     void *p
35     )
36 greg 2.1 {
37 greg 2.12 char fmt[MAXFMTLEN];
38 greg 2.1
39     if (formatval(fmt, s)) { /* check if format string */
40     if (!strcmp(fmt,COLRFMT))
41 greg 2.14 infmt = InpRGB;
42 greg 2.1 else if (!strcmp(fmt,CIEFMT))
43 greg 2.14 infmt = InpXYZ;
44     else if (!strcmp(fmt,SPECFMT))
45     infmt = InpSPEC;
46 greg 2.1 else
47 greg 2.14 infmt = InpUNK;
48 gwlarson 2.5 return(0); /* don't echo */
49 greg 2.1 }
50 greg 2.10 if (origexp > 0.0 && isexpos(s)) {
51     origexp *= exposval(s);
52     return(0); /* don't echo */
53     }
54 greg 2.1 if (isprims(s)) { /* get input primaries */
55     primsval(inprims, s);
56 gwlarson 2.5 return(0); /* don't echo */
57 greg 2.1 }
58 greg 2.14 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 greg 2.1 /* should I grok colcorr also? */
67 gwlarson 2.5 return(fputs(s, stdout));
68 greg 2.1 }
69    
70    
71 schorsch 2.9 int
72     main(int argc, char *argv[])
73 greg 2.1 {
74     int i;
75 greg 2.16
76 schorsch 2.7 SET_DEFAULT_BINARY();
77     SET_FILE_BINARY(stdin);
78     SET_FILE_BINARY(stdout);
79 greg 2.16 fixargv0(argv[0]);
80 greg 2.1
81     for (i = 1; i < argc; i++)
82     if (argv[i][0] == '-')
83     switch (argv[i][1]) {
84     case 'c': /* rle-compressed output */
85     doflat = 0;
86     break;
87     case 'u': /* flat output */
88     doflat = 1;
89     break;
90     case 'r': /* RGBE output */
91     rgbout = 1;
92     break;
93     case 'p': /* RGB primaries */
94 greg 2.2 if (i+8 >= argc)
95 greg 2.1 goto userr;
96     outprims[RED][CIEX] = atof(argv[++i]);
97     outprims[RED][CIEY] = atof(argv[++i]);
98     outprims[GRN][CIEX] = atof(argv[++i]);
99     outprims[GRN][CIEY] = atof(argv[++i]);
100     outprims[BLU][CIEX] = atof(argv[++i]);
101     outprims[BLU][CIEY] = atof(argv[++i]);
102     outprims[WHT][CIEX] = atof(argv[++i]);
103     outprims[WHT][CIEY] = atof(argv[++i]);
104     break;
105 greg 2.10 case 'o': /* original exposure */
106     origexp = 1.0;
107     break;
108 greg 2.1 case 'e': /* exposure compensation */
109     expcomp = atof(argv[++i]);
110     if (argv[i][0] == '+' || argv[i][0] == '-')
111     expcomp = pow(2., expcomp);
112     break;
113     default:
114     goto userr;
115     }
116     else
117     break;
118    
119     if (doflat < 0)
120     doflat = !rgbout;
121     if (i < argc-2)
122     goto userr;
123     if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
124     fprintf(stderr, "%s: can't open input \"%s\"\n",
125     progname, argv[i]);
126     exit(1);
127     }
128     if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
129     fprintf(stderr, "%s: can't open output \"%s\"\n",
130     progname, argv[i+1]);
131     exit(1);
132     }
133     getheader(stdin, headline, NULL);
134 greg 2.14 if (infmt == InpUNK)
135     quiterr("unrecognized/missing input file format");
136 greg 2.15 if (infmt == InpSPEC ? (NCSAMP <= 3) | (NCSAMP > MAXCSAMP) :
137     NCSAMP != 3)
138     quiterr("bad number of color components");
139 greg 2.1 printargs(argc, argv, stdout); /* add to header */
140     convert(); /* convert picture */
141     exit(0);
142     userr:
143 greg 2.10 fprintf(stderr, "Usage: %s [-r][-o][-e exp][-c|-u]", progname);
144 greg 2.1 fprintf(stderr, "[-p rx ry gx gy bx by wx wy] [input [output]]\n");
145     exit(1);
146     }
147    
148    
149 schorsch 2.9 static void
150     quiterr( /* print message and exit */
151     char *err
152     )
153 greg 2.1 {
154     if (err != NULL) {
155     fprintf(stderr, "%s: %s\n", progname, err);
156     exit(1);
157     }
158     exit(0);
159     }
160    
161    
162 schorsch 2.9 static void
163 greg 2.14 myreadscan(COLOR *scn, int len)
164     {
165     if (infmt == InpSPEC) { /* read & convert to XYZ */
166 greg 2.15 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 greg 2.14 while (len-- > 0) {
181     if (getbinary(sclr, LSCOLR, 1, stdin) != 1)
182     goto readerr;
183     scolr_scolor(scol, sclr);
184 greg 2.15 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 greg 2.14 }
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 schorsch 2.9 convert(void) /* convert to XYZE or RGBE picture */
203 greg 2.1 {
204     int order;
205     int xmax, ymax;
206     COLORMAT xfm;
207 greg 2.14 COLOR *scanin;
208     COLR *scanout;
209 greg 2.10 double exp2do = expcomp;
210     double exp2report = expcomp;
211 greg 2.1 int y;
212 greg 2.14 int x;
213 greg 2.10 /* recover original? */
214     if (origexp > 0.0)
215     exp2do /= origexp;
216 greg 2.1 /* compute transform */
217     if (rgbout) {
218 greg 2.14 if (infmt == InpRGB) { /* RGBE -> RGBE */
219 greg 2.6 comprgb2rgbWBmat(xfm, inprims, outprims);
220 greg 2.14 } else { /* XYZE/Spectral -> RGBE */
221 greg 2.6 compxyz2rgbWBmat(xfm, outprims);
222 greg 2.14 }
223     if (infmt == InpXYZ) {
224 greg 2.10 if (origexp > 0.0)
225     exp2do /= WHTEFFICACY;
226     else
227     exp2report *= WHTEFFICACY;
228 greg 2.1 }
229     } else {
230 greg 2.14 if (infmt == InpRGB) { /* RGBE -> XYZE */
231 greg 2.6 comprgb2xyzWBmat(xfm, inprims);
232 greg 2.14 } 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 greg 2.10 exp2do *= WHTEFFICACY;
240     else
241     exp2report /= WHTEFFICACY;
242 greg 2.1 }
243     }
244 gregl 2.4 for (y = 0; y < 3; y++)
245     for (x = 0; x < 3; x++)
246 greg 2.10 xfm[y][x] *= exp2do;
247 greg 2.1 /* get input resolution */
248     if ((order = fgetresolu(&xmax, &ymax, stdin)) < 0)
249     quiterr("bad picture format");
250     /* complete output header */
251 greg 2.10 if ((exp2report < 0.99) | (exp2report > 1.01))
252     fputexpos(exp2report, stdout);
253 greg 2.1 if (rgbout) {
254     fputprims(outprims, stdout);
255     fputformat(COLRFMT, stdout);
256     } else
257     fputformat(CIEFMT, stdout);
258     putc('\n', stdout);
259     fputresolu(order, xmax, ymax, stdout);
260     /* allocate scanline */
261     scanin = (COLOR *)malloc(xmax*sizeof(COLOR));
262     if (scanin == NULL)
263     quiterr("out of memory in convert");
264 greg 2.14 scanout = doflat ? (COLR *)malloc(xmax*sizeof(COLR)) : (COLR *)NULL;
265 greg 2.1 /* convert image */
266     for (y = 0; y < ymax; y++) {
267 greg 2.14 myreadscan(scanin, xmax);
268 greg 2.3 for (x = 0; x < xmax; x++) {
269 greg 2.1 colortrans(scanin[x], xfm, scanin[x]);
270 greg 2.3 if (rgbout)
271     clipgamut(scanin[x], bright(scanin[x]),
272     CGAMUT_LOWER, cblack, cwhite);
273     }
274 greg 2.1 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 greg 2.14 putbinary(scanout, sizeof(COLR), xmax, stdout);
280 greg 2.1 } else
281     fwritescan(scanin, xmax, stdout);
282     if (ferror(stdout))
283     quiterr("error writing output picture");
284     }
285     /* free scanline */
286 greg 2.14 free(scanin);
287 greg 2.1 if (scanout != NULL)
288 greg 2.14 free(scanout);
289 greg 2.1 }