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

File Contents

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