ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhpict.c
Revision: 3.23
Committed: Fri Jun 6 19:11:21 2025 UTC (3 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.22: +3 -4 lines
Log Message:
refactor: Making use of printargs() more consistent with fixargv0()

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rhpict.c,v 3.22 2023/02/06 22:40:21 greg Exp $";
3 #endif
4 /*
5 * Radiance holodeck picture generator
6 */
7
8 #include <string.h>
9 #include "paths.h"
10 #include "platform.h"
11 #include "rterror.h"
12 #include "rholo.h"
13
14 char *hdkfile; /* holodeck file name */
15 char gargc; /* global argc */
16 char **gargv; /* global argv */
17
18 VIEW myview = STDVIEW; /* current output view */
19 int xres = 512, yres = 512; /* max. horizontal and vertical resolution */
20 char *outspec = NULL; /* output file specification */
21 double randfrac = -1.; /* random resampling fraction */
22 double pixaspect = 1.; /* pixel aspect ratio */
23 int seqstart = 0; /* sequence start frame */
24 double expval = 1.; /* exposure value */
25
26 COLOR *mypixel; /* pixels being rendered */
27 float *myweight; /* weights (used to compute final pixels) */
28 float *mydepth; /* depth values (visibility culling) */
29 int hres, vres; /* current horizontal and vertical res. */
30
31 extern int nowarn; /* turn warnings off? */
32
33 static void dopicture(int fn);
34 static void render_frame(PACKHEAD *bl, int nb);
35 static void startpicture(int fn);
36 static int endpicture(void);
37 static void initialize(void);
38 /* from rhpict2.c */
39 extern void pixFinish(double ransamp);
40 extern void pixBeam(BEAM *bp, HDBEAMI *hb);
41
42
43 int
44 main(
45 int argc,
46 char *argv[]
47 )
48 {
49 int i, rval;
50
51 gargc = argc; gargv = argv;
52 fixargv0(argv[0]); /* get arguments */
53 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
54 rval = getviewopt(&myview, argc-i, argv+i);
55 if (rval >= 0) { /* view option */
56 i += rval;
57 continue;
58 }
59 switch (argv[i][1]) {
60 case 'w': /* turn off warnings */
61 nowarn++;
62 break;
63 case 'p': /* pixel aspect/exposure */
64 if (badarg(argc-i-1,argv+i+1,"f"))
65 goto userr;
66 if (argv[i][2] == 'a')
67 pixaspect = atof(argv[++i]);
68 else if (argv[i][2] == 'e') {
69 expval = atof(argv[++i]);
70 if ((argv[i][0] == '-') | (argv[i][0] == '+'))
71 expval = pow(2., expval);
72 } else
73 goto userr;
74 break;
75 case 'x': /* horizontal resolution */
76 if (badarg(argc-i-1,argv+i+1,"i"))
77 goto userr;
78 xres = atoi(argv[++i]);
79 break;
80 case 'y': /* vertical resolution */
81 if (badarg(argc-i-1,argv+i+1,"i"))
82 goto userr;
83 yres = atoi(argv[++i]);
84 break;
85 case 'o': /* output file specificaiton */
86 if (badarg(argc-i-1,argv+i+1,"s"))
87 goto userr;
88 outspec = argv[++i];
89 break;
90 case 'r': /* random sampling */
91 if (badarg(argc-i-1,argv+i+1,"f"))
92 goto userr;
93 randfrac = atof(argv[++i]);
94 break;
95 case 's': /* smooth sampling */
96 randfrac = -1.;
97 break;
98 case 'S': /* sequence start */
99 if (badarg(argc-i-1,argv+i+1,"i"))
100 goto userr;
101 seqstart = atoi(argv[++i]);
102 break;
103 case 'v': /* view file */
104 if (argv[i][2]!='f' || badarg(argc-i-1,argv+i+1,"s"))
105 goto userr;
106 rval = viewfile(argv[++i], &myview, NULL);
107 if (rval < 0) {
108 sprintf(errmsg, "cannot open view file \"%s\"",
109 argv[i]);
110 error(SYSTEM, errmsg);
111 } else if (rval == 0) {
112 sprintf(errmsg, "bad view file \"%s\"",
113 argv[i]);
114 error(USER, errmsg);
115 }
116 break;
117 default:
118 goto userr;
119 }
120 }
121 /* open holodeck file */
122 if (i != argc-1)
123 goto userr;
124 hdkfile = argv[i];
125 initialize();
126 /* render picture(s) */
127 if (seqstart <= 0)
128 dopicture(0);
129 else
130 while (nextview(&myview, stdin) != EOF)
131 dopicture(seqstart++);
132 quit(0); /* all done! */
133 userr:
134 fprintf(stderr,
135 "Usage: %s [-w][-r rf][-pa pa][-pe ex][-x hr][-y vr][-S stfn][-o outp][view] input.hdk\n",
136 progname);
137 quit(1);
138 return 1; /* pro forma return */
139 }
140
141
142 static void
143 dopicture( /* render view from holodeck */
144 int fn
145 )
146 {
147 char *err;
148 int rval;
149 BEAMLIST blist;
150
151 if ((err = setview(&myview)) != NULL) {
152 sprintf(errmsg, "%s -- skipping frame %d", err, fn);
153 error(WARNING, errmsg);
154 return;
155 }
156 startpicture(fn); /* open output picture */
157 /* determine relevant beams */
158 viewbeams(&myview, hres, vres, &blist);
159 /* render image */
160 if (blist.nb > 0) {
161 render_frame(blist.bl, blist.nb);
162 free((void *)blist.bl);
163 } else {
164 sprintf(errmsg, "no section visible in frame %d", fn);
165 error(WARNING, errmsg);
166 }
167 rval = endpicture(); /* write pixel values */
168 if (rval < 0) {
169 sprintf(errmsg, "error writing frame %d", fn);
170 error(SYSTEM, errmsg);
171 }
172 #ifdef DEBUG
173 if (blist.nb > 0 & rval > 0) {
174 sprintf(errmsg, "%d unrendered pixels in frame %d (%.1f%%)",
175 rval, fn, 100.*rval/(hres*vres));
176 error(WARNING, errmsg);
177 }
178 #endif
179 }
180
181
182 static void
183 render_frame( /* render frame from beam values */
184 PACKHEAD *bl,
185 int nb
186 )
187 {
188 HDBEAMI *bil;
189 int i;
190
191 if (nb <= 0) return;
192 if ((bil = (HDBEAMI *)malloc(nb*sizeof(HDBEAMI))) == NULL)
193 error(SYSTEM, "out of memory in render_frame");
194 for (i = nb; i--; ) {
195 bil[i].h = hdlist[bl[i].hd];
196 bil[i].b = bl[i].bi;
197 }
198 hdloadbeams(bil, nb, pixBeam);
199 pixFinish(randfrac);
200 free((void *)bil);
201 }
202
203
204 static void
205 startpicture( /* initialize picture for rendering & output */
206 int fn
207 )
208 {
209 extern char VersionID[];
210 double pa = pixaspect;
211 char fname[256];
212 /* compute picture resolution */
213 hres = xres; vres = yres;
214 normaspect(viewaspect(&myview), &pa, &hres, &vres);
215 /* prepare output */
216 if (outspec != NULL) {
217 sprintf(fname, outspec, fn);
218 if (freopen(fname, "wb", stdout) == NULL) {
219 sprintf(errmsg, "cannot open output \"%s\"", fname);
220 error(SYSTEM, errmsg);
221 }
222 }
223 /* write header */
224 newheader("RADIANCE", stdout);
225 printf("SOFTWARE= %s\n", VersionID);
226 printargs(gargc, gargv, stdout);
227 if (fn)
228 printf("FRAME=%d\n", fn);
229 fputs(VIEWSTR, stdout);
230 fprintview(&myview, stdout);
231 fputc('\n', stdout);
232 if ((pa < 0.99) | (pa > 1.01))
233 fputaspect(pa, stdout);
234 if ((expval < 0.99) | (expval > 1.01))
235 fputexpos(expval, stdout);
236 fputformat(COLRFMT, stdout);
237 fputc('\n', stdout);
238 /* write resolution (standard order) */
239 fprtresolu(hres, vres, stdout);
240 /* prepare image buffers */
241 memset((char *)mypixel, '\0', hres*vres*sizeof(COLOR));
242 memset((char *)myweight, '\0', hres*vres*sizeof(float));
243 memset((char *)mydepth, '\0', hres*vres*sizeof(float));
244 }
245
246
247 static int
248 endpicture(void) /* finish and write out pixels */
249 {
250 int lastr = -1, nunrend = 0;
251 int32 lastp, lastrp;
252 int32 p;
253 double d;
254 /* compute final pixel values */
255 for (p = hres*vres; p--; ) {
256 if (myweight[p] <= FTINY) {
257 if (lastr >= 0) {
258 if (p/hres == lastp/hres)
259 copycolor(mypixel[p], mypixel[lastp]);
260 else
261 copycolor(mypixel[p], mypixel[lastrp]);
262 }
263 nunrend++;
264 continue;
265 }
266 d = expval/myweight[p];
267 scalecolor(mypixel[p], d);
268 if ((lastp=p)/hres != lastr)
269 lastr = (lastrp=p)/hres;
270 }
271 /* write each scanline */
272 for (p = vres; p--; )
273 if (fwritescan(mypixel+p*hres, hres, stdout) < 0)
274 return(-1);
275 if (fflush(stdout) == EOF)
276 return(-1);
277 return(nunrend);
278 }
279
280
281 static void
282 initialize(void) /* initialize holodeck and buffers */
283 {
284 int fd;
285 FILE *fp;
286 int n;
287 off_t nextloc;
288 /* open holodeck file */
289 if ((fp = fopen(hdkfile, "rb")) == NULL) {
290 sprintf(errmsg, "cannot open \"%s\" for reading", hdkfile);
291 error(SYSTEM, errmsg);
292 }
293 /* check header format */
294 checkheader(fp, HOLOFMT, NULL);
295 /* check magic number */
296 if (getw(fp) != HOLOMAGIC) {
297 sprintf(errmsg, "bad magic number in holodeck file \"%s\"",
298 hdkfile);
299 error(USER, errmsg);
300 }
301 nextloc = ftell(fp); /* get stdio position */
302 fd = dup(fileno(fp)); /* dup file descriptor */
303 fclose(fp); /* done with stdio */
304 for (n = 0; nextloc > 0L; n++) { /* initialize each section */
305 lseek(fd, nextloc, SEEK_SET);
306 read(fd, (char *)&nextloc, sizeof(nextloc));
307 hdinit(fd, NULL);
308 }
309 /* allocate picture buffer */
310 mypixel = (COLOR *)bmalloc(xres*yres*sizeof(COLOR));
311 myweight = (float *)bmalloc(xres*yres*sizeof(float));
312 mydepth = (float *)bmalloc(xres*yres*sizeof(float));
313 if ((mypixel == NULL) | (myweight == NULL) | (mydepth == NULL))
314 error(SYSTEM, "out of memory in initialize");
315 }
316
317
318 void
319 eputs(const char *s) /* put error message to stderr */
320 {
321 static int midline = 0;
322
323 if (!*s)
324 return;
325 if (!midline++) { /* prepend line with program name */
326 fputs(progname, stderr);
327 fputs(": ", stderr);
328 }
329 fputs(s, stderr);
330 if (s[strlen(s)-1] == '\n') {
331 fflush(stderr);
332 midline = 0;
333 }
334 }