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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines