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 weeks, 1 day 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

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