ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rpiece.c
(Generate patch)

Comparing ray/src/util/rpiece.c (file contents):
Revision 2.5 by greg, Fri Aug 7 11:05:30 1992 UTC vs.
Revision 2.24 by greg, Fri Aug 6 12:58:43 1993 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1992 Regents of the University of California */
1 > /* Copyright (c) 1993 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 10 | Line 10 | static char SCCSid[] = "$SunId$ LBL";
10  
11   #include "standard.h"
12   #include <fcntl.h>
13 +
14 + #ifndef F_SETLKW
15 +
16 + main(argc, argv)
17 + int argc;
18 + char *argv[];
19 + {
20 +        fprintf(stderr, "%s: no NFS lock manager on this machine\n", argv[0]);
21 +        exit(1);
22 + }
23 +
24 + #else
25 +
26 + #include <signal.h>
27   #include "color.h"
28   #include "view.h"
29   #include "resolu.h"
30  
31 + #ifndef NFS
32 + #define  NFS                    1
33 + #endif
34 +                                /* set the following to 0 to forgo forking */
35 + #ifndef MAXFORK
36 + #if NFS
37 + #define  MAXFORK                3       /* allotment of duped processes */
38 + #else
39 + #define  MAXFORK                0
40 + #endif
41 + #endif
42 +                                        /* protection from SYSV signals(!) */
43 + #if defined(sgi) || defined(hpux)
44 + #define guard_io()      sighold(SIGALRM)
45 + #define unguard()       sigrelse(SIGALRM)
46 + #endif
47 + #ifndef guard_io
48 + #define guard_io()      0
49 + #define unguard()       0
50 + #endif
51                                  /* rpict command */
52 < char  *rpargv[128] = {"rpict", "-S", "1", "-x", "512", "-y", "512", "-pa", "1"};
53 < int  rpargc = 9;
52 > char  *rpargv[128] = {"rpict", "-S", "1"};
53 > int  rpargc = 3;
54   int  rpd[3];
55   FILE  *torp, *fromrp;
56 < COLR  *scanline;
56 > COLR  *pbuf;
57                                  /* our view parameters */
58   VIEW  ourview = STDVIEW;
59   double  pixaspect = 1.0;
60 < int  hres = 512, vres = 512, hmult = 2, vmult = 2;
60 > int  hres = 1024, vres = 1024, hmult = 4, vmult = 4;
61                                  /* output file */
62   char  *outfile = NULL;
63   int  outfd;
64   long  scanorig;
65   int  syncfd = -1;               /* lock file descriptor */
66 + int  nforked = 0;
67  
68   char  *progname;
69   int  verbose = 0;
70  
71   extern long  lseek(), ftell();
72  
73 + int  gotalrm = 0;
74 + int  onalrm() { gotalrm++; }
75  
76 +
77   main(argc, argv)
78   int  argc;
79   char  *argv[];
# Line 44 | Line 82 | char  *argv[];
82          
83          progname = argv[0];
84          for (i = 1; i < argc; i++) {
85 +                                                /* expand arguments */
86 +                while (rval = expandarg(&argc, &argv, i))
87 +                        if (rval < 0) {
88 +                                fprintf(stderr, "%s: cannot expand '%s'",
89 +                                                argv[0], argv[i]);
90 +                                exit(1);
91 +                        }
92                  if (argv[i][0] == '-')
93                          switch (argv[i][1]) {
94                          case 'v':
# Line 68 | Line 113 | char  *argv[];
113                                  }
114                                  break;
115                          case 'p':               /* pixel aspect ratio? */
116 <                                if (argv[i][2] == 'a' && !argv[i][3])
117 <                                        pixaspect = atof(argv[i+1]);
118 <                                break;
119 <                        case 'x':               /* piece x resolution */
120 <                                if (!argv[i][2])
121 <                                        hres = atoi(argv[i+1]);
122 <                                break;
123 <                        case 'y':               /* piece y resolution */
124 <                                if (!argv[i][2])
125 <                                        vres = atoi(argv[i+1]);
126 <                                break;
116 >                                if (argv[i][2] != 'a' || argv[i][3])
117 >                                        break;
118 >                                pixaspect = atof(argv[i+1]);
119 >                                continue;
120 >                        case 'x':               /* overall x resolution */
121 >                                if (argv[i][2])
122 >                                        break;
123 >                                hres = atoi(argv[++i]);
124 >                                continue;
125 >                        case 'y':               /* overall y resolution */
126 >                                if (argv[i][2])
127 >                                        break;
128 >                                vres = atoi(argv[++i]);
129 >                                continue;
130                          case 'X':               /* horizontal multiplier */
131                                  if (argv[i][2])
132                                          break;
# Line 92 | Line 140 | char  *argv[];
140                          case 'F':               /* syncronization file */
141                                  if (argv[i][2])
142                                          break;
143 <                                if ((syncfd = open(argv[++i], O_RDWR)) < 0) {
143 >                                if ((syncfd = open(argv[++i],
144 >                                                O_RDWR|O_CREAT, 0666)) < 0) {
145                                          fprintf(stderr, "%s: cannot open\n",
146                                                          argv[i]);
147                                          exit(1);
148                                  }
149                                  continue;
150 +                        case 'z':               /* z-file ist verbotten */
151 +                                fprintf(stderr, "%s: -z option not allowed\n",
152 +                                                argv[0]);
153 +                                exit(1);
154                          case 'o':               /* output file */
155                                  if (argv[i][2])
156                                          break;
157                                  outfile = argv[++i];
158                                  continue;
159 <                        }
159 >                        } else if (i >= argc-1)
160 >                                break;
161                  rpargv[rpargc++] = argv[i];
162          }
163 <        rpargv[rpargc] = NULL;
163 >        if (i >= argc) {
164 >                fprintf(stderr, "%s: missing octree argument\n", argv[0]);
165 >                exit(1);
166 >        }
167          if (outfile == NULL) {
168                  fprintf(stderr, "%s: missing output file\n", argv[0]);
169                  exit(1);
170          }
171          init(argc, argv);
172          rpiece();
173 <        rval = cleanup();
117 <        exit(rval);
173 >        exit(cleanup(0));
174   }
175  
176  
# Line 122 | Line 178 | init(ac, av)                   /* set up output file and start rpict *
178   int  ac;
179   char  **av;
180   {
181 +        static char  hrbuf[16], vrbuf[16];
182          extern char  VersionID[];
183          char  *err;
184          FILE  *fp;
# Line 136 | Line 193 | char  **av;
193                  buf[read(syncfd, buf, sizeof(buf)-1)] = '\0';
194                  sscanf(buf, "%d %d", &hmult, &vmult);
195          }
196 +                                        /* compute piece size */
197 +        hres /= hmult;
198 +        vres /= vmult;
199          normaspect(viewaspect(&ourview)*hmult/vmult, &pixaspect, &hres, &vres);
200 +        sprintf(hrbuf, "%d", hres);
201 +        rpargv[rpargc++] = "-x"; rpargv[rpargc++] = hrbuf;
202 +        sprintf(vrbuf, "%d", vres);
203 +        rpargv[rpargc++] = "-y"; rpargv[rpargc++] = vrbuf;
204 +        rpargv[rpargc++] = "-pa"; rpargv[rpargc++] = "0";
205 +        rpargv[rpargc++] = av[ac-1];
206 +        rpargv[rpargc] = NULL;
207                                          /* open output file */
208          if ((outfd = open(outfile, O_WRONLY|O_CREAT|O_EXCL, 0666)) >= 0) {
209                  if ((fp = fdopen(dup(outfd), "w")) == NULL)
# Line 154 | Line 221 | char  **av;
221          } else if ((outfd = open(outfile, O_RDWR)) >= 0) {
222                  if ((fp = fdopen(dup(outfd), "r+")) == NULL)
223                          goto filerr;
224 <                getheader(fp, NULL);            /* skip header */
225 <                if (fscnresolu(&hr, &vr, fp) < 0 ||     /* check resolution */
224 >                getheader(fp, NULL, NULL);      /* skip header */
225 >                if (!fscnresolu(&hr, &vr, fp) ||        /* check resolution */
226                                  hr != hres*hmult || vr != vres*vmult) {
227 <                        fprintf(stderr, "%s: picture resolution mismatch\n",
228 <                                        outfile);
227 >                        fprintf(stderr, "%s: resolution mismatch on file \"%s\"\n",
228 >                                        progname, outfile);
229                          exit(1);
230                  }
231          } else {
232 <                fprintf(stderr, "%s: cannot open\n", outfile);
232 >                fprintf(stderr, "%s: cannot open file \"%s\"\n",
233 >                                progname, outfile);
234                  exit(1);
235          }
236          scanorig = ftell(fp);           /* record position of first scanline */
237          if (fclose(fp) == -1)           /* done with stream i/o */
238                  goto filerr;
239 <        sync();                         /* avoid NFS buffering */
239 > #if NFS
240 >        sync();                         /* flush NFS buffers */
241 > #endif
242                                          /* start rpict process */
243          if (open_process(rpd, rpargv) <= 0) {
244                  fprintf(stderr, "%s: cannot start %s\n", progname, rpargv[0]);
# Line 180 | Line 250 | char  **av;
250                                  progname, rpargv[0]);
251                  exit(1);
252          }
253 <        if ((scanline = (COLR *)malloc(hres*sizeof(COLR))) == NULL) {
253 >        if ((pbuf = (COLR *)bmalloc(hres*vres*sizeof(COLR))) == NULL) {
254                  fprintf(stderr, "%s: out of memory\n", progname);
255                  exit(1);
256          }
257 +        signal(SIGALRM, onalrm);
258          return;
259   filerr:
260 <        fprintf(stderr, "%s: file i/o error\n", outfile);
260 >        fprintf(stderr, "%s: i/o error on file \"%s\"\n", progname, outfile);
261          exit(1);
262   }
263  
# Line 195 | Line 266 | int
266   nextpiece(xp, yp)               /* get next piece assignment */
267   int  *xp, *yp;
268   {
198        extern char  *fgets();
269          struct flock  fls;
270          char  buf[64];
271  
272 <        if (syncfd != -1) {             /* using sync file */
272 >        if (gotalrm)                    /* someone wants us to quit */
273 >                return(0);
274 >        if (syncfd != -1) {             /* use sync file */
275                  fls.l_type = F_WRLCK;           /* gain exclusive access */
276                  fls.l_whence = 0;
277                  fls.l_start = 0L;
# Line 208 | Line 280 | int  *xp, *yp;
280                  lseek(syncfd, 0L, 0);
281                  buf[read(syncfd, buf, sizeof(buf)-1)] = '\0';
282                  if (sscanf(buf, "%*d %*d %d %d", xp, yp) < 2) {
211                        *xp = hmult;
212                        *yp = vmult-1;
213                }
214                if (--(*xp) < 0) {              /* decrement position */
283                          *xp = hmult-1;
284 <                        if (--(*yp) < 0) {      /* all done! */
284 >                        *yp = vmult;
285 >                }
286 >                if (--(*yp) < 0) {              /* decrement position */
287 >                        *yp = vmult-1;
288 >                        if (--(*xp) < 0) {      /* all done! */
289                                  close(syncfd);
290                                  return(0);
291                          }
292                  }
293 <                sprintf(buf, "%d %d\n%d %d\n", hmult, vmult, *xp, *yp);
293 >                sprintf(buf, "%4d %4d\n%4d %4d\n", hmult, vmult, *xp, *yp);
294                  lseek(syncfd, 0L, 0);           /* write new position */
295                  write(syncfd, buf, strlen(buf));
296                  fls.l_type = F_UNLCK;           /* release sync file */
297                  fcntl(syncfd, F_SETLKW, &fls);
298                  return(1);
299          }
300 <        if (fgets(buf, sizeof(buf), stdin) == NULL)     /* using stdin */
300 >        if (fgets(buf, sizeof(buf), stdin) == NULL)     /* use stdin */
301                  return(0);
302          if (sscanf(buf, "%d %d", xp, yp) == 2)
303                  return(1);
304          fprintf(stderr, "%s: input format error\n", progname);
305 <        exit(1);
305 >        exit(cleanup(1));
306   }
307  
308  
309   int
310 < cleanup()                       /* close rpict process and clean up */
310 > cleanup(rstat)                  /* close rpict process and clean up */
311 > int  rstat;
312   {
313 <        register int  rpstat;
313 >        int  status;
314  
315 <        free((char *)scanline);
315 >        bfree((char *)pbuf, hres*vres*sizeof(COLR));
316          fclose(torp);
317          fclose(fromrp);
318 <        rpstat = close_process(rpd);
319 <        if (rpstat == -1)
320 <                rpstat = 0;
321 <        return(rpstat);
318 >        while (wait(&status) != -1)
319 >                if (rstat == 0)
320 >                        rstat = status>>8 & 0xff;
321 >        return(rstat);
322   }
323  
324  
# Line 253 | Line 326 | rpiece()                       /* render picture piece by piece */
326   {
327          VIEW  pview;
328          int  xorg, yorg;
329 <        
329 >                                        /* compute view parameters */
330 >        copystruct(&pview, &ourview);
331 >        switch (ourview.type) {
332 >        case VT_PER:
333 >                pview.horiz = 2.*180./PI*atan(
334 >                                tan(PI/180./2.*ourview.horiz)/hmult );
335 >                pview.vert = 2.*180./PI*atan(
336 >                                tan(PI/180./2.*ourview.vert)/vmult );
337 >                break;
338 >        case VT_PAR:
339 >        case VT_ANG:
340 >                pview.horiz = ourview.horiz / hmult;
341 >                pview.vert = ourview.vert / vmult;
342 >                break;
343 >        case VT_HEM:
344 >                pview.horiz = 2.*180./PI*asin(
345 >                                sin(PI/180./2.*ourview.horiz)/hmult );
346 >                pview.vert = 2.*180./PI*asin(
347 >                                sin(PI/180./2.*ourview.vert)/vmult );
348 >                break;
349 >        default:
350 >                fprintf(stderr, "%s: unknown view type '-vt%c'\n",
351 >                                progname, ourview.type);
352 >                exit(cleanup(1));
353 >        }
354 >                                        /* render each piece */
355          while (nextpiece(&xorg, &yorg)) {
356 <                copystruct(&pview, &ourview);   /* compute view for piece */
357 <                switch (ourview.type) {
260 <                case VT_PER:
261 <                        pview.horiz = 2.*180./PI*atan(
262 <                                        tan(PI/180./2.*ourview.horiz)/hmult );
263 <                        pview.vert = 2.*180./PI*atan(
264 <                                        tan(PI/180./2.*ourview.vert)/vmult );
265 <                        break;
266 <                case VT_PAR:
267 <                case VT_ANG:
268 <                        pview.horiz = ourview.horiz / hmult;
269 <                        pview.vert = ourview.vert / vmult;
270 <                        break;
271 <                case VT_HEM:
272 <                        pview.horiz = 2.*180./PI*asin(
273 <                                        sin(PI/180./2.*ourview.horiz)/hmult );
274 <                        pview.vert = 2.*180./PI*asin(
275 <                                        sin(PI/180./2.*ourview.vert)/vmult );
276 <                        break;
277 <                default:
278 <                        fprintf(stderr, "%s: unknown view type '-vt%c'\n",
279 <                                        progname, ourview.type);
280 <                        exit(1);
281 <                }
282 <                pview.hoff += xorg - 0.5*(hmult-1);
283 <                pview.voff += yorg - 0.5*(vmult-1);
356 >                pview.hoff = ourview.hoff + xorg - 0.5*(hmult-1);
357 >                pview.voff = ourview.voff + yorg - 0.5*(vmult-1);
358                  fputs(VIEWSTR, torp);
359                  fprintview(&pview, torp);
360                  putc('\n', torp);
361 <                fflush(torp);                   /* assign piece to rpict */
361 >                fflush(torp);                   /* assigns piece to rpict */
362                  putpiece(xorg, yorg);           /* place piece in output */
289                if (verbose) {                  /* notify caller */
290                        printf("%d %d done\n", xorg, yorg);
291                        fflush(stdout);
292                }
363          }
364   }
365  
366  
367 + int
368   putpiece(xpos, ypos)            /* get next piece from rpict */
369   int  xpos, ypos;
370   {
371 +        struct flock  fls;
372 +        int  pid, status;
373          int  hr, vr;
374 <        int  y;
375 <
374 >        register int  y;
375 >                                /* check bounds */
376          if (xpos < 0 | ypos < 0 | xpos >= hmult | ypos >= vmult) {
377                  fprintf(stderr, "%s: requested piece (%d,%d) out of range\n",
378                                  progname, xpos, ypos);
379 <                exit(1);
379 >                exit(cleanup(1));
380          }
381 <        getheader(fromrp, NULL);        /* discard header info. */
382 <        if (fscnresolu(&hr, &vr, fromrp) < 0 || /* check resolution */
383 <                        hr != hres || vr != vres) {
381 >                                /* check header from rpict */
382 >        guard_io();
383 >        getheader(fromrp, NULL, NULL);
384 >        if (!fscnresolu(&hr, &vr, fromrp) || hr != hres | vr != vres) {
385                  fprintf(stderr, "%s: resolution mismatch from %s\n",
386                                  progname, rpargv[0]);
387 <                exit(1);
387 >                exit(cleanup(1));
388          }
389 <        for (y = 0; y < vr; y++) {      /* transfer scanlines */
390 <                if (freadcolrs(scanline, hr, fromrp) < 0) {
389 >        if (verbose) {                          /* notify caller */
390 >                printf("%d %d begun\n", xpos, ypos);
391 >                fflush(stdout);
392 >        }
393 >        unguard();
394 >                                /* load new piece into buffer */
395 >        for (y = 0; y < vr; y++) {
396 >                guard_io();
397 >                if (freadcolrs(pbuf+y*hr, hr, fromrp) < 0) {
398                          fprintf(stderr, "%s: read error from %s\n",
399                                          progname, rpargv[0]);
400 <                        exit(1);
400 >                        exit(cleanup(1));
401                  }
402 <                if ((y == 0 || hmult != 1) && lseek(outfd,
403 < scanorig+((long)((vmult-1-ypos)*vres+y)*hmult*hres+xpos*hres)*sizeof(COLR),
404 <                                0) == -1) {
405 <                        fprintf(stderr, "%s: seek error\n", outfile);
406 <                        exit(1);
402 >                unguard();
403 >        }
404 > #if MAXFORK
405 >                                /* fork so we don't slow rpict down */
406 >        if ((pid = fork()) > 0) {
407 >                if (++nforked >= MAXFORK) {
408 >                        wait(&status);          /* reap a child */
409 >                        if (status)
410 >                                exit(cleanup(status>>8 & 0xff));
411 >                        nforked--;
412                  }
413 <                if (writebuf(outfd, (char *)scanline, hr*sizeof(COLR)) !=
414 <                                hr*sizeof(COLR)) {
415 <                        fprintf(stderr, "%s: write error\n", outfile);
416 <                        exit(1);
413 >                return(pid);
414 >        }
415 > #else
416 >        pid = -1;               /* no forking */
417 > #endif
418 >        fls.l_start = scanorig +
419 >                ((long)(vmult-1-ypos)*vres*hmult+xpos)*hres*sizeof(COLR);
420 > #if NFS
421 >        fls.l_len = ((long)(vres-1)*hmult+1)*hres*sizeof(COLR);
422 >                                /* lock file section so NFS doesn't mess up */
423 >        fls.l_whence = 0;
424 >        fls.l_type = F_WRLCK;
425 >        fcntl(outfd, F_SETLKW, &fls);
426 > #endif
427 >                                /* write new piece to file */
428 >        if (lseek(outfd, fls.l_start, 0) == -1)
429 >                goto seekerr;
430 >        if (hmult == 1) {
431 >                if (writebuf(outfd, (char *)pbuf,
432 >                                vr*hr*sizeof(COLR)) != vr*hr*sizeof(COLR))
433 >                        goto writerr;
434 >        } else
435 >                for (y = 0; y < vr; y++) {
436 >                        if (writebuf(outfd, (char *)(pbuf+y*hr),
437 >                                        hr*sizeof(COLR)) != hr*sizeof(COLR))
438 >                                goto writerr;
439 >                        if (y < vr-1 && lseek(outfd,
440 >                                        (long)(hmult-1)*hr*sizeof(COLR),
441 >                                        1) == -1)
442 >                                goto seekerr;
443                  }
444 +        if (verbose) {                          /* notify caller */
445 +                printf("%d %d done\n", xpos, ypos);
446 +                fflush(stdout);
447          }
448 +        if (pid == -1) {        /* didn't fork or fork failed */
449 + #if NFS
450 +                fls.l_type = F_UNLCK;           /* release lock */
451 +                fcntl(outfd, F_SETLKW, &fls);
452 + #endif
453 +                return(0);
454 +        }
455 +        _exit(0);               /* else exit child process (releasing lock) */
456 + seekerr:
457 +        fprintf(stderr, "%s: seek error on file \"%s\"\n", progname, outfile);
458 +        _exit(1);
459 + writerr:
460 +        fprintf(stderr, "%s: write error on file \"%s\"\n", progname, outfile);
461 +        _exit(1);
462   }
463 +
464 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines