--- ray/src/util/ranimate.c 1996/07/17 17:45:11 2.20 +++ ray/src/util/ranimate.c 2004/03/26 21:36:20 2.46 @@ -1,77 +1,91 @@ -/* Copyright (c) 1996 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: ranimate.c,v 2.46 2004/03/26 21:36:20 schorsch Exp $"; #endif - /* * Radiance animation control program + * + * The main difference between this program and ranimove is that + * we have many optimizations here for camera motion in static + * environments, calling rpict and pinterp on multiple processors, + * where ranimove puts its emphasis on object motion, and does + * not use any external programs for image generation. + * + * See the ranimate(1) man page for further details. */ -#include "standard.h" +#include "copyright.h" + +#include #include -#include #include +#include +#include + +#include "platform.h" +#include "paths.h" +#include "rtio.h" +#include "rterror.h" +#include "rtmisc.h" #include "view.h" #include "vars.h" #include "netproc.h" + /* default blur samples */ +#ifndef DEF_NBLUR +#define DEF_NBLUR 5 +#endif /* default remote shell */ -#ifdef _AUX_SOURCE -#define REMSH "remsh" -#else #define REMSH "rsh" -#endif - /* input variables */ -#define HOST 0 /* rendering host machine */ -#define RENDER 1 /* rendering options */ -#define PFILT 2 /* pfilt options */ -#define PINTERP 3 /* pinterp options */ -#define OCTREE 4 /* octree file name */ -#define DIRECTORY 5 /* working (sub)directory */ -#define BASENAME 6 /* output image base name */ -#define VIEWFILE 7 /* animation frame views */ -#define START 8 /* starting frame number */ -#define END 9 /* ending frame number */ -#define RIF 10 /* rad input file */ -#define NEXTANIM 11 /* next animation file */ -#define ANIMATE 12 /* animation command */ -#define TRANSFER 13 /* frame transfer command */ -#define ARCHIVE 14 /* archiving command */ -#define INTERP 15 /* # frames to interpolate */ -#define OVERSAMP 16 /* # times to oversample image */ -#define MBLUR 17 /* samples for motion blur */ -#define RTRACE 18 /* use rtrace with pinterp? */ -#define DISKSPACE 19 /* how much disk space to use */ -#define RESOLUTION 20 /* desired final resolution */ -#define EXPOSURE 21 /* how to compute exposure */ -#define RSH 22 /* remote shell script or program */ + /* input variables (alphabetical by name) */ +#define ANIMATE 0 /* animation command */ +#define ARCHIVE 1 /* archiving command */ +#define BASENAME 2 /* output image base name */ +#define DIRECTORY 3 /* working (sub)directory */ +#define DISKSPACE 4 /* how much disk space to use */ +#define END 5 /* ending frame number */ +#define EXPOSURE 6 /* how to compute exposure */ +#define HOST 7 /* rendering host machine */ +#define INTERP 8 /* # frames to interpolate */ +#define MBLUR 9 /* motion blur parameters */ +#define NEXTANIM 10 /* next animation file */ +#define OCTREE 11 /* octree file name */ +#define OVERSAMP 12 /* # times to oversample image */ +#define PFILT 13 /* pfilt options */ +#define PINTERP 14 /* pinterp options */ +#define RENDER 15 /* rendering options */ +#define RESOLUTION 16 /* desired final resolution */ +#define RIF 17 /* rad input file */ +#define RSH 18 /* remote shell script or program */ +#define RTRACE 19 /* use rtrace with pinterp? */ +#define START 20 /* starting frame number */ +#define TRANSFER 21 /* frame transfer command */ +#define VIEWFILE 22 /* animation frame views */ int NVARS = 23; /* total number of variables */ VARIABLE vv[] = { /* variable-value pairs */ - {"host", 4, 0, NULL, NULL}, - {"render", 3, 0, NULL, catvalues}, - {"pfilt", 2, 0, NULL, catvalues}, - {"pinterp", 2, 0, NULL, catvalues}, - {"OCTREE", 3, 0, NULL, onevalue}, - {"DIRECTORY", 3, 0, NULL, onevalue}, - {"BASENAME", 3, 0, NULL, onevalue}, - {"VIEWFILE", 2, 0, NULL, onevalue}, - {"START", 2, 0, NULL, intvalue}, - {"END", 2, 0, NULL, intvalue}, - {"RIF", 3, 0, NULL, onevalue}, - {"NEXTANIM", 3, 0, NULL, onevalue}, {"ANIMATE", 2, 0, NULL, onevalue}, - {"TRANSFER", 2, 0, NULL, onevalue}, {"ARCHIVE", 2, 0, NULL, onevalue}, + {"BASENAME", 3, 0, NULL, onevalue}, + {"DIRECTORY", 3, 0, NULL, onevalue}, + {"DISKSPACE", 3, 0, NULL, fltvalue}, + {"END", 2, 0, NULL, intvalue}, + {"EXPOSURE", 3, 0, NULL, onevalue}, + {"host", 4, 0, NULL, NULL}, {"INTERPOLATE", 3, 0, NULL, intvalue}, - {"OVERSAMPLE", 2, 0, NULL, fltvalue}, {"MBLUR", 2, 0, NULL, onevalue}, - {"RTRACE", 2, 0, NULL, boolvalue}, - {"DISKSPACE", 3, 0, NULL, fltvalue}, + {"NEXTANIM", 3, 0, NULL, onevalue}, + {"OCTREE", 3, 0, NULL, onevalue}, + {"OVERSAMPLE", 2, 0, NULL, fltvalue}, + {"pfilt", 2, 0, NULL, catvalues}, + {"pinterp", 2, 0, NULL, catvalues}, + {"render", 3, 0, NULL, catvalues}, {"RESOLUTION", 3, 0, NULL, onevalue}, - {"EXPOSURE", 3, 0, NULL, onevalue}, + {"RIF", 3, 0, NULL, onevalue}, {"RSH", 3, 0, NULL, onevalue}, + {"RTRACE", 2, 0, NULL, boolvalue}, + {"START", 2, 0, NULL, intvalue}, + {"TRANSFER", 2, 0, NULL, onevalue}, + {"VIEWFILE", 2, 0, NULL, onevalue}, }; #define SFNAME "STATUS" /* status file name */ @@ -93,7 +107,7 @@ int silent = 0; /* silent mode? */ int noaction = 0; /* take no action? */ char *remsh; /* remote shell program/script */ -char rendopt[2048] = ""; /* rendering options */ +char rendopt[2048]; /* rendering options */ char rresopt[32]; /* rendering resolution options */ char fresopt[32]; /* filter resolution options */ int pfiltalways; /* always use pfilt? */ @@ -109,20 +123,46 @@ struct pslot { int npslots; /* number of process slots */ #define phostname(ps) ((ps)->hostname[0] ? (ps)->hostname : astat.host) - -struct pslot *findpslot(); - PSERVER *lastpserver; /* last process server with error */ -VIEW *getview(); -char *getexp(); +static struct pslot * findpslot(int pid); +static void checkdir(void); +static VIEW * getview(int n); -extern time_t fdate(), time(); +static char * dirfile(char *df, register char *path); +static char * getexp(int n); +static int getblur(double *bf); +static int getastat(void); +static void getradfile(char *rfargs); +static void badvalue(int vc); +static int rmfile(char *fn); +static int runcom(char *cs); +static int pruncom(char *com, char *ppins, int maxcopies); +static void bwait(int ncoms); +static int bruncom(char *com, int fout, int (*rf)()); +static int serverdown(void); +static pscompfunc donecom; +static int countviews(void); +static int dofilt(int frame, int rvr); +static void archive(void); +static int frecover(int frame); +static int recover(int frame); +static void sethosts(void); +static void walkwait(int first, int last, char *vfn); +static void animrend(int frame, VIEW *vp); +static void transferframes(void); +static void filterframes(void); +static void renderframes(int nframes); +static void animate(void); +static void setdefaults(void); +static void putastat(void); -main(argc, argv) -int argc; -char *argv[]; +int +main( + int argc, + char *argv[] +) { int explicate = 0; int i; @@ -150,6 +190,8 @@ char *argv[]; cfname = argv[i]; /* load variables */ loadvars(cfname); + /* check variables */ + checkvalues(); /* did we get DIRECTORY? */ checkdir(); /* check status */ @@ -183,13 +225,16 @@ char *argv[]; quit(1); } quit(0); + return 0; /* pro forma return */ userr: fprintf(stderr, "Usage: %s [-s][-n][-w][-e] anim_file\n", progname); quit(1); + return 1; /* pro forma return */ } -getastat() /* check/set animation status */ +static int +getastat(void) /* check/set animation status */ { char sfname[256]; FILE *fp; @@ -253,7 +298,8 @@ fmterr: } -putastat() /* put out current status */ +static void +putastat(void) /* put out current status */ { char buf[256]; FILE *fp; @@ -275,7 +321,8 @@ putastat() /* put out current status */ } -checkdir() /* make sure we have our directory */ +static void +checkdir(void) /* make sure we have our directory */ { struct stat stb; @@ -297,7 +344,8 @@ checkdir() /* make sure we have our directory */ } -setdefaults() /* set default values */ +static void +setdefaults(void) /* set default values */ { extern char *atos(); int decades; @@ -385,7 +433,8 @@ setdefaults() /* set default values */ } -sethosts() /* set up process servers */ +static void +sethosts(void) /* set up process servers */ { extern char *iskip(); char buf[256], *dir, *uname; @@ -440,40 +489,47 @@ sethosts() /* set up process servers */ } } - -getradfile(rfargs) /* run rad and get needed variables */ -char *rfargs; +static void +getradfile(char *rfargs) /* run rad and get needed variables */ { static short mvar[] = {OCTREE,PFILT,RESOLUTION,EXPOSURE,-1}; char combuf[256]; register int i; register char *cp; + char *pippt = NULL; /* create rad command */ sprintf(rendopt, " @%s/render.opt", vval(DIRECTORY)); sprintf(combuf, "rad -v 0 -s -e -w %s OPTFILE=%s | egrep '^[ \t]*(NOMATCH", rfargs, rendopt+2); cp = combuf; - while (*cp) cp++; /* match unset variables */ + while (*cp) { + if (*cp == '|') pippt = cp; + cp++; + } /* match unset variables */ for (i = 0; mvar[i] >= 0; i++) if (!vdef(mvar[i])) { *cp++ = '|'; strcpy(cp, vnam(mvar[i])); while (*cp) cp++; + pippt = NULL; } - sprintf(cp, ")[ \t]*=' > %s/radset.var", vval(DIRECTORY)); - cp += 11; /* point to file name */ - if (system(combuf)) { - fprintf(stderr, "%s: error executing rad command:\n\t%s\n", - progname, combuf); - quit(1); + if (pippt != NULL) + strcpy(pippt, "> " NULL_DEVICE); /* nothing to match */ + else { + sprintf(cp, ")[ \t]*=' > %s/radset.var", vval(DIRECTORY)); + cp += 11; /* point to file name */ } - loadvars(cp); /* load variables and remove file */ - unlink(cp); + system(combuf); /* ignore exit code */ + if (pippt == NULL) { /* load variables and remove file */ + loadvars(cp); + unlink(cp); + } } -animate() /* run animation */ +static void +animate(void) /* run animation */ { int xres, yres; float pa, mult; @@ -503,7 +559,7 @@ animate() /* run animation */ progname, vnam(INTERP)); vval(INTERP) = "0"; } - if (atoi(vval(MBLUR))) { /* can't handle this yet */ + if (strcmp(vval(MBLUR),"0")) { /* can't handle this */ if (!nowarn) fprintf(stderr, "%s: resetting %s=0 for animation\n", @@ -513,7 +569,7 @@ animate() /* run animation */ } /* figure # frames per batch */ d1 = mult*xres*mult*yres*4; /* space for orig. picture */ - if ((i=vint(INTERP)) || atoi(vval(MBLUR))) + if ((i=vint(INTERP)) || getblur(NULL) > 1) d1 += mult*xres*mult*yres*sizeof(float); /* Z-buffer */ d2 = xres*yres*4; /* space for final picture */ frames_batch = (i+1)*(vflt(DISKSPACE)*1048576.-d1)/(d1+i*d2); @@ -523,9 +579,7 @@ animate() /* run animation */ quit(1); } /* initialize archive argument list */ - i = 16; - if (vdef(ARCHIVE) && strlen(vval(ARCHIVE)) > i) - i = strlen(vval(ARCHIVE)); + i = vdef(ARCHIVE) ? strlen(vval(ARCHIVE))+132 : 132; arcnext = arcfirst = arcargs + i; /* initialize status file */ if (astat.rnext == 0) @@ -546,8 +600,8 @@ animate() /* run animation */ } -renderframes(nframes) /* render next nframes frames */ -int nframes; +static void +renderframes(int nframes) /* render next nframes frames */ { static char vendbuf[16]; VIEW *vp; @@ -603,23 +657,17 @@ int nframes; } -filterframes() /* catch up with filtering */ +static void +filterframes(void) /* catch up with filtering */ { - VIEW *vp; register int i; if (astat.tnext < astat.fnext) /* other work to do first */ return; /* filter each view */ - for (i = astat.fnext; i < astat.rnext; i++) { - if ((vp = getview(i)) == NULL) { /* get view i */ - fprintf(stderr, - "%s: unexpected error reading view for frame %d\n", - progname, i); - quit(1); - } - dofilt(i, vp, getexp(i), 0); /* filter frame */ - } + for (i = astat.fnext; i < astat.rnext; i++) + dofilt(i, 0); + bwait(0); /* wait for filter processes */ archive(); /* archive originals */ astat.fnext = i; /* update status */ @@ -627,9 +675,10 @@ filterframes() /* catch up with filtering */ } -transferframes() /* catch up with picture transfers */ +static void +transferframes(void) /* catch up with picture transfers */ { - char combuf[10240]; + char combuf[10240], *fbase; register char *cp; register int i; @@ -640,12 +689,19 @@ transferframes() /* catch up with picture transfers putastat(); /* update status */ return; } - strcpy(combuf, vval(TRANSFER)); /* start transfer command */ - cp = combuf + strlen(combuf); + strcpy(combuf, "cd "); /* start transfer command */ + fbase = dirfile(cp = combuf+3, vval(BASENAME)); + if (*cp) { + while (*++cp) ; + *cp++ = ';'; *cp++ = ' '; + } else + cp = combuf; + strcpy(cp, vval(TRANSFER)); + while (*cp) cp++; /* make argument list */ for (i = astat.tnext; i < astat.fnext; i++) { *cp++ = ' '; - sprintf(cp, vval(BASENAME), i); + sprintf(cp, fbase, i); while (*cp) cp++; strcpy(cp, ".pic"); cp += 4; @@ -660,11 +716,12 @@ transferframes() /* catch up with picture transfers } -animrend(frame, vp) /* start animation frame */ -int frame; -VIEW *vp; +static void +animrend( /* start animation frame */ +int frame, +VIEW *vp +) { - extern int recover(); char combuf[2048]; char fname[128]; @@ -678,12 +735,17 @@ VIEW *vp; } -walkwait(first, last, vfn) /* walk-through frames */ -int first, last; -char *vfn; +static void +walkwait( /* walk-through frames */ +int first, +int last, +char *vfn +) { + double blurf; + int nblur = getblur(&blurf); char combuf[2048]; - char *inspoint; + register char *inspoint; register int i; if (!noaction && vint(INTERP)) /* create dummy frames */ @@ -694,12 +756,21 @@ char *vfn; close(open(combuf, O_RDONLY|O_CREAT, 0666)); } /* create command */ - sprintf(combuf, "rpict%s -w0", rendopt); - if (vint(INTERP) || atoi(vval(MBLUR))) - sprintf(combuf+strlen(combuf), " -z %s.zbf", vval(BASENAME)); - sprintf(combuf+strlen(combuf), " -o %s.unf %s -S %d", + sprintf(combuf, "rpict%s%s -w0", rendopt, + viewopt(getview(first>1 ? first-1 : 1))); + inspoint = combuf; + while (*inspoint) inspoint++; + if (nblur) { + sprintf(inspoint, " -pm %.3f", blurf/nblur); + while (*inspoint) inspoint++; + } + if (nblur > 1 || vint(INTERP)) { + sprintf(inspoint, " -z %s.zbf", vval(BASENAME)); + while (*inspoint) inspoint++; + } + sprintf(inspoint, " -o %s.unf %s -S %d", vval(BASENAME), rresopt, first); - inspoint = combuf + strlen(combuf); + while (*inspoint) inspoint++; sprintf(inspoint, " %s < %s", vval(OCTREE), vfn); /* run in parallel */ i = (last-first+1)/(vint(INTERP)+1); @@ -719,12 +790,13 @@ char *vfn; } -int -recover(frame) /* recover the specified frame */ -int frame; +static int +recover(int frame) /* recover the specified frame */ { static int *rfrm; /* list of recovered frames */ static int nrfrms = 0; + double blurf; + int nblur = getblur(&blurf); char combuf[2048]; char fname[128]; register char *cp; @@ -740,8 +812,13 @@ int frame; vval(ANIMATE), frame, rendopt); else sprintf(combuf, "rpict%s -w0", rendopt); - cp = combuf + strlen(combuf); - if (vint(INTERP) || atoi(vval(MBLUR))) { + cp = combuf; + while (*cp) cp++; + if (nblur) { + sprintf(cp, " -pm %.3f", blurf/nblur); + while (*cp) cp++; + } + if (nblur > 1 || vint(INTERP)) { sprintf(cp, " -z %s.zbf", fname); while (*cp) cp++; } @@ -755,7 +832,7 @@ int frame; return(1); /* add frame to recovered list */ if (nrfrms) - rfrm = (int *)realloc((char *)rfrm, (nrfrms+1)*sizeof(int)); + rfrm = (int *)realloc((void *)rfrm, (nrfrms+1)*sizeof(int)); else rfrm = (int *)malloc(sizeof(int)); if (rfrm == NULL) { @@ -767,62 +844,83 @@ int frame; } -int -frecover(frame) /* recover filtered frame */ -int frame; +static int +frecover(int frame) /* recover filtered frame */ { - VIEW *vp; - char *ex; - - vp = getview(frame); - ex = getexp(frame); - if (dofilt(frame, vp, ex, 2) && dofilt(frame, vp, ex, 1)) + if (dofilt(frame, 2) && dofilt(frame, 1)) return(1); return(0); } -archive() /* archive and remove renderings */ +static void +archive(void) /* archive and remove renderings */ { #define RMCOML (sizeof(rmcom)-1) static char rmcom[] = "rm -f"; - register int i; + char basedir[128]; + int dlen, alen; + register int j; if (arcnext == arcfirst) return; /* nothing to do */ + dirfile(basedir, vval(BASENAME)); + dlen = strlen(basedir); if (vdef(ARCHIVE)) { /* run archive command */ - i = strlen(vval(ARCHIVE)); - strncpy(arcfirst-i, vval(ARCHIVE), i); - if (runcom(arcfirst-i)) { + alen = strlen(vval(ARCHIVE)); + if (dlen) { + j = alen + dlen + 5; + strncpy(arcfirst-j, "cd ", 3); + strncpy(arcfirst-j+3, basedir, dlen); + (arcfirst-j)[dlen+3] = ';'; (arcfirst-j)[dlen+4] = ' '; + } else + j = alen; + strncpy(arcfirst-alen, vval(ARCHIVE), alen); + if (runcom(arcfirst-j)) { fprintf(stderr, "%s: error running archive command\n", progname); quit(1); } } + if (dlen) { + j = RMCOML + dlen + 5; + strncpy(arcfirst-j, "cd ", 3); + strncpy(arcfirst-j+3, basedir, dlen); + (arcfirst-j)[dlen+3] = ';'; (arcfirst-j)[dlen+4] = ' '; + } else + j = RMCOML; /* run remove command */ strncpy(arcfirst-RMCOML, rmcom, RMCOML); - runcom(arcfirst-RMCOML); + runcom(arcfirst-j); arcnext = arcfirst; /* reset argument list */ #undef RMCOML } -int -dofilt(frame, vp, ep, rvr) /* filter frame */ -int frame; -VIEW *vp; -char *ep; -int rvr; +static int +dofilt( /* filter frame */ +int frame, +int rvr +) { - extern int frecover(); static int iter = 0; - char fnbefore[128], fnafter[128]; + double blurf; + int nblur = getblur(&blurf); + VIEW *vp = getview(frame); + char *ep = getexp(frame); + char fnbefore[128], fnafter[128], *fbase; char combuf[1024], fname0[128], fname1[128]; int usepinterp, usepfilt, nora_rgbe; int frseq[2]; /* check what is needed */ - usepinterp = atoi(vval(MBLUR)); - usepfilt = pfiltalways | ep==NULL; + if (vp == NULL) { + fprintf(stderr, + "%s: unexpected error reading view for frame %d\n", + progname, frame); + quit(1); + } + usepinterp = (nblur > 1); + usepfilt = pfiltalways | (ep==NULL); if (ep != NULL && !strcmp(ep, "1")) ep = "+0"; nora_rgbe = strcmp(vval(OVERSAMP),"1") || ep==NULL || @@ -830,6 +928,7 @@ int rvr; /* compute rendered views */ frseq[0] = frame - ((frame-1) % (vint(INTERP)+1)); frseq[1] = frseq[0] + vint(INTERP) + 1; + fbase = dirfile(NULL, vval(BASENAME)); if (frseq[1] > vint(END)) frseq[1] = vint(END); if (frseq[1] == frame) { /* pfilt only */ @@ -839,14 +938,13 @@ int rvr; } else if (frseq[0] == frame) { /* no interpolation needed */ if (!rvr && frame > 1+vint(INTERP)) { /* archive previous */ *arcnext++ = ' '; - sprintf(arcnext, vval(BASENAME), frame-vint(INTERP)-1); + sprintf(arcnext, fbase, frame-vint(INTERP)-1); while (*arcnext) arcnext++; strcpy(arcnext, ".unf"); arcnext += 4; if (usepinterp || vint(INTERP)) { /* and Z-buf */ *arcnext++ = ' '; - sprintf(arcnext, vval(BASENAME), - frame-vint(INTERP)-1); + sprintf(arcnext, fbase, frame-vint(INTERP)-1); while (*arcnext) arcnext++; strcpy(arcnext, ".zbf"); arcnext += 4; @@ -866,34 +964,35 @@ int rvr; if (usepinterp) { /* using pinterp */ if (rvr == 2 && recover(frseq[1])) /* recover after? */ return(1); - if (atoi(vval(MBLUR))) { - FILE *fp; /* motion blurring */ + if (nblur > 1) { /* with pmblur */ sprintf(fname0, "%s/vw0%c", vval(DIRECTORY), 'a'+(iter%26)); - if ((fp = fopen(fname0, "w")) == NULL) { - perror(fname0); quit(1); - } - fputs(VIEWSTR, fp); - fprintview(vp, fp); - putc('\n', fp); fclose(fp); - if ((vp = getview(frame+1)) == NULL) { - fprintf(stderr, - "%s: unexpected error reading view for frame %d\n", - progname, frame+1); - quit(1); - } sprintf(fname1, "%s/vw1%c", vval(DIRECTORY), 'a'+(iter%26)); - if ((fp = fopen(fname1, "w")) == NULL) { - perror(fname1); quit(1); + if (!noaction) { + FILE *fp; /* motion blurring */ + if ((fp = fopen(fname0, "w")) == NULL) { + perror(fname0); quit(1); + } + fputs(VIEWSTR, fp); + fprintview(vp, fp); + putc('\n', fp); fclose(fp); + if ((vp = getview(frame+1)) == NULL) { + fprintf(stderr, + "%s: unexpected error reading view for frame %d\n", + progname, frame+1); + quit(1); + } + if ((fp = fopen(fname1, "w")) == NULL) { + perror(fname1); quit(1); + } + fputs(VIEWSTR, fp); + fprintview(vp, fp); + putc('\n', fp); fclose(fp); } - fputs(VIEWSTR, fp); - fprintview(vp, fp); - putc('\n', fp); fclose(fp); sprintf(combuf, - "(pmblur %s %d %s %s; rm -f %s %s) | pinterp -B", - *sskip(vval(MBLUR)) ? sskip2(vval(MBLUR),1) : "1", - atoi(vval(MBLUR)), + "(pmblur %.3f %d %s %s; rm -f %s %s) | pinterp -B -a", + blurf, nblur, fname0, fname1, fname0, fname1); iter++; } else /* no blurring */ @@ -901,13 +1000,13 @@ int rvr; strcat(combuf, viewopt(vp)); if (vbool(RTRACE)) sprintf(combuf+strlen(combuf), " -ff -fr '%s -w0 %s'", - rendopt, vval(OCTREE)); + rendopt+1, vval(OCTREE)); if (vdef(PINTERP)) sprintf(combuf+strlen(combuf), " %s", vval(PINTERP)); if (usepfilt) sprintf(combuf+strlen(combuf), " %s", rresopt); else - sprintf(combuf+strlen(combuf), " %s -e %s", + sprintf(combuf+strlen(combuf), " -a %s -e %s", fresopt, ep); sprintf(combuf+strlen(combuf), " %s.unf %s.zbf", fnbefore, fnbefore); @@ -954,9 +1053,8 @@ int rvr; } -VIEW * -getview(n) /* get view number n */ -int n; +static VIEW * +getview(int n) /* get view number n */ { static FILE *viewfp = NULL; /* view file pointer */ static int viewnum = 0; /* current view number */ @@ -968,25 +1066,32 @@ int n; fclose(viewfp); viewfp = NULL; viewnum = 0; - copystruct(&curview, &stdview); + curview = stdview; } return(NULL); } - if (viewfp == NULL) { /* open file */ + if (viewfp == NULL) { /* open file */ if ((viewfp = fopen(vval(VIEWFILE), "r")) == NULL) { perror(vval(VIEWFILE)); quit(1); } - } else if (n < viewnum) { /* rewind file */ + } else if (n > 0 && n < viewnum) { /* rewind file */ if (viewnum == 1 && feof(viewfp)) return(&curview); /* just one view */ if (fseek(viewfp, 0L, 0) == EOF) { perror(vval(VIEWFILE)); quit(1); } - copystruct(&curview, &stdview); + curview = stdview; viewnum = 0; } + if (n < 0) { /* get next view */ + register int c = getc(viewfp); + if (c == EOF) + return((VIEW *)NULL); /* that's it */ + ungetc(c, viewfp); + n = viewnum + 1; + } while (n > viewnum) { /* scan to desired view */ if (fgets(linebuf, sizeof(linebuf), viewfp) == NULL) return(viewnum==1 ? &curview : (VIEW *)NULL); @@ -997,20 +1102,21 @@ int n; } -int -countviews() /* count views in view file */ +static int +countviews(void) /* count views in view file */ { - register int n = 0; + int n; - while (getview(n+1) != NULL) + if (getview(n=1) == NULL) + return(0); + while (getview(-1) != NULL) n++; return(n); } -char * -getexp(n) /* get exposure for nth frame */ -int n; +static char * +getexp(int n) /* get exposure for nth frame */ { extern char *fskip(); static char expval[32]; @@ -1022,7 +1128,7 @@ int n; if (n == 0) { /* signal to close file */ if (expfp != NULL) { fclose(expfp); - free((char *)exppos); + free((void *)exppos); expfp = NULL; } return(NULL); @@ -1079,9 +1185,8 @@ int n; } -struct pslot * -findpslot(pid) /* find or allocate a process slot */ -int pid; +static struct pslot * +findpslot(int pid) /* find or allocate a process slot */ { register struct pslot *psempty = NULL; register int i; @@ -1096,13 +1201,14 @@ int pid; } -int -donecom(ps, pn, status) /* clean up after finished process */ -PSERVER *ps; -int pn; -int status; +static int +donecom( /* clean up after finished process */ + PSERVER *ps, + int pn, + int status +) { - register PROC *pp; + register NETPROC *pp; register struct pslot *psl; pp = ps->proc + pn; @@ -1137,8 +1243,8 @@ int status; } -int -serverdown() /* check status of last process server */ +static int +serverdown(void) /* check status of last process server */ { if (lastpserver == NULL || !lastpserver->hostname[0]) return(0); @@ -1154,11 +1260,12 @@ serverdown() /* check status of last process server } -int -bruncom(com, fout, rf) /* run a command in the background */ -char *com; -int fout; -int (*rf)(); +static int +bruncom( /* run a command in the background */ +char *com, +int fout, +int (*rf)() +) { int pid; register struct pslot *psl; @@ -1187,8 +1294,8 @@ int (*rf)(); } -bwait(ncoms) /* wait for batch job(s) to finish */ -int ncoms; +static void +bwait(int ncoms) /* wait for batch job(s) to finish */ { int status; @@ -1202,10 +1309,12 @@ int ncoms; } -int -pruncom(com, ppins, maxcopies) /* run a command in parallel over network */ -char *com, *ppins; -int maxcopies; +static int +pruncom( /* run a command in parallel over network */ +char *com, +char *ppins, +int maxcopies +) { int retstatus = 0; int hostcopies; @@ -1227,6 +1336,7 @@ int maxcopies; strcpy(com1=buf, com); /* build -PP command */ sprintf(com1+(ppins-com), " -PP %s/%s.persist", vval(DIRECTORY), phostname(ps)); + unlink(com1+(ppins-com)+5); strcat(com1, ppins); } else com1 = com; @@ -1271,8 +1381,8 @@ int maxcopies; } -runcom(cs) /* run a command locally and wait for it */ -char *cs; +static int +runcom(char *cs) /* run a command locally and wait for it */ { if (!silent) /* echo it */ printf("\t%s\n", cs); @@ -1283,11 +1393,11 @@ char *cs; } -rmfile(fn) /* remove a file */ -char *fn; +static int +rmfile(char *fn) /* remove a file */ { if (!silent) -#ifdef MSDOS +#ifdef _WIN32 printf("\tdel %s\n", fn); #else printf("\trm -f %s\n", fn); @@ -1298,10 +1408,65 @@ char *fn; } -badvalue(vc) /* report bad variable value and exit */ -int vc; +static void +badvalue(int vc) /* report bad variable value and exit */ { fprintf(stderr, "%s: bad value for variable '%s'\n", progname, vnam(vc)); quit(1); +} + + +static char * +dirfile( /* separate path into directory and file */ +char *df, +register char *path +) +{ + register int i; + int psep; + + for (i = 0, psep = -1; path[i]; i++) + if (path[i] == '/') + psep = i; + if (df != NULL) { + if (psep == 0) { + df[0] = '/'; + df[1] = '\0'; + } else if (psep > 0) { + strncpy(df, path, psep); + df[psep] = '\0'; + } else + df[0] = '\0'; + } + return(path+psep+1); +} + + +static int +getblur(double *bf) /* get # blur samples (and fraction) */ +{ + double blurf; + int nblur; + char *s; + + if (!vdef(MBLUR)) { + if (bf != NULL) + *bf = 0.0; + return(0); + } + blurf = atof(vval(MBLUR)); + if (blurf < 0.0) + blurf = 0.0; + if (bf != NULL) + *bf = blurf; + if (blurf <= FTINY) + return(0); + s = sskip(vval(MBLUR)); + if (!*s) + return(DEF_NBLUR); + nblur = atoi(s); + if (nblur <= 0) + return(1); + return(nblur); }