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

Comparing ray/src/rt/rc2.c (file contents):
Revision 2.2 by greg, Sun Jun 10 05:25:42 2012 UTC vs.
Revision 2.21 by greg, Fri Sep 16 05:06:07 2016 UTC

# Line 6 | Line 6 | static const char RCSid[] = "$Id$";
6   * File i/o and recovery
7   */
8  
9 + #include <ctype.h>
10 + #include "platform.h"
11   #include "rcontrib.h"
12   #include "resolu.h"
11 #include "platform.h"
13  
14 + /* Close output stream and free record */
15 + static void
16 + closestream(void *p)
17 + {
18 +        STREAMOUT       *sop = (STREAMOUT *)p;
19 +        
20 +        if (sop->ofp != NULL) {
21 +                int     status = 0;
22 +                if (sop->outpipe)
23 +                        status = pclose(sop->ofp);
24 +                else if (sop->ofp != stdout)
25 +                        status = fclose(sop->ofp);
26 +                if (status)
27 +                        error(SYSTEM, "error closing output stream");
28 +        }
29 +        free(p);
30 + }
31 +
32 + LUTAB   ofiletab = LU_SINIT(free,closestream);  /* output file table */
33 +
34   #define OF_MODIFIER     01
35   #define OF_BIN          02
36  
# Line 92 | Line 113 | printheader(FILE *fout, const char *info)
113          printargs(gargc-1, gargv, fout);        /* add our command */
114          fprintf(fout, "SOFTWARE= %s\n", VersionID);
115          fputnow(fout);
116 +        fputs("NCOMP=3\n", fout);               /* always RGB */
117          if (info != NULL)                       /* add extra info if given */
118                  fputs(info, fout);
119          fputformat(formstr(outfmt), fout);
# Line 112 | Line 134 | printresolu(FILE *fout, int xr, int yr)
134   STREAMOUT *
135   getostream(const char *ospec, const char *mname, int bn, int noopen)
136   {
115        /* static const DCOLOR  nocontrib = BLKCOLOR; */
137          static STREAMOUT        stdos;
138 +        char                    info[1024];
139          int                     ofl;
140          char                    oname[1024];
141          LUENT                   *lep;
142          STREAMOUT               *sop;
143 +        char                    *cp;
144          
145          if (ospec == NULL) {                    /* use stdout? */
146 <                if (!noopen && !using_stdout) {
146 >                if (!noopen & !using_stdout) {
147                          if (outfmt != 'a')
148                                  SET_FILE_BINARY(stdout);
149 <                        if (header)
150 <                                printheader(stdout, NULL);
151 <                        printresolu(stdout, xres, yres);
149 >                        if (header) {
150 >                                cp = info;
151 >                                if (yres > 0) {
152 >                                        sprintf(cp, "NROWS=%d\n", yres *
153 >                                                        (xres + !xres) );
154 >                                        while (*cp) ++cp;
155 >                                }
156 >                                if ((xres <= 0) | (stdos.reclen > 1))
157 >                                        sprintf(cp, "NCOLS=%d\n", stdos.reclen);
158 >                                printheader(stdout, info);
159 >                        }
160 >                        if (stdos.reclen == 1)
161 >                                printresolu(stdout, xres, yres);
162                          if (waitflush > 0)
163                                  fflush(stdout);
164                          stdos.xr = xres; stdos.yr = yres;
# Line 151 | Line 184 | getostream(const char *ospec, const char *mname, int b
184                  sop = (STREAMOUT *)malloc(sizeof(STREAMOUT));
185                  if (sop == NULL)
186                          error(SYSTEM, "out of memory in getostream");
187 <                sop->outpipe = oname[0] == '!';
187 >                sop->outpipe = (oname[0] == '!');
188                  sop->reclen = 0;
189                  sop->ofp = NULL;                /* open iff noopen==0 */
190                  sop->xr = xres; sop->yr = yres;
# Line 161 | Line 194 | getostream(const char *ospec, const char *mname, int b
194                          errno = EEXIST;         /* file exists */
195                          goto openerr;
196                  }
197 +        } else if (noopen && outfmt == 'c' &&   /* stream exists to picture? */
198 +                        (sop->xr > 0) & (sop->yr > 0)) {
199 +                if (ofl & OF_BIN)
200 +                        return(NULL);           /* let caller offset bins */
201 +                sprintf(errmsg, "output '%s' not a valid picture", oname);
202 +                error(WARNING, errmsg);
203          }
204          if (!noopen && sop->ofp == NULL) {      /* open output stream */
166                long            i;
205                  if (oname[0] == '!')            /* output to command */
206                          sop->ofp = popen(oname+1, "w");
207                  else                            /* else open file */
# Line 175 | Line 213 | getostream(const char *ospec, const char *mname, int b
213   #ifdef getc_unlocked
214                  flockfile(sop->ofp);            /* avoid lock/unlock overhead */
215   #endif
216 +                if (accumulate > 0) {           /* global resolution */
217 +                        sop->xr = xres; sop->yr = yres;
218 +                }
219                  if (header) {
220 <                        char    info[512];
180 <                        char    *cp = info;
220 >                        cp = info;
221                          if (ofl & OF_MODIFIER || sop->reclen == 1) {
222                                  sprintf(cp, "MODIFIER=%s\n", mname);
223                                  while (*cp) ++cp;
# Line 186 | Line 226 | getostream(const char *ospec, const char *mname, int b
226                                  sprintf(cp, "BIN=%d\n", bn);
227                                  while (*cp) ++cp;
228                          }
229 <                        *cp = '\0';
229 >                        if (sop->yr > 0) {
230 >                                sprintf(cp, "NROWS=%d\n", sop->yr *
231 >                                                (sop->xr + !sop->xr) );
232 >                                while (*cp) ++cp;
233 >                        }
234 >                        if ((sop->xr <= 0) | (sop->reclen > 1))
235 >                                sprintf(cp, "NCOLS=%d\n", sop->reclen);
236                          printheader(sop->ofp, info);
237                  }
238 <                if (accumulate > 0) {           /* global resolution */
239 <                        sop->xr = xres; sop->yr = yres;
194 <                }
195 <                printresolu(sop->ofp, sop->xr, sop->yr);
196 < #if 0
197 <                                                /* play catch-up */
198 <                for (i = accumulate > 0 ? lastdone/accumulate : 0; i--; ) {
199 <                        int     j = sop->reclen;
200 <                        if (j <= 0) j = 1;
201 <                        while (j--)
202 <                                put_contrib(nocontrib, sop->ofp);
203 <                        if (outfmt == 'a')
204 <                                putc('\n', sop->ofp);
205 <                }
206 < #endif
238 >                if (sop->reclen == 1)
239 >                        printresolu(sop->ofp, sop->xr, sop->yr);
240                  if (waitflush > 0)
241                          fflush(sop->ofp);
242          }
# Line 235 | Line 268 | getvec(FVECT vec)
268                  }
269                  break;
270          case 'f':                                       /* binary float */
271 <                if (fread((char *)vf, sizeof(float), 3, stdin) != 3)
271 >                if (getbinary((char *)vf, sizeof(float), 3, stdin) != 3)
272                          return(-1);
273                  VCOPY(vec, vf);
274                  break;
275          case 'd':                                       /* binary double */
276 <                if (fread((char *)vd, sizeof(double), 3, stdin) != 3)
276 >                if (getbinary((char *)vd, sizeof(double), 3, stdin) != 3)
277                          return(-1);
278                  VCOPY(vec, vd);
279                  break;
# Line 276 | Line 309 | put_contrib(const DCOLOR cnt, FILE *fout)
309                          scalecolor(fv, sf);
310                  } else
311                          copycolor(fv, cnt);
312 <                fwrite(fv, sizeof(float), 3, fout);
312 >                putbinary(fv, sizeof(float), 3, fout);
313                  break;
314          case 'd':
315                  if (accumulate > 1) {
316                          DCOLOR  dv;
317                          copycolor(dv, cnt);
318                          scalecolor(dv, sf);
319 <                        fwrite(dv, sizeof(double), 3, fout);
319 >                        putbinary(dv, sizeof(double), 3, fout);
320                  } else
321 <                        fwrite(cnt, sizeof(double), 3, fout);
321 >                        putbinary(cnt, sizeof(double), 3, fout);
322                  break;
323          case 'c':
324                  if (accumulate > 1)
325                          setcolr(cv, sf*cnt[0], sf*cnt[1], sf*cnt[2]);
326                  else
327                          setcolr(cv, cnt[0], cnt[1], cnt[2]);
328 <                fwrite(cv, sizeof(cv), 1, fout);
328 >                putbinary(cv, sizeof(cv), 1, fout);
329                  break;
330          default:
331                  error(INTERNAL, "botched output format");
# Line 304 | Line 337 | put_contrib(const DCOLOR cnt, FILE *fout)
337   void
338   mod_output(MODCONT *mp)
339   {
340 <        STREAMOUT       *sop = getostream(mp->outspec, mp->modname, 0, 0);
340 >        STREAMOUT       *sop = getostream(mp->outspec, mp->modname, mp->bin0, 0);
341          int             j;
342  
343          put_contrib(mp->cbin[0], sop->ofp);
344          if (mp->nbins > 3 &&    /* minor optimization */
345 <                        sop == getostream(mp->outspec, mp->modname, 1, 0))
345 >                        sop == getostream(mp->outspec, mp->modname, mp->bin0+1, 0)) {
346                  for (j = 1; j < mp->nbins; j++)
347                          put_contrib(mp->cbin[j], sop->ofp);
348 <        else
348 >        } else {
349                  for (j = 1; j < mp->nbins; j++) {
350 <                        sop = getostream(mp->outspec, mp->modname, j, 0);
350 >                        sop = getostream(mp->outspec, mp->modname, mp->bin0+j, 0);
351                          put_contrib(mp->cbin[j], sop->ofp);
352                  }
353 +        }
354   }
355  
356  
# Line 343 | Line 377 | void
377   end_record()
378   {
379          --waitflush;
380 <        lu_doall(&ofiletab, puteol, NULL);
380 >        lu_doall(&ofiletab, &puteol, NULL);
381          if (using_stdout & (outfmt == 'a'))
382                  putc('\n', stdout);
383          if (!waitflush) {
# Line 366 | Line 400 | get_contrib(DCOLOR cnt, FILE *finp)
400          case 'a':
401                  return(fscanf(finp,"%lf %lf %lf",&cnt[0],&cnt[1],&cnt[2]) == 3);
402          case 'f':
403 <                if (fread(fv, sizeof(fv[0]), 3, finp) != 3)
403 >                if (getbinary(fv, sizeof(fv[0]), 3, finp) != 3)
404                          return(0);
405                  copycolor(cnt, fv);
406                  return(1);
407          case 'd':
408 <                return(fread(cnt, sizeof(cnt[0]), 3, finp) == 3);
408 >                return(getbinary(cnt, sizeof(cnt[0]), 3, finp) == 3);
409          case 'c':
410 <                if (fread(cv, sizeof(cv), 1, finp) != 1)
410 >                if (getbinary(cv, sizeof(cv), 1, finp) != 1)
411                          return(0);
412                  colr_color(fv, cv);
413                  copycolor(cnt, fv);
# Line 411 | Line 445 | reload_output()
445          char            *outvfmt;
446          LUENT           *oent;
447          int             xr, yr;
448 <        STREAMOUT       sout;
448 >        STREAMOUT       *sop;
449          DCOLOR          rgbv;
450  
451          if (outfmt == 'a')
# Line 424 | Line 458 | reload_output()
458                          error(USER, "cannot reload from stdout");
459                  if (mp->outspec[0] == '!')
460                          error(USER, "cannot reload from command");
461 <                for (j = 0; ; j++) {            /* load each modifier bin */
462 <                        ofl = ofname(oname, mp->outspec, mp->modname, j);
461 >                for (j = 0; j < mp->nbins; j++) { /* load each modifier bin */
462 >                        ofl = ofname(oname, mp->outspec, mp->modname, mp->bin0+j);
463                          if (ofl < 0)
464                                  error(USER, "bad output file specification");
465                          oent = lu_find(&ofiletab, oname);
466 <                        if (oent->data != NULL) {
467 <                                sout = *(STREAMOUT *)oent->data;
468 <                        } else {
469 <                                sout.reclen = 0;
470 <                                sout.outpipe = 0;
471 <                                sout.xr = xres; sout.yr = yres;
438 <                                sout.ofp = NULL;
439 <                        }
440 <                        if (sout.ofp == NULL) { /* open output as input */
441 <                                sout.ofp = fopen(oname, fmode);
442 <                                if (sout.ofp == NULL) {
443 <                                        if (j == mp->nbins)
444 <                                                break;  /* assume end of modifier */
466 >                        if (oent->data == NULL)
467 >                                error(INTERNAL, "unallocated stream in reload_output()");
468 >                        sop = (STREAMOUT *)oent->data;
469 >                        if (sop->ofp == NULL) { /* open output as input */
470 >                                sop->ofp = fopen(oname, fmode);
471 >                                if (sop->ofp == NULL) {
472                                          sprintf(errmsg, "missing reload file '%s'",
473                                                          oname);
474                                          error(WARNING, errmsg);
475                                          break;
476                                  }
477   #ifdef getc_unlocked
478 <                                flockfile(sout.ofp);
478 >                                flockfile(sop->ofp);
479   #endif
480 <                                if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) {
480 >                                if (header && checkheader(sop->ofp, outvfmt, NULL) != 1) {
481                                          sprintf(errmsg, "format mismatch for '%s'",
482                                                          oname);
483                                          error(USER, errmsg);
484                                  }
485 <                                if ((sout.xr > 0) & (sout.yr > 0) &&
486 <                                                (!fscnresolu(&xr, &yr, sout.ofp) ||
487 <                                                        (xr != sout.xr) |
488 <                                                        (yr != sout.yr))) {
485 >                                if ((sop->reclen == 1) & (sop->xr > 0) & (sop->yr > 0) &&
486 >                                                (!fscnresolu(&xr, &yr, sop->ofp) ||
487 >                                                        (xr != sop->xr) |
488 >                                                        (yr != sop->yr))) {
489                                          sprintf(errmsg, "resolution mismatch for '%s'",
490                                                          oname);
491                                          error(USER, errmsg);
492                                  }
493                          }
494                                                          /* read in RGB value */
495 <                        if (!get_contrib(rgbv, sout.ofp)) {
495 >                        if (!get_contrib(rgbv, sop->ofp)) {
496                                  if (!j) {
497 <                                        fclose(sout.ofp);
497 >                                        fclose(sop->ofp);
498                                          break;          /* ignore empty file */
499                                  }
500                                  if (j < mp->nbins) {
# Line 476 | Line 503 | reload_output()
503                                          error(USER, errmsg);
504                                  }
505                                  break;
506 <                        }
480 <                        if (j >= mp->nbins) {           /* check modifier size */
481 <                                sprintf(errmsg,
482 <                                "mismatched -bn setting for reloading '%s'",
483 <                                                modname[i]);
484 <                                error(USER, errmsg);
485 <                        }
486 <                                
506 >                        }                              
507                          copycolor(mp->cbin[j], rgbv);
488                        if (oent->key == NULL)          /* new file entry */
489                                oent->key = strcpy((char *)
490                                                malloc(strlen(oname)+1), oname);
491                        if (oent->data == NULL)
492                                oent->data = (char *)malloc(sizeof(STREAMOUT));
493                        *(STREAMOUT *)oent->data = sout;
508                  }
509          }
510 <        lu_doall(&ofiletab, myclose, NULL);     /* close all files */
510 >        lu_doall(&ofiletab, &myclose, NULL);    /* close all files */
511   }
512  
513  
# Line 526 | Line 540 | recover_output()
540          int             ofl;
541          char            oname[1024];
542          LUENT           *oent;
543 <        STREAMOUT       sout;
543 >        STREAMOUT       *sop;
544          off_t           nvals;
545          int             xr, yr;
546  
# Line 555 | Line 569 | recover_output()
569                          error(USER, "cannot recover from stdout");
570                  if (mp->outspec[0] == '!')
571                          error(USER, "cannot recover from command");
572 <                for (j = 0; ; j++) {            /* check each bin's file */
573 <                        ofl = ofname(oname, mp->outspec, mp->modname, j);
572 >                for (j = 0; j < mp->nbins; j++) { /* check each bin's file */
573 >                        ofl = ofname(oname, mp->outspec, mp->modname, mp->bin0+j);
574                          if (ofl < 0)
575                                  error(USER, "bad output file specification");
576                          oent = lu_find(&ofiletab, oname);
577 <                        if (oent->data != NULL) {
578 <                                sout = *(STREAMOUT *)oent->data;
579 <                        } else {
580 <                                sout.reclen = 0;
567 <                                sout.outpipe = 0;
568 <                                sout.ofp = NULL;
569 <                        }
570 <                        if (sout.ofp != NULL) { /* already open? */
577 >                        if (oent->data == NULL)
578 >                                error(INTERNAL, "unallocated stream in recover_output()");
579 >                        sop = (STREAMOUT *)oent->data;
580 >                        if (sop->ofp != NULL) { /* already open? */
581                                  if (ofl & OF_BIN)
582                                          continue;
583                                  break;
584                          }
585                                                  /* open output */
586 <                        sout.ofp = fopen(oname, "rb+");
587 <                        if (sout.ofp == NULL) {
578 <                                if (j == mp->nbins)
579 <                                        break;  /* assume end of modifier */
586 >                        sop->ofp = fopen(oname, "rb+");
587 >                        if (sop->ofp == NULL) {
588                                  sprintf(errmsg, "missing recover file '%s'",
589                                                  oname);
590                                  error(WARNING, errmsg);
591 +                                lastout = 0;
592                                  break;
593                          }
594 <                        nvals = lseek(fileno(sout.ofp), 0, SEEK_END);
594 >                        nvals = lseek(fileno(sop->ofp), 0, SEEK_END);
595                          if (nvals <= 0) {
596                                  lastout = 0;    /* empty output, quit here */
597 <                                fclose(sout.ofp);
597 >                                fclose(sop->ofp);
598                                  break;
599                          }
600 <                        if (!sout.reclen) {
592 <                                if (!(ofl & OF_BIN)) {
593 <                                        sprintf(errmsg,
594 <                                                "need -bn to recover file '%s'",
595 <                                                        oname);
596 <                                        error(USER, errmsg);
597 <                                }
598 <                                recsiz = outvsiz;
599 <                        } else
600 <                                recsiz = outvsiz * sout.reclen;
600 >                        recsiz = outvsiz * sop->reclen;
601  
602 <                        lseek(fileno(sout.ofp), 0, SEEK_SET);
603 <                        if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) {
602 >                        lseek(fileno(sop->ofp), 0, SEEK_SET);
603 >                        if (header && checkheader(sop->ofp, outvfmt, NULL) != 1) {
604                                  sprintf(errmsg, "format mismatch for '%s'",
605                                                  oname);
606                                  error(USER, errmsg);
607                          }
608 <                        sout.xr = xres; sout.yr = yres;
609 <                        if ((sout.xr > 0) & (sout.yr > 0) &&
610 <                                        (!fscnresolu(&xr, &yr, sout.ofp) ||
611 <                                                (xr != sout.xr) |
612 <                                                (yr != sout.yr))) {
608 >                        if ((sop->reclen == 1) & (sop->xr > 0) & (sop->yr > 0) &&
609 >                                        (!fscnresolu(&xr, &yr, sop->ofp) ||
610 >                                                (xr != sop->xr) |
611 >                                                (yr != sop->yr))) {
612                                  sprintf(errmsg, "resolution mismatch for '%s'",
613                                                  oname);
614                                  error(USER, errmsg);
615                          }
616 <                        nvals = (nvals - (off_t)ftell(sout.ofp)) / recsiz;
616 >                        nvals = (nvals - (off_t)ftell(sop->ofp)) / recsiz;
617                          if ((lastout < 0) | (nvals < lastout))
618                                  lastout = nvals;
620                        if (oent->key == NULL)  /* new entry */
621                                oent->key = strcpy((char *)
622                                                malloc(strlen(oname)+1), oname);
623                        if (oent->data == NULL)
624                                oent->data = (char *)malloc(sizeof(STREAMOUT));
625                        *(STREAMOUT *)oent->data = sout;
619                          if (!(ofl & OF_BIN))
620                                  break;          /* no bin separation */
621                  }
622                  if (!lastout) {                 /* empty output */
623                          error(WARNING, "no previous data to recover");
624 <                        lu_done(&ofiletab);     /* reclose all outputs */
624 >                                                /* reclose all outputs */
625 >                        lu_doall(&ofiletab, &myclose, NULL);
626                          return;
627                  }
634                if (j > mp->nbins) {            /* check modifier size */
635                        sprintf(errmsg,
636                                "mismatched -bn setting for recovering '%s'",
637                                        modname[i]);
638                        error(USER, errmsg);
639                }
628          }
629          if (lastout < 0) {
630                  error(WARNING, "no output files to recover");
# Line 649 | Line 637 | recover_output()
637          }
638                                                  /* seek on all files */
639          nvals = lastout * outvsiz;
640 <        lu_doall(&ofiletab, myseeko, &nvals);
640 >        lu_doall(&ofiletab, &myseeko, &nvals);
641                                                  /* skip repeated input */
642 +        lastout *= accumulate;
643          for (nvals = 0; nvals < lastout; nvals++) {
644                  FVECT   vdummy;
645                  if (getvec(vdummy) < 0 || getvec(vdummy) < 0)
646                          error(USER, "unexpected EOF on input");
647          }
648 <        lastray = lastdone = lastout * accumulate;
648 >        lastray = lastdone = (RNUMBER)lastout;
649          if (raysleft)
650                  raysleft -= lastray;
651   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines