--- ray/src/hd/rhcopy.c 1997/12/18 09:33:42 3.1 +++ ray/src/hd/rhcopy.c 2022/11/16 00:44:04 3.35 @@ -1,217 +1,645 @@ -/* Copyright (c) 1997 Silicon Graphics, Inc. */ - #ifndef lint -static char SCCSid[] = "$SunId$ SGI"; +static const char RCSid[] = "$Id: rhcopy.c,v 3.35 2022/11/16 00:44:04 greg Exp $"; #endif - /* * Copy data into a holodeck file */ +#include "platform.h" +#include "rterror.h" #include "holo.h" #include "view.h" -#include "resolu.h" -int frompicz; /* input from pictures & depth-buffers? */ -int noutsects; /* number of output sections */ -int obstructions = -1; /* interior obstructions allowed? */ +#ifndef BKBSIZE +#define BKBSIZE 256 /* beam clump size (kilobytes) */ +#endif + /* possible operations */ +#define FROM_HOLO 1 /* copy between holodecks */ +#define FROM_PICZ 2 /* copy from HDR + depth to holodeck */ +#define FROM_STDIN 3 /* copy from stdin to holodeck */ +#define TO_STDOUT 4 /* copy rays from holodeck to stdout */ +int operation = 0; /* what we are doing */ +char *rspec = ""; /* ray details for i/o */ +int checkdepth = 1; /* check depth (!-d option)? */ +int checkrepeats = 0; /* check for repeats (-u option)? */ +int nholosects; /* number of original holodeck sections */ +int iofmt = 'a'; /* input/output format for rays */ + + /* holodeck flags */ +#define H_BADF 01 /* bad format */ +#define H_OBST 02 /* OBSTRUCTIONS= True */ +#define H_OBSF 04 /* OBSTRUCTIONS= False */ +#define H_VDST 010 /* VDISTANCE= True */ +#define H_SWAP 020 /* byte order is different */ + char *progname; /* global argv[0] */ +struct phead { + VIEW vw; + double expos; + short gotview; + short badfmt; + short altprims; +}; -main(argc, argv) -int argc; -char *argv[]; +typedef struct { + FVECT ro; + FVECT rd; + RREAL d; + COLR cv; +} RAYPAR; + +static int openholo(char *fname, int append); +static void addray(RAYPAR *rp); +static int readval(RREAL *v, int n, FILE *fp); +static void readrays(FILE *fp); +static int writeval(RREAL *v, int n, FILE *fp); +static int write_ray(RAYPAR *rp, FILE *fp); +static void writerays(FILE *fp); +static gethfunc holheadline; +static int bpcmp(const void *b1p, const void *b2p); +static int addclump(HOLO *hp, int *bq, int nb); +static void addholo(char *hdf); +static gethfunc picheadline; +static void addpicz(char *pcf, char *zbf); + + +int +main( + int argc, + char *argv[] +) { int i; progname = argv[0]; - if (argc < 4) + for (i = 2; i < argc && argv[i][0] == '-'; i++) + switch (argv[i][1]) { + case 'u': + checkrepeats = 1; + break; + case 'd': + checkdepth = 0; + break; + case 'f': + iofmt = argv[i][2]; + if (!strchr("afd", iofmt)) + error(USER, "-f? i/o format must be 'a', 'f', or 'd'"); + break; + case 'h': + operation = FROM_HOLO; + break; + case 'p': + operation = FROM_PICZ; + break; + case 'i': + operation = FROM_STDIN; + rspec = argv[i]+2; + break; + case 'o': + operation = TO_STDOUT; + rspec = argv[i]+2; + break; + default: + goto userr; + } + if (!operation | (i > argc-((operation==FROM_HOLO)|(operation==FROM_PICZ)))) goto userr; - if (!strcmp(argv[2], "-h")) - frompicz = 0; - else if (!strcmp(argv[2], "-pz")) - frompicz = 1; - else + if (operation == FROM_PICZ && (argc-i)%2) goto userr; - if (frompicz && (argc-3)%2) - goto userr; - noutsects = openholo(argv[1], 1); - if (frompicz) - for (i = 3; i < argc; i += 2) + nholosects = openholo(argv[1], (operation != TO_STDOUT)); + /* check requested i/o is compatible */ + if (strchr(rspec, 'l') && !(*(int *)hdlist[0]->priv & H_VDST)) + error(USER, "i/o parameter 'l' incompatible with VDISTANCE=False"); + if (strchr(rspec, 'L') && *(int *)hdlist[0]->priv & H_VDST) + error(USER, "i/o parameter 'L' incompatible with VDISTANCE=True"); + + switch (operation) { /* perform requested operation */ + case FROM_PICZ: + for ( ; i < argc; i += 2) addpicz(argv[i], argv[i+1]); - else - for (i = 3; i < argc; i++) + break; + case FROM_HOLO: + if (BKBSIZE*1024*1.5 > hdcachesize) + hdcachesize = BKBSIZE*1024*1.5; + for ( ; i < argc; i++) addholo(argv[i]); + break; + case FROM_STDIN: + readrays(stdin); + break; + case TO_STDOUT: + writerays(stdout); + break; + } quit(0); userr: - fprintf(stderr, "Usage: %s output.hdk -h inp1.hdk ..\n", progname); - fprintf(stderr, " Or: %s output.hdk -pz inp1.pic inp1.zbf ..\n", + fprintf(stderr, "Usage: %s dest.hdk [-u][-d] -h inp1.hdk ..\n", progname); + fprintf(stderr, " Or: %s dest.hdk [-u][-d] -p inp1.hdr inp1.zbf ..\n", + progname); + fprintf(stderr, " Or: %s dest.hdk [-f{a|f|d}][-u][-d] -i[odplLv]\n", + progname); + fprintf(stderr, " Or: %s src.hdk [-f{a|f|d}] -o[odplLv] ..\n", + progname); exit(1); } - -holheadline(s, bf) /* check holodeck header line */ -register char *s; -int *bf; +static int +holheadline( /* check holodeck header line */ + char *s, + void *vhf +) { - char fmt[32]; + int be; + char fmt[MAXFMTLEN]; + int *hf = (int *)vhf; if (formatval(fmt, s)) { - *bf = strcmp(fmt, HOLOFMT); - return; + if (strcmp(fmt, HOLOFMT)) + *hf |= H_BADF; + else + *hf &= ~H_BADF; + return(0); } if (!strncmp(s, "OBSTRUCTIONS=", 13)) { s += 13; while (*s == ' ') s++; - if (*s == 't' | *s == 'T') - obstructions = 1; - else if (*s == 'f' | *s == 'F') - obstructions = 0; + if ((*s == 't') | (*s == 'T')) + *hf |= H_OBST; + else if ((*s == 'f') | (*s == 'F')) + *hf |= H_OBSF; else error(WARNING, "bad OBSTRUCTIONS value in holodeck"); - return; + return(0); } + if (!strncmp(s, "VDISTANCE=", 10)) { + s += 10; + while (*s == ' ') s++; + if ((*s == 't') | (*s == 'T')) + *hf |= H_VDST; + else if ((*s != 'f') % (*s != 'F')) + error(WARNING, "bad VDISTANCE value in holodeck"); + return(0); + } + if ((be = isbigendian(s)) >= 0) { + if (be != nativebigendian()) + *hf |= H_SWAP; + return(0); + } + return(0); } - int -openholo(fname, append) /* open existing holodeck file for i/o */ -char *fname; -int append; +openholo( /* open existing holodeck file for i/o */ + char *fname, + int append +) { - extern long ftell(); FILE *fp; int fd; - int badfmt = 0; - int4 nextloc; + int hflags = 0; + int *hfstore; + off_t nextloc; int n; /* open holodeck file */ - if ((fp = fopen(fname, append ? "r+" : "r")) == NULL) { + if ((fp = fopen(fname, append ? "rb+" : "rb")) == NULL) { sprintf(errmsg, "cannot open \"%s\" for %s", fname, append ? "appending" : "reading"); error(SYSTEM, errmsg); } /* check header and magic number */ - if (append) - badfmt |= getheader(fp, holheadline, &badfmt) < 0; - else - badfmt = checkheader(fp, HOLOFMT, NULL) < 0; - if (badfmt || getw(fp) != HOLOMAGIC) { - sprintf(errmsg, "file \"%s\" not in holodeck format", fname); + if (getheader(fp, holheadline, &hflags) < 0 || + hflags&(H_BADF|H_SWAP) || getw(fp) != HOLOMAGIC) { + sprintf(errmsg, "holodeck \"%s\" not in expected format", fname); error(USER, errmsg); } fd = dup(fileno(fp)); /* dup file handle */ nextloc = ftell(fp); /* get stdio position */ fclose(fp); /* done with stdio */ + hfstore = (int *)malloc(sizeof(int)); /* tiny memory leak but who cares? */ + *hfstore = hflags; for (n = 0; nextloc > 0L; n++) { /* initialize each section */ - lseek(fd, (long)nextloc, 0); + lseek(fd, nextloc, SEEK_SET); read(fd, (char *)&nextloc, sizeof(nextloc)); - hdinit(fd, NULL); + hdinit(fd, NULL)->priv = hfstore; } return(n); } - -addray(ro, rd, d, cv) /* add a ray to our output holodeck */ -FVECT ro, rd; -double d; -COLR cv; +void +addray( /* add a ray to our output holodeck */ + RAYPAR *rp +) { - int sn; - register HOLO *hp; + int sn, bi, n; + HOLO *hp; GCOORD gc[2]; - BYTE rr[2][2]; + uby8 rr[2][2]; + BEAM *bp; double d0, d1; - register RAYVAL *rv; + unsigned dc; + RAYVAL *rv; /* check each output section */ - for (sn = noutsects; sn--; ) { + for (sn = nholosects; sn--; ) { hp = hdlist[sn]; - d0 = hdinter(gc, rr, &d1, hp, ro, rd); - if (d <= d0 || d1 < -0.001) + d0 = hdinter(gc, rr, &d1, hp, rp->ro, rp->rd); + if (rp->d <= d0 || d1 < -0.001) continue; /* missed section */ - if (obstructions > 0 && d0 < -0.001) - continue; /* ray starts too late */ - if (!obstructions && d < 0.999*d1) - continue; /* ray ends too soon */ - /* should we check for duplicates? */ - rv = hdnewrays(hp, hdbindex(hp, gc), 1); + if (checkdepth) { /* check depth */ + if (*(int *)hp->priv & H_OBST && d0 < -0.001) + continue; /* ray starts too late */ + if (*(int *)hp->priv & H_OBSF && rp->d < 0.999*d1) + continue; /* ray ends too soon */ + } + dc = hdcode(hp, rp->d-d0); + bi = hdbindex(hp, gc); /* check for duplicates */ + if (checkrepeats && (bp = hdgetbeam(hp, bi)) != NULL) { + for (n = bp->nrm, rv = hdbray(bp); n--; rv++) + if ((rv->d == dc || *(int *)hp->priv & (H_OBST|H_OBSF)) && + rv->r[0][0] == rr[0][0] && + rv->r[0][1] == rr[0][1] && + rv->r[1][0] == rr[1][0] && + rv->r[1][1] == rr[1][1]) + break; + if (n >= 0) + continue; /* found a matching ray */ + } + rv = hdnewrays(hp, bi, 1); + rv->d = dc; rv->r[0][0] = rr[0][0]; rv->r[0][1] = rr[0][1]; rv->r[1][0] = rr[1][0]; rv->r[1][1] = rr[1][1]; - copycolr(rv->v, cv); - rv->d = hdcode(hp, d-d0); + copycolr(rv->v, rp->cv); } } +/* Read n-vector from file stream */ +static int +readval(RREAL *v, int n, FILE *fp) +{ + int i; +#ifdef SMLFLT + double vd[3]; + switch (iofmt) { + case 'f': + return getbinary(v, sizeof(float), n, fp); + case 'd': + n = getbinary(vd, sizeof(double), n, fp); + for (i = n; i-- > 0; ) v[i] = vd[i]; + return n; + case 'a': + for (i = 0; i < n; i++) + if (fscanf(fp, "%f ", &v[i]) != 1) + break; + return i; + } +#else + float vf[3]; + switch (iofmt) { + case 'd': + return getbinary(v, sizeof(double), n, fp); + case 'f': + n = getbinary(vf, sizeof(float), n, fp); + for (i = n; i-- > 0; ) v[i] = vf[i]; + return n; + case 'a': + for (i = 0; i < n; i++) + if (fscanf(fp, "%lf ", &v[i]) != 1) + break; + return i; + } +#endif + return -1; +} -addholo(hdf) /* add a holodeck file */ -char *hdf; +#define GOT_ORG 0x01 +#define GOT_DIR 0x02 +#define GOT_LEN 0x04 +#define GOT_VAL 0x10 +#define ALSO_POS 0x20 +#define BAD_DIR 0x40 +#define BAD_LEN 0x80 + +/* Read rays from stream and add to holodeck */ +static void +readrays(FILE *fp) { - int fd; - register HOLO *hp; - register BEAM *bp; + if (iofmt != 'a') + SET_FILE_BINARY(fp); +#ifdef getc_unlocked + flockfile(fp); +#endif + while (!feof(fp)) { /* read entirety of input */ + RAYPAR ryp; + FVECT pos; + FVECT col; + int flags = 0; + int i; + for (i = 0; rspec[i]; i++) { + switch (rspec[i]) { + case 'o': /* ray origin */ + if (readval(ryp.ro, 3, fp) < 3) + break; + flags |= GOT_ORG; + continue; + case 'd': /* ray direction */ + if (readval(ryp.rd, 3, fp) < 3) + break; + if (normalize(ryp.rd) == 0) + flags |= BAD_DIR; + else + flags |= GOT_DIR; + continue; + case 'p': /* ray intersection */ + if (readval(pos, 3, fp) < 3) + break; + flags |= ALSO_POS; + continue; + case 'L': /* ray first length */ + case 'l': /* ray virtual length */ + if (readval(&ryp.d, 1, fp) < 1) + break; + if (ryp.d <= FTINY) + flags |= BAD_LEN; + else + flags |= GOT_LEN; + continue; + case 'v': /* ray value */ + if (readval(col, 3, fp) < 3) + break; + setcolr(ryp.cv, col[0], col[1], col[2]); + flags |= GOT_VAL; + continue; + default: + sprintf(errmsg, "unsupported parameter '%c' in -i%s", + rspec[i], rspec); + error(USER, errmsg); + } + if (!flags) /* got nothing, so may be normal EOF */ + return; + } + if (flags & (BAD_DIR|BAD_LEN)) + continue; /* just a bad ray is all -- skip */ + if (!(flags & GOT_VAL)) + goto missingData; + if ((flags & (GOT_ORG|GOT_DIR|GOT_LEN)) != (GOT_ORG|GOT_DIR|GOT_LEN)) { + if (!(flags & ALSO_POS)) + goto missingData; + if (flags & GOT_ORG) { + VSUB(ryp.rd, pos, ryp.ro); + ryp.d = normalize(ryp.rd); + if (ryp.d == 0) + continue; + } else if ((flags & (GOT_DIR|GOT_LEN)) == (GOT_DIR|GOT_LEN)) { + VSUM(ryp.ro, pos, ryp.rd, -ryp.d); + } else + goto missingData; + } + addray(&ryp); /* add our ray to holodeck */ + } + return; +missingData: + sprintf(errmsg, "insufficient data in -i%s", rspec); + error(USER, errmsg); +} + +/* Write vector value to file stream */ +static int +writeval(RREAL *v, int n, FILE *fp) +{ + int i; + + if (iofmt == 'a') { + for (i = 0; i < n; i++) + if (fprintf(fp, "\t%.4e", v[i]) < 0) + break; + return i; + } +#ifdef SMLFLT + if (iofmt == 'd') { + double vd[3]; + for (i = n; i--; ) vd[i] = v[i]; + return putbinary(vd, sizeof(double), n, fp); + } +#else + if (iofmt == 'f') { + float vf[3]; + for (i = n; i--; ) vf[i] = v[i]; + return putbinary(vf, sizeof(float), n, fp); + } +#endif + return putbinary(v, sizeof(*v), n, fp); +} + +/* Write out an individual ray as requested */ +static int +write_ray(RAYPAR *rp, FILE *fp) +{ + COLOR cval; + FVECT v3; + char *typ = rspec; + + for ( ; ; ) { + switch (*typ++) { + case 'o': /* ray origin */ + if (writeval(rp->ro, 3, fp) < 3) + break; + continue; + case 'd': /* ray direction */ + if (writeval(rp->rd, 3, fp) < 3) + break; + continue; + case 'p': /* ray intersection */ + VSUM(v3, rp->ro, rp->rd, rp->d); + if (writeval(v3, 3, fp) < 3) + break; + continue; + case 'L': /* ray first length */ + case 'l': /* ray virtual length */ + if (writeval(&rp->d, 1, fp) < 1) + break; + continue; + case 'v': /* ray value */ + colr_color(cval, rp->cv); + VCOPY(v3, cval); + if (writeval(v3, 3, fp) < 3) + break; + continue; + case '\0': /* end of spec -- success */ + if (iofmt == 'a') + fputc('\n', fp); + return(1); + default: + sprintf(errmsg, "unsupported parameter '%c' in -o%s", typ[-1], rspec); + } + break; /* land here on error */ + } + return 0; /* write error? */ +} + +static BEAMI *beamdir; + +static int +bpcmp( /* compare beam positions on disk */ + const void *b1p, + const void *b2p +) +{ + off_t pdif = beamdir[*(int *)b1p].fo - beamdir[*(int *)b2p].fo; + + if (pdif > 0L) return(1); + if (pdif < 0L) return(-1); + return(0); +} + +/* Write all rays from holodeck to stream */ +static void +writerays(FILE *fp) +{ + int sn, bi, k; GCOORD gc[2]; - FVECT ro, rd; - double d; - int i, j; - register int k; + RAYVAL *rv; + RAYPAR ryp; - openholo(hdf, 0); /* open the holodeck for reading */ - fd = hdlist[noutsects]->fd; /* remember the file handle */ - while ((hp = hdlist[noutsects]) != NULL) { /* load each section */ - for (j = nbeams(hp); j > 0; j--) /* load each beam */ - if ((bp = hdgetbeam(hp, j)) != NULL) { - hdbcoord(gc, hp, j); - for (k = bp->nrm; k--; ) { - hdray(ro, rd, hp, gc, hdbray(bp)[k].r); - d = hddepth(hp, hdbray(bp)[k].d); - addray(ro, rd, d, hdbray(bp)[k].v); + if (!*rspec) { + error(WARNING, "empty -o* output spec, quitting"); + return; + } + if (iofmt != 'a') + SET_FILE_BINARY(fp); +#ifdef getc_unlocked + flockfile(fp); +#endif + for (sn = 0; sn < nholosects; sn++) { /* write each holodeck section */ + HOLO *hp = hdlist[sn]; + int nb = nbeams(hp); /* sort beams by file location */ + int *bq = (int *)malloc(nb*sizeof(int)); + if (!bq) + error(SYSTEM, "out of memory in writerays()"); + for (bi = nb; bi--; ) bq[bi] = bi+1; + beamdir = hp->bi; + qsort(bq, nb, sizeof(*bq), bpcmp); + for (bi = 0; bi < nb; bi++) { + BEAM *bp = hdgetbeam(hp, bq[bi]); + if (!bp) /* empty beam? */ + continue; + hdbcoord(gc, hp, bq[bi]); + rv = hdbray(bp); + for (k = bp->nrm; k--; rv++) { + ryp.d = hdray(ryp.ro, ryp.rd, hp, gc, rv->r); + if (*(int *)hp->priv & H_OBSF) + VSUM(ryp.ro, ryp.ro, ryp.rd, ryp.d); + else + ryp.d = 0.; + ryp.d = hddepth(hp, rv->d) - ryp.d; + copycolr(ryp.cv, rv->v); + if (!write_ray(&ryp, fp)) { + free(bq); + goto writError; } - hdfreebeam(hp, j); /* free the beam */ } - hddone(hp); /* free the section */ + hdfreebeam(hp, bq[bi]); + } + free(bq); } - close(fd); /* close the file */ + if (fflush(fp) != EOF) + return; +writError: + error(SYSTEM, "error writing holodeck rays"); } +static int +addclump( /* transfer the given clump and free */ + HOLO *hp, + int *bq, + int nb +) +{ + GCOORD gc[2]; + RAYPAR ryp; + RAYVAL *rv; + int i; + int k; + BEAM *bp; + /* sort based on file position */ + beamdir = hp->bi; + qsort(bq, nb, sizeof(*bq), bpcmp); + /* transfer each beam */ + for (i = 0; i < nb; i++) { + bp = hdgetbeam(hp, bq[i]); + hdbcoord(gc, hp, bq[i]); + rv = hdbray(bp); /* add each ray to output */ + for (k = bp->nrm; k--; rv++) { + ryp.d = hdray(ryp.ro, ryp.rd, hp, gc, rv->r); + if (*(int *)hp->priv & H_OBSF) + VSUM(ryp.ro, ryp.ro, ryp.rd, ryp.d); + else + ryp.d = 0.; + ryp.d = hddepth(hp, rv->d) - ryp.d; + copycolr(ryp.cv, rv->v); + addray(&ryp); + } + hdfreebeam(hp, bq[i]); /* free the beam */ + } + return(0); +} -struct phead { - VIEW vw; - double expos; - short gotview; - short badfmt; - short altprims; -}; +void +addholo( /* add a holodeck file */ + char *hdf +) +{ + int fd; + /* open the holodeck for reading */ + openholo(hdf, 0); + fd = hdlist[nholosects]->fd; /* remember the file handle */ + while (hdlist[nholosects] != NULL) { /* load each section */ + /* clump the beams */ + clumpbeams(hdlist[nholosects], 0, BKBSIZE*1024, addclump); + hddone(hdlist[nholosects]); /* free the section */ + } + close(fd); /* close input file */ + hdflush(NULL); /* flush output */ +} -picheadline(s, ph) /* process picture header line */ -char *s; -struct phead *ph; + + +static int +picheadline( /* process picture header line */ + char *s, + void *vph +) { char fmt[32]; + struct phead *ph = (struct phead *)vph; if (formatval(fmt, s)) { ph->badfmt = strcmp(fmt, COLRFMT); - return; + return(0); } if (isprims(s)) { ph->altprims++; /* don't want to deal with this */ - return; + return(0); } if (isexpos(s)) { ph->expos *= exposval(s); - return; + return(0); } if (isview(s)) { ph->gotview += sscanview(&ph->vw, s); - return; + return(0); } + return(0); } -addpicz(pcf, zbf) /* add a picture + depth-buffer */ -char *pcf, *zbf; +void +addpicz( /* add a picture + depth-buffer */ + char *pcf, + char *zbf +) { FILE *pfp; int zfd; @@ -221,23 +649,16 @@ char *pcf, *zbf; int eshft; double emult; RESOLU prs; - FLOAT vl[2]; - FVECT ro, rd; + RREAL vl[2]; + RAYPAR ryp; double aftd; - COLOR ctmp; - int j; - register int i; - /* open files */ - if ((pfp = fopen(pcf, "r")) == NULL) { + int j, i; + /* open picture & get header */ + if ((pfp = fopen(pcf, "rb")) == NULL) { sprintf(errmsg, "cannot open picture file \"%s\"", pcf); error(SYSTEM, pcf); } - if ((zfd = open(zbf, O_RDONLY)) < 0) { - sprintf(errmsg, "cannot open depth file \"%s\"", zbf); - error(SYSTEM, pcf); - } - /* load picture header */ - copystruct(&phd.vw, &stdview); + phd.vw = stdview; phd.expos = 1.0; phd.badfmt = phd.gotview = phd.altprims = 0; if (getheader(pfp, picheadline, &phd) < 0 || @@ -251,16 +672,19 @@ char *pcf, *zbf; error(USER, errmsg); } if (phd.altprims) { - sprintf(errmsg, "ignoring primary values in picture \"%s\"", + sprintf(errmsg, "ignoring color primaries in picture \"%s\"", pcf); error(WARNING, errmsg); } + /* open depth buffer */ + if ((zfd = open_float_depth(zbf, prs.xr*prs.yr)) < 0) + quit(1); /* figure out what to do about exposure */ - if (phd.expos < 0.99 | phd.expos > 1.01) { + if ((phd.expos < 0.99) | (phd.expos > 1.01)) { emult = -log(phd.expos)/log(2.); eshft = emult >= 0. ? emult+.5 : emult-.5; emult -= (double)eshft; - if (emult <= 0.01 & emult >= -0.01) + if ((emult <= 0.01) & (emult >= -0.01)) emult = -1.; else { emult = 1./phd.expos; @@ -273,7 +697,7 @@ char *pcf, *zbf; /* allocate buffers */ cscn = (COLR *)malloc(scanlen(&prs)*sizeof(COLR)); zscn = (float *)malloc(scanlen(&prs)*sizeof(float)); - if (cscn == NULL | zscn == NULL) + if ((cscn == NULL) | (zscn == NULL)) error(SYSTEM, "out of memory in addpicz"); /* read and process each scanline */ for (j = 0; j < numscans(&prs); j++) { @@ -284,37 +708,46 @@ char *pcf, *zbf; } if (eshft) /* shift exposure */ shiftcolrs(cscn, i, eshft); - i *= sizeof(float); /* read depth */ - if (read(zfd, (char *)zscn, i) != i) { + /* read depth */ + if (read(zfd, zscn, i*sizeof(float)) != i*sizeof(float)) { sprintf(errmsg, "error reading depth file \"%s\"", zbf); error(USER, errmsg); } - for (i = scanlen(&prs); i--; ) { /* do each pixel */ + while (i--) { /* process each pixel */ + if (zscn[i] <= 0.0) + continue; /* illegal depth */ pix2loc(vl, &prs, i, j); - aftd = viewray(ro, rd, &phd.vw, vl[0], vl[1]); + aftd = viewray(ryp.ro, ryp.rd, &phd.vw, vl[0], vl[1]); if (aftd < -FTINY) continue; /* off view */ if (aftd > FTINY && zscn[i] > aftd) continue; /* aft clipped */ + ryp.d = (RREAL)zscn[i]; + copycolr(ryp.cv, cscn[i]); if (emult > 0.) { /* whatta pain */ - colr_color(ctmp, cscn[i]); + COLOR ctmp; + colr_color(ctmp, ryp.cv); scalecolor(ctmp, emult); - setcolr(cscn[i], colval(ctmp,RED), + setcolr(ryp.cv, colval(ctmp,RED), colval(ctmp,GRN), colval(ctmp,BLU)); } - addray(ro, rd, (double)zscn[i], cscn[i]); + addray(&ryp); } } + /* write output and free beams */ + hdflush(NULL); /* clean up */ - free((char *)cscn); - free((char *)zscn); + free((void *)cscn); + free((void *)zscn); fclose(pfp); close(zfd); } -eputs(s) /* put error message to stderr */ -register char *s; +void +eputs( /* put error message to stderr */ + char *s +) { static int midline = 0; @@ -332,8 +765,10 @@ register char *s; } -quit(code) /* exit the program gracefully */ -int code; +void +quit( /* exit the program gracefully */ + int code +) { hdsync(NULL, 1); /* write out any buffered data */ exit(code);