--- ray/src/hd/rhcopy.c 1998/11/12 15:06:00 3.11 +++ ray/src/hd/rhcopy.c 2023/12/19 20:22:36 3.37 @@ -1,38 +1,79 @@ -/* Copyright (c) 1998 Silicon Graphics, Inc. */ - #ifndef lint -static char SCCSid[] = "$SunId$ SGI"; +static const char RCSid[] = "$Id: rhcopy.c,v 3.37 2023/12/19 20:22:36 greg Exp $"; #endif - /* * Copy data into a holodeck file */ +#include "platform.h" +#include "rterror.h" #include "holo.h" #include "view.h" -#include "resolu.h" #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 checkdepth = 1; /* check depth (!-f option)? */ -int checkrepeats = 0; /* check for repeats (-c option)? */ -int frompicz; /* input from pictures & depth-buffers? */ -int noutsects; /* number of output sections */ -char obstr, unobstr; /* flag pointer values */ +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]; - frompicz = -1; for (i = 2; i < argc && argv[i][0] == '-'; i++) switch (argv[i][1]) { case 'u': @@ -41,49 +82,79 @@ char *argv[]; 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': - frompicz = 0; + operation = FROM_HOLO; break; case 'p': - frompicz = 1; + 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 (i >= argc || frompicz < 0) + if (!operation | (i > argc-((operation==FROM_HOLO)|(operation==FROM_PICZ)))) goto userr; - if (frompicz && (argc-i)%2) + if (operation == FROM_PICZ && (argc-i)%2) goto userr; - noutsects = openholo(argv[1], 1); - if (frompicz) { + 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 { + 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 [-u][-d] -h inp1.hdk ..\n", + fprintf(stderr, "Usage: %s dest.hdk [-u][-d] -h inp1.hdk ..\n", progname); - fprintf(stderr, " Or: %s output.hdk [-u][-d] -p inp1.pic inp1.zbf ..\n", + 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); } - -#define H_BADF 01 -#define H_OBST 02 -#define H_OBSF 04 - -int -holheadline(s, hf) /* check holodeck header line */ -register char *s; -int *hf; +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)) { if (strcmp(fmt, HOLOFMT)) @@ -95,87 +166,98 @@ int *hf; if (!strncmp(s, "OBSTRUCTIONS=", 13)) { s += 13; while (*s == ' ') s++; - if (*s == 't' | *s == 'T') + if ((*s == 't') | (*s == 'T')) *hf |= H_OBST; - else if (*s == 'f' | *s == 'F') + else if ((*s == 'f') | (*s == 'F')) *hf |= H_OBSF; else error(WARNING, "bad OBSTRUCTIONS value in holodeck"); 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 hflags = 0; - long nextloc; + 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 (getheader(fp, holheadline, &hflags) < 0 || - hflags&H_BADF || getw(fp) != HOLOMAGIC) { - sprintf(errmsg, "file \"%s\" not in holodeck format", fname); + 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, nextloc, 0); + lseek(fd, nextloc, SEEK_SET); read(fd, (char *)&nextloc, sizeof(nextloc)); - hdinit(fd, NULL)->priv = hflags&H_OBST ? &obstr : - hflags&H_OBSF ? &unobstr : (char *)NULL; + hdinit(fd, NULL)->priv = hfstore; } return(n); } -#undef H_BADF -#undef H_OBST -#undef H_OBSF - - -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, bi, n; - register HOLO *hp; + HOLO *hp; GCOORD gc[2]; - BYTE rr[2][2]; + uby8 rr[2][2]; BEAM *bp; double d0, d1; unsigned dc; - register RAYVAL *rv; + 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 (checkdepth) { /* check depth */ - if (hp->priv == &obstr && d0 < -0.001) + if (*(int *)hp->priv & H_OBST && d0 < -0.001) continue; /* ray starts too late */ - if (hp->priv == &unobstr && d < 0.999*d1) + if (*(int *)hp->priv & H_OBSF && rp->d < 0.999*d1) continue; /* ray ends too soon */ } - dc = hdcode(hp, d-d0); + 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 && + 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] && @@ -188,89 +270,350 @@ COLR cv; 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); + 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; +} +#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) +{ + 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 or read error for -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(b1p, b2p) /* compare beam positions on disk */ -int *b1p, *b2p; +bpcmp( /* compare beam positions on disk */ + const void *b1p, + const void *b2p +) { - register long pdif = beamdir[*b1p].fo - beamdir[*b2p].fo; + 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]; + RAYVAL *rv; + RAYPAR ryp; + + 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, bq[bi]); + } + free(bq); + } + if (fflush(fp) != EOF) + return; +writError: + error(SYSTEM, "error writing holodeck rays"); +} + static int -addclump(hp, bq, nb) /* transfer the given clump and free */ -HOLO *hp; -int *bq, nb; +addclump( /* transfer the given clump and free */ + HOLO *hp, + int *bq, + int nb +) { GCOORD gc[2]; - FVECT ro, rd; - double d; + RAYPAR ryp; + RAYVAL *rv; int i; - register int k; - register BEAM *bp; + int k; + BEAM *bp; /* sort based on file position */ beamdir = hp->bi; - qsort((char *)bq, nb, sizeof(*bq), bpcmp); + 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]); - /* add each ray to output */ - for (k = bp->nrm; k--; ) { - d = hdray(ro, rd, hp, gc, hdbray(bp)[k].r); - if (hp->priv == &unobstr) - VSUM(ro, ro, rd, d); + 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 - d = 0.; - d = hddepth(hp, hdbray(bp)[k].d) - d; - addray(ro, rd, d, hdbray(bp)[k].v); + 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 */ } - hdflush(NULL); /* write & free clump */ return(0); } -addholo(hdf) /* add a holodeck file */ -char *hdf; + +void +addholo( /* add a holodeck file */ + char *hdf +) { int fd; /* open the holodeck for reading */ openholo(hdf, 0); - fd = hdlist[noutsects]->fd; /* remember the file handle */ - while (hdlist[noutsects] != NULL) { /* load each section */ + fd = hdlist[nholosects]->fd; /* remember the file handle */ + while (hdlist[nholosects] != NULL) { /* load each section */ /* clump the beams */ - clumpbeams(hdlist[noutsects], 0, BKBSIZE*1024, addclump); - hddone(hdlist[noutsects]); /* free the section */ + clumpbeams(hdlist[nholosects], 0, BKBSIZE*1024, addclump); + hddone(hdlist[nholosects]); /* free the section */ } close(fd); /* close input file */ + hdflush(NULL); /* flush output */ } -struct phead { - VIEW vw; - double expos; - short gotview; - short badfmt; - short altprims; -}; - -int -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); @@ -292,8 +635,11 @@ struct phead *ph; } -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; @@ -303,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 || @@ -333,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; @@ -355,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++) { @@ -366,39 +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 */ + const char *s +) { static int midline = 0; @@ -416,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);