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

Comparing ray/src/rt/RpictSimulManager.cpp (file contents):
Revision 2.2 by greg, Sun Aug 18 00:37:13 2024 UTC vs.
Revision 2.5 by greg, Wed Aug 21 23:32:24 2024 UTC

# Line 359 | Line 359 | RpictSimulManager::RenderRect()
359          int             sp2 = ceil(log2((TWidth()>THeight() ? TWidth() : THeight()) - 1.));
360          int             layer = 0;
361          int             x, y;
362 < fprintf(stderr, "Rendering %dx%d tile with psample=%d, maxdiff=%.3f ...\n",
363 < TWidth(), THeight(), psample, maxdiff);
362 > // fprintf(stderr, "Rendering %dx%d tile with psample=%d, maxdiff=%.3f ...\n",
363 > // TWidth(), THeight(), psample, maxdiff);
364          while (sp2 > 0) {
365                  ABitMap2        sampMap(TWidth(), THeight());
366                  int             noff[4][2];
# Line 394 | Line 394 | TWidth(), THeight(), psample, maxdiff);
394                          if (!ComputePixel(x, y))
395                                  return false;
396                  doneSamples |= sampMap; // samples now done or at least queued
397 < fprintf(stderr, "Sampled %ld pixels at (sp2,layer)=(%d,%d)\n",
398 < (long)sampMap.SumTotal(), sp2, layer);
399 < fprintf(stderr, "\t%ld pixels (%.3f%%) completed (+%ld in process)\n",
400 < (long)doneMap.SumTotal(), 100.*doneMap.SumTotal()/doneMap.Width()/doneMap.Height(),
401 < (long)(doneSamples.SumTotal()-doneMap.SumTotal()));
397 > // fprintf(stderr, "Sampled %ld pixels at (sp2,layer)=(%d,%d)\n",
398 > // (long)sampMap.SumTotal(), sp2, layer);
399 > // fprintf(stderr, "\t%ld pixels (%.3f%%) completed (+%ld in process)\n",
400 > // (long)doneMap.SumTotal(), 100.*doneMap.SumTotal()/doneMap.Width()/doneMap.Height(),
401 > // (long)(doneSamples.SumTotal()-doneMap.SumTotal()));
402                  sp2 -= layer++ & 1;     // next denser sampling
403          }
404          if (FlushQueue() < 0)           // make sure we got everyone
# Line 471 | Line 471 | RpictSimulManager::RenderTile(COLRV *bp, int ystride,
471          return SetTile(tile) && RenderRect();
472   }
473  
474 + // Back to float color with 16-bit depth
475 + bool
476 + RpictSimulManager::RenderTile(COLORV *rp, int ystride, short *dp, const int *tile)
477 + {
478 +        if (!rp | (GetWidth() <= 0) | (GetHeight() <= 0) | !vw.type)
479 +                return false;
480 +        if (!ystride)                   // contiguous rows?
481 +                ystride = TWidth();
482 +        pacc.Init(rp, ystride, dp);
483 +        if (prims == xyzprims)
484 +                pacc.SetColorSpace(RDTxyz);
485 +        else if (prims)
486 +                pacc.SetColorSpace(RDTrgb, prims);
487 +
488 +        return SetTile(tile) && RenderRect();
489 + }
490 +
491   // Allocate a new render bar
492   void
493   RpictSimulManager::NewBar(int ht)
# Line 501 | Line 518 | RpictSimulManager::NewBar(int ht)
518  
519   // Shift render bar area the specified amount down the frame
520   bool
521 < RpictSimulManager::LowerBar(int v)
521 > RpictSimulManager::LowerBar(int v, int ytop)
522   {
506        if (v <= 0) return !v;
523          if (!barPix | !barDepth | (v > THeight()) | !tvw.type)
524                  return false;
525 +        if (v <= 0) return !v;
526 +        if ((ytop -= v) <= 0)
527 +                return true;
528          tvw.voff -= double(v)/THeight();
529          ptvw.voff -= double(v)/THeight();
530          if (v == THeight()) {
# Line 518 | Line 537 | RpictSimulManager::LowerBar(int v)
537                          sizeof(COLORV)*NC*TWidth()*(THeight()-v));
538          memmove(barDepth, barDepth + TWidth()*v,
539                          sizeof(float)*TWidth()*(THeight()-v));
540 +        if (ytop < THeight()) {                 // mark what we won't do as finished
541 +                doneMap.ClearRect(0, 0, TWidth(), THeight()-ytop, true);
542 +                memset(barPix, 0, sizeof(COLORV)*NC*TWidth()*(THeight()-ytop));
543 +                memset(barDepth, 0, sizeof(float)*TWidth()*(THeight()-ytop));
544 +        }
545          return true;
546   }
547  
# Line 559 | Line 583 | RpictSimulManager::RenderBelow(int ytop, const int vst
583          }
584          int             lastOut = ytop;         // render down frame
585          while (ytop > 0) {
586 < fprintf(stderr, "At y=%d, source drawing %s...\n", ytop, parr ? "ON" : "OFF");
563 <                if (ytop < THeight())           // mark what we won't do as finished
564 <                        doneMap.ClearRect(0, 0, TWidth(), THeight()-ytop, true);
586 > // fprintf(stderr, "At y=%d, source drawing %s...\n", ytop, parr ? "ON" : "OFF");
587                  if (prCB)
588                          (*prCB)(100.*(GetHeight()-ytop)/GetHeight());
589                  if (!RenderRect())              // render this bar
# Line 612 | Line 634 | fprintf(stderr, "At y=%d, source drawing %s...\n", yto
634                  if (fflush(pfp) == EOF || (dfp && fflush(dfp) == EOF))
635                          error(SYSTEM, "output write error");
636                                                  // advance down the frame
637 <                if (lastOut > 0 && !LowerBar(vstep))
637 >                if (lastOut > 0 && !LowerBar(vstep, ytop))
638                          return false;
639                  ytop -= vstep;
640          }
# Line 623 | Line 645 | fprintf(stderr, "At y=%d, source drawing %s...\n", yto
645          return true;
646   }
647  
648 < /*
627 < * Render and write a frame to the named file
628 < * Include any header lines set prior to call
629 < * Picture file must not already exist
630 < * Write pixels to stdout if !pfname
631 < * Write depth to a command if dfname[0]=='!'
632 < */
648 > // Open new output picture file (and optional depth file)
649   RenderDataType
650 < RpictSimulManager::RenderFrame(const char *pfname, RenderDataType dt, const char *dfname)
650 > RpictSimulManager::NewOutput(FILE *pdfp[2], const char *pfname,
651 >                                RenderDataType dt, const char *dfname)
652   {
653 <        int     fd = 1;
637 <        FILE *  pfp = NULL;
638 <        FILE *  dfp = NULL;
639 <
653 >        pdfp[0] = pdfp[1] = NULL;
654          if (!RDTcolorT(dt))
655 <                error(INTERNAL, "botched color output type in RenderFrame()");
655 >                error(INTERNAL, "botched color output type in NewOutput()");
656          if (NCSAMP == 3) {
657                  if (RDTcolorT(dt) == RDTscolr)
658                          dt = RDTnewCT(dt, prims==xyzprims ? RDTxyze : RDTrgbe);
# Line 646 | Line 660 | RpictSimulManager::RenderFrame(const char *pfname, Ren
660                          dt = RDTnewCT(dt, prims==xyzprims ? RDTxyz : RDTrgb);
661          }
662          if (!RDTdepthT(dt) ^ !dfname)
663 <                error(INTERNAL, "depth output requires file name and type in RenderFrame()");
663 >                error(INTERNAL, "depth output requires file name and type in NewOutput()");
664 >        int     fd = 1;
665          if (pfname) {                           // open picture output file
666                  if (pfname[0] == '!') {
667                          error(INTERNAL, "writing picture to a command not supported");
# Line 662 | Line 677 | RpictSimulManager::RenderFrame(const char *pfname, Ren
677                  return RDTnone;                 // expected in parallel sequence
678          }
679          if (fd == 1)
680 <                pfp = stdout;
681 <        else if (!(pfp = fdopen(fd, "w")))
680 >                pdfp[0] = stdout;
681 >        else if (!(pdfp[0] = fdopen(fd, "w")))
682                  error(SYSTEM, "failure calling fdopen()");
683 <        SET_FILE_BINARY(pfp);                   // write picture header
684 <        if ((pfp != stdout) | (frameNo <= 1)) {
685 <                newheader("RADIANCE", pfp);
686 <                fputs(GetHeader(), pfp);
683 >        SET_FILE_BINARY(pdfp[0]);               // write picture header
684 >        if ((pdfp[0] != stdout) | (frameNo <= 1)) {
685 >                newheader("RADIANCE", pdfp[0]);
686 >                fputs(GetHeader(), pdfp[0]);
687          }
688 <        fputs(VIEWSTR, pfp); fprintview(&vw, pfp); fputc('\n', pfp);
688 >        fputs(VIEWSTR, pdfp[0]); fprintview(&vw, pdfp[0]); fputc('\n', pdfp[0]);
689          if (frameNo > 0)
690 <                fprintf(pfp, "FRAME=%d\n", frameNo);
690 >                fprintf(pdfp[0], "FRAME=%d\n", frameNo);
691          double  pasp = viewaspect(&vw) * GetWidth() / GetHeight();
692          if ((0.99 > pasp) | (pasp > 1.01))
693 <                fputaspect(pasp, pfp);
694 <        fputnow(pfp);
693 >                fputaspect(pasp, pdfp[0]);
694 >        fputnow(pdfp[0]);
695          switch (RDTcolorT(dt)) {                // set primaries and picture format
696          case RDTrgbe:
697                  if (!prims | (prims == xyzprims)) prims = stdprims;
698 <                fputprims(prims, pfp);
699 <                fputformat(COLRFMT, pfp);
698 >                fputprims(prims, pdfp[0]);
699 >                fputformat(COLRFMT, pdfp[0]);
700                  break;
701          case RDTxyze:
702                  prims = xyzprims;
703 <                fputformat(CIEFMT, pfp);
703 >                fputformat(CIEFMT, pdfp[0]);
704                  break;
705          case RDTscolr:
706                  prims = NULL;
707 <                fputwlsplit(WLPART, pfp);
708 <                fputncomp(NCSAMP, pfp);
709 <                fputformat(SPECFMT, pfp);
707 >                fputwlsplit(WLPART, pdfp[0]);
708 >                fputncomp(NCSAMP, pdfp[0]);
709 >                fputformat(SPECFMT, pdfp[0]);
710                  break;
711          case RDTrgb:
712                  if (!prims | (prims == xyzprims)) prims = stdprims;
713 <                fputprims(prims, pfp);
714 <                fputncomp(3, pfp);
715 <                fputendian(pfp);
716 <                fputformat("float", pfp);
713 >                fputprims(prims, pdfp[0]);
714 >                fputncomp(3, pdfp[0]);
715 >                fputendian(pdfp[0]);
716 >                fputformat("float", pdfp[0]);
717                  break;
718          case RDTxyz:
719                  prims = xyzprims;
720 <                fputprims(prims, pfp);
721 <                fputncomp(3, pfp);
722 <                fputendian(pfp);
723 <                fputformat("float", pfp);
720 >                fputprims(prims, pdfp[0]);
721 >                fputncomp(3, pdfp[0]);
722 >                fputendian(pdfp[0]);
723 >                fputformat("float", pdfp[0]);
724                  break;
725          case RDTscolor:
726                  prims = NULL;
727 <                fputwlsplit(WLPART, pfp);
728 <                fputncomp(NCSAMP, pfp);
729 <                fputendian(pfp);
730 <                fputformat("float", pfp);
727 >                fputwlsplit(WLPART, pdfp[0]);
728 >                fputncomp(NCSAMP, pdfp[0]);
729 >                fputendian(pdfp[0]);
730 >                fputformat("float", pdfp[0]);
731                  break;
732          default:;
733          }
734 <        fputc('\n', pfp);                       // end picture header
735 <        fprtresolu(GetWidth(), GetHeight(), pfp);
734 >        fputc('\n', pdfp[0]);                   // flush picture header + resolution
735 >        fprtresolu(GetWidth(), GetHeight(), pdfp[0]);
736 >        if (fflush(pdfp[0]) == EOF) {
737 >                sprintf(errmsg, "cannot write header to picture '%s'", pfname);
738 >                error(SYSTEM, errmsg);
739 >                fclose(pdfp[0]);
740 >                pdfp[0] = NULL;
741 >                return RDTnone;
742 >        }
743          if (dfname) {
744                  if (dfname[0] == '!')
745 <                        dfp = popen(dfname+1, "w");
745 >                        pdfp[1] = popen(dfname+1, "w");
746                  else
747 <                        dfp = fopen(dfname, "w");
748 <                if (!dfp) {
747 >                        pdfp[1] = fopen(dfname, "w");
748 >                if (!pdfp[1]) {
749                          sprintf(errmsg, "cannot open depth output '%s'", dfname);
750                          error(SYSTEM, errmsg);
751 +                        fclose(pdfp[0]);
752 +                        pdfp[0] = NULL;
753                          return RDTnone;
754                  }
755 <                SET_FILE_BINARY(dfp);
755 >                SET_FILE_BINARY(pdfp[1]);
756          }
757          if (RDTdepthT(dt) == RDTdshort) {       // write header for 16-bit depth?
758 <                newheader("RADIANCE", dfp);
759 <                fputs(GetHeader(), dfp);
760 <                fputs(VIEWSTR, dfp); fprintview(&vw, dfp); fputc('\n', dfp);
761 <                fputs(DEPTHSTR, dfp); fputs(dunit, dfp); fputc('\n', dfp);
762 <                fputformat(DEPTH16FMT, dfp);
763 <                fputc('\n', dfp);               // end-of-info
764 <                fprtresolu(GetWidth(), GetHeight(), dfp);
758 >                newheader("RADIANCE", pdfp[1]);
759 >                fputs(GetHeader(), pdfp[1]);
760 >                fputs(VIEWSTR, pdfp[1]); fprintview(&vw, pdfp[1]); fputc('\n', pdfp[1]);
761 >                fputs(DEPTHSTR, pdfp[1]); fputs(dunit, pdfp[1]); fputc('\n', pdfp[1]);
762 >                fputformat(DEPTH16FMT, pdfp[1]);
763 >                fputc('\n', pdfp[1]);           // end-of-info
764 >                fprtresolu(GetWidth(), GetHeight(), pdfp[1]);
765 >                if (fflush(pdfp[1]) == EOF) {
766 >                        sprintf(errmsg, "cannot write header to '%s'", dfname);
767 >                        error(SYSTEM, errmsg);
768 >                        fclose(pdfp[0]); fclose(pdfp[1]);
769 >                        pdfp[0] = pdfp[1] = NULL;
770 >                        return RDTnone;
771 >                }
772          }
773 +        return dt;                              // ready to roll
774 + }
775 +
776 + /*
777 + * Render and write a frame to the named file
778 + * Include any header lines set prior to call
779 + * Picture file must not exist
780 + * Write pixels to stdout if !pfname
781 + * Write depth to a command if dfname[0]=='!'
782 + */
783 + RenderDataType
784 + RpictSimulManager::RenderFrame(const char *pfname, RenderDataType dt, const char *dfname)
785 + {
786 +        FILE    *pdfp[2];
787 +                                                // prepare output file(s)
788 +        dt = NewOutput(pdfp, pfname, dt, dfname);
789 +        if (dt == RDTnone)
790 +                return RDTnone;
791 +
792          const int       bheight = (psample > 1) ? int(2*psample+.99) : 4;
793          const int       vstep =  bheight >> (psample > 1);
794  
795          NewBar(bheight);                        // render frame if we can
796 <        if (!RenderBelow(GetHeight(), vstep, pfp, dt, dfp)) {
797 <                fclose(pfp);
798 <                if (dfp) (dfname[0] == '!') ? pclose(dfp) : fclose(dfp);
796 >        if (!RenderBelow(GetHeight(), vstep, pdfp[0], dt, pdfp[1])) {
797 >                fclose(pdfp[0]);
798 >                if (pdfp[1]) (dfname[0] == '!') ? pclose(pdfp[1]) : fclose(pdfp[1]);
799                  Cleanup();
800                  return RDTnone;
801          }
802          NewBar();                               // clean up and return
803 <        if (pfp != stdout)
804 <                fclose(pfp);
805 <        if (dfp) {
803 >        if (pdfp[0] != stdout)
804 >                fclose(pdfp[0]);
805 >        if (pdfp[1]) {
806                  if (dfname[0] == '!') {
807 <                        int     status = pclose(dfp);
807 >                        int     status = pclose(pdfp[1]);
808                          if (status) {
809                                  sprintf(errmsg, "depth output (%s) error status: %d",
810                                                  dfname, status);
# Line 762 | Line 812 | RpictSimulManager::RenderFrame(const char *pfname, Ren
812                                  return RDTnone;
813                          }
814                  } else
815 <                        fclose(dfp);
815 >                        fclose(pdfp[1]);
816          }
817          return dt;
818   }
819  
820   // passed struct for header line callback
821 < struct HeaderInfo {
821 > static struct HeaderInfo {
822          char            fmt[MAXFMTLEN];
823          char            depth_unit[32];
824          int             ncomp;
# Line 789 | Line 839 | struct HeaderInfo {
839                                  gotview = false;
840                                  endianMatch = true;
841                          }
842 < };
842 > }       hinfo;          // XXX single copy to hold custom primitives
843  
844   // helper function checks header line and records req. info.
845   static int
# Line 831 | Line 881 | head_check(char *s, void *p)
881          return 0;
882   }
883  
884 < // Resume partially finished rendering
835 < // Picture file must exist
884 > // Reopen output file(s), leaving pointers at end of (each) header
885   RenderDataType
886 < RpictSimulManager::ResumeFrame(const char *pfname, const char *dfname)
886 > RpictSimulManager::ReopenOutput(FILE *pdfp[2], const char *pfname, const char *dfname)
887   {
888 <        if (!pfname || pfname[0] == '!')
840 <                return RDTnone;
888 >        extern const char       HDRSTR[];
889  
890 +        if (!pfname || pfname[0] == '!') {
891 +                pdfp[0] = pdfp[1] = NULL;
892 +                return RDTnone;
893 +        }
894          RenderDataType  dt = RDTnone;
895 <        FILE *          dfp = NULL;
896 <        FILE *          pfp = fopen(pfname, "r+");
897 <        if (!pfp) {
895 >        pdfp[1] = NULL;
896 >        pdfp[0] = fopen(pfname, "r+");
897 >        if (!pdfp[0]) {
898                  sprintf(errmsg, "cannot reopen output picture '%s'", pfname);
899                  error(SYSTEM, errmsg);
900                  return RDTnone;
901          }
902 <        SET_FILE_BINARY(pfp);
903 <        HeaderInfo      hinfo;          // read header information & dimensions
904 <        RESOLU          res;
905 <        if (getheader(pfp, head_check, &hinfo) < 0) {
854 <                fclose(pfp);
902 >        SET_FILE_BINARY(pdfp[0]);       // read header information
903 >        if (getheader(pdfp[0], head_check, &hinfo) < 0) {
904 >                fclose(pdfp[0]);
905 >                pdfp[0] = NULL;
906                  return RDTnone;
907          }
857        if (!fgetsresolu(&res, pfp) || res.rt != PIXSTANDARD) {
858                sprintf(errmsg, "missing/bad resolution for '%s'", pfname);
859                error(USER, errmsg);
860                fclose(pfp);
861                return RDTnone;
862        }
908          if (!hinfo.gotview) {
909                  sprintf(errmsg, "missing view for '%s'", pfname);
910                  error(USER, errmsg);
911 <                fclose(pfp);
911 >                fclose(pdfp[0]);
912 >                pdfp[0] = NULL;
913                  return RDTnone;
914          }
915          if (hinfo.ncomp < 3) {
916                  sprintf(errmsg, "bad # components (%d) in '%s'", hinfo.ncomp, pfname);
917                  error(USER, errmsg);
918 <                fclose(pfp);
918 >                fclose(pdfp[0]);
919 >                pdfp[0] = NULL;
920                  return RDTnone;
921          }
922 <        int     bytesPer = 0;           // complicated part to set rendering/output space
922 >                                        // set rendering/output space
923          if (!strcmp(hinfo.fmt, COLRFMT)) {
924 <                prims = hinfo.prims;
924 >                prims = hinfo.prims;    // XXX static array
925                  int     n = 8*hinfo.gotprims;
926                  while (n--)
927                          if (!FABSEQ(hinfo.prims[0][n], stdprims[0][n]))
# Line 890 | Line 937 | RpictSimulManager::ResumeFrame(const char *pfname, con
937                          sprintf(errmsg, "incompatible sample count (%d) in '%s'",
938                                          hinfo.ncomp, pfname);
939                          error(USER, errmsg);
940 <                        fclose(pfp);
940 >                        fclose(pdfp[0]);
941 >                        pdfp[0] = NULL;
942                          return RDTnone;
943                  }
944 <                NCSAMP = hinfo.ncomp;   // overrides global setting
944 >                NCSAMP = hinfo.ncomp;           // overrides global setting
945                  prims = NULL;
946                  dt = RDTnewCT(dt, RDTscolr);
899                bytesPer = hinfo.ncomp + 1;     // XXX assumes no compression
947          } else if (!strcmp(hinfo.fmt, "float")) {
948                  if (!hinfo.endianMatch) {
949                          sprintf(errmsg, "incompatible byte ordering in '%s'", pfname);
950                          error(USER, errmsg);
951 <                        fclose(pfp);
951 >                        fclose(pdfp[0]);
952 >                        pdfp[0] = NULL;
953                          return RDTnone;
954                  }
955                  if (hinfo.ncomp == 3) {
956 <                        prims = hinfo.prims;            // custom primaries?
956 >                        prims = hinfo.prims;    // custom primaries?
957                          int     n = 8*hinfo.gotprims;
958                          while (n--)
959                                  if (!FABSEQ(hinfo.prims[0][n], stdprims[0][n]))
960                                          break;
961 <                        if (n < 0)                      // standard primaries?
961 >                        if (n < 0)              // standard primaries?
962                                  prims = stdprims;
963                          else if (hinfo.gotprims) {      // or check if XYZ
964                                  for (n = 8; n--; )
# Line 928 | Line 976 | RpictSimulManager::ResumeFrame(const char *pfname, con
976                          prims = NULL;
977                          dt = RDTnewCT(dt, RDTscolor);
978                  }
931                bytesPer = sizeof(float)*hinfo.ncomp;
979          } else {
980                  sprintf(errmsg, "unknown format (%s) for '%s'", hinfo.fmt, pfname);
981                  error(USER, errmsg);
982 <                fclose(pfp);
982 >                fclose(pdfp[0]);
983 >                pdfp[0] = NULL;
984                  return RDTnone;
985          }
986 +        if (!dfname)                            // no depth file?
987 +                return dt;
988 +
989 +        if (dfname[0] == '!') {
990 +                error(USER, "depth data cannot be reloaded from command");
991 +                fclose(pdfp[0]);
992 +                pdfp[0] = NULL;
993 +                return RDTnone;
994 +        }
995 +        pdfp[1] = fopen(dfname, "r+");
996 +        if (!pdfp[1]) {
997 +                sprintf(errmsg, "cannot reopen depth file '%s'", dfname);
998 +                error(SYSTEM, errmsg);
999 +                fclose(pdfp[0]);
1000 +                pdfp[0] = NULL;
1001 +                return RDTnone;
1002 +        }
1003 +        SET_FILE_BINARY(pdfp[1]);
1004 +        int     n, len = strlen(HDRSTR);
1005 +        char    buf[32];                // sniff for 16-bit header
1006 +        if (read(fileno(pdfp[1]), buf, len+1) < len+1) {
1007 +                sprintf(errmsg, "empty depth file '%s'", dfname);
1008 +                error(SYSTEM, errmsg);
1009 +                fclose(pdfp[0]); fclose(pdfp[1]);
1010 +                pdfp[0] = pdfp[1] = NULL;
1011 +                return RDTnone;
1012 +        }
1013 +        for (n = 0; n < len; n++)
1014 +                if (buf[n] != HDRSTR[n])
1015 +                        break;          // not a Radiance header
1016 +        lseek(fileno(pdfp[1]), 0, SEEK_SET);
1017 +        if ((n < len) | !isprint(buf[len]))
1018 +                return RDTnewDT(dt, RDTdfloat);
1019 +
1020 +        HeaderInfo      dinfo;          // thinking it's 16-bit encoded
1021 +        if (getheader(pdfp[1], head_check, &dinfo) < 0)
1022 +                sprintf(errmsg, "bad header in encoded depth file '%s'",
1023 +                                dfname);
1024 +        else if (strcmp(dinfo.fmt, DEPTH16FMT))
1025 +                sprintf(errmsg, "wrong format (%s) for depth file '%s'",
1026 +                                dinfo.fmt, dfname);
1027 +        else if (!SetReferenceDepth(dinfo.depth_unit))
1028 +                sprintf(errmsg, "bad/missing reference depth (%s) in '%s'",
1029 +                                dinfo.depth_unit, dfname);
1030 +        else
1031 +                errmsg[0] = '\0';
1032 +
1033 +        if (errmsg[0]) {
1034 +                error(USER, errmsg);
1035 +                fclose(pdfp[1]); fclose(pdfp[0]);
1036 +                pdfp[0] = pdfp[1] = NULL;
1037 +                return RDTnone;
1038 +        }
1039 +        return RDTnewDT(dt, RDTdshort);
1040 + }
1041 +
1042 + // Resume partially finished rendering
1043 + // Picture file must exist
1044 + RenderDataType
1045 + RpictSimulManager::ResumeFrame(const char *pfname, const char *dfname)
1046 + {
1047 +        FILE            *pdfp[2];
1048 +
1049 +        RenderDataType  dt = ReopenOutput(pdfp, pfname, dfname);
1050 +        if (dt == RDTnone)
1051 +                return RDTnone;
1052 +
1053 +        int     bytesPer = 0;           // figure out how far we got...
1054 +        switch (RDTcolorT(dt)) {
1055 +        case RDTrgbe:
1056 +        case RDTxyze:
1057 +                break;
1058 +        case RDTscolr:
1059 +                bytesPer = hinfo.ncomp + 1;     // XXX assumes no compression
1060 +                break;
1061 +        case RDTrgb:
1062 +        case RDTxyz:
1063 +                bytesPer = sizeof(float)*3;
1064 +                break;
1065 +        case RDTscolor:
1066 +                bytesPer = sizeof(float)*hinfo.ncomp;
1067 +                break;
1068 +        default:
1069 +                sprintf(errmsg, "unknown format (%s) for '%s'", hinfo.fmt, pfname);
1070 +                error(USER, errmsg);
1071 +                fclose(pdfp[0]);
1072 +                if (pdfp[1]) fclose(pdfp[1]);
1073 +                return RDTnone;
1074 +        }
1075 +        RESOLU  res;
1076 +        if (!fgetsresolu(&res, pdfp[0]) || res.rt != PIXSTANDARD) {
1077 +                sprintf(errmsg, "missing/bad resolution for '%s'", pfname);
1078 +                error(USER, errmsg);
1079 +                fclose(pdfp[0]);
1080 +                if (pdfp[1]) fclose(pdfp[1]);
1081 +                return RDTnone;
1082 +        }
1083          vw.type = 0;                            // set up new (unreferenced) frame
1084          frameNo = 0;
1085          int     hvdim[2] = {res.xr, res.yr};
1086          double  noAdj = 0;
1087          if (!NewFrame(hinfo.vw, hvdim, &noAdj) ||
1088                          (hvdim[0] != res.xr) | (hvdim[1] != res.yr)) {
1089 <                fclose(pfp);
1089 >                error(CONSISTENCY, "unexpected resolution change in ResumeFrame()");
1090 >                fclose(pdfp[0]);
1091 >                if (pdfp[1]) fclose(pdfp[1]);
1092                  return RDTnone;
1093          }
1094 <        long    dataStart = ftell(pfp);         // picture starting point
1094 >        long    dataStart = ftell(pdfp[0]);     // picture starting point
1095          if (dataStart < 0) {
1096                  sprintf(errmsg, "cannot seek on '%s'", pfname);
1097                  error(SYSTEM, errmsg);
1098 <                fclose(pfp);
1098 >                fclose(pdfp[0]);
1099 >                if (pdfp[1]) fclose(pdfp[1]);
1100                  return RDTnone;
1101          }
1102          long    doneScans = 0;
1103          if (bytesPer) {                         // fixed-width records?
1104 <                fseek(pfp, 0, SEEK_END);
1105 <                long    dataEnd = ftell(pfp);
1104 >                fseek(pdfp[0], 0, SEEK_END);
1105 >                long    dataEnd = ftell(pdfp[0]);
1106                  doneScans = (dataEnd - dataStart)/(bytesPer*GetWidth());
1107                  if (dataEnd-dataStart > bytesPer*GetWidth()*doneScans)
1108 <                        fseek(pfp, dataStart + bytesPer*GetWidth()*doneScans, SEEK_SET);
1108 >                        fseek(pdfp[0], dataStart + bytesPer*GetWidth()*doneScans, SEEK_SET);
1109          } else {                                // else get compressed scanlines
1110                  COLR *  scan = (COLR *)tempbuffer(sizeof(COLR)*GetWidth());
1111 <                while (freadcolrs(scan, GetWidth(), pfp) >= 0)
1111 >                while (freadcolrs(scan, GetWidth(), pdfp[0]) >= 0)
1112                          ++doneScans;
1113 <                if (!feof(pfp)) {
1113 >                if (!feof(pdfp[0])) {
1114                          sprintf(errmsg, "error reading compressed scanline from '%s'", pfname);
1115                          error(USER, errmsg);
1116 <                        fclose(pfp);
1116 >                        fclose(pdfp[0]);
1117 >                        if (pdfp[1]) fclose(pdfp[1]);
1118                          return RDTnone;
1119                  }
1120          }
1121          if (doneScans >= GetHeight()) {         // nothing left to do?
1122                  sprintf(errmsg, "output file '%s' is already complete", pfname);
1123                  error(WARNING, errmsg);
1124 <                fclose(pfp);
1124 >                fclose(pdfp[0]);
1125 >                if (pdfp[1]) fclose(pdfp[1]);
1126                  return dt;
1127          }
1128          if (!doneScans) {
1129                  sprintf(errmsg, "restarting empty frame '%s'", pfname);
1130                  error(WARNING, errmsg);
1131          }
1132 <        if (dfname) {                           // append depth file, too?
1133 <                if (dfname[0] == '!') {
1134 <                        error(USER, "depth data cannot be reloaded from command");
1135 <                        fclose(pfp);
1132 >        long    toSkip = 0;
1133 >        switch (RDTdepthT(dt)) {                        // append depth file, too?
1134 >        case RDTdfloat:
1135 >                toSkip = sizeof(float)*GetWidth()*doneScans;
1136 >                break;
1137 >        case RDTdshort:
1138 >                if (!fgetsresolu(&res, pdfp[1]) || (res.rt != PIXSTANDARD) |
1139 >                                (res.xr != GetWidth()) | (res.yr != GetHeight())) {
1140 >                        sprintf(errmsg, "missing/bad resolution for '%s'", dfname);
1141 >                        error(USER, errmsg);
1142 >                        fclose(pdfp[0]); fclose(pdfp[0]);
1143                          return RDTnone;
1144                  }
1145 <                dfp = fopen(dfname, "a");
1146 <                if (!dfp) {
1147 <                        sprintf(errmsg, "cannot reopen depth file '%s'", dfname);
991 <                        error(SYSTEM, errmsg);
992 <                        fclose(pfp);
993 <                        return RDTnone;
994 <                }
995 <                SET_FILE_BINARY(dfp);
996 <                const long      dflen = ftell(dfp);
997 <                if (dflen != sizeof(float)*GetWidth()*doneScans) {
998 <                        fclose(dfp);
999 <                        dfp = fopen(dfname, "r+");
1000 <                        if (!dfp) return RDTnone;       // WTH?
1001 <                        SET_FILE_BINARY(dfp);
1002 <                }
1003 <                if (dflen < sizeof(float)*GetWidth()*doneScans) {
1004 <                        HeaderInfo      dinfo;
1005 <                        if (getheader(dfp, head_check, &dinfo) < 0)
1006 <                                sprintf(errmsg, "bad header in encoded depth file '%s'",
1007 <                                                dfname);
1008 <                        else if (strcmp(dinfo.fmt, DEPTH16FMT))
1009 <                                sprintf(errmsg, "wrong format (%s) for depth file '%s'",
1010 <                                                dinfo.fmt, dfname);
1011 <                        else if (!SetReferenceDepth(dinfo.depth_unit))
1012 <                                sprintf(errmsg, "bad/missing reference depth (%s) in '%s'",
1013 <                                                dinfo.depth_unit, dfname);
1014 <                        else if (!fscnresolu(hvdim, hvdim+1, dfp) ||
1015 <                                        (hvdim[0] != GetWidth()) | (hvdim[1] != GetHeight()))
1016 <                                sprintf(errmsg, "bad/mismatched resolution in '%s'",
1017 <                                                dfname);
1018 <                        else
1019 <                                errmsg[0] = '\0';
1020 <
1021 <                        if (errmsg[0]) {
1022 <                                error(USER, errmsg);
1023 <                                fclose(dfp);
1024 <                                fclose(pfp);
1025 <                                return RDTnone;
1026 <                        }
1027 <                        const long      dStart = ftell(dfp);
1028 <                        if (dflen-dStart < 2*GetWidth()*doneScans) {
1029 <                                sprintf(errmsg, "missing %ld depths in '%s'",
1030 <                                        (long)GetWidth()*doneScans - (dflen-dStart)/2,
1031 <                                        dfname);
1032 <                                error(WARNING, errmsg);
1033 <                        }
1034 <                        fseek(dfp, dStart + 2*GetWidth()*doneScans, SEEK_SET);
1035 <                        dt = RDTnewDT(dt, RDTdshort);
1036 <                } else {
1037 <                        if (dflen > sizeof(float)*GetWidth()*doneScans)
1038 <                                fseek(dfp, sizeof(float)*GetWidth()*doneScans, SEEK_SET);
1039 <                        dt = RDTnewDT(dt, RDTdfloat);
1040 <                }
1145 >                toSkip = 2L*GetWidth()*doneScans;
1146 >                break;
1147 >        default:;
1148          }
1149 +        if (toSkip && fseek(pdfp[1], toSkip, SEEK_CUR) < 0) {
1150 +                sprintf(errmsg, "cannot seek on depth file '%s'", dfname);
1151 +                error(SYSTEM, errmsg);
1152 +                fclose(pdfp[0]); fclose(pdfp[1]);
1153 +                return RDTnone;
1154 +        }
1155          int     bheight = (psample > 1) ? int(2*psample+.99) : 4;
1156          if (bheight > GetHeight()-doneScans)
1157                  bheight = GetHeight()-doneScans;
# Line 1046 | Line 1159 | RpictSimulManager::ResumeFrame(const char *pfname, con
1159          vstep += !vstep;
1160  
1161          NewBar(bheight);                        // render remainder if we can
1162 <        if (!RenderBelow(GetHeight()-doneScans, vstep, pfp, dt, dfp)) {
1163 <                fclose(pfp);
1164 <                if (dfp) fclose(dfp);
1162 >        if (!RenderBelow(GetHeight()-doneScans, vstep, pdfp[0], dt, pdfp[1])) {
1163 >                fclose(pdfp[0]);
1164 >                if (pdfp[1]) fclose(pdfp[1]);
1165                  Cleanup();
1166                  return RDTnone;
1167          }
1168          NewBar();                               // close up and return success
1169 <        fclose(pfp);
1170 <        if (dfp) fclose(dfp);
1169 >        fclose(pdfp[0]);
1170 >        if (pdfp[1]) fclose(pdfp[1]);
1171          return dt;
1172   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines