--- ray/src/util/ranimove1.c 2003/02/25 02:47:24 3.2 +++ ray/src/util/ranimove1.c 2012/10/05 00:59:38 3.21 @@ -1,18 +1,22 @@ #ifndef lint -static const char RCSid[] = "$Id: ranimove1.c,v 3.2 2003/02/25 02:47:24 greg Exp $"; +static const char RCSid[] = "$Id: ranimove1.c,v 3.21 2012/10/05 00:59:38 greg Exp $"; #endif /* * ranimove1.c * - * Basic frame rendering routines for ranimate(1). + * Basic frame rendering routines for ranimove(1). * * Created by Gregory Ward on Wed Jan 08 2003. */ #include "copyright.h" +#include + +#include "platform.h" #include "ranimove.h" #include "otypes.h" +#include "source.h" #include "random.h" double acctab[256]; /* accuracy value table */ @@ -26,14 +30,15 @@ float *zbuffer; /* depth at each pixel */ OBJECT *obuffer; /* object id at each pixel */ short *xmbuffer; /* x motion at each pixel */ short *ymbuffer; /* y motion at each pixel */ -BYTE *abuffer; /* accuracy at each pixel */ -BYTE *sbuffer; /* sample count per pixel */ +uby8 *abuffer; /* accuracy at each pixel */ +uby8 *sbuffer; /* sample count per pixel */ +COLOR *outbuffer; /* output buffer (may equal cbuffer) */ VIEW vwprev; /* last frame's view */ COLOR *cprev; /* last frame colors */ float *zprev; /* last frame depth */ OBJECT *oprev; /* last frame objects */ -BYTE *aprev; /* last frame accuracy */ +uby8 *aprev; /* last frame accuracy */ float *cerrmap; /* conspicuous error map */ COLOR *val2map; /* value-squared map for variance */ @@ -43,10 +48,19 @@ double frm_stop; /* when to stop rendering this frame double hlsmax; /* maximum high-level saliency this frame */ +static void next_frame(void); +static int sample_here(int x, int y); +static int offset_cmp(const void *p1, const void *p2); +static void setmotion(int n, FVECT wpos); +static void init_frame_sample(void); + + +#if 0 void -write_map(mp, fn) /* write out float map (debugging) */ -float *mp; -char *fn; +write_map( /* write out float map (debugging) */ + float *mp, + char *fn +) { FILE *fp = fopen(fn, "w"); COLOR scanbuf[2048]; @@ -67,18 +81,19 @@ char *fn; } fclose(fp); } +#endif static void -next_frame() /* prepare next frame buffer */ +next_frame(void) /* prepare next frame buffer */ { VIEW *fv; char *err; /* get previous view */ if (vw.type != 0) - copystruct(&vwprev, &vw); + vwprev = vw; else if (fcur > 1 && (fv = getview(fcur-1)) != NULL) { - copystruct(&vwprev, fv); + vwprev = *fv; if (setview(&vwprev) != NULL) vwprev.type = 0; } @@ -87,13 +102,13 @@ next_frame() /* prepare next frame buffer */ sprintf(errmsg, "cannot get view for frame %d", fcur); error(USER, errmsg); } - copystruct(&vw, fv); + vw = *fv; if ((err = setview(&vw)) != NULL) { sprintf(errmsg, "view error at frame %d: %s", fcur, err); error(USER, errmsg); } if (cbuffer == NULL) { - /* compute resolution and allocate */ + int n; /* compute resolution and allocate */ switch (sscanf(vval(RESOLUTION), "%d %d %lf", &hres, &vres, &pixaspect)) { case 1: @@ -103,7 +118,7 @@ next_frame() /* prepare next frame buffer */ pixaspect = 1.; /* fall through */ case 3: - if ((hres > 0 & vres > 0)) + if ((hres > 0) & (vres > 0)) break; /* fall through */ default: @@ -116,30 +131,44 @@ next_frame() /* prepare next frame buffer */ obuffer = (OBJECT *)malloc(sizeof(OBJECT)*hres*vres); xmbuffer = (short *)malloc(sizeof(short)*hres*vres); ymbuffer = (short *)malloc(sizeof(short)*hres*vres); - abuffer = (BYTE *)calloc(hres*vres, sizeof(BYTE)); - sbuffer = (BYTE *)calloc(hres*vres, sizeof(BYTE)); + abuffer = (uby8 *)calloc(hres*vres, sizeof(uby8)); + sbuffer = (uby8 *)calloc(hres*vres, sizeof(uby8)); cprev = (COLOR *)malloc(sizeof(COLOR)*hres*vres); zprev = (float *)malloc(sizeof(float)*hres*vres); oprev = (OBJECT *)malloc(sizeof(OBJECT)*hres*vres); - aprev = (BYTE *)malloc(sizeof(BYTE)*hres*vres); - if ((cbuffer==NULL | zbuffer==NULL | obuffer==NULL | - xmbuffer==NULL | ymbuffer==NULL | - abuffer==NULL | sbuffer==NULL | - cprev==NULL | zprev == NULL | - oprev==NULL | aprev==NULL)) + aprev = (uby8 *)malloc(sizeof(uby8)*hres*vres); + if (mblur > .02) + outbuffer = (COLOR *)malloc(sizeof(COLOR)*hres*vres); + else + outbuffer = cbuffer; + if ((cbuffer==NULL) | (zbuffer==NULL) | (obuffer==NULL) | + (xmbuffer==NULL) | (ymbuffer==NULL) | + (abuffer==NULL) | (sbuffer==NULL) | + (cprev==NULL) | (zprev == NULL) | + (oprev==NULL) | (aprev==NULL) | + (outbuffer==NULL)) error(SYSTEM, "out of memory in init_frame"); + for (n = hres*vres; n--; ) { + zprev[n] = -1.f; + oprev[n] = OVOID; + } frm_stop = getTime() + rtperfrm; - } else { - COLOR *cp; /* else just swap buffers */ + } else { /* else just swap buffers */ float *fp; OBJECT *op; - BYTE *bp; - cp = cprev; cprev = cbuffer; cbuffer = cp; + uby8 *bp; + if (outbuffer != cbuffer) { + COLOR *cp = cprev; + cprev = cbuffer; cbuffer = cp; + } else { + outbuffer = cprev; cprev = cbuffer; + cbuffer = outbuffer; + } fp = zprev; zprev = zbuffer; zbuffer = fp; op = oprev; oprev = obuffer; obuffer = op; bp = aprev; aprev = abuffer; abuffer = bp; - bzero(abuffer, sizeof(BYTE)*hres*vres); - bzero(sbuffer, sizeof(BYTE)*hres*vres); + memset(abuffer, 0, sizeof(uby8)*hres*vres); + memset(sbuffer, 0, sizeof(uby8)*hres*vres); frm_stop += rtperfrm; } cerrmap = NULL; @@ -152,8 +181,10 @@ next_frame() /* prepare next frame buffer */ static int -sample_here(x, y) /* 4x4 quincunx sample at this pixel? */ -register int x, y; +sample_here( /* 4x4 quincunx sample at this pixel? */ + int x, + int y +) { if (y & 0x1) /* every other row has samples */ return(0); @@ -164,10 +195,12 @@ register int x, y; void -sample_pos(hv, x, y, sn) /* compute jittered sample position */ -double hv[2]; -int x, y; -int sn; +sample_pos( /* compute jittered sample position */ + double hv[2], + int x, + int y, + int sn +) { int hl[2]; @@ -179,11 +212,15 @@ int sn; double -sample_wt(xo, yo) /* compute interpolant sample weight */ -int xo, yo; +sample_wt( /* compute interpolant sample weight */ + int xo, + int yo +) { static double etab[400]; - int rad2 = xo*xo + yo*yo; + /* we can't use the name rad2 here, for some reason Visual C + thinks that is a constant (compiler bug?) */ + int rad_2 = xo*xo + yo*yo; int i; if (etab[0] <= FTINY) /* initialize exponent table */ @@ -191,7 +228,7 @@ int xo, yo; etab[i] = exp(-0.1*i); /* look up Gaussian */ - i = (int)((10.*3./(double)SAMPDIST2)*rad2 + .5); + i = (int)((10.*3./(double)SAMPDIST2)*rad_2 + .5); if (i >= 400) return(0.0); return(etab[i]); @@ -199,30 +236,34 @@ int xo, yo; static int -offset_cmp(p1, p2) /* compare offset distances */ -const void *p1, *p2; +offset_cmp( /* compare offset distances */ + const void *p1, + const void *p2 +) { return(*(const int *)p1 - *(const int *)p2); } int -getclosest(iarr, nc, x, y) /* get nc closest neighbors on same object */ -int *iarr; -int nc; -int x, y; +getclosest( /* get nc closest neighbors on same object */ + int *iarr, + int nc, + int x, + int y +) { #define NSCHECK ((2*SAMPDIST+1)*(2*SAMPDIST+1)) static int hro, vro; static int ioffs[NSCHECK]; OBJECT myobj; int i0, nf; - register int i, j; + int i, j; /* get our object number */ myobj = obuffer[fndx(x, y)]; /* special case for borders */ - if ((x < SAMPDIST | x >= hres-SAMPDIST | - y < SAMPDIST | y >= vres-SAMPDIST)) { + if ((x < SAMPDIST) | (x >= hres-SAMPDIST) | + (y < SAMPDIST) | (y >= vres-SAMPDIST)) { int tndx[NSCHECK][2]; nf = 0; for (j = y - SAMPDIST; j <= y + SAMPDIST; j++) { @@ -234,7 +275,7 @@ int x, y; i0 = fndx(i, j); if (!sbuffer[i0]) continue; - if ((myobj != OVOID & obuffer[i0] != myobj)) + if ((myobj != OVOID) & (obuffer[i0] != myobj)) continue; tndx[nf][0] = (i-x)*(i-x) + (j-y)*(j-y); tndx[nf][1] = i0; @@ -249,7 +290,7 @@ int x, y; return(nf); } /* initialize offset array */ - if ((hres != hro | vres != vro)) { + if ((hres != hro) | (vres != vro)) { int toffs[NSCHECK][2]; i0 = fndx(SAMPDIST, SAMPDIST); nf = 0; @@ -268,9 +309,9 @@ int x, y; } /* find up to nc neighbors */ i0 = fndx(x, y); - for (j = 0, nf = 0; (j < NSCHECK & nf < nc); j++) { + for (j = 0, nf = 0; (j < NSCHECK) & (nf < nc); j++) { i = i0 + ioffs[j]; - if (sbuffer[i] && (myobj == OVOID | obuffer[i] == myobj)) + if (sbuffer[i] && (myobj == OVOID) | (obuffer[i] == myobj)) iarr[nf++] = i; } /* return number found */ @@ -280,13 +321,12 @@ int x, y; static void -setmotion(n, wpos) /* compute motion vector for this pixel */ -register int n; -FVECT wpos; +setmotion( /* compute motion vector for this pixel */ + int n, + FVECT wpos +) { FVECT ovp; - MAT4 xfm; - double d; int moi; int xp, yp; /* ID object and update maximum HLS */ @@ -306,22 +346,22 @@ FVECT wpos; yp = (int)(ovp[1]*vres); xmbuffer[n] = xp - (n % hres); ymbuffer[n] = yp - (n / hres); - if ((xp < 0 | xp >= hres)) + if ((xp < 0) | (xp >= hres)) return; - if ((yp < 0 | yp >= vres)) + if ((yp < 0) | (yp >= vres)) return; n = fndx(xp, yp); - if ((zprev[n] < 0.97*ovp[2] | zprev[n] > 1.03*ovp[2])) + if ((zprev[n] < 0.97*ovp[2]) | (zprev[n] > 1.03*ovp[2])) oprev[n] = OVOID; /* assume it's a bad match */ } static void -init_frame_sample() /* sample our initial frame */ +init_frame_sample(void) /* sample our initial frame */ { RAY ir; int x, y; - register int n; + int n; if (!silent) { printf("\tComputing initial samples..."); @@ -332,8 +372,7 @@ init_frame_sample() /* sample our initial frame */ for (x = hres; x--; ) { double hv[2]; n = fndx(x, y); - xmbuffer[n] = MO_UNK; - ymbuffer[n] = MO_UNK; + xmbuffer[n] = ymbuffer[n] = MO_UNK; sample_pos(hv, x, y, 0); ir.rmax = viewray(ir.rorg, ir.rdir, &vw, hv[0], hv[1]); if (ir.rmax < -FTINY) { @@ -344,10 +383,12 @@ init_frame_sample() /* sample our initial frame */ continue; } if (!sample_here(x, y)) { /* just cast */ - rayorigin(&ir, NULL, PRIMARY, 1.0); + rayorigin(&ir, PRIMARY, NULL, NULL); if (!localhit(&ir, &thescene)) { - if (ir.ro != &Aftplane) - sourcehit(&ir); + if (ir.ro != &Aftplane && sourcehit(&ir)) { + rayshade(&ir, ir.ro->omod); + rayparticipate(&ir); + } copycolor(cbuffer[n], ir.rcol); zbuffer[n] = ir.rot; obuffer[n] = ir.robj; @@ -362,7 +403,7 @@ init_frame_sample() /* sample our initial frame */ } if (nprocs > 1) { /* get sample */ int rval; - rayorigin(&ir, NULL, PRIMARY, 1.0); + rayorigin(&ir, PRIMARY, NULL, NULL); ir.rno = n; rval = ray_pqueue(&ir); if (!rval) @@ -376,7 +417,7 @@ init_frame_sample() /* sample our initial frame */ zbuffer[n] = ir.rot; obuffer[n] = ir.robj; sbuffer[n] = 1; - if (ir.rot >= FHUGE) + if (ir.rot >= 0.99*FHUGE) abuffer[n] = ADISTANT; else { abuffer[n] = ALOWQ; @@ -404,11 +445,11 @@ init_frame_sample() /* sample our initial frame */ n = fndx(x, y); if ((obj = obuffer[n]) == OVOID) continue; - if ((obuffer[n+1] != OVOID & obuffer[n+1] != obj)) { + if ((obuffer[n+1] != OVOID) & (obuffer[n+1] != obj)) { obuffer[n] = OVOID; obuffer[n+1] = OVOID; } - if ((obuffer[n+hres] != OVOID & obuffer[n+hres] != obj)) { + if ((obuffer[n+hres] != OVOID) & (obuffer[n+hres] != obj)) { obuffer[n] = OVOID; obuffer[n+hres] = OVOID; } @@ -420,23 +461,21 @@ init_frame_sample() /* sample our initial frame */ int -getambcolor(clr, obj) /* get ambient color for object if we can */ -COLOR clr; -int obj; +getambcolor( /* get ambient color for object if we can */ + COLOR clr, + int obj +) { - register OBJREC *op; + OBJREC *op; if (obj == OVOID) return(0); - op = objptr(obj); - if ((op->otype == OBJ_INSTANCE & op->omod == OVOID)) + op = objptr(obj); /* search for material */ + if (op->omod == OVOID) return(0); - /* search for material */ - do { - if (op->omod == OVOID || ofun[op->otype].flags & T_X) - return(0); - op = objptr(op->omod); - } while (!ismaterial(op->otype)); + op = findmaterial(objptr(op->omod)); + if (op == NULL) + return(0); /* * Since this routine is called to compute the difference * from rendering with and without interreflections, @@ -450,7 +489,7 @@ int obj; if (lv[0] == op->oname[0] && !strcmp(lv+1, op->oname+1)) break; - if ((lv != NULL) != hirendparams.ambincl) + if ((lv != NULL) ^ hirendparams.ambincl) return(0); } switch (op->otype) { @@ -490,9 +529,12 @@ int obj; double -estimaterr(cs, cs2, ns, ns0) /* estimate relative error from samples */ -COLOR cs, cs2; -int ns; +estimaterr( /* estimate relative error from samples */ + COLOR cs, + COLOR cs2, + int ns, + int ns0 +) { double d, d2, brt; @@ -513,20 +555,21 @@ int ns; double -comperr(neigh, nc, ns0) /* estimate relative error in neighborhood */ -int *neigh; -int nc; -int ns0; +comperr( /* estimate relative error in neighborhood */ + int *neigh, + int nc, + int ns0 +) { COLOR csum, csum2; COLOR ctmp; int i; int ns; - register int n; + int n; /* add together samples */ setcolor(csum, 0., 0., 0.); setcolor(csum2, 0., 0., 0.); - for (i = 0, ns = 0; (i < nc & ns < NSAMPOK); i++) { + for (i = 0, ns = 0; (i < nc) & (ns < NSAMPOK); i++) { n = neigh[i]; addcolor(csum, cbuffer[n]); if (val2map != NULL) { @@ -536,10 +579,8 @@ int ns0; } if (sbuffer[n] != 1) error(CONSISTENCY, "bad count in comperr"); - setcolor(ctmp, - colval(cbuffer[n],RED)*colval(cbuffer[n],RED), - colval(cbuffer[n],GRN)*colval(cbuffer[n],GRN), - colval(cbuffer[n],BLU)*colval(cbuffer[n],BLU)); + copycolor(ctmp, cbuffer[n]); + multcolor(ctmp, ctmp); addcolor(csum2, ctmp); ns++; } @@ -548,15 +589,15 @@ int ns0; void -comp_frame_error() /* initialize frame error values */ +comp_frame_error(void) /* initialize frame error values */ { - BYTE *edone = NULL; + uby8 *edone = NULL; COLOR objamb; double eest; int neigh[NSAMPOK]; int nc; - int x, y, i, j; - register int n; + int x, y, i; + int n; if (!silent) { printf("\tComputing error map\n"); @@ -574,11 +615,9 @@ comp_frame_error() /* initialize frame error values * * error should be less than the ambient value divided * by the returned ray value -- we take half of this. */ - edone = (BYTE *)calloc(hres*vres, sizeof(BYTE)); - for (y = vres; y--; ) - for (x = hres; x--; ) { - n = fndx(x, y); - if ((abuffer[n] != ALOWQ | obuffer[n] == OVOID)) + edone = (uby8 *)calloc(hres*vres, sizeof(uby8)); + for (n = hres*vres; n--; ) { + if ((abuffer[n] != ALOWQ) | (obuffer[n] == OVOID)) continue; if (!getambcolor(objamb, obuffer[n])) continue; @@ -594,7 +633,7 @@ comp_frame_error() /* initialize frame error values * else if (i >= ADISTANT/2) i = ADISTANT/2-1; abuffer[n] = i; edone[n] = 1; - } + } } /* final statistical estimate */ for (y = vres; y--; ) @@ -627,21 +666,15 @@ comp_frame_error() /* initialize frame error values * void -init_frame() /* render base (low quality) frame */ +init_frame(void) /* render base (low quality) frame */ { int restart; - /* allocate/swap buffers */ next_frame(); /* check rendering status */ restart = (!nobjects || vdef(MOVE)); if (!restart && curparams != &lorendparams && nprocs > 1) restart = -1; - if (restart > 0) - if (nprocs > 1) - ray_pdone(1); - else - ray_done(1); /* post low quality parameters */ if (curparams != &lorendparams) ray_restore(curparams = &lorendparams); @@ -673,11 +706,11 @@ init_frame() /* render base (low quality) frame */ init_frame_sample(); /* initialize frame error */ comp_frame_error(); -return; +#if 0 { float *ebuf = (float *)malloc(sizeof(float)*hres*vres); char fnm[256]; - register int n; + int n; for (n = hres*vres; n--; ) ebuf[n] = acctab[abuffer[n]]; sprintf(fnm, vval(BASENAME), fcur); @@ -685,46 +718,44 @@ return; write_map(ebuf, fnm); free((void *)ebuf); } +#endif } void -filter_frame() /* interpolation, motion-blur, and exposure */ +filter_frame(void) /* interpolation, motion-blur, and exposure */ { - double expval = expspec_val(getexp(fcur)); - int x, y; - int neigh[NPINTERP]; - int nc; - COLOR cval; - double w, wsum; - register int n; + const double expval = expspec_val(getexp(fcur)); + int x, y; + int neigh[NPINTERP]; + int nc; + COLOR cval; + double w, wsum; + int n; #if 0 -/* XXX TEMPORARY!! */ -conspicuity(); -write_map(cerrmap, "outcmap.pic"); -{ - float *ebuf = (float *)malloc(sizeof(float)*hres*vres); - for (n = hres*vres; n--; ) - ebuf[n] = acctab[abuffer[n]]; - write_map(ebuf, "outerr.pic"); - free((void *)ebuf); -} + /* XXX TEMPORARY!! */ + conspicuity(); + write_map(cerrmap, "outcmap.pic"); + { + float *ebuf = (float *)malloc(sizeof(float)*hres*vres); + for (n = hres*vres; n--; ) + ebuf[n] = acctab[abuffer[n]]; + write_map(ebuf, "outerr.pic"); + free((void *)ebuf); + } #endif - if (!silent) { printf("\tFiltering frame\n"); fflush(stdout); } /* normalize samples */ - for (y = vres; y--; ) - for (x = hres; x--; ) { - n = fndx(x, y); + for (n = hres*vres; n--; ) { if (sbuffer[n] <= 1) continue; w = 1.0/(double)sbuffer[n]; scalecolor(cbuffer[n], w); - } + } /* interpolate samples */ for (y = vres; y--; ) for (x = hres; x--; ) { @@ -733,6 +764,16 @@ write_map(cerrmap, "outcmap.pic"); continue; nc = getclosest(neigh, NPINTERP, x, y); setcolor(cbuffer[n], 0., 0., 0.); + if (nc <= 0) { /* no acceptable neighbors */ + if (y < vres-1) + nc = fndx(x, y+1); + else if (x < hres-1) + nc = fndx(x+1, y); + else + continue; + copycolor(cbuffer[n], cbuffer[nc]); + continue; + } wsum = 0.; while (nc-- > 0) { copycolor(cval, cbuffer[neigh[nc]]); @@ -742,22 +783,21 @@ write_map(cerrmap, "outcmap.pic"); addcolor(cbuffer[n], cval); wsum += w; } - if (wsum > FTINY) { - w = 1.0/wsum; - scalecolor(cbuffer[n], w); - } + w = 1.0/wsum; + scalecolor(cbuffer[n], w); } /* motion blur if requested */ - if (mblur > .02) { - int len; + if (outbuffer != cbuffer) { int xs, ys, xl, yl; int rise, run; long rise2, run2; int n2; int cnt; +fprintf(stderr, "outbuffer=0x%lx, cbuffer=0x%lx, cprev=0x%lx\n", +(size_t)outbuffer, (size_t)cbuffer, (size_t)cprev); /* sum in motion streaks */ - bzero(outbuffer, sizeof(COLOR)*hres*vres); - bzero(wbuffer, sizeof(float)*hres*vres); + memset(outbuffer, 0, sizeof(COLOR)*hres*vres); + memset(wbuffer, 0, sizeof(float)*hres*vres); for (y = vres; y--; ) for (x = hres; x--; ) { n = fndx(x, y); @@ -772,8 +812,7 @@ write_map(cerrmap, "outcmap.pic"); wbuffer[n] += 1.; continue; } - xl = x - run/4; - yl = y - rise/4; + xl = x; yl = y; if (run < 0) { xs = -1; run = -run; } else xs = 1; if (rise < 0) { ys = -1; rise = -rise; } @@ -786,8 +825,8 @@ write_map(cerrmap, "outcmap.pic"); scalecolor(cval, w); while (cnt) if (rise2 >= run2) { - if ((xl >= 0 & xl < hres & - yl >= 0 & yl < vres)) { + if ((xl >= 0) & (xl < hres) & + (yl >= 0) & (yl < vres)) { n2 = fndx(xl, yl); addcolor(outbuffer[n2], cval); @@ -807,8 +846,8 @@ write_map(cerrmap, "outcmap.pic"); scalecolor(cval, w); while (cnt) if (run2 >= rise2) { - if ((xl >= 0 & xl < hres & - yl >= 0 & yl < vres)) { + if ((xl >= 0) & (xl < hres) & + (yl >= 0) & (yl < vres)) { n2 = fndx(xl, yl); addcolor(outbuffer[n2], cval); @@ -824,60 +863,58 @@ write_map(cerrmap, "outcmap.pic"); } } /* compute final results */ - for (y = vres; y--; ) - for (x = hres; x--; ) { - n = fndx(x, y); - if (wbuffer[n] <= FTINY) - continue; - w = 1./wbuffer[n]; - scalecolor(outbuffer[n], w); - } - } else for (n = hres*vres; n--; ) - copycolor(outbuffer[n], cbuffer[n]); -/* -for (n = hres*vres; n--; ) - if (!sbuffer[n]) - setcolor(outbuffer[n], 0., 0., 0.); -*/ - /* adjust exposure */ - if ((expval < 0.99 | expval > 1.01)) + if (wbuffer[n] > 1.02) { + w = 1./wbuffer[n]; + scalecolor(outbuffer[n], w); + } else if (wbuffer[n] < 0.98) { + w = 1.-wbuffer[n]; + copycolor(cval, cprev[n]); + scalecolor(cval, w); + addcolor(outbuffer[n], cval); + } + } + /* adjust exposure */ + for (n = ((expval < 0.98) | (expval > 1.02))*hres*vres; n--; ) + scalecolor(outbuffer[n], expval); + /* + for (n = hres*vres; n--; ) + if (!sbuffer[n]) + setcolor(outbuffer[n], 0., 0., 0.); + */ +#if 0 + { + float *sbuf = (float *)malloc(sizeof(float)*hres*vres); + char fnm[256]; + sprintf(fnm, vval(BASENAME), fcur); + strcat(fnm, "_outsamp.pic"); for (n = hres*vres; n--; ) - scalecolor(outbuffer[n], expval); -return; -{ - float *sbuf = (float *)malloc(sizeof(float)*hres*vres); - char fnm[256]; - sprintf(fnm, vval(BASENAME), fcur); - strcat(fnm, "_outsamp.pic"); - for (n = hres*vres; n--; ) - sbuf[n] = (float)sbuffer[n]; - write_map(sbuf, fnm); - free((void *)sbuf); + sbuf[n] = (float)sbuffer[n]; + write_map(sbuf, fnm); + free((void *)sbuf); + } +#endif } -} void -send_frame() /* send frame to destination */ +send_frame(void) /* send frame to destination */ { - char pfname[1024]; + char fname[1024]; double d; FILE *fp; int y; /* open output picture */ - sprintf(pfname, vval(BASENAME), fcur); - strcat(pfname, ".pic"); - fp = fopen(pfname, "w"); + sprintf(fname, vval(BASENAME), fcur); + strcat(fname, ".hdr"); + fp = fopen(fname, "w"); if (fp == NULL) { - sprintf(errmsg, "cannot open output frame \"%s\"", pfname); + sprintf(errmsg, "cannot open output frame \"%s\"", fname); error(SYSTEM, errmsg); } -#ifdef MSDOS - setmode(fileno(fp), O_BINARY); -#endif + SET_FILE_BINARY(fp); if (!silent) { - printf("\tWriting to \"%s\"\n", pfname); + printf("\tWriting to \"%s\"\n", fname); fflush(stdout); } /* write header */ @@ -888,10 +925,10 @@ send_frame() /* send frame to destination */ fputnow(fp); fputs(VIEWSTR, fp); fprintview(&vw, fp); fputc('\n', fp); d = expspec_val(getexp(fcur)); - if ((d < 0.99 | d > 1.01)) + if ((d < 0.99) | (d > 1.01)) fputexpos(d, fp); d = viewaspect(&vw) * hres / vres; - if ((d < 0.99 | d > 1.01)) + if ((d < 0.99) | (d > 1.01)) fputaspect(d, fp); fputformat(COLRFMT, fp); fputc('\n', fp); /* end header */ @@ -906,18 +943,75 @@ send_frame() /* send frame to destination */ goto writerr; if (fclose(fp) == EOF) goto writerr; + if (vdef(ZNAME)) { /* output z-buffer */ + sprintf(fname, vval(ZNAME), fcur); + strcat(fname, ".zbf"); + fp = fopen(fname, "w"); + if (fp == NULL) { + sprintf(errmsg, "cannot open z-file \"%s\"\n", fname); + error(SYSTEM, errmsg); + } + SET_FILE_BINARY(fp); + if (!silent) { + printf("\tWriting depths to \"%s\"\n", fname); + fflush(stdout); + } + for (y = vres; y--; ) + if (fwrite(zbuffer+y*hres, sizeof(float), + hres, fp) != hres) + goto writerr; + if (fclose(fp) == EOF) + goto writerr; + } + if (vdef(MNAME)) { /* output motion buffer */ + unsigned short *mbuffer = (unsigned short *)malloc( + sizeof(unsigned short)*3*hres); + int x, n; + if (mbuffer == NULL) + error(SYSTEM, "out of memory in send_frame"); + sprintf(fname, vval(MNAME), fcur); + strcat(fname, ".mvo"); + fp = fopen(fname, "w"); + if (fp == NULL) { + sprintf(errmsg, "cannot open motion file \"%s\"\n", + fname); + error(SYSTEM, errmsg); + } + SET_FILE_BINARY(fp); + if (!silent) { + printf("\tWriting motion vectors to \"%s\"\n", fname); + fflush(stdout); + } + for (y = vres; y--; ) { + for (x = hres; x--; ) { + n = fndx(x,y); + mbuffer[3*x] = xmbuffer[n] + 0x8000; + mbuffer[3*x+1] = ymbuffer[n] + 0x8000; + mbuffer[3*x+2] = (oprev[n]!=OVOID)*0x8000; + } + if (fwrite(mbuffer, sizeof(*mbuffer), + 3*hres, fp) != 3*hres) + goto writerr; + } + free((void *)mbuffer); + if (fclose(fp) == EOF) + goto writerr; + } return; /* all is well */ writerr: - sprintf(errmsg, "error writing frame \"%s\"", pfname); + sprintf(errmsg, "error writing file \"%s\"", fname); error(SYSTEM, errmsg); } void -free_frame() /* free frame allocation */ +free_frame(void) /* free frame allocation */ { if (cbuffer == NULL) return; + if (outbuffer != cbuffer) + free((void *)outbuffer); + outbuffer = NULL; free((void *)cbuffer); cbuffer = NULL; free((void *)zbuffer); zbuffer = NULL; free((void *)obuffer); obuffer = NULL;