ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rvmain.c
Revision: 2.26
Committed: Fri Jun 20 16:34:23 2025 UTC (32 hours, 57 minutes ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.25: +1 -3 lines
Log Message:
fix: Avoid array bounds errors in dimlist[] in deep ray trees

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rvmain.c,v 2.25 2025/06/07 05:09:46 greg Exp $";
3 #endif
4 /*
5 * rvmain.c - main for rview interactive viewer
6 */
7
8 #include "copyright.h"
9
10 #include <signal.h>
11 #include <time.h>
12
13 #include "platform.h"
14 #include "ray.h"
15 #include "source.h"
16 #include "ambient.h"
17 #include "rpaint.h"
18 #include "random.h"
19 #include "view.h"
20 #include "pmapray.h"
21
22 VIEW ourview = STDVIEW; /* viewing parameters */
23 int hresolu, vresolu; /* image resolution */
24
25 int psample = 8; /* pixel sample size */
26 double maxdiff = .15; /* max. sample difference */
27
28 int greyscale = 0; /* map colors to brightness? */
29 char *dvcname = dev_default; /* output device name */
30
31 double exposure = 1.0; /* exposure for scene */
32
33 int newparam = 1; /* parameter setting changed */
34
35 struct driver *dev = NULL; /* driver functions */
36
37 char rifname[128]; /* rad input file name */
38
39 VIEW oldview; /* previous view parameters */
40
41 PNODE ptrunk; /* the base of our image */
42 RECT pframe; /* current frame boundaries */
43 int pdepth; /* image depth in current frame */
44
45 char *errfile = NULL; /* error output file */
46
47 int nproc = 1; /* number of processes */
48
49 char *sigerr[NSIG]; /* signal error messages */
50
51 static void onsig(int signo);
52 static void sigdie(int signo, char *msg);
53 static void printdefaults(void);
54
55 static void
56 set_defaults(void)
57 {
58 shadthresh = .1;
59 shadcert = .25;
60 directrelay = 0;
61 vspretest = 128;
62 srcsizerat = 0.;
63 specthresh = .3;
64 specjitter = 1.;
65 maxdepth = 6;
66 minweight = 1e-3;
67 ambacc = 0.3;
68 ambres = 32;
69 ambdiv = 256;
70 ambssamp = 64;
71 }
72
73 int
74 main(int argc, char *argv[])
75 {
76 #define check(ol,al) if (argv[i][ol] || \
77 badarg(argc-i-1,argv+i+1,al)) \
78 goto badopt
79 #define check_bool(olen,var) switch (argv[i][olen]) { \
80 case '\0': var = !var; break; \
81 case 'y': case 'Y': case 't': case 'T': \
82 case '+': case '1': var = 1; break; \
83 case 'n': case 'N': case 'f': case 'F': \
84 case '-': case '0': var = 0; break; \
85 default: goto badopt; }
86 char *octnm = NULL;
87 char *err;
88 int rval;
89 int i;
90 /* global program name */
91 progname = argv[0] = fixargv0(argv[0]);
92 /* set our defaults */
93 set_defaults();
94 /* option city */
95 for (i = 1; i < argc; i++) {
96 /* expand arguments */
97 while ((rval = expandarg(&argc, &argv, i)) > 0)
98 ;
99 if (rval < 0) {
100 sprintf(errmsg, "cannot expand '%s'", argv[i]);
101 error(SYSTEM, errmsg);
102 }
103 if (argv[i] == NULL || argv[i][0] != '-')
104 break; /* break from options */
105 if (!strcmp(argv[i], "-version")) {
106 puts(VersionID);
107 quit(0);
108 }
109 if (!strcmp(argv[i], "-defaults") ||
110 !strcmp(argv[i], "-help")) {
111 printdefaults();
112 quit(0);
113 }
114 if (!strcmp(argv[i], "-devices")) {
115 printdevices();
116 quit(0);
117 }
118 rval = getrenderopt(argc-i, argv+i);
119 if (rval >= 0) {
120 i += rval;
121 continue;
122 }
123 rval = getviewopt(&ourview, argc-i, argv+i);
124 if (rval >= 0) {
125 i += rval;
126 continue;
127 }
128 switch (argv[i][1]) {
129 case 'n': /* # processes */
130 check(2,"i");
131 nproc = atoi(argv[++i]);
132 if (nproc <= 0)
133 error(USER, "bad number of processes");
134 break;
135 case 'v': /* view file */
136 if (argv[i][2] != 'f')
137 goto badopt;
138 check(3,"s");
139 rval = viewfile(argv[++i], &ourview, NULL);
140 if (rval < 0) {
141 sprintf(errmsg,
142 "cannot open view file \"%s\"",
143 argv[i]);
144 error(SYSTEM, errmsg);
145 } else if (rval == 0) {
146 sprintf(errmsg,
147 "bad view file \"%s\"",
148 argv[i]);
149 error(USER, errmsg);
150 }
151 break;
152 case 'b': /* grayscale */
153 check_bool(2,greyscale);
154 break;
155 case 'p': /* pixel */
156 switch (argv[i][2]) {
157 case 's': /* sample */
158 check(3,"i");
159 psample = atoi(argv[++i]);
160 break;
161 case 't': /* threshold */
162 check(3,"f");
163 maxdiff = atof(argv[++i]);
164 break;
165 case 'e': /* exposure */
166 check(3,"f");
167 exposure = atof(argv[++i]);
168 if (argv[i][0] == '+' || argv[i][0] == '-')
169 exposure = pow(2.0, exposure);
170 break;
171 default:
172 goto badopt;
173 }
174 break;
175 case 'w': /* warnings */
176 rval = erract[WARNING].pf != NULL;
177 check_bool(2,rval);
178 if (rval) erract[WARNING].pf = wputs;
179 else erract[WARNING].pf = NULL;
180 break;
181 case 'e': /* error file */
182 check(2,"s");
183 errfile = argv[++i];
184 break;
185 case 'o': /* output device */
186 check(2,"s");
187 dvcname = argv[++i];
188 break;
189 case 'R': /* render input file */
190 check(2,"s");
191 strcpy(rifname, argv[++i]);
192 break;
193 default:
194 goto badopt;
195 }
196 }
197 /* set/check spectral sampling */
198 if (setspectrsamp(CNDX, WLPART) <= 0)
199 error(USER, "unsupported spectral sampling");
200
201 err = setview(&ourview); /* set viewing parameters */
202 if (err != NULL)
203 error(USER, err);
204 /* set up signal handling */
205 sigdie(SIGINT, "Interrupt");
206 sigdie(SIGTERM, "Terminate");
207 #if !defined(_WIN32) && !defined(_WIN64)
208 sigdie(SIGHUP, "Hangup");
209 sigdie(SIGPIPE, "Broken pipe");
210 sigdie(SIGALRM, "Alarm clock");
211 #endif
212 /* open error file */
213 if (errfile != NULL) {
214 if (freopen(errfile, "a", stderr) == NULL)
215 quit(2);
216 fprintf(stderr, "**************\n*** PID %5d: ",
217 getpid());
218 printargs(argc, argv, stderr);
219 putc('\n', stderr);
220 fflush(stderr);
221 }
222 #ifdef NICE
223 nice(NICE); /* lower priority */
224 #endif
225 /* get octree */
226 if (i == argc)
227 octnm = NULL;
228 else if (i == argc-1)
229 octnm = argv[i];
230 else
231 goto badopt;
232 if (octnm == NULL)
233 error(USER, "missing octree argument");
234 /* set up output & start process(es) */
235 SET_FILE_BINARY(stdout);
236
237 ray_init(octnm); /* also calls ray_init_pmap() */
238
239 /* temporary shortcut, until winrview is refactored into a "device" */
240 #ifndef WIN_RVIEW
241 rview(); /* run interactive viewer */
242
243
244 devclose(); /* close output device */
245 #endif
246
247 /* PMAP: free photon maps */
248 ray_done_pmap();
249
250 #ifdef WIN_RVIEW
251 return 1;
252 #endif
253 quit(0);
254
255 badopt:
256 sprintf(errmsg, "command line error at '%s'", argv[i]);
257 error(USER, errmsg);
258 return 1; /* pro forma return */
259
260 #undef check
261 #undef check_bool
262 }
263
264
265 void
266 wputs( /* warning output function */
267 const char *s
268 )
269 {
270 int lasterrno = errno;
271 if (erract[WARNING].pf == NULL)
272 return; /* called by calcomp or someone */
273 eputs(s);
274 errno = lasterrno;
275 }
276
277
278 void
279 eputs( /* put string to stderr */
280 const char *s
281 )
282 {
283 static int midline = 0;
284
285 if (!*s)
286 return;
287 if (!midline++) {
288 fputs(progname, stderr);
289 fputs(": ", stderr);
290 }
291 fputs(s, stderr);
292 if (s[strlen(s)-1] == '\n') {
293 fflush(stderr);
294 midline = 0;
295 }
296 }
297
298
299 static void
300 onsig( /* fatal signal */
301 int signo
302 )
303 {
304 static int gotsig = 0;
305
306 if (gotsig++) /* two signals and we're gone! */
307 _exit(signo);
308
309 #if !defined(_WIN32) && !defined(_WIN64)
310 alarm(15); /* allow 15 seconds to clean up */
311 signal(SIGALRM, SIG_DFL); /* make certain we do die */
312 #endif
313 eputs("signal - ");
314 eputs(sigerr[signo]);
315 eputs("\n");
316 devclose();
317 quit(3);
318 }
319
320
321 static void
322 sigdie( /* set fatal signal */
323 int signo,
324 char *msg
325 )
326 {
327 if (signal(signo, onsig) == SIG_IGN)
328 signal(signo, SIG_IGN);
329 sigerr[signo] = msg;
330 }
331
332
333 static void
334 printdefaults(void) /* print default values to stdout */
335 {
336 printf("-n %-2d\t\t\t\t# number of rendering processes\n", nproc);
337 printf(greyscale ? "-b+\t\t\t\t# greyscale on\n" :
338 "-b-\t\t\t\t# greyscale off\n");
339 printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
340 ourview.type==VT_PER ? "perspective" :
341 ourview.type==VT_PAR ? "parallel" :
342 ourview.type==VT_HEM ? "hemispherical" :
343 ourview.type==VT_ANG ? "angular" :
344 ourview.type==VT_CYL ? "cylindrical" :
345 ourview.type==VT_PLS ? "planisphere" :
346 "unknown");
347 printf("-vp %f %f %f\t# view point\n",
348 ourview.vp[0], ourview.vp[1], ourview.vp[2]);
349 printf("-vd %f %f %f\t# view direction\n",
350 ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
351 printf("-vu %f %f %f\t# view up\n",
352 ourview.vup[0], ourview.vup[1], ourview.vup[2]);
353 printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
354 printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
355 printf("-vo %f\t\t\t# view fore clipping plane\n", ourview.vfore);
356 printf("-va %f\t\t\t# view aft clipping plane\n", ourview.vaft);
357 printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
358 printf("-vl %f\t\t\t# view lift\n", ourview.voff);
359 printf("-pe %f\t\t\t# pixel exposure\n", exposure);
360 printf("-ps %-9d\t\t\t# pixel sample\n", psample);
361 printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
362 printf("-o %s\t\t\t\t# output device\n", dvcname);
363 printf(erract[WARNING].pf != NULL ?
364 "-w+\t\t\t\t# warning messages on\n" :
365 "-w-\t\t\t\t# warning messages off\n");
366 print_rdefaults();
367 }