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.5 by greg, Tue Jun 19 00:12:08 2012 UTC vs.
Revision 2.24 by greg, Wed Sep 4 20:19:51 2019 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
# Line 112 | 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 +        if ((outfmt == 'f') | (outfmt == 'd'))
120 +                fputendian(fout);
121          fputformat(formstr(outfmt), fout);
122          fputc('\n', fout);                      /* empty line ends header */
123   }
# Line 132 | Line 136 | printresolu(FILE *fout, int xr, int yr)
136   STREAMOUT *
137   getostream(const char *ospec, const char *mname, int bn, int noopen)
138   {
135        /* static const DCOLOR  nocontrib = BLKCOLOR; */
139          static STREAMOUT        stdos;
140 +        char                    info[1024];
141          int                     ofl;
142          char                    oname[1024];
143          LUENT                   *lep;
144          STREAMOUT               *sop;
145 +        char                    *cp;
146          
147          if (ospec == NULL) {                    /* use stdout? */
148                  if (!noopen & !using_stdout) {
149                          if (outfmt != 'a')
150                                  SET_FILE_BINARY(stdout);
146                        if (header)
147                                printheader(stdout, NULL);
148                        printresolu(stdout, xres, yres);
149                        if (waitflush > 0)
150                                fflush(stdout);
151                        stdos.xr = xres; stdos.yr = yres;
151   #ifdef getc_unlocked
152                          flockfile(stdout);      /* avoid lock/unlock overhead */
153   #endif
154 +                        if (header) {
155 +                                cp = info;
156 +                                if (yres > 0) {
157 +                                        sprintf(cp, "NROWS=%d\n", yres *
158 +                                                        (xres + !xres) );
159 +                                        while (*cp) ++cp;
160 +                                }
161 +                                if ((xres <= 0) | (stdos.reclen > 1))
162 +                                        sprintf(cp, "NCOLS=%d\n", stdos.reclen);
163 +                                printheader(stdout, info);
164 +                        }
165 +                        if (stdos.reclen == 1)
166 +                                printresolu(stdout, xres, yres);
167 +                        if (waitflush > 0)
168 +                                fflush(stdout);
169 +                        stdos.xr = xres; stdos.yr = yres;
170                          using_stdout = 1;
171                  }
172                  stdos.ofp = stdout;
# Line 171 | Line 186 | getostream(const char *ospec, const char *mname, int b
186                  sop = (STREAMOUT *)malloc(sizeof(STREAMOUT));
187                  if (sop == NULL)
188                          error(SYSTEM, "out of memory in getostream");
189 <                sop->outpipe = oname[0] == '!';
189 >                sop->outpipe = (oname[0] == '!');
190                  sop->reclen = 0;
191                  sop->ofp = NULL;                /* open iff noopen==0 */
192                  sop->xr = xres; sop->yr = yres;
# Line 181 | Line 196 | getostream(const char *ospec, const char *mname, int b
196                          errno = EEXIST;         /* file exists */
197                          goto openerr;
198                  }
199 +        } else if (noopen && outfmt == 'c' &&   /* stream exists to picture? */
200 +                        (sop->xr > 0) & (sop->yr > 0)) {
201 +                if (ofl & OF_BIN)
202 +                        return(NULL);           /* let caller offset bins */
203 +                sprintf(errmsg, "output '%s' not a valid picture", oname);
204 +                error(WARNING, errmsg);
205          }
206          if (!noopen && sop->ofp == NULL) {      /* open output stream */
186                long            i;
207                  if (oname[0] == '!')            /* output to command */
208                          sop->ofp = popen(oname+1, "w");
209                  else                            /* else open file */
# Line 195 | Line 215 | getostream(const char *ospec, const char *mname, int b
215   #ifdef getc_unlocked
216                  flockfile(sop->ofp);            /* avoid lock/unlock overhead */
217   #endif
218 +                if (accumulate > 0) {           /* global resolution */
219 +                        sop->xr = xres; sop->yr = yres;
220 +                }
221                  if (header) {
222 <                        char    info[512];
200 <                        char    *cp = info;
222 >                        cp = info;
223                          if (ofl & OF_MODIFIER || sop->reclen == 1) {
224                                  sprintf(cp, "MODIFIER=%s\n", mname);
225                                  while (*cp) ++cp;
# Line 206 | Line 228 | getostream(const char *ospec, const char *mname, int b
228                                  sprintf(cp, "BIN=%d\n", bn);
229                                  while (*cp) ++cp;
230                          }
231 <                        *cp = '\0';
231 >                        if (sop->yr > 0) {
232 >                                sprintf(cp, "NROWS=%d\n", sop->yr *
233 >                                                (sop->xr + !sop->xr) );
234 >                                while (*cp) ++cp;
235 >                        }
236 >                        if ((sop->xr <= 0) | (sop->reclen > 1))
237 >                                sprintf(cp, "NCOLS=%d\n", sop->reclen);
238                          printheader(sop->ofp, info);
239                  }
240 <                if (accumulate > 0) {           /* global resolution */
241 <                        sop->xr = xres; sop->yr = yres;
214 <                }
215 <                printresolu(sop->ofp, sop->xr, sop->yr);
216 < #if 0
217 <                                                /* play catch-up */
218 <                for (i = accumulate > 0 ? lastdone/accumulate : 0; i--; ) {
219 <                        int     j = sop->reclen;
220 <                        if (j <= 0) j = 1;
221 <                        while (j--)
222 <                                put_contrib(nocontrib, sop->ofp);
223 <                        if (outfmt == 'a')
224 <                                putc('\n', sop->ofp);
225 <                }
226 < #endif
240 >                if (sop->reclen == 1)
241 >                        printresolu(sop->ofp, sop->xr, sop->yr);
242                  if (waitflush > 0)
243                          fflush(sop->ofp);
244          }
# Line 255 | Line 270 | getvec(FVECT vec)
270                  }
271                  break;
272          case 'f':                                       /* binary float */
273 <                if (fread((char *)vf, sizeof(float), 3, stdin) != 3)
273 >                if (getbinary((char *)vf, sizeof(float), 3, stdin) != 3)
274                          return(-1);
275                  VCOPY(vec, vf);
276                  break;
277          case 'd':                                       /* binary double */
278 <                if (fread((char *)vd, sizeof(double), 3, stdin) != 3)
278 >                if (getbinary((char *)vd, sizeof(double), 3, stdin) != 3)
279                          return(-1);
280                  VCOPY(vec, vd);
281                  break;
# Line 296 | Line 311 | put_contrib(const DCOLOR cnt, FILE *fout)
311                          scalecolor(fv, sf);
312                  } else
313                          copycolor(fv, cnt);
314 <                fwrite(fv, sizeof(float), 3, fout);
314 >                putbinary(fv, sizeof(float), 3, fout);
315                  break;
316          case 'd':
317                  if (accumulate > 1) {
318                          DCOLOR  dv;
319                          copycolor(dv, cnt);
320                          scalecolor(dv, sf);
321 <                        fwrite(dv, sizeof(double), 3, fout);
321 >                        putbinary(dv, sizeof(double), 3, fout);
322                  } else
323 <                        fwrite(cnt, sizeof(double), 3, fout);
323 >                        putbinary(cnt, sizeof(double), 3, fout);
324                  break;
325          case 'c':
326                  if (accumulate > 1)
327                          setcolr(cv, sf*cnt[0], sf*cnt[1], sf*cnt[2]);
328                  else
329                          setcolr(cv, cnt[0], cnt[1], cnt[2]);
330 <                fwrite(cv, sizeof(cv), 1, fout);
330 >                putbinary(cv, sizeof(cv), 1, fout);
331                  break;
332          default:
333                  error(INTERNAL, "botched output format");
# Line 324 | Line 339 | put_contrib(const DCOLOR cnt, FILE *fout)
339   void
340   mod_output(MODCONT *mp)
341   {
342 <        STREAMOUT       *sop = getostream(mp->outspec, mp->modname, 0, 0);
342 >        STREAMOUT       *sop = getostream(mp->outspec, mp->modname, mp->bin0, 0);
343          int             j;
344  
345          put_contrib(mp->cbin[0], sop->ofp);
346          if (mp->nbins > 3 &&    /* minor optimization */
347 <                        sop == getostream(mp->outspec, mp->modname, 1, 0)) {
347 >                        sop == getostream(mp->outspec, mp->modname, mp->bin0+1, 0)) {
348                  for (j = 1; j < mp->nbins; j++)
349                          put_contrib(mp->cbin[j], sop->ofp);
350          } else {
351                  for (j = 1; j < mp->nbins; j++) {
352 <                        sop = getostream(mp->outspec, mp->modname, j, 0);
352 >                        sop = getostream(mp->outspec, mp->modname, mp->bin0+j, 0);
353                          put_contrib(mp->cbin[j], sop->ofp);
354                  }
355          }
# Line 364 | Line 379 | void
379   end_record()
380   {
381          --waitflush;
382 <        lu_doall(&ofiletab, puteol, NULL);
382 >        lu_doall(&ofiletab, &puteol, NULL);
383          if (using_stdout & (outfmt == 'a'))
384                  putc('\n', stdout);
385          if (!waitflush) {
# Line 387 | Line 402 | get_contrib(DCOLOR cnt, FILE *finp)
402          case 'a':
403                  return(fscanf(finp,"%lf %lf %lf",&cnt[0],&cnt[1],&cnt[2]) == 3);
404          case 'f':
405 <                if (fread(fv, sizeof(fv[0]), 3, finp) != 3)
405 >                if (getbinary(fv, sizeof(fv[0]), 3, finp) != 3)
406                          return(0);
407                  copycolor(cnt, fv);
408                  return(1);
409          case 'd':
410 <                return(fread(cnt, sizeof(cnt[0]), 3, finp) == 3);
410 >                return(getbinary(cnt, sizeof(cnt[0]), 3, finp) == 3);
411          case 'c':
412 <                if (fread(cv, sizeof(cv), 1, finp) != 1)
412 >                if (getbinary(cv, sizeof(cv), 1, finp) != 1)
413                          return(0);
414                  colr_color(fv, cv);
415                  copycolor(cnt, fv);
# Line 432 | Line 447 | reload_output()
447          char            *outvfmt;
448          LUENT           *oent;
449          int             xr, yr;
450 <        STREAMOUT       sout;
450 >        STREAMOUT       *sop;
451          DCOLOR          rgbv;
452  
453          if (outfmt == 'a')
# Line 445 | Line 460 | reload_output()
460                          error(USER, "cannot reload from stdout");
461                  if (mp->outspec[0] == '!')
462                          error(USER, "cannot reload from command");
463 <                for (j = 0; ; j++) {            /* load each modifier bin */
464 <                        ofl = ofname(oname, mp->outspec, mp->modname, j);
463 >                for (j = 0; j < mp->nbins; j++) { /* load each modifier bin */
464 >                        ofl = ofname(oname, mp->outspec, mp->modname, mp->bin0+j);
465                          if (ofl < 0)
466                                  error(USER, "bad output file specification");
467                          oent = lu_find(&ofiletab, oname);
468 <                        if (oent->data != NULL) {
469 <                                sout = *(STREAMOUT *)oent->data;
470 <                        } else {
471 <                                sout.reclen = 0;
472 <                                sout.outpipe = 0;
473 <                                sout.xr = xres; sout.yr = yres;
459 <                                sout.ofp = NULL;
460 <                        }
461 <                        if (sout.ofp == NULL) { /* open output as input */
462 <                                sout.ofp = fopen(oname, fmode);
463 <                                if (sout.ofp == NULL) {
464 <                                        if (j == mp->nbins)
465 <                                                break;  /* assume end of modifier */
468 >                        if (oent->data == NULL)
469 >                                error(INTERNAL, "unallocated stream in reload_output()");
470 >                        sop = (STREAMOUT *)oent->data;
471 >                        if (sop->ofp == NULL) { /* open output as input */
472 >                                sop->ofp = fopen(oname, fmode);
473 >                                if (sop->ofp == NULL) {
474                                          sprintf(errmsg, "missing reload file '%s'",
475                                                          oname);
476                                          error(WARNING, errmsg);
477                                          break;
478                                  }
479   #ifdef getc_unlocked
480 <                                flockfile(sout.ofp);
480 >                                flockfile(sop->ofp);
481   #endif
482 <                                if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) {
482 >                                if (header && checkheader(sop->ofp, outvfmt, NULL) != 1) {
483                                          sprintf(errmsg, "format mismatch for '%s'",
484                                                          oname);
485                                          error(USER, errmsg);
486                                  }
487 <                                if ((sout.xr > 0) & (sout.yr > 0) &&
488 <                                                (!fscnresolu(&xr, &yr, sout.ofp) ||
489 <                                                        (xr != sout.xr) |
490 <                                                        (yr != sout.yr))) {
487 >                                if ((sop->reclen == 1) & (sop->xr > 0) & (sop->yr > 0) &&
488 >                                                (!fscnresolu(&xr, &yr, sop->ofp) ||
489 >                                                        (xr != sop->xr) |
490 >                                                        (yr != sop->yr))) {
491                                          sprintf(errmsg, "resolution mismatch for '%s'",
492                                                          oname);
493                                          error(USER, errmsg);
494                                  }
495                          }
496                                                          /* read in RGB value */
497 <                        if (!get_contrib(rgbv, sout.ofp)) {
497 >                        if (!get_contrib(rgbv, sop->ofp)) {
498                                  if (!j) {
499 <                                        fclose(sout.ofp);
499 >                                        fclose(sop->ofp);
500                                          break;          /* ignore empty file */
501                                  }
502                                  if (j < mp->nbins) {
# Line 497 | Line 505 | reload_output()
505                                          error(USER, errmsg);
506                                  }
507                                  break;
508 <                        }
501 <                        if (j >= mp->nbins) {           /* check modifier size */
502 <                                sprintf(errmsg,
503 <                                "mismatched -bn setting for reloading '%s'",
504 <                                                modname[i]);
505 <                                error(USER, errmsg);
506 <                        }
507 <                                
508 >                        }                              
509                          copycolor(mp->cbin[j], rgbv);
509                        if (oent->key == NULL)          /* new file entry */
510                                oent->key = strcpy((char *)
511                                                malloc(strlen(oname)+1), oname);
512                        if (oent->data == NULL)
513                                oent->data = (char *)malloc(sizeof(STREAMOUT));
514                        *(STREAMOUT *)oent->data = sout;
510                  }
511          }
512 <        lu_doall(&ofiletab, myclose, NULL);     /* close all files */
512 >        lu_doall(&ofiletab, &myclose, NULL);    /* close all files */
513   }
514  
515  
# Line 526 | Line 521 | myseeko(const LUENT *e, void *p)
521          off_t           nbytes = *(off_t *)p;
522          
523          if (sop->reclen > 1)
524 <                nbytes = nbytes * sop->reclen;
524 >                nbytes *= (off_t)sop->reclen;
525          if (fseeko(sop->ofp, nbytes, SEEK_CUR) < 0) {
526                  sprintf(errmsg, "seek error on file '%s'", e->key);
527                  error(SYSTEM, errmsg);
# Line 547 | Line 542 | recover_output()
542          int             ofl;
543          char            oname[1024];
544          LUENT           *oent;
545 <        STREAMOUT       sout;
545 >        STREAMOUT       *sop;
546          off_t           nvals;
547          int             xr, yr;
548  
# Line 576 | Line 571 | recover_output()
571                          error(USER, "cannot recover from stdout");
572                  if (mp->outspec[0] == '!')
573                          error(USER, "cannot recover from command");
574 <                for (j = 0; ; j++) {            /* check each bin's file */
575 <                        ofl = ofname(oname, mp->outspec, mp->modname, j);
574 >                for (j = 0; j < mp->nbins; j++) { /* check each bin's file */
575 >                        ofl = ofname(oname, mp->outspec, mp->modname, mp->bin0+j);
576                          if (ofl < 0)
577                                  error(USER, "bad output file specification");
578                          oent = lu_find(&ofiletab, oname);
579 <                        if (oent->data != NULL) {
580 <                                sout = *(STREAMOUT *)oent->data;
581 <                        } else {
582 <                                sout.reclen = 0;
588 <                                sout.outpipe = 0;
589 <                                sout.ofp = NULL;
590 <                        }
591 <                        if (sout.ofp != NULL) { /* already open? */
579 >                        if (oent->data == NULL)
580 >                                error(INTERNAL, "unallocated stream in recover_output()");
581 >                        sop = (STREAMOUT *)oent->data;
582 >                        if (sop->ofp != NULL) { /* already open? */
583                                  if (ofl & OF_BIN)
584                                          continue;
585                                  break;
586                          }
587                                                  /* open output */
588 <                        sout.ofp = fopen(oname, "rb+");
589 <                        if (sout.ofp == NULL) {
599 <                                if (j == mp->nbins)
600 <                                        break;  /* assume end of modifier */
588 >                        sop->ofp = fopen(oname, "rb+");
589 >                        if (sop->ofp == NULL) {
590                                  sprintf(errmsg, "missing recover file '%s'",
591                                                  oname);
592                                  error(WARNING, errmsg);
593 +                                lastout = 0;
594                                  break;
595                          }
596 <                        nvals = lseek(fileno(sout.ofp), 0, SEEK_END);
596 >                        nvals = lseek(fileno(sop->ofp), 0, SEEK_END);
597                          if (nvals <= 0) {
598                                  lastout = 0;    /* empty output, quit here */
599 <                                fclose(sout.ofp);
599 >                                fclose(sop->ofp);
600                                  break;
601                          }
602 <                        if (!sout.reclen) {
613 <                                if (!(ofl & OF_BIN)) {
614 <                                        sprintf(errmsg,
615 <                                                "need -bn to recover file '%s'",
616 <                                                        oname);
617 <                                        error(USER, errmsg);
618 <                                }
619 <                                recsiz = outvsiz;
620 <                        } else
621 <                                recsiz = outvsiz * sout.reclen;
602 >                        recsiz = outvsiz * sop->reclen;
603  
604 <                        lseek(fileno(sout.ofp), 0, SEEK_SET);
605 <                        if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) {
604 >                        lseek(fileno(sop->ofp), 0, SEEK_SET);
605 >                        if (header && checkheader(sop->ofp, outvfmt, NULL) != 1) {
606                                  sprintf(errmsg, "format mismatch for '%s'",
607                                                  oname);
608                                  error(USER, errmsg);
609                          }
610 <                        sout.xr = xres; sout.yr = yres;
611 <                        if ((sout.xr > 0) & (sout.yr > 0) &&
612 <                                        (!fscnresolu(&xr, &yr, sout.ofp) ||
613 <                                                (xr != sout.xr) |
633 <                                                (yr != sout.yr))) {
610 >                        if ((sop->reclen == 1) & (sop->xr > 0) & (sop->yr > 0) &&
611 >                                        (!fscnresolu(&xr, &yr, sop->ofp) ||
612 >                                                (xr != sop->xr) |
613 >                                                (yr != sop->yr))) {
614                                  sprintf(errmsg, "resolution mismatch for '%s'",
615                                                  oname);
616                                  error(USER, errmsg);
617                          }
618 <                        nvals = (nvals - (off_t)ftell(sout.ofp)) / recsiz;
618 >                        nvals = (nvals - (off_t)ftell(sop->ofp)) / recsiz;
619                          if ((lastout < 0) | (nvals < lastout))
620                                  lastout = nvals;
641                        if (oent->key == NULL)  /* new entry */
642                                oent->key = strcpy((char *)
643                                                malloc(strlen(oname)+1), oname);
644                        if (oent->data == NULL)
645                                oent->data = (char *)malloc(sizeof(STREAMOUT));
646                        *(STREAMOUT *)oent->data = sout;
621                          if (!(ofl & OF_BIN))
622                                  break;          /* no bin separation */
623                  }
624                  if (!lastout) {                 /* empty output */
625                          error(WARNING, "no previous data to recover");
626 <                        lu_done(&ofiletab);     /* reclose all outputs */
626 >                                                /* reclose all outputs */
627 >                        lu_doall(&ofiletab, &myclose, NULL);
628                          return;
629                  }
655                if (j > mp->nbins) {            /* check modifier size */
656                        sprintf(errmsg,
657                                "mismatched -bn setting for recovering '%s'",
658                                        modname[i]);
659                        error(USER, errmsg);
660                }
630          }
631          if (lastout < 0) {
632                  error(WARNING, "no output files to recover");
# Line 670 | Line 639 | recover_output()
639          }
640                                                  /* seek on all files */
641          nvals = lastout * outvsiz;
642 <        lu_doall(&ofiletab, myseeko, &nvals);
642 >        lu_doall(&ofiletab, &myseeko, &nvals);
643                                                  /* skip repeated input */
644          lastout *= accumulate;
645          for (nvals = 0; nvals < lastout; nvals++) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines