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

Comparing ray/src/hd/rhcopy.c (file contents):
Revision 3.8 by gregl, Fri Jan 23 09:05:14 1998 UTC vs.
Revision 3.36 by greg, Mon Feb 6 22:40:21 2023 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1997 Silicon Graphics, Inc. */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ SGI";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Copy data into a holodeck file
6   */
7  
8 + #include "platform.h"
9 + #include "rterror.h"
10   #include "holo.h"
11   #include "view.h"
13 #include "resolu.h"
12  
13 < #ifndef BLOADSIZE
14 < #define BLOADSIZE       1024    /* number of input beams to load at a time */
13 > #ifndef BKBSIZE
14 > #define BKBSIZE         256             /* beam clump size (kilobytes) */
15   #endif
16 +                                /* possible operations */
17 + #define FROM_HOLO       1               /* copy between holodecks */
18 + #define FROM_PICZ       2               /* copy from HDR + depth to holodeck */
19 + #define FROM_STDIN      3               /* copy from stdin to holodeck */
20 + #define TO_STDOUT       4               /* copy rays from holodeck to stdout */
21  
22 < int     checkdepth = 1;         /* check depth (!-f option)? */
23 < int     checkrepeats = 0;       /* check for repeats (-c option)? */
24 < int     frompicz;               /* input from pictures & depth-buffers? */
25 < int     noutsects;              /* number of output sections */
26 < char    obstr, unobstr;         /* flag pointer values */
22 > int     operation = 0;          /* what we are doing */
23 > char    *rspec = "";            /* ray details for i/o */
24 > int     checkdepth = 1;         /* check depth (!-d option)? */
25 > int     checkrepeats = 0;       /* check for repeats (-u option)? */
26 > int     nholosects;             /* number of original holodeck sections */
27 > int     iofmt = 'a';            /* input/output format for rays */
28  
29 +                                /* holodeck flags */
30 + #define H_BADF          01              /* bad format */
31 + #define H_OBST          02              /* OBSTRUCTIONS= True */
32 + #define H_OBSF          04              /* OBSTRUCTIONS= False */
33 + #define H_VDST          010             /* VDISTANCE= True */
34 + #define H_SWAP          020             /* byte order is different */
35 +
36   char    *progname;              /* global argv[0] */
37  
38 + struct phead {
39 +        VIEW    vw;
40 +        double  expos;
41 +        short   gotview;
42 +        short   badfmt;
43 +        short   altprims;
44 + };
45  
46 < main(argc, argv)
47 < int     argc;
48 < char    *argv[];
46 > typedef struct {
47 >        FVECT   ro;
48 >        FVECT   rd;
49 >        RREAL   d;
50 >        COLR    cv;
51 > } RAYPAR;
52 >
53 > static int openholo(char *fname, int append);
54 > static void addray(RAYPAR *rp);
55 > static int readval(RREAL *v, int n, FILE *fp);
56 > static void readrays(FILE *fp);
57 > static int writeval(RREAL *v, int n, FILE *fp);
58 > static int write_ray(RAYPAR *rp, FILE *fp);
59 > static void writerays(FILE *fp);
60 > static gethfunc holheadline;
61 > static int bpcmp(const void *b1p, const void *b2p);
62 > static int addclump(HOLO *hp, int *bq, int nb);
63 > static void addholo(char *hdf);
64 > static gethfunc picheadline;
65 > static void addpicz(char *pcf, char *zbf);
66 >
67 >
68 > int
69 > main(
70 >        int     argc,
71 >        char    *argv[]
72 > )
73   {
74          int     i;
75  
76          progname = argv[0];
35        frompicz = -1;
77          for (i = 2; i < argc && argv[i][0] == '-'; i++)
78                  switch (argv[i][1]) {
79                  case 'u':
# Line 41 | Line 82 | char   *argv[];
82                  case 'd':
83                          checkdepth = 0;
84                          break;
85 +                case 'f':
86 +                        iofmt = argv[i][2];
87 +                        if (!strchr("afd", iofmt))
88 +                                error(USER, "-f? i/o format must be 'a', 'f', or 'd'");
89 +                        break;
90                  case 'h':
91 <                        frompicz = 0;
91 >                        operation = FROM_HOLO;
92                          break;
93                  case 'p':
94 <                        frompicz = 1;
94 >                        operation = FROM_PICZ;
95                          break;
96 +                case 'i':
97 +                        operation = FROM_STDIN;
98 +                        rspec = argv[i]+2;
99 +                        break;
100 +                case 'o':
101 +                        operation = TO_STDOUT;
102 +                        rspec = argv[i]+2;
103 +                        break;
104                  default:
105                          goto userr;
106                  }
107 <        if (i >= argc || frompicz < 0)
107 >        if (!operation | (i > argc-((operation==FROM_HOLO)|(operation==FROM_PICZ))))
108                  goto userr;
109 <        if (frompicz && (argc-i)%2)
109 >        if (operation == FROM_PICZ && (argc-i)%2)
110                  goto userr;
111 <        noutsects = openholo(argv[1], 1);
112 <        if (frompicz)
111 >        nholosects = openholo(argv[1], (operation != TO_STDOUT));
112 >                                        /* check requested i/o is compatible */
113 >        if (strchr(rspec, 'l') && !(*(int *)hdlist[0]->priv & H_VDST))
114 >                error(USER, "i/o parameter 'l' incompatible with VDISTANCE=False");
115 >        if (strchr(rspec, 'L') && *(int *)hdlist[0]->priv & H_VDST)
116 >                error(USER, "i/o parameter 'L' incompatible with VDISTANCE=True");
117 >
118 >        switch (operation) {            /* perform requested operation */
119 >        case FROM_PICZ:
120                  for ( ; i < argc; i += 2)
121                          addpicz(argv[i], argv[i+1]);
122 <        else
122 >                break;
123 >        case FROM_HOLO:
124 >                if (BKBSIZE*1024*1.5 > hdcachesize)
125 >                        hdcachesize = BKBSIZE*1024*1.5;
126                  for ( ; i < argc; i++)
127                          addholo(argv[i]);
128 +                break;
129 +        case FROM_STDIN:
130 +                readrays(stdin);
131 +                break;
132 +        case TO_STDOUT:
133 +                writerays(stdout);
134 +                break;
135 +        }
136          quit(0);
137   userr:
138 <        fprintf(stderr, "Usage: %s output.hdk [-u][-d] -h inp1.hdk ..\n",
138 >        fprintf(stderr, "Usage: %s dest.hdk [-u][-d] -h inp1.hdk ..\n",
139                          progname);
140 <        fprintf(stderr, "   Or: %s output.hdk [-u][-d] -pz inp1.pic inp1.zbf ..\n",
140 >        fprintf(stderr, "   Or: %s dest.hdk [-u][-d] -p inp1.hdr inp1.zbf ..\n",
141                          progname);
142 +        fprintf(stderr, "   Or: %s dest.hdk [-f{a|f|d}][-u][-d] -i[odplLv]\n",
143 +                        progname);
144 +        fprintf(stderr, "   Or: %s src.hdk [-f{a|f|d}] -o[odplLv] ..\n",
145 +                        progname);
146          exit(1);
147   }
148  
149 <
150 < #define H_BADF  01
151 < #define H_OBST  02
152 < #define H_OBSF  04
153 <
78 < holheadline(s, hf)              /* check holodeck header line */
79 < register char   *s;
80 < int     *hf;
149 > static int
150 > holheadline(            /* check holodeck header line */
151 >        char    *s,
152 >        void    *vhf
153 > )
154   {
155 <        char    fmt[32];
155 >        int     be;
156 >        char    fmt[MAXFMTLEN];
157 >        int     *hf = (int *)vhf;
158  
159          if (formatval(fmt, s)) {
160                  if (strcmp(fmt, HOLOFMT))
161                          *hf |= H_BADF;
162                  else
163                          *hf &= ~H_BADF;
164 <                return;
164 >                return(0);
165          }
166          if (!strncmp(s, "OBSTRUCTIONS=", 13)) {
167                  s += 13;
168                  while (*s == ' ') s++;
169 <                if (*s == 't' | *s == 'T')
169 >                if ((*s == 't') | (*s == 'T'))
170                          *hf |= H_OBST;
171 <                else if (*s == 'f' | *s == 'F')
171 >                else if ((*s == 'f') | (*s == 'F'))
172                          *hf |= H_OBSF;
173                  else
174                          error(WARNING, "bad OBSTRUCTIONS value in holodeck");
175 <                return;
175 >                return(0);
176          }
177 +        if (!strncmp(s, "VDISTANCE=", 10)) {
178 +                s += 10;
179 +                while (*s == ' ') s++;
180 +                if ((*s == 't') | (*s == 'T'))
181 +                        *hf |= H_VDST;
182 +                else if ((*s != 'f') % (*s != 'F'))
183 +                        error(WARNING, "bad VDISTANCE value in holodeck");
184 +                return(0);
185 +        }
186 +        if ((be = isbigendian(s)) >= 0) {
187 +                if (be != nativebigendian())
188 +                        *hf |= H_SWAP;
189 +                return(0);
190 +        }
191 +        return(0);
192   }
193  
194   int
195 < openholo(fname, append)         /* open existing holodeck file for i/o */
196 < char    *fname;
197 < int     append;
195 > openholo(               /* open existing holodeck file for i/o */
196 >        char    *fname,
197 >        int     append
198 > )
199   {
109        extern long     ftell();
200          FILE    *fp;
201          int     fd;
202          int     hflags = 0;
203 <        long    nextloc;
203 >        int     *hfstore;
204 >        off_t   nextloc;
205          int     n;
206                                          /* open holodeck file */
207 <        if ((fp = fopen(fname, append ? "r+" : "r")) == NULL) {
207 >        if ((fp = fopen(fname, append ? "rb+" : "rb")) == NULL) {
208                  sprintf(errmsg, "cannot open \"%s\" for %s", fname,
209                                  append ? "appending" : "reading");
210                  error(SYSTEM, errmsg);
211          }
212                                          /* check header and magic number */
213          if (getheader(fp, holheadline, &hflags) < 0 ||
214 <                        hflags&H_BADF || getw(fp) != HOLOMAGIC) {
215 <                sprintf(errmsg, "file \"%s\" not in holodeck format", fname);
214 >                        hflags&(H_BADF|H_SWAP) || getw(fp) != HOLOMAGIC) {
215 >                sprintf(errmsg, "holodeck \"%s\" not in expected format", fname);
216                  error(USER, errmsg);
217          }
218          fd = dup(fileno(fp));                   /* dup file handle */
219          nextloc = ftell(fp);                    /* get stdio position */
220          fclose(fp);                             /* done with stdio */
221 +        hfstore = (int *)malloc(sizeof(int));   /* tiny memory leak but who cares? */
222 +        *hfstore = hflags;
223          for (n = 0; nextloc > 0L; n++) {        /* initialize each section */
224 <                lseek(fd, nextloc, 0);
224 >                lseek(fd, nextloc, SEEK_SET);
225                  read(fd, (char *)&nextloc, sizeof(nextloc));
226 <                hdinit(fd, NULL)->priv = hflags&H_OBST ? &obstr :
134 <                                hflags&H_OBSF ? &unobstr : (char *)NULL;
226 >                hdinit(fd, NULL)->priv = hfstore;
227          }
228          return(n);
229   }
230  
231 < #undef H_BADF
232 < #undef H_OBST
233 < #undef H_OBSF
234 <
143 <
144 < addray(ro, rd, d, cv)           /* add a ray to our output holodeck */
145 < FVECT   ro, rd;
146 < double  d;
147 < COLR    cv;
231 > void
232 > addray(         /* add a ray to our output holodeck */
233 >        RAYPAR *rp
234 > )
235   {
236          int     sn, bi, n;
237 <        register HOLO   *hp;
237 >        HOLO    *hp;
238          GCOORD  gc[2];
239 <        BYTE    rr[2][2];
239 >        uby8    rr[2][2];
240          BEAM    *bp;
241          double  d0, d1;
242          unsigned        dc;
243 <        register RAYVAL *rv;
243 >        RAYVAL  *rv;
244                                  /* check each output section */
245 <        for (sn = noutsects; sn--; ) {
245 >        for (sn = nholosects; sn--; ) {
246                  hp = hdlist[sn];
247 <                d0 = hdinter(gc, rr, &d1, hp, ro, rd);
248 <                if (d <= d0 || d1 < -0.001)
247 >                d0 = hdinter(gc, rr, &d1, hp, rp->ro, rp->rd);
248 >                if (rp->d <= d0 || d1 < -0.001)
249                          continue;       /* missed section */
250                  if (checkdepth) {               /* check depth */
251 <                        if (hp->priv == &obstr && d0 < -0.001)
251 >                        if (*(int *)hp->priv & H_OBST && d0 < -0.001)
252                                  continue;       /* ray starts too late */
253 <                        if (hp->priv == &unobstr && d < 0.999*d1)
253 >                        if (*(int *)hp->priv & H_OBSF && rp->d < 0.999*d1)
254                                  continue;       /* ray ends too soon */
255                  }
256 <                dc = hdcode(hp, d-d0);
256 >                dc = hdcode(hp, rp->d-d0);
257                  bi = hdbindex(hp, gc);          /* check for duplicates */
258                  if (checkrepeats && (bp = hdgetbeam(hp, bi)) != NULL) {
259                          for (n = bp->nrm, rv = hdbray(bp); n--; rv++)
260 <                                if (rv->d == dc &&
260 >                                if ((rv->d == dc || *(int *)hp->priv & (H_OBST|H_OBSF)) &&
261                                                  rv->r[0][0] == rr[0][0] &&
262                                                  rv->r[0][1] == rr[0][1] &&
263                                                  rv->r[1][0] == rr[1][0] &&
# Line 183 | Line 270 | COLR   cv;
270                  rv->d = dc;
271                  rv->r[0][0] = rr[0][0]; rv->r[0][1] = rr[0][1];
272                  rv->r[1][0] = rr[1][0]; rv->r[1][1] = rr[1][1];
273 <                copycolr(rv->v, cv);
273 >                copycolr(rv->v, rp->cv);
274          }
275   }
276  
277 + /* Read n-vector from file stream */
278 + static int
279 + readval(RREAL *v, int n, FILE *fp)
280 + {
281 +        int     i;
282 + #ifdef SMLFLT
283 +        double  vd[3];
284 +        switch (iofmt) {
285 +        case 'f':
286 +                return getbinary(v, sizeof(float), n, fp);
287 +        case 'd':
288 +                n = getbinary(vd, sizeof(double), n, fp);
289 +                for (i = n; i-- > 0; ) v[i] = vd[i];
290 +                return n;
291 +        case 'a':
292 +                for (i = 0; i < n; i++)
293 +                        if (fscanf(fp, "%f ", &v[i]) != 1)
294 +                                break;
295 +                return i;
296 +        }
297 + #else
298 +        float   vf[3];
299 +        switch (iofmt) {
300 +        case 'd':
301 +                return getbinary(v, sizeof(double), n, fp);
302 +        case 'f':
303 +                n = getbinary(vf, sizeof(float), n, fp);
304 +                for (i = n; i-- > 0; ) v[i] = vf[i];
305 +                return n;
306 +        case 'a':
307 +                for (i = 0; i < n; i++)
308 +                        if (fscanf(fp, "%lf ", &v[i]) != 1)
309 +                                break;
310 +                return i;
311 +        }
312 + #endif
313 +        return -1;
314 + }
315  
316 < addholo(hdf)                    /* add a holodeck file */
317 < char    *hdf;
316 > #define GOT_ORG         0x01
317 > #define GOT_DIR         0x02
318 > #define GOT_LEN         0x04
319 > #define GOT_VAL         0x10
320 > #define ALSO_POS        0x20
321 > #define BAD_DIR         0x40
322 > #define BAD_LEN         0x80
323 >
324 > /* Read rays from stream and add to holodeck */
325 > static void
326 > readrays(FILE *fp)
327   {
328 <        HDBEAMI hbl[BLOADSIZE];
329 <        int     fd;
330 <        register HOLO   *hp;
331 <        register BEAM   *bp;
328 >        if (iofmt != 'a')
329 >                SET_FILE_BINARY(fp);
330 > #ifdef getc_unlocked
331 >        flockfile(fp);
332 > #endif
333 >        while (!feof(fp)) {             /* read entirety of input */
334 >                RAYPAR  ryp;
335 >                FVECT   pos;
336 >                FVECT   col;
337 >                int     flags = 0;
338 >                int     i;
339 >                for (i = 0; rspec[i]; i++) {
340 >                        switch (rspec[i]) {
341 >                        case 'o':               /* ray origin */
342 >                                if (readval(ryp.ro, 3, fp) < 3)
343 >                                        break;
344 >                                flags |= GOT_ORG;
345 >                                continue;
346 >                        case 'd':               /* ray direction */
347 >                                if (readval(ryp.rd, 3, fp) < 3)
348 >                                        break;
349 >                                if (normalize(ryp.rd) == 0)
350 >                                        flags |= BAD_DIR;
351 >                                else
352 >                                        flags |= GOT_DIR;
353 >                                continue;
354 >                        case 'p':               /* ray intersection */
355 >                                if (readval(pos, 3, fp) < 3)
356 >                                        break;
357 >                                flags |= ALSO_POS;
358 >                                continue;
359 >                        case 'L':               /* ray first length */
360 >                        case 'l':               /* ray virtual length */
361 >                                if (readval(&ryp.d, 1, fp) < 1)
362 >                                        break;
363 >                                if (ryp.d <= FTINY)
364 >                                        flags |= BAD_LEN;
365 >                                else
366 >                                        flags |= GOT_LEN;
367 >                                continue;
368 >                        case 'v':               /* ray value */
369 >                                if (readval(col, 3, fp) < 3)
370 >                                        break;
371 >                                setcolr(ryp.cv, col[0], col[1], col[2]);
372 >                                flags |= GOT_VAL;
373 >                                continue;
374 >                        default:
375 >                                sprintf(errmsg, "unsupported parameter '%c' in -i%s",
376 >                                                rspec[i], rspec);
377 >                                error(USER, errmsg);
378 >                        }
379 >                        if (!flags)     /* got nothing, so may be normal EOF */
380 >                                return;
381 >                }
382 >                if (flags & (BAD_DIR|BAD_LEN))
383 >                        continue;       /* just a bad ray is all -- skip */
384 >                if (!(flags & GOT_VAL))
385 >                        goto missingData;
386 >                if ((flags & (GOT_ORG|GOT_DIR|GOT_LEN)) != (GOT_ORG|GOT_DIR|GOT_LEN)) {
387 >                        if (!(flags & ALSO_POS))
388 >                                goto missingData;
389 >                        if (flags & GOT_ORG) {
390 >                                VSUB(ryp.rd, pos, ryp.ro);
391 >                                ryp.d = normalize(ryp.rd);
392 >                                if (ryp.d == 0)
393 >                                        continue;
394 >                        } else if ((flags & (GOT_DIR|GOT_LEN)) == (GOT_DIR|GOT_LEN)) {
395 >                                VSUM(ryp.ro, pos, ryp.rd, -ryp.d);
396 >                        } else
397 >                                goto missingData;
398 >                }
399 >                addray(&ryp);           /* add our ray to holodeck */
400 >        }
401 >        return;
402 > missingData:
403 >        sprintf(errmsg, "insufficient data in -i%s", rspec);
404 >        error(USER, errmsg);
405 > }
406 >
407 > /* Write vector value to file stream */
408 > static int
409 > writeval(RREAL *v, int n, FILE *fp)
410 > {
411 >        int     i;
412 >
413 >        if (iofmt == 'a') {
414 >                for (i = 0; i < n; i++)
415 >                        if (fprintf(fp, "\t%.4e", v[i]) < 0)
416 >                                break;
417 >                return i;
418 >        }
419 > #ifdef SMLFLT
420 >        if (iofmt == 'd') {
421 >                double  vd[3];
422 >                for (i = n; i--; ) vd[i] = v[i];
423 >                return putbinary(vd, sizeof(double), n, fp);
424 >        }
425 > #else
426 >        if (iofmt == 'f') {
427 >                float   vf[3];
428 >                for (i = n; i--; ) vf[i] = v[i];
429 >                return putbinary(vf, sizeof(float), n, fp);
430 >        }
431 > #endif
432 >        return putbinary(v, sizeof(*v), n, fp);
433 > }
434 >
435 > /* Write out an individual ray as requested */
436 > static int
437 > write_ray(RAYPAR *rp, FILE *fp)
438 > {
439 >        COLOR   cval;
440 >        FVECT   v3;
441 >        char    *typ = rspec;
442 >
443 >        for ( ; ; ) {
444 >                switch (*typ++) {
445 >                case 'o':               /* ray origin */
446 >                        if (writeval(rp->ro, 3, fp) < 3)
447 >                                break;
448 >                        continue;
449 >                case 'd':               /* ray direction */
450 >                        if (writeval(rp->rd, 3, fp) < 3)
451 >                                break;
452 >                        continue;
453 >                case 'p':               /* ray intersection */
454 >                        VSUM(v3, rp->ro, rp->rd, rp->d);
455 >                        if (writeval(v3, 3, fp) < 3)
456 >                                break;
457 >                        continue;
458 >                case 'L':               /* ray first length */
459 >                case 'l':               /* ray virtual length */
460 >                        if (writeval(&rp->d, 1, fp) < 1)
461 >                                break;
462 >                        continue;
463 >                case 'v':               /* ray value */
464 >                        colr_color(cval, rp->cv);
465 >                        VCOPY(v3, cval);
466 >                        if (writeval(v3, 3, fp) < 3)
467 >                                break;
468 >                        continue;
469 >                case '\0':              /* end of spec -- success */
470 >                        if (iofmt == 'a')
471 >                                fputc('\n', fp);
472 >                        return(1);
473 >                default:
474 >                        sprintf(errmsg, "unsupported parameter '%c' in -o%s", typ[-1], rspec);
475 >                }
476 >                break;                  /* land here on error */
477 >        }
478 >        return 0;                       /* write error? */
479 > }
480 >
481 > static BEAMI    *beamdir;
482 >
483 > static int
484 > bpcmp(                  /* compare beam positions on disk */
485 >        const void      *b1p,
486 >        const void      *b2p
487 > )
488 > {
489 >        off_t   pdif = beamdir[*(int *)b1p].fo - beamdir[*(int *)b2p].fo;
490 >
491 >        if (pdif > 0L) return(1);
492 >        if (pdif < 0L) return(-1);
493 >        return(0);
494 > }
495 >
496 > /* Write all rays from holodeck to stream */
497 > static void
498 > writerays(FILE *fp)
499 > {
500 >        int     sn, bi, k;
501          GCOORD  gc[2];
502 <        FVECT   ro, rd;
503 <        double  d;
504 <        int     i, j, n, li;
505 <        register int    k;
506 <                                        /* open the holodeck for reading */
507 <        openholo(hdf, 0);
508 <        fd = hdlist[noutsects]->fd;     /* remember the file handle */
509 <        while ((hp = hdlist[noutsects]) != NULL) {      /* load each section */
510 <                for (j = 0; j < nbeams(hp); j++) {      /* load each beam */
511 <                        if (!(li = j % BLOADSIZE)) {    /* optimize order */
512 <                                if (j+BLOADSIZE > nbeams(hp))
513 <                                        k = n = nbeams(hp) - j;
502 >        RAYVAL  *rv;
503 >        RAYPAR  ryp;
504 >
505 >        if (!*rspec) {
506 >                error(WARNING, "empty -o* output spec, quitting");
507 >                return;
508 >        }
509 >        if (iofmt != 'a')
510 >                SET_FILE_BINARY(fp);
511 > #ifdef getc_unlocked
512 >        flockfile(fp);
513 > #endif
514 >        for (sn = 0; sn < nholosects; sn++) {   /* write each holodeck section */
515 >                HOLO    *hp = hdlist[sn];
516 >                int     nb = nbeams(hp);        /* sort beams by file location */
517 >                int     *bq = (int *)malloc(nb*sizeof(int));
518 >                if (!bq)
519 >                        error(SYSTEM, "out of memory in writerays()");
520 >                for (bi = nb; bi--; ) bq[bi] = bi+1;
521 >                beamdir = hp->bi;
522 >                qsort(bq, nb, sizeof(*bq), bpcmp);
523 >                for (bi = 0; bi < nb; bi++) {
524 >                        BEAM    *bp = hdgetbeam(hp, bq[bi]);
525 >                        if (!bp)                /* empty beam? */
526 >                                continue;
527 >                        hdbcoord(gc, hp, bq[bi]);
528 >                        rv = hdbray(bp);
529 >                        for (k = bp->nrm; k--; rv++) {
530 >                                ryp.d = hdray(ryp.ro, ryp.rd, hp, gc, rv->r);
531 >                                if (*(int *)hp->priv & H_OBSF)
532 >                                        VSUM(ryp.ro, ryp.ro, ryp.rd, ryp.d);
533                                  else
534 <                                        k = n = BLOADSIZE;
535 <                                while (k--) {
536 <                                        hbl[k].h = hp;
537 <                                        hbl[k].b = j+k+1;
534 >                                        ryp.d = 0.;
535 >                                ryp.d = hddepth(hp, rv->d) - ryp.d;
536 >                                copycolr(ryp.cv, rv->v);
537 >                                if (!write_ray(&ryp, fp)) {
538 >                                        free(bq);
539 >                                        goto writError;
540                                  }
217                                qsort((char *)hbl, n,
218                                                sizeof(HDBEAMI), hdfilord);
541                          }
542 <                        if ((bp = hdgetbeam(hp, hbl[li].b)) != NULL) {
221 <                                hdbcoord(gc, hp, hbl[li].b);
222 <                                for (k = bp->nrm; k--; ) {
223 <                                        d = hdray(ro, rd,
224 <                                                hp, gc, hdbray(bp)[k].r);
225 <                                        if (hp->priv == &unobstr)
226 <                                                VSUM(ro, ro, rd, d);
227 <                                        else
228 <                                                d = 0.;
229 <                                        d = hddepth(hp, hdbray(bp)[k].d) - d;
230 <                                        addray(ro, rd, d, hdbray(bp)[k].v);
231 <                                }
232 <                                hdfreebeam(hp, hbl[li].b);      /* free beam */
233 <                        }
542 >                        hdfreebeam(hp, bq[bi]);
543                  }
544 <                hddone(hp);                             /* free the section */
544 >                free(bq);
545          }
546 <        close(fd);                      /* close the file */
546 >        if (fflush(fp) != EOF)
547 >                return;
548 > writError:
549 >        error(SYSTEM, "error writing holodeck rays");
550   }
551  
552 + static int
553 + addclump(               /* transfer the given clump and free */
554 +        HOLO    *hp,
555 +        int     *bq,
556 +        int     nb
557 + )
558 + {
559 +        GCOORD  gc[2];
560 +        RAYPAR  ryp;
561 +        RAYVAL  *rv;
562 +        int     i;
563 +        int     k;
564 +        BEAM    *bp;
565 +                                        /* sort based on file position */
566 +        beamdir = hp->bi;
567 +        qsort(bq, nb, sizeof(*bq), bpcmp);
568 +                                        /* transfer each beam */
569 +        for (i = 0; i < nb; i++) {
570 +                bp = hdgetbeam(hp, bq[i]);
571 +                hdbcoord(gc, hp, bq[i]);
572 +                rv = hdbray(bp);                        /* add each ray to output */
573 +                for (k = bp->nrm; k--; rv++) {
574 +                        ryp.d = hdray(ryp.ro, ryp.rd, hp, gc, rv->r);
575 +                        if (*(int *)hp->priv & H_OBSF)
576 +                                VSUM(ryp.ro, ryp.ro, ryp.rd, ryp.d);
577 +                        else
578 +                                ryp.d = 0.;
579 +                        ryp.d = hddepth(hp, rv->d) - ryp.d;
580 +                        copycolr(ryp.cv, rv->v);
581 +                        addray(&ryp);
582 +                }
583 +                hdfreebeam(hp, bq[i]);          /* free the beam */
584 +        }
585 +        return(0);
586 + }
587  
241 struct phead {
242        VIEW    vw;
243        double  expos;
244        short   gotview;
245        short   badfmt;
246        short   altprims;
247 };
588  
589 + void
590 + addholo(                        /* add a holodeck file */
591 +        char    *hdf
592 + )
593 + {
594 +        int     fd;
595 +                                        /* open the holodeck for reading */
596 +        openholo(hdf, 0);
597 +        fd = hdlist[nholosects]->fd;    /* remember the file handle */
598 +        while (hdlist[nholosects] != NULL) {    /* load each section */
599 +                                                        /* clump the beams */
600 +                clumpbeams(hdlist[nholosects], 0, BKBSIZE*1024, addclump);
601 +                hddone(hdlist[nholosects]);             /* free the section */
602 +        }
603 +        close(fd);                      /* close input file */
604 +        hdflush(NULL);                  /* flush output */
605 + }
606  
607 < picheadline(s, ph)              /* process picture header line */
608 < char    *s;
609 < struct phead    *ph;
607 >
608 >
609 > static int
610 > picheadline(            /* process picture header line */
611 >        char    *s,
612 >        void    *vph
613 > )
614   {
615          char    fmt[32];
616 +        struct phead *ph = (struct phead *)vph;
617  
618          if (formatval(fmt, s)) {
619                  ph->badfmt = strcmp(fmt, COLRFMT);
620 <                return;
620 >                return(0);
621          }
622          if (isprims(s)) {
623                  ph->altprims++;         /* don't want to deal with this */
624 <                return;
624 >                return(0);
625          }
626          if (isexpos(s)) {
627                  ph->expos *= exposval(s);
628 <                return;
628 >                return(0);
629          }
630          if (isview(s)) {
631                  ph->gotview += sscanview(&ph->vw, s);
632 <                return;
632 >                return(0);
633          }
634 +        return(0);
635   }
636  
637  
638 < addpicz(pcf, zbf)               /* add a picture + depth-buffer */
639 < char    *pcf, *zbf;
638 > void
639 > addpicz(                /* add a picture + depth-buffer */
640 >        char    *pcf,
641 >        char    *zbf
642 > )
643   {
644          FILE    *pfp;
645          int     zfd;
# Line 283 | Line 649 | char   *pcf, *zbf;
649          int     eshft;
650          double  emult;
651          RESOLU  prs;
652 <        FLOAT   vl[2];
653 <        FVECT   ro, rd;
652 >        RREAL   vl[2];
653 >        RAYPAR  ryp;
654          double  aftd;
655 <        COLOR   ctmp;
656 <        int     j;
657 <        register int    i;
292 <                                /* open files */
293 <        if ((pfp = fopen(pcf, "r")) == NULL) {
655 >        int     j, i;
656 >                                /* open picture & get header */
657 >        if ((pfp = fopen(pcf, "rb")) == NULL) {
658                  sprintf(errmsg, "cannot open picture file \"%s\"", pcf);
659                  error(SYSTEM, pcf);
660          }
661 <        if ((zfd = open(zbf, O_RDONLY)) < 0) {
298 <                sprintf(errmsg, "cannot open depth file \"%s\"", zbf);
299 <                error(SYSTEM, pcf);
300 <        }
301 <                                /* load picture header */
302 <        copystruct(&phd.vw, &stdview);
661 >        phd.vw = stdview;
662          phd.expos = 1.0;
663          phd.badfmt = phd.gotview = phd.altprims = 0;
664          if (getheader(pfp, picheadline, &phd) < 0 ||
# Line 313 | Line 672 | char   *pcf, *zbf;
672                  error(USER, errmsg);
673          }
674          if (phd.altprims) {
675 <                sprintf(errmsg, "ignoring primary values in picture \"%s\"",
675 >                sprintf(errmsg, "ignoring color primaries in picture \"%s\"",
676                                  pcf);
677                  error(WARNING, errmsg);
678          }
679 +                                /* open depth buffer */
680 +        if ((zfd = open_float_depth(zbf, prs.xr*prs.yr)) < 0)
681 +                quit(1);
682                                  /* figure out what to do about exposure */
683 <        if (phd.expos < 0.99 | phd.expos > 1.01) {
683 >        if ((phd.expos < 0.99) | (phd.expos > 1.01)) {
684                  emult = -log(phd.expos)/log(2.);
685                  eshft = emult >= 0. ? emult+.5 : emult-.5;
686                  emult -= (double)eshft;
687 <                if (emult <= 0.01 & emult >= -0.01)
687 >                if ((emult <= 0.01) & (emult >= -0.01))
688                          emult = -1.;
689                  else {
690                          emult = 1./phd.expos;
# Line 335 | Line 697 | char   *pcf, *zbf;
697                                  /* allocate buffers */
698          cscn = (COLR *)malloc(scanlen(&prs)*sizeof(COLR));
699          zscn = (float *)malloc(scanlen(&prs)*sizeof(float));
700 <        if (cscn == NULL | zscn == NULL)
700 >        if ((cscn == NULL) | (zscn == NULL))
701                  error(SYSTEM, "out of memory in addpicz");
702                                  /* read and process each scanline */
703          for (j = 0; j < numscans(&prs); j++) {
# Line 346 | Line 708 | char   *pcf, *zbf;
708                  }
709                  if (eshft)                              /* shift exposure */
710                          shiftcolrs(cscn, i, eshft);
711 <                i *= sizeof(float);                     /* read depth */
712 <                if (read(zfd, (char *)zscn, i) != i) {
711 >                                                        /* read depth */
712 >                if (read(zfd, zscn, i*sizeof(float)) != i*sizeof(float)) {
713                          sprintf(errmsg, "error reading depth file \"%s\"", zbf);
714                          error(USER, errmsg);
715                  }
716 <                for (i = scanlen(&prs); i--; ) {        /* do each pixel */
716 >                while (i--) {                           /* process each pixel */
717 >                        if (zscn[i] <= 0.0)
718 >                                continue;               /* illegal depth */
719                          pix2loc(vl, &prs, i, j);
720 <                        aftd = viewray(ro, rd, &phd.vw, vl[0], vl[1]);
720 >                        aftd = viewray(ryp.ro, ryp.rd, &phd.vw, vl[0], vl[1]);
721                          if (aftd < -FTINY)
722                                  continue;               /* off view */
723                          if (aftd > FTINY && zscn[i] > aftd)
724                                  continue;               /* aft clipped */
725 +                        ryp.d = (RREAL)zscn[i];
726 +                        copycolr(ryp.cv, cscn[i]);
727                          if (emult > 0.) {               /* whatta pain */
728 <                                colr_color(ctmp, cscn[i]);
728 >                                COLOR   ctmp;
729 >                                colr_color(ctmp, ryp.cv);
730                                  scalecolor(ctmp, emult);
731 <                                setcolr(cscn[i], colval(ctmp,RED),
731 >                                setcolr(ryp.cv, colval(ctmp,RED),
732                                          colval(ctmp,GRN), colval(ctmp,BLU));
733                          }
734 <                        addray(ro, rd, (double)zscn[i], cscn[i]);
734 >                        addray(&ryp);
735                  }
736          }
737 +                                /* write output and free beams */
738 +        hdflush(NULL);
739                                  /* clean up */
740 <        free((char *)cscn);
741 <        free((char *)zscn);
740 >        free((void *)cscn);
741 >        free((void *)zscn);
742          fclose(pfp);
743          close(zfd);
744   }
745  
746  
747 < eputs(s)                        /* put error message to stderr */
748 < register char  *s;
747 > void
748 > eputs(                  /* put error message to stderr */
749 >        const char  *s
750 > )
751   {
752          static int  midline = 0;
753  
# Line 394 | Line 765 | register char  *s;
765   }
766  
767  
768 < quit(code)                      /* exit the program gracefully */
769 < int     code;
768 > void
769 > quit(                   /* exit the program gracefully */
770 >        int     code
771 > )
772   {
773          hdsync(NULL, 1);        /* write out any buffered data */
774          exit(code);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines