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.10 by greg, Fri May 30 16:05:52 2014 UTC vs.
Revision 2.25 by greg, Fri Apr 7 00:03:26 2023 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 <ctype.h>
13  
14   /* Close output stream and free record */
15   static void
# Line 115 | Line 116 | printheader(FILE *fout, const char *info)
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 139 | Line 142 | getostream(const char *ospec, const char *mname, int b
142          char                    oname[1024];
143          LUENT                   *lep;
144          STREAMOUT               *sop;
145 <        
145 >        char                    *cp;
146 >
147 >        info[0] = '\0';
148          if (ospec == NULL) {                    /* use stdout? */
149                  if (!noopen & !using_stdout) {
150                          if (outfmt != 'a')
151                                  SET_FILE_BINARY(stdout);
152 + #ifdef getc_unlocked
153 +                        flockfile(stdout);      /* avoid lock/unlock overhead */
154 + #endif
155                          if (header) {
156 <                                sprintf(info, "NCOLS=%d\nNCOMP=3\n",
157 <                                                stdos.reclen);
156 >                                cp = info;
157 >                                if (yres > 0) {
158 >                                        sprintf(cp, "NROWS=%d\n", yres *
159 >                                                        (xres + !xres) );
160 >                                        while (*cp) ++cp;
161 >                                }
162 >                                if ((xres <= 0) | (stdos.reclen > 1))
163 >                                        sprintf(cp, "NCOLS=%d\n", stdos.reclen);
164                                  printheader(stdout, info);
165                          }
166 <                        printresolu(stdout, xres, yres);
166 >                        if (stdos.reclen == 1)
167 >                                printresolu(stdout, xres, yres);
168                          if (waitflush > 0)
169                                  fflush(stdout);
170                          stdos.xr = xres; stdos.yr = yres;
156 #ifdef getc_unlocked
157                        flockfile(stdout);      /* avoid lock/unlock overhead */
158 #endif
171                          using_stdout = 1;
172                  }
173                  stdos.ofp = stdout;
# Line 175 | Line 187 | getostream(const char *ospec, const char *mname, int b
187                  sop = (STREAMOUT *)malloc(sizeof(STREAMOUT));
188                  if (sop == NULL)
189                          error(SYSTEM, "out of memory in getostream");
190 <                sop->outpipe = oname[0] == '!';
190 >                sop->outpipe = (oname[0] == '!');
191                  sop->reclen = 0;
192                  sop->ofp = NULL;                /* open iff noopen==0 */
193                  sop->xr = xres; sop->yr = yres;
# Line 185 | Line 197 | getostream(const char *ospec, const char *mname, int b
197                          errno = EEXIST;         /* file exists */
198                          goto openerr;
199                  }
200 +        } else if (noopen && outfmt == 'c' &&   /* stream exists to picture? */
201 +                        (sop->xr > 0) & (sop->yr > 0)) {
202 +                if (ofl & OF_BIN)
203 +                        return(NULL);           /* let caller offset bins */
204 +                sprintf(errmsg, "output '%s' not a valid picture", oname);
205 +                error(WARNING, errmsg);
206          }
207          if (!noopen && sop->ofp == NULL) {      /* open output stream */
208                  if (oname[0] == '!')            /* output to command */
# Line 198 | Line 216 | getostream(const char *ospec, const char *mname, int b
216   #ifdef getc_unlocked
217                  flockfile(sop->ofp);            /* avoid lock/unlock overhead */
218   #endif
219 +                if (accumulate > 0) {           /* global resolution */
220 +                        sop->xr = xres; sop->yr = yres;
221 +                }
222                  if (header) {
223 <                        char    *cp = info;
223 >                        cp = info;
224                          if (ofl & OF_MODIFIER || sop->reclen == 1) {
225                                  sprintf(cp, "MODIFIER=%s\n", mname);
226                                  while (*cp) ++cp;
# Line 208 | Line 229 | getostream(const char *ospec, const char *mname, int b
229                                  sprintf(cp, "BIN=%d\n", bn);
230                                  while (*cp) ++cp;
231                          }
232 <                        sprintf(cp, "NCOLS=%d\nNCOMP=3\n", sop->reclen);
232 >                        if (sop->yr > 0) {
233 >                                sprintf(cp, "NROWS=%d\n", sop->yr *
234 >                                                (sop->xr + !sop->xr) );
235 >                                while (*cp) ++cp;
236 >                        }
237 >                        if ((sop->xr <= 0) | (sop->reclen > 1))
238 >                                sprintf(cp, "NCOLS=%d\n", sop->reclen);
239                          printheader(sop->ofp, info);
240                  }
241 <                if (accumulate > 0) {           /* global resolution */
242 <                        sop->xr = xres; sop->yr = yres;
216 <                }
217 <                printresolu(sop->ofp, sop->xr, sop->yr);
241 >                if (sop->reclen == 1)
242 >                        printresolu(sop->ofp, sop->xr, sop->yr);
243                  if (waitflush > 0)
244                          fflush(sop->ofp);
245          }
# Line 246 | Line 271 | getvec(FVECT vec)
271                  }
272                  break;
273          case 'f':                                       /* binary float */
274 <                if (fread((char *)vf, sizeof(float), 3, stdin) != 3)
274 >                if (getbinary((char *)vf, sizeof(float), 3, stdin) != 3)
275                          return(-1);
276                  VCOPY(vec, vf);
277                  break;
278          case 'd':                                       /* binary double */
279 <                if (fread((char *)vd, sizeof(double), 3, stdin) != 3)
279 >                if (getbinary((char *)vd, sizeof(double), 3, stdin) != 3)
280                          return(-1);
281                  VCOPY(vec, vd);
282                  break;
# Line 287 | Line 312 | put_contrib(const DCOLOR cnt, FILE *fout)
312                          scalecolor(fv, sf);
313                  } else
314                          copycolor(fv, cnt);
315 <                fwrite(fv, sizeof(float), 3, fout);
315 >                putbinary(fv, sizeof(float), 3, fout);
316                  break;
317          case 'd':
318                  if (accumulate > 1) {
319                          DCOLOR  dv;
320                          copycolor(dv, cnt);
321                          scalecolor(dv, sf);
322 <                        fwrite(dv, sizeof(double), 3, fout);
322 >                        putbinary(dv, sizeof(double), 3, fout);
323                  } else
324 <                        fwrite(cnt, sizeof(double), 3, fout);
324 >                        putbinary(cnt, sizeof(double), 3, fout);
325                  break;
326          case 'c':
327                  if (accumulate > 1)
328                          setcolr(cv, sf*cnt[0], sf*cnt[1], sf*cnt[2]);
329                  else
330                          setcolr(cv, cnt[0], cnt[1], cnt[2]);
331 <                fwrite(cv, sizeof(cv), 1, fout);
331 >                putbinary(cv, sizeof(cv), 1, fout);
332                  break;
333          default:
334                  error(INTERNAL, "botched output format");
# Line 315 | Line 340 | put_contrib(const DCOLOR cnt, FILE *fout)
340   void
341   mod_output(MODCONT *mp)
342   {
343 <        STREAMOUT       *sop = getostream(mp->outspec, mp->modname, 0, 0);
343 >        STREAMOUT       *sop = getostream(mp->outspec, mp->modname, mp->bin0, 0);
344          int             j;
345  
346          put_contrib(mp->cbin[0], sop->ofp);
347          if (mp->nbins > 3 &&    /* minor optimization */
348 <                        sop == getostream(mp->outspec, mp->modname, 1, 0)) {
348 >                        sop == getostream(mp->outspec, mp->modname, mp->bin0+1, 0)) {
349                  for (j = 1; j < mp->nbins; j++)
350                          put_contrib(mp->cbin[j], sop->ofp);
351          } else {
352                  for (j = 1; j < mp->nbins; j++) {
353 <                        sop = getostream(mp->outspec, mp->modname, j, 0);
353 >                        sop = getostream(mp->outspec, mp->modname, mp->bin0+j, 0);
354                          put_contrib(mp->cbin[j], sop->ofp);
355                  }
356          }
# Line 378 | Line 403 | get_contrib(DCOLOR cnt, FILE *finp)
403          case 'a':
404                  return(fscanf(finp,"%lf %lf %lf",&cnt[0],&cnt[1],&cnt[2]) == 3);
405          case 'f':
406 <                if (fread(fv, sizeof(fv[0]), 3, finp) != 3)
406 >                if (getbinary(fv, sizeof(fv[0]), 3, finp) != 3)
407                          return(0);
408                  copycolor(cnt, fv);
409                  return(1);
410          case 'd':
411 <                return(fread(cnt, sizeof(cnt[0]), 3, finp) == 3);
411 >                return(getbinary(cnt, sizeof(cnt[0]), 3, finp) == 3);
412          case 'c':
413 <                if (fread(cv, sizeof(cv), 1, finp) != 1)
413 >                if (getbinary(cv, sizeof(cv), 1, finp) != 1)
414                          return(0);
415                  colr_color(fv, cv);
416                  copycolor(cnt, fv);
# Line 423 | Line 448 | reload_output()
448          char            *outvfmt;
449          LUENT           *oent;
450          int             xr, yr;
451 <        STREAMOUT       sout;
451 >        STREAMOUT       *sop;
452          DCOLOR          rgbv;
453  
454          if (outfmt == 'a')
# Line 436 | Line 461 | reload_output()
461                          error(USER, "cannot reload from stdout");
462                  if (mp->outspec[0] == '!')
463                          error(USER, "cannot reload from command");
464 <                for (j = 0; ; j++) {            /* load each modifier bin */
465 <                        ofl = ofname(oname, mp->outspec, mp->modname, j);
464 >                for (j = 0; j < mp->nbins; j++) { /* load each modifier bin */
465 >                        ofl = ofname(oname, mp->outspec, mp->modname, mp->bin0+j);
466                          if (ofl < 0)
467                                  error(USER, "bad output file specification");
468                          oent = lu_find(&ofiletab, oname);
469 <                        if (oent->data != NULL) {
470 <                                sout = *(STREAMOUT *)oent->data;
471 <                        } else {
472 <                                sout.reclen = 0;
473 <                                sout.outpipe = 0;
474 <                                sout.xr = xres; sout.yr = yres;
450 <                                sout.ofp = NULL;
451 <                        }
452 <                        if (sout.ofp == NULL) { /* open output as input */
453 <                                sout.ofp = fopen(oname, fmode);
454 <                                if (sout.ofp == NULL) {
455 <                                        if (j == mp->nbins)
456 <                                                break;  /* assume end of modifier */
469 >                        if (oent->data == NULL)
470 >                                error(INTERNAL, "unallocated stream in reload_output()");
471 >                        sop = (STREAMOUT *)oent->data;
472 >                        if (sop->ofp == NULL) { /* open output as input */
473 >                                sop->ofp = fopen(oname, fmode);
474 >                                if (sop->ofp == NULL) {
475                                          sprintf(errmsg, "missing reload file '%s'",
476                                                          oname);
477                                          error(WARNING, errmsg);
478                                          break;
479                                  }
480   #ifdef getc_unlocked
481 <                                flockfile(sout.ofp);
481 >                                flockfile(sop->ofp);
482   #endif
483 <                                if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) {
483 >                                if (header && checkheader(sop->ofp, outvfmt, NULL) != 1) {
484                                          sprintf(errmsg, "format mismatch for '%s'",
485                                                          oname);
486                                          error(USER, errmsg);
487                                  }
488 <                                if ((sout.xr > 0) & (sout.yr > 0) &&
489 <                                                (!fscnresolu(&xr, &yr, sout.ofp) ||
490 <                                                        (xr != sout.xr) |
491 <                                                        (yr != sout.yr))) {
488 >                                if ((sop->reclen == 1) & (sop->xr > 0) & (sop->yr > 0) &&
489 >                                                (!fscnresolu(&xr, &yr, sop->ofp) ||
490 >                                                        (xr != sop->xr) |
491 >                                                        (yr != sop->yr))) {
492                                          sprintf(errmsg, "resolution mismatch for '%s'",
493                                                          oname);
494                                          error(USER, errmsg);
495                                  }
496                          }
497                                                          /* read in RGB value */
498 <                        if (!get_contrib(rgbv, sout.ofp)) {
498 >                        if (!get_contrib(rgbv, sop->ofp)) {
499                                  if (!j) {
500 <                                        fclose(sout.ofp);
500 >                                        fclose(sop->ofp);
501                                          break;          /* ignore empty file */
502                                  }
503                                  if (j < mp->nbins) {
# Line 488 | Line 506 | reload_output()
506                                          error(USER, errmsg);
507                                  }
508                                  break;
509 <                        }
492 <                        if (j >= mp->nbins) {           /* check modifier size */
493 <                                sprintf(errmsg,
494 <                                "mismatched -bn setting for reloading '%s'",
495 <                                                modname[i]);
496 <                                error(USER, errmsg);
497 <                        }
498 <                                
509 >                        }                              
510                          copycolor(mp->cbin[j], rgbv);
500                        if (oent->key == NULL)          /* new file entry */
501                                oent->key = strcpy((char *)
502                                                malloc(strlen(oname)+1), oname);
503                        if (oent->data == NULL)
504                                oent->data = (char *)malloc(sizeof(STREAMOUT));
505                        *(STREAMOUT *)oent->data = sout;
511                  }
512          }
513          lu_doall(&ofiletab, &myclose, NULL);    /* close all files */
# Line 517 | Line 522 | myseeko(const LUENT *e, void *p)
522          off_t           nbytes = *(off_t *)p;
523          
524          if (sop->reclen > 1)
525 <                nbytes = nbytes * sop->reclen;
525 >                nbytes *= (off_t)sop->reclen;
526          if (fseeko(sop->ofp, nbytes, SEEK_CUR) < 0) {
527                  sprintf(errmsg, "seek error on file '%s'", e->key);
528                  error(SYSTEM, errmsg);
# Line 538 | Line 543 | recover_output()
543          int             ofl;
544          char            oname[1024];
545          LUENT           *oent;
546 <        STREAMOUT       sout;
546 >        STREAMOUT       *sop;
547          off_t           nvals;
548          int             xr, yr;
549  
# Line 567 | Line 572 | recover_output()
572                          error(USER, "cannot recover from stdout");
573                  if (mp->outspec[0] == '!')
574                          error(USER, "cannot recover from command");
575 <                for (j = 0; ; j++) {            /* check each bin's file */
576 <                        ofl = ofname(oname, mp->outspec, mp->modname, j);
575 >                for (j = 0; j < mp->nbins; j++) { /* check each bin's file */
576 >                        ofl = ofname(oname, mp->outspec, mp->modname, mp->bin0+j);
577                          if (ofl < 0)
578                                  error(USER, "bad output file specification");
579                          oent = lu_find(&ofiletab, oname);
580 <                        if (oent->data != NULL) {
581 <                                sout = *(STREAMOUT *)oent->data;
582 <                        } else {
583 <                                sout.reclen = 0;
579 <                                sout.outpipe = 0;
580 <                                sout.ofp = NULL;
581 <                        }
582 <                        if (sout.ofp != NULL) { /* already open? */
580 >                        if (oent->data == NULL)
581 >                                error(INTERNAL, "unallocated stream in recover_output()");
582 >                        sop = (STREAMOUT *)oent->data;
583 >                        if (sop->ofp != NULL) { /* already open? */
584                                  if (ofl & OF_BIN)
585                                          continue;
586                                  break;
587                          }
588                                                  /* open output */
589 <                        sout.ofp = fopen(oname, "rb+");
590 <                        if (sout.ofp == NULL) {
590 <                                if (j == mp->nbins)
591 <                                        break;  /* assume end of modifier */
589 >                        sop->ofp = fopen(oname, "rb+");
590 >                        if (sop->ofp == NULL) {
591                                  sprintf(errmsg, "missing recover file '%s'",
592                                                  oname);
593                                  error(WARNING, errmsg);
594 +                                lastout = 0;
595                                  break;
596                          }
597 <                        nvals = lseek(fileno(sout.ofp), 0, SEEK_END);
597 >                        nvals = lseek(fileno(sop->ofp), 0, SEEK_END);
598                          if (nvals <= 0) {
599                                  lastout = 0;    /* empty output, quit here */
600 <                                fclose(sout.ofp);
600 >                                fclose(sop->ofp);
601                                  break;
602                          }
603 <                        if (!sout.reclen) {
604 <                                if (!(ofl & OF_BIN)) {
605 <                                        sprintf(errmsg,
606 <                                                "need -bn to recover file '%s'",
607 <                                                        oname);
608 <                                        error(USER, errmsg);
609 <                                }
610 <                                recsiz = outvsiz;
611 <                        } else
612 <                                recsiz = outvsiz * sout.reclen;
603 >                        recsiz = outvsiz * sop->reclen;
604  
605 <                        lseek(fileno(sout.ofp), 0, SEEK_SET);
606 <                        if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) {
605 >                        lseek(fileno(sop->ofp), 0, SEEK_SET);
606 >                        if (header && checkheader(sop->ofp, outvfmt, NULL) != 1) {
607                                  sprintf(errmsg, "format mismatch for '%s'",
608                                                  oname);
609                                  error(USER, errmsg);
610                          }
611 <                        sout.xr = xres; sout.yr = yres;
612 <                        if ((sout.xr > 0) & (sout.yr > 0) &&
613 <                                        (!fscnresolu(&xr, &yr, sout.ofp) ||
614 <                                                (xr != sout.xr) |
624 <                                                (yr != sout.yr))) {
611 >                        if ((sop->reclen == 1) & (sop->xr > 0) & (sop->yr > 0) &&
612 >                                        (!fscnresolu(&xr, &yr, sop->ofp) ||
613 >                                                (xr != sop->xr) |
614 >                                                (yr != sop->yr))) {
615                                  sprintf(errmsg, "resolution mismatch for '%s'",
616                                                  oname);
617                                  error(USER, errmsg);
618                          }
619 <                        nvals = (nvals - (off_t)ftell(sout.ofp)) / recsiz;
619 >                        nvals = (nvals - (off_t)ftell(sop->ofp)) / recsiz;
620                          if ((lastout < 0) | (nvals < lastout))
621                                  lastout = nvals;
632                        if (oent->key == NULL)  /* new entry */
633                                oent->key = strcpy((char *)
634                                                malloc(strlen(oname)+1), oname);
635                        if (oent->data == NULL)
636                                oent->data = (char *)malloc(sizeof(STREAMOUT));
637                        *(STREAMOUT *)oent->data = sout;
622                          if (!(ofl & OF_BIN))
623                                  break;          /* no bin separation */
624                  }
625                  if (!lastout) {                 /* empty output */
626                          error(WARNING, "no previous data to recover");
627 <                        lu_done(&ofiletab);     /* reclose all outputs */
627 >                                                /* reclose all outputs */
628 >                        lu_doall(&ofiletab, &myclose, NULL);
629                          return;
645                }
646                if (j > mp->nbins) {            /* check modifier size */
647                        sprintf(errmsg,
648                                "mismatched -bn setting for recovering '%s'",
649                                        modname[i]);
650                        error(USER, errmsg);
630                  }
631          }
632          if (lastout < 0) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines