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 (2 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

# User Rev Content
1 gwlarson 3.1 #ifndef lint
2 greg 3.23 static const char RCSid[] = "$Id: rhpict.c,v 3.22 2023/02/06 22:40:21 greg Exp $";
3 gwlarson 3.1 #endif
4     /*
5     * Radiance holodeck picture generator
6     */
7    
8 schorsch 3.11 #include <string.h>
9 greg 3.23 #include "paths.h"
10 greg 3.16 #include "platform.h"
11 schorsch 3.17 #include "rterror.h"
12 gwlarson 3.1 #include "rholo.h"
13    
14     char *hdkfile; /* holodeck file name */
15 gwlarson 3.7 char gargc; /* global argc */
16     char **gargv; /* global argv */
17 gwlarson 3.1
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 gwlarson 3.6 double randfrac = -1.; /* random resampling fraction */
22 gwlarson 3.1 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 gwlarson 3.2 float *mydepth; /* depth values (visibility culling) */
29 gwlarson 3.1 int hres, vres; /* current horizontal and vertical res. */
30    
31     extern int nowarn; /* turn warnings off? */
32    
33 schorsch 3.17 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 gwlarson 3.1
42 schorsch 3.17
43     int
44     main(
45     int argc,
46     char *argv[]
47     )
48 gwlarson 3.1 {
49     int i, rval;
50    
51 gwlarson 3.7 gargc = argc; gargv = argv;
52 greg 3.23 fixargv0(argv[0]); /* get arguments */
53 gwlarson 3.1 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 gwlarson 3.3 if (argv[i][2] == 'a')
67 gwlarson 3.1 pixaspect = atof(argv[++i]);
68 gwlarson 3.3 else if (argv[i][2] == 'e') {
69 gwlarson 3.1 expval = atof(argv[++i]);
70 schorsch 3.14 if ((argv[i][0] == '-') | (argv[i][0] == '+'))
71 gwlarson 3.1 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 gwlarson 3.5 case 'r': /* random sampling */
91 gwlarson 3.6 if (badarg(argc-i-1,argv+i+1,"f"))
92     goto userr;
93     randfrac = atof(argv[++i]);
94 gwlarson 3.5 break;
95     case 's': /* smooth sampling */
96 gwlarson 3.6 randfrac = -1.;
97 gwlarson 3.5 break;
98 gwlarson 3.1 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 gwlarson 3.4 if (argv[i][2]!='f' || badarg(argc-i-1,argv+i+1,"s"))
105 gwlarson 3.1 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 gwlarson 3.3 if (i != argc-1)
123 gwlarson 3.1 goto userr;
124 gwlarson 3.3 hdkfile = argv[i];
125 gwlarson 3.1 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 gwlarson 3.6 "Usage: %s [-w][-r rf][-pa pa][-pe ex][-x hr][-y vr][-S stfn][-o outp][view] input.hdk\n",
136 gwlarson 3.1 progname);
137     quit(1);
138 schorsch 3.17 return 1; /* pro forma return */
139 gwlarson 3.1 }
140    
141    
142 schorsch 3.17 static void
143     dopicture( /* render view from holodeck */
144     int fn
145     )
146 gwlarson 3.1 {
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 greg 3.8 free((void *)blist.bl);
163 gwlarson 3.1 } 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 gwlarson 3.3 #ifdef DEBUG
173 gwlarson 3.1 if (blist.nb > 0 & rval > 0) {
174 gwlarson 3.3 sprintf(errmsg, "%d unrendered pixels in frame %d (%.1f%%)",
175     rval, fn, 100.*rval/(hres*vres));
176 gwlarson 3.1 error(WARNING, errmsg);
177     }
178 gwlarson 3.3 #endif
179 gwlarson 3.1 }
180    
181    
182 schorsch 3.17 static void
183     render_frame( /* render frame from beam values */
184 greg 3.20 PACKHEAD *bl,
185 schorsch 3.17 int nb
186     )
187 gwlarson 3.1 {
188 greg 3.20 HDBEAMI *bil;
189     int i;
190 gwlarson 3.1
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 gwlarson 3.2 hdloadbeams(bil, nb, pixBeam);
199 gwlarson 3.6 pixFinish(randfrac);
200 greg 3.8 free((void *)bil);
201 gwlarson 3.1 }
202    
203    
204 schorsch 3.17 static void
205     startpicture( /* initialize picture for rendering & output */
206     int fn
207     )
208 gwlarson 3.1 {
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 greg 3.21 if (freopen(fname, "wb", stdout) == NULL) {
219 gwlarson 3.1 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 gwlarson 3.7 printargs(gargc, gargv, stdout);
227 gwlarson 3.1 if (fn)
228     printf("FRAME=%d\n", fn);
229     fputs(VIEWSTR, stdout);
230     fprintview(&myview, stdout);
231     fputc('\n', stdout);
232 schorsch 3.14 if ((pa < 0.99) | (pa > 1.01))
233 gwlarson 3.1 fputaspect(pa, stdout);
234 schorsch 3.14 if ((expval < 0.99) | (expval > 1.01))
235 gwlarson 3.1 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 schorsch 3.11 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 gwlarson 3.1 }
245    
246    
247 schorsch 3.17 static int
248     endpicture(void) /* finish and write out pixels */
249 gwlarson 3.1 {
250 gwlarson 3.4 int lastr = -1, nunrend = 0;
251 greg 3.10 int32 lastp, lastrp;
252 greg 3.20 int32 p;
253     double d;
254 gwlarson 3.1 /* compute final pixel values */
255     for (p = hres*vres; p--; ) {
256     if (myweight[p] <= FTINY) {
257 schorsch 3.13 if (lastr >= 0) {
258 gwlarson 3.4 if (p/hres == lastp/hres)
259     copycolor(mypixel[p], mypixel[lastp]);
260     else
261     copycolor(mypixel[p], mypixel[lastrp]);
262 schorsch 3.13 }
263 gwlarson 3.1 nunrend++;
264     continue;
265     }
266     d = expval/myweight[p];
267     scalecolor(mypixel[p], d);
268 gwlarson 3.4 if ((lastp=p)/hres != lastr)
269     lastr = (lastrp=p)/hres;
270 gwlarson 3.1 }
271     /* write each scanline */
272 gwlarson 3.4 for (p = vres; p--; )
273     if (fwritescan(mypixel+p*hres, hres, stdout) < 0)
274 gwlarson 3.1 return(-1);
275     if (fflush(stdout) == EOF)
276     return(-1);
277     return(nunrend);
278     }
279    
280    
281 schorsch 3.17 static void
282     initialize(void) /* initialize holodeck and buffers */
283 gwlarson 3.1 {
284     int fd;
285     FILE *fp;
286     int n;
287 greg 3.19 off_t nextloc;
288 gwlarson 3.1 /* open holodeck file */
289 greg 3.21 if ((fp = fopen(hdkfile, "rb")) == NULL) {
290 gwlarson 3.1 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 greg 3.19 lseek(fd, nextloc, SEEK_SET);
306 gwlarson 3.1 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 gwlarson 3.2 mydepth = (float *)bmalloc(xres*yres*sizeof(float));
313 schorsch 3.14 if ((mypixel == NULL) | (myweight == NULL) | (mydepth == NULL))
314 gwlarson 3.1 error(SYSTEM, "out of memory in initialize");
315     }
316    
317    
318 greg 3.8 void
319 greg 3.22 eputs(const char *s) /* put error message to stderr */
320 gwlarson 3.1 {
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     }