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.3 by greg, Sun Aug 18 17:24:48 2024 UTC vs.
Revision 2.8 by greg, Fri Aug 23 02:08:28 2024 UTC

# Line 196 | Line 196 | RpictSimulManager::SetTile(const int ti[2])
196   bool
197   RpictSimulManager::ComputePixel(int x, int y)
198   {
199        static const SCOLOR     scBlack = {0};
199          int     i;
200          FVECT   rodir[2];
201          double  hpos = (x+pixjitter())/TWidth();
202          double  vpos = (y+pixjitter())/THeight();
203          double  dlim = viewray(rodir[0], rodir[1], &tvw, hpos, vpos);
204          if (dlim < -FTINY) {    // off view?
205 <                pacc.SetPixel(x, y, scBlack);
205 >                pacc.SetPixel(x, y, scblack);
206                  doneMap.Set(x, y);
207                  return true;
208          }
# Line 328 | Line 327 | RpictSimulManager::FillSquare(const int x, const int y
327  
328   // helper function to set up quincunx sampling
329   static void
330 < SetQuincunx(ABitMap2 *bmp2, int noff[4][2], const int spc, const bool odd)
330 > SetQuincunx(ABitMap2 *bmp2, int noff[4][2], const int spc, bool odd, int x0, int y)
331   {
332 <        for (int y = 0; y < bmp2->Height(); y += spc>>1)
334 <            for (int x = (odd^(y&1))*(spc>>1); x < bmp2->Width(); x += spc)
335 <                bmp2->Set(x, y);
336 <                                        // order neighbors CCW
337 <        if (odd) {
332 >        if (odd) {                      // order neighbors CCW
333                  noff[0][0] = spc>>1; noff[0][1] = 0;
334                  noff[1][0] = 0; noff[1][1] = spc>>1;
335                  noff[2][0] = -(spc>>1); noff[2][1] = 0;
# Line 345 | Line 340 | SetQuincunx(ABitMap2 *bmp2, int noff[4][2], const int
340                  noff[2][0] = -(spc>>1); noff[2][1] = -(spc>>1);
341                  noff[3][0] = spc>>1; noff[3][1] = -(spc>>1);
342          }
343 +        int     nsteps;                 // non-negative range
344 +        if (x0 < -(spc>>1)) {
345 +                nsteps = (spc-1 - x0 - (spc>>1))/spc;
346 +                x0 += nsteps*spc;
347 +        }
348 +        if (y < 0) {                    // get past y==0
349 +                nsteps = ((spc>>1)-1 - y)/(spc>>1);
350 +                y += nsteps*(spc>>1);
351 +                odd ^= nsteps&1;
352 +        }
353 +        while (y < bmp2->Height()) {
354 +            for (int x = x0 + odd*(spc>>1); x < bmp2->Width(); x += spc)
355 +                bmp2->Set(x, y);
356 +            y += spc>>1;
357 +            odd = !odd;
358 +        }
359   }
360  
361   // Render (or finish rendering) current tile
362   bool
363 < RpictSimulManager::RenderRect()
363 > RpictSimulManager::RenderRect(const int x0, const int y0)
364   {
365          if (!tvw.type || !Ready()) {
366                  error(INTERNAL, "need octree and view for RenderRect()");
# Line 359 | Line 370 | RpictSimulManager::RenderRect()
370          int             sp2 = ceil(log2((TWidth()>THeight() ? TWidth() : THeight()) - 1.));
371          int             layer = 0;
372          int             x, y;
362 // fprintf(stderr, "Rendering %dx%d tile with psample=%d, maxdiff=%.3f ...\n",
363 // TWidth(), THeight(), psample, maxdiff);
373          while (sp2 > 0) {
374                  ABitMap2        sampMap(TWidth(), THeight());
375                  int             noff[4][2];
376                  if ((prCB != NULL) & (barPix == NULL))
377                          (*prCB)(100.*doneMap.SumTotal()/doneMap.Width()/doneMap.Height());
378 <                SetQuincunx(&sampMap, noff, 1<<sp2, layer&1);
378 >                SetQuincunx(&sampMap, noff, 1<<sp2, layer&1, x0, y0);
379                  sampMap -= doneSamples; // avoid resampling pixels
380                  // Are we into adaptive sampling realm?
381 <                if (noff[0][0]*noff[0][0] + noff[0][1]*noff[0][1] < psample*psample) {
381 >                if (noff[0][0]*noff[0][0] + noff[0][1]*noff[0][1] < 4*psample*psample) {
382                          if (FlushQueue() < 0)   // need results to check thresholds
383                                  return false;
384                          ABitMap2        fillMap = sampMap;
# Line 394 | Line 403 | RpictSimulManager::RenderRect()
403                          if (!ComputePixel(x, y))
404                                  return false;
405                  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()));
406                  sp2 -= layer++ & 1;     // next denser sampling
407          }
408          if (FlushQueue() < 0)           // make sure we got everyone
# Line 433 | Line 437 | RpictSimulManager::RenderTile(COLORV *rp, int ystride,
437                  pacc.SetColorSpace(RDTxyz);
438          else if (prims)
439                  pacc.SetColorSpace(RDTrgb, prims);
440 <                
441 <        return SetTile(tile) && RenderRect();
440 >
441 >        int     x0=0, y0=0;
442 >        if (tile) {
443 >                x0 = -tile[0]*TWidth();
444 >                y0 = -tile[1]*THeight();
445 >        }
446 >        return SetTile(tile) && RenderRect(x0, y0);
447   }
448  
449   // Same but store as common-exponent COLR or SCOLR
# Line 451 | Line 460 | RpictSimulManager::RenderTile(COLRV *bp, int ystride,
460          else if (prims)
461                  pacc.SetColorSpace(RDTrgbe, prims);
462  
463 <        return SetTile(tile) && RenderRect();
463 >        int     x0=0, y0=0;
464 >        if (tile) {
465 >                x0 = -tile[0]*TWidth();
466 >                y0 = -tile[1]*THeight();
467 >        }
468 >        return SetTile(tile) && RenderRect(x0, y0);
469   }
470  
471   // Same but also use 16-bit encoded depth buffer
# Line 468 | Line 482 | RpictSimulManager::RenderTile(COLRV *bp, int ystride,
482          else if (prims)
483                  pacc.SetColorSpace(RDTrgbe, prims);
484  
485 <        return SetTile(tile) && RenderRect();
485 >        int     x0=0, y0=0;
486 >        if (tile) {
487 >                x0 = -tile[0]*TWidth();
488 >                y0 = -tile[1]*THeight();
489 >        }
490 >        return SetTile(tile) && RenderRect(x0, y0);
491   }
492  
493 + // Back to float color with 16-bit depth
494 + bool
495 + RpictSimulManager::RenderTile(COLORV *rp, int ystride, short *dp, const int *tile)
496 + {
497 +        if (!rp | (GetWidth() <= 0) | (GetHeight() <= 0) | !vw.type)
498 +                return false;
499 +        if (!ystride)                   // contiguous rows?
500 +                ystride = TWidth();
501 +        pacc.Init(rp, ystride, dp);
502 +        if (prims == xyzprims)
503 +                pacc.SetColorSpace(RDTxyz);
504 +        else if (prims)
505 +                pacc.SetColorSpace(RDTrgb, prims);
506 +
507 +        int     x0=0, y0=0;
508 +        if (tile) {
509 +                x0 = -tile[0]*TWidth();
510 +                y0 = -tile[1]*THeight();
511 +        }
512 +        return SetTile(tile) && RenderRect(x0, y0);
513 + }
514 +
515   // Allocate a new render bar
516   void
517   RpictSimulManager::NewBar(int ht)
# Line 566 | Line 607 | RpictSimulManager::RenderBelow(int ytop, const int vst
607          }
608          int             lastOut = ytop;         // render down frame
609          while (ytop > 0) {
569 // fprintf(stderr, "At y=%d, source drawing %s...\n", ytop, parr ? "ON" : "OFF");
610                  if (prCB)
611                          (*prCB)(100.*(GetHeight()-ytop)/GetHeight());
612 <                if (!RenderRect())              // render this bar
612 >                if (!RenderRect(0, THeight()-ytop))     // render this bar
613                          return false;
614                  int     nlines = lastOut - ytop + THeight();
615                  if (nlines > ytop)
# Line 628 | Line 668 | RpictSimulManager::RenderBelow(int ytop, const int vst
668          return true;
669   }
670  
671 < /*
632 < * Render and write a frame to the named file
633 < * Include any header lines set prior to call
634 < * Picture file must not already exist
635 < * Write pixels to stdout if !pfname
636 < * Write depth to a command if dfname[0]=='!'
637 < */
671 > // Open new output picture file (and optional depth file)
672   RenderDataType
673 < RpictSimulManager::RenderFrame(const char *pfname, RenderDataType dt, const char *dfname)
673 > RpictSimulManager::NewOutput(FILE *pdfp[2], const char *pfname,
674 >                                RenderDataType dt, const char *dfname)
675   {
676 <        int     fd = 1;
642 <        FILE *  pfp = NULL;
643 <        FILE *  dfp = NULL;
644 <
676 >        pdfp[0] = pdfp[1] = NULL;
677          if (!RDTcolorT(dt))
678 <                error(INTERNAL, "botched color output type in RenderFrame()");
678 >                error(INTERNAL, "botched color output type in NewOutput()");
679          if (NCSAMP == 3) {
680                  if (RDTcolorT(dt) == RDTscolr)
681                          dt = RDTnewCT(dt, prims==xyzprims ? RDTxyze : RDTrgbe);
# Line 651 | Line 683 | RpictSimulManager::RenderFrame(const char *pfname, Ren
683                          dt = RDTnewCT(dt, prims==xyzprims ? RDTxyz : RDTrgb);
684          }
685          if (!RDTdepthT(dt) ^ !dfname)
686 <                error(INTERNAL, "depth output requires file name and type in RenderFrame()");
686 >                error(INTERNAL, "depth output requires file name and type in NewOutput()");
687 >        int     fd = 1;
688          if (pfname) {                           // open picture output file
689                  if (pfname[0] == '!') {
690                          error(INTERNAL, "writing picture to a command not supported");
# Line 667 | Line 700 | RpictSimulManager::RenderFrame(const char *pfname, Ren
700                  return RDTnone;                 // expected in parallel sequence
701          }
702          if (fd == 1)
703 <                pfp = stdout;
704 <        else if (!(pfp = fdopen(fd, "w")))
703 >                pdfp[0] = stdout;
704 >        else if (!(pdfp[0] = fdopen(fd, "w")))
705                  error(SYSTEM, "failure calling fdopen()");
706 <        SET_FILE_BINARY(pfp);                   // write picture header
707 <        if ((pfp != stdout) | (frameNo <= 1)) {
708 <                newheader("RADIANCE", pfp);
709 <                fputs(GetHeader(), pfp);
706 >        SET_FILE_BINARY(pdfp[0]);               // write picture header
707 >        if ((pdfp[0] != stdout) | (frameNo <= 1)) {
708 >                newheader("RADIANCE", pdfp[0]);
709 >                fputs(GetHeader(), pdfp[0]);
710          }
711 <        fputs(VIEWSTR, pfp); fprintview(&vw, pfp); fputc('\n', pfp);
711 >        fputs(VIEWSTR, pdfp[0]); fprintview(&vw, pdfp[0]); fputc('\n', pdfp[0]);
712          if (frameNo > 0)
713 <                fprintf(pfp, "FRAME=%d\n", frameNo);
713 >                fprintf(pdfp[0], "FRAME=%d\n", frameNo);
714          double  pasp = viewaspect(&vw) * GetWidth() / GetHeight();
715          if ((0.99 > pasp) | (pasp > 1.01))
716 <                fputaspect(pasp, pfp);
717 <        fputnow(pfp);
716 >                fputaspect(pasp, pdfp[0]);
717 >        fputnow(pdfp[0]);
718          switch (RDTcolorT(dt)) {                // set primaries and picture format
719          case RDTrgbe:
720                  if (!prims | (prims == xyzprims)) prims = stdprims;
721 <                fputprims(prims, pfp);
722 <                fputformat(COLRFMT, pfp);
721 >                fputprims(prims, pdfp[0]);
722 >                fputformat(COLRFMT, pdfp[0]);
723                  break;
724          case RDTxyze:
725                  prims = xyzprims;
726 <                fputformat(CIEFMT, pfp);
726 >                fputformat(CIEFMT, pdfp[0]);
727                  break;
728          case RDTscolr:
729                  prims = NULL;
730 <                fputwlsplit(WLPART, pfp);
731 <                fputncomp(NCSAMP, pfp);
732 <                fputformat(SPECFMT, pfp);
730 >                fputwlsplit(WLPART, pdfp[0]);
731 >                fputncomp(NCSAMP, pdfp[0]);
732 >                fputformat(SPECFMT, pdfp[0]);
733                  break;
734          case RDTrgb:
735                  if (!prims | (prims == xyzprims)) prims = stdprims;
736 <                fputprims(prims, pfp);
737 <                fputncomp(3, pfp);
738 <                fputendian(pfp);
739 <                fputformat("float", pfp);
736 >                fputprims(prims, pdfp[0]);
737 >                fputncomp(3, pdfp[0]);
738 >                fputendian(pdfp[0]);
739 >                fputformat("float", pdfp[0]);
740                  break;
741          case RDTxyz:
742                  prims = xyzprims;
743 <                fputprims(prims, pfp);
744 <                fputncomp(3, pfp);
745 <                fputendian(pfp);
746 <                fputformat("float", pfp);
743 >                fputprims(prims, pdfp[0]);
744 >                fputncomp(3, pdfp[0]);
745 >                fputendian(pdfp[0]);
746 >                fputformat("float", pdfp[0]);
747                  break;
748          case RDTscolor:
749                  prims = NULL;
750 <                fputwlsplit(WLPART, pfp);
751 <                fputncomp(NCSAMP, pfp);
752 <                fputendian(pfp);
753 <                fputformat("float", pfp);
750 >                fputwlsplit(WLPART, pdfp[0]);
751 >                fputncomp(NCSAMP, pdfp[0]);
752 >                fputendian(pdfp[0]);
753 >                fputformat("float", pdfp[0]);
754                  break;
755          default:;
756          }
757 <        fputc('\n', pfp);                       // end picture header
758 <        fprtresolu(GetWidth(), GetHeight(), pfp);
759 <        if (dfname) {
757 >        fputc('\n', pdfp[0]);                   // flush picture header + resolution
758 >        if (fflush(pdfp[0]) == EOF) {
759 >                sprintf(errmsg, "cannot write header to picture '%s'", pfname);
760 >                error(SYSTEM, errmsg);
761 >                fclose(pdfp[0]);
762 >                pdfp[0] = NULL;
763 >                return RDTnone;
764 >        }
765 >        if (dfname) {                           // open depth output
766                  if (dfname[0] == '!')
767 <                        dfp = popen(dfname+1, "w");
767 >                        pdfp[1] = popen(dfname+1, "w");
768                  else
769 <                        dfp = fopen(dfname, "w");
770 <                if (!dfp) {
769 >                        pdfp[1] = fopen(dfname, "w");
770 >                if (!pdfp[1]) {
771                          sprintf(errmsg, "cannot open depth output '%s'", dfname);
772                          error(SYSTEM, errmsg);
773 +                        fclose(pdfp[0]);
774 +                        pdfp[0] = NULL;
775                          return RDTnone;
776                  }
777 <                SET_FILE_BINARY(dfp);
777 >                SET_FILE_BINARY(pdfp[1]);
778          }
779          if (RDTdepthT(dt) == RDTdshort) {       // write header for 16-bit depth?
780 <                newheader("RADIANCE", dfp);
781 <                fputs(GetHeader(), dfp);
782 <                fputs(VIEWSTR, dfp); fprintview(&vw, dfp); fputc('\n', dfp);
783 <                fputs(DEPTHSTR, dfp); fputs(dunit, dfp); fputc('\n', dfp);
784 <                fputformat(DEPTH16FMT, dfp);
785 <                fputc('\n', dfp);               // end-of-info
786 <                fprtresolu(GetWidth(), GetHeight(), dfp);
780 >                newheader("RADIANCE", pdfp[1]);
781 >                fputs(GetHeader(), pdfp[1]);
782 >                fputs(VIEWSTR, pdfp[1]); fprintview(&vw, pdfp[1]); fputc('\n', pdfp[1]);
783 >                fputs(DEPTHSTR, pdfp[1]); fputs(dunit, pdfp[1]); fputc('\n', pdfp[1]);
784 >                fputformat(DEPTH16FMT, pdfp[1]);
785 >                fputc('\n', pdfp[1]);           // end-of-info
786 >                if (fflush(pdfp[1]) == EOF) {
787 >                        sprintf(errmsg, "cannot write header to '%s'", dfname);
788 >                        error(SYSTEM, errmsg);
789 >                        fclose(pdfp[0]); fclose(pdfp[1]);
790 >                        pdfp[0] = pdfp[1] = NULL;
791 >                        return RDTnone;
792 >                }
793          }
794 <        const int       bheight = (psample > 1) ? int(2*psample+.99) : 4;
795 <        const int       vstep =  bheight >> (psample > 1);
794 >        return dt;                              // ready to roll
795 > }
796  
797 + /*
798 + * Render and write a frame to the named file
799 + * Include any header lines set prior to call
800 + * Picture file must not exist
801 + * Write pixels to stdout if !pfname
802 + * Write depth to a command if dfname[0]=='!'
803 + */
804 + RenderDataType
805 + RpictSimulManager::RenderFrame(const char *pfname, RenderDataType dt, const char *dfname)
806 + {
807 +        FILE    *pdfp[2];
808 +                                                // prepare output file(s)
809 +        dt = NewOutput(pdfp, pfname, dt, dfname);
810 +        if (dt == RDTnone)
811 +                return RDTnone;
812 +                                                // add resolution string(s)
813 +        fprtresolu(GetWidth(), GetHeight(), pdfp[0]);
814 +        if (RDTdepthT(dt) == RDTdshort)
815 +                fprtresolu(GetWidth(), GetHeight(), pdfp[1]);
816 +
817 +        const int       bheight = (psample > 1) ? int(4*psample+.99) : 8;
818 +        const int       vstep = bheight >> (psample > 1);
819 +
820          NewBar(bheight);                        // render frame if we can
821 <        if (!RenderBelow(GetHeight(), vstep, pfp, dt, dfp)) {
822 <                fclose(pfp);
823 <                if (dfp) (dfname[0] == '!') ? pclose(dfp) : fclose(dfp);
821 >        if (!RenderBelow(GetHeight(), vstep, pdfp[0], dt, pdfp[1])) {
822 >                fclose(pdfp[0]);
823 >                if (pdfp[1]) (dfname[0] == '!') ? pclose(pdfp[1]) : fclose(pdfp[1]);
824                  Cleanup();
825                  return RDTnone;
826          }
827          NewBar();                               // clean up and return
828 <        if (pfp != stdout)
829 <                fclose(pfp);
830 <        if (dfp) {
828 >        if (pdfp[0] != stdout)
829 >                fclose(pdfp[0]);
830 >        if (pdfp[1]) {
831                  if (dfname[0] == '!') {
832 <                        int     status = pclose(dfp);
832 >                        int     status = pclose(pdfp[1]);
833                          if (status) {
834                                  sprintf(errmsg, "depth output (%s) error status: %d",
835                                                  dfname, status);
# Line 767 | Line 837 | RpictSimulManager::RenderFrame(const char *pfname, Ren
837                                  return RDTnone;
838                          }
839                  } else
840 <                        fclose(dfp);
840 >                        fclose(pdfp[1]);
841          }
842          return dt;
843   }
844  
845   // passed struct for header line callback
846 < struct HeaderInfo {
846 > static struct HeaderInfo {
847          char            fmt[MAXFMTLEN];
848          char            depth_unit[32];
849          int             ncomp;
# Line 794 | Line 864 | struct HeaderInfo {
864                                  gotview = false;
865                                  endianMatch = true;
866                          }
867 < };
867 > }       hinfo;          // XXX single copy to hold custom primitives
868  
869   // helper function checks header line and records req. info.
870   static int
# Line 836 | Line 906 | head_check(char *s, void *p)
906          return 0;
907   }
908  
909 < // Resume partially finished rendering
840 < // Picture file must exist
909 > // Reopen output file(s), leaving pointers at end of (each) header
910   RenderDataType
911 < RpictSimulManager::ResumeFrame(const char *pfname, const char *dfname)
911 > RpictSimulManager::ReopenOutput(FILE *pdfp[2], const char *pfname, const char *dfname)
912   {
913 <        if (!pfname || pfname[0] == '!')
845 <                return RDTnone;
913 >        extern const char       HDRSTR[];
914  
915 +        if (!pfname || pfname[0] == '!') {
916 +                pdfp[0] = pdfp[1] = NULL;
917 +                return RDTnone;
918 +        }
919          RenderDataType  dt = RDTnone;
920 <        FILE *          dfp = NULL;
921 <        FILE *          pfp = fopen(pfname, "r+");
922 <        if (!pfp) {
920 >        pdfp[1] = NULL;
921 >        pdfp[0] = fopen(pfname, "r+");
922 >        if (!pdfp[0]) {
923                  sprintf(errmsg, "cannot reopen output picture '%s'", pfname);
924                  error(SYSTEM, errmsg);
925                  return RDTnone;
926          }
927 <        SET_FILE_BINARY(pfp);
928 <        HeaderInfo      hinfo;          // read header information & dimensions
929 <        RESOLU          res;
930 <        if (getheader(pfp, head_check, &hinfo) < 0) {
859 <                fclose(pfp);
927 >        SET_FILE_BINARY(pdfp[0]);       // read header information
928 >        if (getheader(pdfp[0], head_check, &hinfo) < 0) {
929 >                fclose(pdfp[0]);
930 >                pdfp[0] = NULL;
931                  return RDTnone;
932          }
862        if (!fgetsresolu(&res, pfp) || res.rt != PIXSTANDARD) {
863                sprintf(errmsg, "missing/bad resolution for '%s'", pfname);
864                error(USER, errmsg);
865                fclose(pfp);
866                return RDTnone;
867        }
933          if (!hinfo.gotview) {
934                  sprintf(errmsg, "missing view for '%s'", pfname);
935                  error(USER, errmsg);
936 <                fclose(pfp);
936 >                fclose(pdfp[0]);
937 >                pdfp[0] = NULL;
938                  return RDTnone;
939          }
940          if (hinfo.ncomp < 3) {
941                  sprintf(errmsg, "bad # components (%d) in '%s'", hinfo.ncomp, pfname);
942                  error(USER, errmsg);
943 <                fclose(pfp);
943 >                fclose(pdfp[0]);
944 >                pdfp[0] = NULL;
945                  return RDTnone;
946          }
947 <        int     bytesPer = 0;           // complicated part to set rendering/output space
947 >                                        // set rendering/output space
948          if (!strcmp(hinfo.fmt, COLRFMT)) {
949 <                prims = hinfo.prims;
949 >                prims = hinfo.prims;    // XXX static array
950                  int     n = 8*hinfo.gotprims;
951                  while (n--)
952                          if (!FABSEQ(hinfo.prims[0][n], stdprims[0][n]))
# Line 895 | Line 962 | RpictSimulManager::ResumeFrame(const char *pfname, con
962                          sprintf(errmsg, "incompatible sample count (%d) in '%s'",
963                                          hinfo.ncomp, pfname);
964                          error(USER, errmsg);
965 <                        fclose(pfp);
965 >                        fclose(pdfp[0]);
966 >                        pdfp[0] = NULL;
967                          return RDTnone;
968                  }
969 <                NCSAMP = hinfo.ncomp;   // overrides global setting
969 >                NCSAMP = hinfo.ncomp;           // overrides global setting
970                  prims = NULL;
971                  dt = RDTnewCT(dt, RDTscolr);
904                bytesPer = hinfo.ncomp + 1;     // XXX assumes no compression
972          } else if (!strcmp(hinfo.fmt, "float")) {
973                  if (!hinfo.endianMatch) {
974                          sprintf(errmsg, "incompatible byte ordering in '%s'", pfname);
975                          error(USER, errmsg);
976 <                        fclose(pfp);
976 >                        fclose(pdfp[0]);
977 >                        pdfp[0] = NULL;
978                          return RDTnone;
979                  }
980                  if (hinfo.ncomp == 3) {
981 <                        prims = hinfo.prims;            // custom primaries?
981 >                        prims = hinfo.prims;    // custom primaries?
982                          int     n = 8*hinfo.gotprims;
983                          while (n--)
984                                  if (!FABSEQ(hinfo.prims[0][n], stdprims[0][n]))
985                                          break;
986 <                        if (n < 0)                      // standard primaries?
986 >                        if (n < 0)              // standard primaries?
987                                  prims = stdprims;
988                          else if (hinfo.gotprims) {      // or check if XYZ
989                                  for (n = 8; n--; )
# Line 933 | Line 1001 | RpictSimulManager::ResumeFrame(const char *pfname, con
1001                          prims = NULL;
1002                          dt = RDTnewCT(dt, RDTscolor);
1003                  }
936                bytesPer = sizeof(float)*hinfo.ncomp;
1004          } else {
1005                  sprintf(errmsg, "unknown format (%s) for '%s'", hinfo.fmt, pfname);
1006                  error(USER, errmsg);
1007 <                fclose(pfp);
1007 >                fclose(pdfp[0]);
1008 >                pdfp[0] = NULL;
1009                  return RDTnone;
1010          }
1011 +        if (!dfname)                            // no depth file?
1012 +                return dt;
1013 +
1014 +        if (dfname[0] == '!') {
1015 +                error(USER, "depth data cannot be reloaded from command");
1016 +                fclose(pdfp[0]);
1017 +                pdfp[0] = NULL;
1018 +                return RDTnone;
1019 +        }
1020 +        pdfp[1] = fopen(dfname, "r+");
1021 +        if (!pdfp[1]) {
1022 +                sprintf(errmsg, "cannot reopen depth file '%s'", dfname);
1023 +                error(SYSTEM, errmsg);
1024 +                fclose(pdfp[0]);
1025 +                pdfp[0] = NULL;
1026 +                return RDTnone;
1027 +        }
1028 +        SET_FILE_BINARY(pdfp[1]);
1029 +        int     n, len = strlen(HDRSTR);
1030 +        char    buf[32];                // sniff for 16-bit header
1031 +        if (getbinary(buf, 1, len+1, pdfp[1]) < len+1) {
1032 +                sprintf(errmsg, "empty depth file '%s'", dfname);
1033 +                error(SYSTEM, errmsg);
1034 +                fclose(pdfp[0]); fclose(pdfp[1]);
1035 +                pdfp[0] = pdfp[1] = NULL;
1036 +                return RDTnone;
1037 +        }
1038 +        for (n = 0; n < len; n++)
1039 +                if (buf[n] != HDRSTR[n])
1040 +                        break;          // not a Radiance header
1041 +        rewind(pdfp[1]);
1042 +        if ((n < len) | !isprint(buf[len]))
1043 +                return RDTnewDT(dt, RDTdfloat);
1044 +
1045 +        HeaderInfo      dinfo;          // thinking it's 16-bit encoded
1046 +        if (getheader(pdfp[1], head_check, &dinfo) < 0)
1047 +                sprintf(errmsg, "bad header in encoded depth file '%s'",
1048 +                                dfname);
1049 +        else if (strcmp(dinfo.fmt, DEPTH16FMT))
1050 +                sprintf(errmsg, "wrong format (%s) for depth file '%s'",
1051 +                                dinfo.fmt, dfname);
1052 +        else if (!SetReferenceDepth(dinfo.depth_unit))
1053 +                sprintf(errmsg, "bad/missing reference depth (%s) in '%s'",
1054 +                                dinfo.depth_unit, dfname);
1055 +        else
1056 +                errmsg[0] = '\0';
1057 +
1058 +        if (errmsg[0]) {
1059 +                error(USER, errmsg);
1060 +                fclose(pdfp[1]); fclose(pdfp[0]);
1061 +                pdfp[0] = pdfp[1] = NULL;
1062 +                return RDTnone;
1063 +        }
1064 +        return RDTnewDT(dt, RDTdshort);
1065 + }
1066 +
1067 + // Resume partially finished rendering
1068 + // Picture file must exist
1069 + RenderDataType
1070 + RpictSimulManager::ResumeFrame(const char *pfname, const char *dfname)
1071 + {
1072 +        FILE            *pdfp[2];
1073 +
1074 +        RenderDataType  dt = ReopenOutput(pdfp, pfname, dfname);
1075 +        if (dt == RDTnone)
1076 +                return RDTnone;
1077 +
1078 +        int     bytesPer = 0;           // figure out how far we got...
1079 +        switch (RDTcolorT(dt)) {
1080 +        case RDTrgbe:
1081 +        case RDTxyze:
1082 +                break;
1083 +        case RDTscolr:
1084 +                bytesPer = hinfo.ncomp + 1;     // XXX assumes no compression
1085 +                break;
1086 +        case RDTrgb:
1087 +        case RDTxyz:
1088 +                bytesPer = sizeof(float)*3;
1089 +                break;
1090 +        case RDTscolor:
1091 +                bytesPer = sizeof(float)*hinfo.ncomp;
1092 +                break;
1093 +        default:
1094 +                sprintf(errmsg, "unknown format (%s) for '%s'", hinfo.fmt, pfname);
1095 +                error(USER, errmsg);
1096 +                fclose(pdfp[0]);
1097 +                if (pdfp[1]) fclose(pdfp[1]);
1098 +                return RDTnone;
1099 +        }
1100 +        RESOLU  res;
1101 +        if (!fgetsresolu(&res, pdfp[0]) || res.rt != PIXSTANDARD) {
1102 +                sprintf(errmsg, "missing/bad resolution for '%s'", pfname);
1103 +                error(USER, errmsg);
1104 +                fclose(pdfp[0]);
1105 +                if (pdfp[1]) fclose(pdfp[1]);
1106 +                return RDTnone;
1107 +        }
1108          vw.type = 0;                            // set up new (unreferenced) frame
1109          frameNo = 0;
1110          int     hvdim[2] = {res.xr, res.yr};
1111          double  noAdj = 0;
1112          if (!NewFrame(hinfo.vw, hvdim, &noAdj) ||
1113                          (hvdim[0] != res.xr) | (hvdim[1] != res.yr)) {
1114 <                fclose(pfp);
1114 >                error(CONSISTENCY, "unexpected resolution change in ResumeFrame()");
1115 >                fclose(pdfp[0]);
1116 >                if (pdfp[1]) fclose(pdfp[1]);
1117                  return RDTnone;
1118          }
1119 <        long    dataStart = ftell(pfp);         // picture starting point
1119 >        long    dataStart = ftell(pdfp[0]);     // picture starting point
1120          if (dataStart < 0) {
1121                  sprintf(errmsg, "cannot seek on '%s'", pfname);
1122                  error(SYSTEM, errmsg);
1123 <                fclose(pfp);
1123 >                fclose(pdfp[0]);
1124 >                if (pdfp[1]) fclose(pdfp[1]);
1125                  return RDTnone;
1126          }
1127          long    doneScans = 0;
1128          if (bytesPer) {                         // fixed-width records?
1129 <                fseek(pfp, 0, SEEK_END);
1130 <                long    dataEnd = ftell(pfp);
1129 >                fseek(pdfp[0], 0, SEEK_END);
1130 >                long    dataEnd = ftell(pdfp[0]);
1131                  doneScans = (dataEnd - dataStart)/(bytesPer*GetWidth());
1132                  if (dataEnd-dataStart > bytesPer*GetWidth()*doneScans)
1133 <                        fseek(pfp, dataStart + bytesPer*GetWidth()*doneScans, SEEK_SET);
1133 >                        fseek(pdfp[0], dataStart + bytesPer*GetWidth()*doneScans, SEEK_SET);
1134          } else {                                // else get compressed scanlines
1135                  COLR *  scan = (COLR *)tempbuffer(sizeof(COLR)*GetWidth());
1136 <                while (freadcolrs(scan, GetWidth(), pfp) >= 0)
1136 >                while (freadcolrs(scan, GetWidth(), pdfp[0]) >= 0)
1137                          ++doneScans;
1138 <                if (!feof(pfp)) {
1138 >                if (!feof(pdfp[0])) {
1139                          sprintf(errmsg, "error reading compressed scanline from '%s'", pfname);
1140                          error(USER, errmsg);
1141 <                        fclose(pfp);
1141 >                        fclose(pdfp[0]);
1142 >                        if (pdfp[1]) fclose(pdfp[1]);
1143                          return RDTnone;
1144                  }
1145          }
1146          if (doneScans >= GetHeight()) {         // nothing left to do?
1147                  sprintf(errmsg, "output file '%s' is already complete", pfname);
1148                  error(WARNING, errmsg);
1149 <                fclose(pfp);
1149 >                fclose(pdfp[0]);
1150 >                if (pdfp[1]) fclose(pdfp[1]);
1151                  return dt;
1152          }
1153          if (!doneScans) {
1154                  sprintf(errmsg, "restarting empty frame '%s'", pfname);
1155                  error(WARNING, errmsg);
1156          }
1157 <        if (dfname) {                           // append depth file, too?
1158 <                if (dfname[0] == '!') {
1159 <                        error(USER, "depth data cannot be reloaded from command");
1160 <                        fclose(pfp);
1157 >        long    toSkip = 0;
1158 >        switch (RDTdepthT(dt)) {                // append depth file, too?
1159 >        case RDTdfloat:
1160 >                toSkip = sizeof(float)*GetWidth()*doneScans;
1161 >                break;
1162 >        case RDTdshort:
1163 >                if (!fgetsresolu(&res, pdfp[1]) || (res.rt != PIXSTANDARD) |
1164 >                                (res.xr != GetWidth()) | (res.yr != GetHeight())) {
1165 >                        sprintf(errmsg, "missing/bad resolution for '%s'", dfname);
1166 >                        error(USER, errmsg);
1167 >                        fclose(pdfp[0]); fclose(pdfp[0]);
1168                          return RDTnone;
1169                  }
1170 <                dfp = fopen(dfname, "a");
1171 <                if (!dfp) {
1172 <                        sprintf(errmsg, "cannot reopen depth file '%s'", dfname);
1173 <                        error(SYSTEM, errmsg);
1174 <                        fclose(pfp);
1175 <                        return RDTnone;
1176 <                }
1177 <                SET_FILE_BINARY(dfp);
1178 <                const long      dflen = ftell(dfp);
1002 <                if (dflen != sizeof(float)*GetWidth()*doneScans) {
1003 <                        fclose(dfp);
1004 <                        dfp = fopen(dfname, "r+");
1005 <                        if (!dfp) return RDTnone;       // WTH?
1006 <                        SET_FILE_BINARY(dfp);
1007 <                }
1008 <                if (dflen < sizeof(float)*GetWidth()*doneScans) {
1009 <                        HeaderInfo      dinfo;
1010 <                        if (getheader(dfp, head_check, &dinfo) < 0)
1011 <                                sprintf(errmsg, "bad header in encoded depth file '%s'",
1012 <                                                dfname);
1013 <                        else if (strcmp(dinfo.fmt, DEPTH16FMT))
1014 <                                sprintf(errmsg, "wrong format (%s) for depth file '%s'",
1015 <                                                dinfo.fmt, dfname);
1016 <                        else if (!SetReferenceDepth(dinfo.depth_unit))
1017 <                                sprintf(errmsg, "bad/missing reference depth (%s) in '%s'",
1018 <                                                dinfo.depth_unit, dfname);
1019 <                        else if (!fscnresolu(hvdim, hvdim+1, dfp) ||
1020 <                                        (hvdim[0] != GetWidth()) | (hvdim[1] != GetHeight()))
1021 <                                sprintf(errmsg, "bad/mismatched resolution in '%s'",
1022 <                                                dfname);
1023 <                        else
1024 <                                errmsg[0] = '\0';
1025 <
1026 <                        if (errmsg[0]) {
1027 <                                error(USER, errmsg);
1028 <                                fclose(dfp);
1029 <                                fclose(pfp);
1030 <                                return RDTnone;
1031 <                        }
1032 <                        const long      dStart = ftell(dfp);
1033 <                        if (dflen-dStart < 2*GetWidth()*doneScans) {
1034 <                                sprintf(errmsg, "missing %ld depths in '%s'",
1035 <                                        (long)GetWidth()*doneScans - (dflen-dStart)/2,
1036 <                                        dfname);
1037 <                                error(WARNING, errmsg);
1038 <                        }
1039 <                        fseek(dfp, dStart + 2*GetWidth()*doneScans, SEEK_SET);
1040 <                        dt = RDTnewDT(dt, RDTdshort);
1041 <                } else {
1042 <                        if (dflen > sizeof(float)*GetWidth()*doneScans)
1043 <                                fseek(dfp, sizeof(float)*GetWidth()*doneScans, SEEK_SET);
1044 <                        dt = RDTnewDT(dt, RDTdfloat);
1045 <                }
1170 >                toSkip = 2L*GetWidth()*doneScans;
1171 >                break;
1172 >        default:;
1173 >        }                                       // fseek() needed for output
1174 >        if (pdfp[1] && fseek(pdfp[1], toSkip, SEEK_CUR) < 0) {
1175 >                sprintf(errmsg, "cannot seek on depth file '%s'", dfname);
1176 >                error(SYSTEM, errmsg);
1177 >                fclose(pdfp[0]); fclose(pdfp[1]);
1178 >                return RDTnone;
1179          }
1180 <        int     bheight = (psample > 1) ? int(2*psample+.99) : 4;
1180 >        int     bheight = (psample > 1) ? int(4*psample+.99) : 8;
1181          if (bheight > GetHeight()-doneScans)
1182                  bheight = GetHeight()-doneScans;
1183          int     vstep =  bheight >> (psample > 1);
1184          vstep += !vstep;
1185  
1186          NewBar(bheight);                        // render remainder if we can
1187 <        if (!RenderBelow(GetHeight()-doneScans, vstep, pfp, dt, dfp)) {
1188 <                fclose(pfp);
1189 <                if (dfp) fclose(dfp);
1187 >        if (!RenderBelow(GetHeight()-doneScans, vstep, pdfp[0], dt, pdfp[1])) {
1188 >                fclose(pdfp[0]);
1189 >                if (pdfp[1]) fclose(pdfp[1]);
1190                  Cleanup();
1191                  return RDTnone;
1192          }
1193          NewBar();                               // close up and return success
1194 <        fclose(pfp);
1195 <        if (dfp) fclose(dfp);
1194 >        fclose(pdfp[0]);
1195 >        if (pdfp[1]) fclose(pdfp[1]);
1196          return dt;
1197   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines