ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/Development/ray/src/util/pvsum.c
(Generate patch)

Comparing ray/src/util/pvsum.c (file contents):
Revision 2.1 by greg, Thu Mar 27 01:26:55 2025 UTC vs.
Revision 2.8 by greg, Fri Oct 24 22:41:10 2025 UTC

# Line 10 | Line 10 | static const char RCSid[] = "$Id$";
10   #include "rtio.h"
11   #include "resolu.h"
12   #include "platform.h"
13 < #include "paths.h"
13 > #include "random.h"
14   #include "rmatrix.h"
15   #if !defined(_WIN32) && !defined(_WIN64)
16   #include <sys/mman.h>
17 + #include <sys/wait.h>
18   #endif
19  
20 + #define  VIEWSTR        "VIEW="         /* borrowed from common/view.h */
21 + #define  VIEWSTRL       5
22 +
23   int     nprocs = 1;                     /* # of calculation processes (Unix) */
24   int     in_type = DTfromHeader;         /* input data type */
25   int     out_type = DTfromHeader;        /* output data type */
# Line 25 | Line 29 | char   *out_spec = NULL;               /* output file specification *
29   int     iswapped = 0;                   /* input data is byte-swapped? */
30   int     ncomp = 3;                      /* # input components */
31   int     xres=0, yres=0;                 /* input image dimensions */
32 + char    viewspec[128] = "";             /* VIEW= line from first header */
33 + char    pixasp[48] = "";                /* PIXASPECT= line from header */
34  
35 + int     gargc;                          /* global argc */
36 + char    **gargv;                        /* global argv */
37 +
38   RMATRIX *cmtx = NULL;                   /* coefficient matrix */
39  
40   /* does the given spec contain integer format? */
# Line 67 | Line 76 | iheadline(char *s, void *p)
76                  ncomp = ncompval(s);
77                  return(1);
78          }
70        if (isexpos(s)) {
71                if (fabs(1. - exposval(s)) > 0.04)
72                        fputs("Warning - ignoring EXPOSURE setting\n", stderr);
73                return(1);
74        }
79          if (formatval(fmt, s)) {
80                  for (in_type = DTend; --in_type > DTfromHeader; )
81                          if (!strcmp(fmt, cm_fmt_id[in_type]))
# Line 83 | Line 87 | iheadline(char *s, void *p)
87                  iswapped = (i != nativebigendian());
88                  return(1);
89          }
90 +        if (!strncmp(s, VIEWSTR, VIEWSTRL)) {
91 +                strcpy(viewspec, s);
92 +                return(1);
93 +        }
94 +        if (isaspect(s)) {
95 +                strcpy(pixasp, s);
96 +                return(1);
97 +        }
98          return(0);
99   }
100  
# Line 154 | Line 166 | get_iotypes(void)
166   int
167   checkline(char *s, void *p)
168   {
169 <        int     *xyres = (int *)p;
170 <        char    fmt[MAXFMTLEN];
169 >        static int      exposWarned = 0;
170 >        int             *xyres = (int *)p;
171 >        char            fmt[MAXFMTLEN];
172  
173          if (!strncmp(s, "NCOLS=", 6)) {
174                  xyres[0] = atoi(s+6);
# Line 175 | Line 188 | checkline(char *s, void *p)
188                  return(1);
189          }
190          if (isexpos(s)) {
191 <                if (fabs(1. - exposval(s)) > 0.04)
192 <                        fputs("Warning - ignoring EXPOSURE setting\n", stderr);
191 >                if (!exposWarned && fabs(1. - exposval(s)) > 0.04) {
192 >                        fputs("Warning - ignoring EXPOSURE setting(s)\n",
193 >                                        stderr);
194 >                        exposWarned++;
195 >                }
196                  return(1);
197          }
198          if (formatval(fmt, s)) {
# Line 227 | Line 243 | open_output(char *ospec, int fno)
243          if (!ospec) {
244                  ospec = "<stdout>";
245                  fp = stdout;
230                SET_FILE_BINARY(fp);
246          } else if (ospec[0] == '!') {
247                  if (!(fp = popen(ospec+1, "w"))) {
248                          fprintf(stderr, "Cannot start: %s\n", ospec);
249                          return(NULL);
250                  }
251 <                SET_FILE_BINARY(fp);
237 <        } else if (!(fp = fopen(ospec, "wb"))) {
251 >        } else if (!(fp = fopen(ospec, "w"))) {
252                  fprintf(stderr, "%s: cannot open for writing\n", ospec);
253                  return(NULL);
254          }
255 +        SET_FILE_BINARY(fp);
256          newheader("RADIANCE", fp);
257 <        fputnow(fp);
257 >        if (cmtx->info)                 /* prepend matrix metadata */
258 >                fputs(cmtx->info, fp);
259 >        else
260 >                fputnow(fp);
261 >        printargs(gargc, gargv, fp);    /* this command */
262          if (fno >= 0)
263                  fprintf(fp, "FRAME=%d\n", fno);
264 +        if (viewspec[0])
265 +                fputs(viewspec, fp);
266 +        if (pixasp[0])
267 +                fputs(pixasp, fp);
268          switch (out_type) {
269          case DTfloat:
270          case DTdouble:
# Line 377 | Line 400 | writerr:
400          return(0);
401   }
402  
403 + #if defined(_WIN32) || defined(_WIN64)
404 + #define multi_process   solo_process
405 + #else
406 +
407 + /* allocate a scrambled index array of the specified length */
408 + int *
409 + scramble(int n)
410 + {
411 +        int     *scarr = (int *)malloc(sizeof(int)*n);
412 +        int     i;
413 +
414 +        if (!scarr) {
415 +                fprintf(stderr, "Out of memory in scramble(%d)\n", n);
416 +                exit(1);
417 +        }
418 +        for (i = n; i--; )
419 +                scarr[i] = i;
420 +                                        /* perform Fisher-Yates shuffle */
421 +        for (i = 0; i < n-1; i++) {
422 +                int     ix = irandom(n-i) + i;
423 +                int     ndx = scarr[i];
424 +                scarr[i] = scarr[ix];
425 +                scarr[ix] = ndx;
426 +        }
427 +        return(scarr);
428 + }
429 +
430   /* run calculation on multiple processes, using memory maps and fork() */
431   int
432   multi_process(void)
433   {
384 #if defined(_WIN32) || defined(_WIN64)
385        fputs("Bad call to multi_process()\n", stderr);
386        return(0);
387 #else
434          int     coff = nprocs;
435          int     odd = 0;
436          char    fbuf[512];
437          float   *osum;
438 +        int     *syarr;
439          int     c;
440                                          /* sanity check */
441          if (sizeof(float) != sizeof(COLORV)) {
# Line 409 | Line 456 | multi_process(void)
456                                  xres, yres, ncomp);
457                  return(0);
458          }
459 +        srandom(113*coff + 5669);       /* randomize row access for this process */
460 +        syarr = scramble(yres);
461                                          /* run through our unique set of columns */
462          for (c = coff; c < cmtx->ncols; c += nprocs) {
463                  FILE    *fout;
# Line 419 | Line 468 | multi_process(void)
468                  while (rc-- > 0) {      /* map & sum each input file */
469                          const int       r = odd ? rc : cmtx->nrows-1 - rc;
470                          const rmx_dtype *cval = rmx_val(cmtx, r, c);
471 <                        long            dstart, n;
471 >                        long            dstart;
472                          size_t          maplen;
473                          void            *imap;
474                          FILE            *finp;
475                          float           *dst;
476 <                        int             i;
476 >                        int             i, x;
477                          for (i = ncomp; i--; )
478                                  if (cval[i] != 0) break;
479                          if (i < 0)      /* this coefficient is zero, skip */
# Line 443 | Line 492 | multi_process(void)
492                                  return(0);
493                          }
494                          i = in_type==DTfloat ? ncomp*(int)sizeof(float) : ncomp+1;
495 <                        maplen = dstart + yres*xres*i;
495 >                        maplen = dstart + (size_t)yres*xres*i;
496                          imap = mmap(NULL, maplen, PROT_READ,
497                                          MAP_FILE|MAP_SHARED, fileno(finp), 0);
498 <                        fclose(finp);           /* will load from map */
498 >                        fclose(finp);           /* will read from map (randomly) */
499                          if (imap == MAP_FAILED) {
500                                  fprintf(stderr, "%s: unable to map input file\n", fbuf);
501                                  return(0);
502                          }
503 <                        dst = osum;             /* -> weighted image sum */
504 <                        if (in_type == DTfloat) {
505 <                            const float *fvp = (float *)((char *)imap + dstart);
506 <                            for (n = (long)yres*xres; n-- > 0;
507 <                                                        dst += ncomp, fvp += ncomp)
508 <                                for (i = ncomp; i--; )
509 <                                    dst[i] += cval[i]*fvp[i];
510 <                        } else {
462 <                            const COLRV *cvp = (COLRV *)((char *)imap + dstart);
463 <                            for (n = (long)yres*xres; n-- > 0;
464 <                                                        dst += ncomp, cvp += ncomp+1) {
465 <                                const rmx_dtype fe = cxponent[cvp[ncomp]];
466 <                                for (i = ncomp; i--; )
467 <                                    dst[i] += cval[i]*(cvp[i]+(rmx_dtype).5)*fe;
503 >                        if (in_type == DTfloat)
504 >                            for (y = yres; y-- > 0; ) {
505 >                                const float     *fvp = (float *)((char *)imap + dstart) +
506 >                                                        (size_t)ncomp*xres*syarr[y];
507 >                                dst = osum + (size_t)ncomp*xres*syarr[y];
508 >                                for (x = xres; x-- > 0; dst += ncomp, fvp += ncomp)
509 >                                    for (i = ncomp; i--; )
510 >                                        dst[i] += cval[i]*fvp[i];
511                              }
512 <                        }
512 >                        else
513 >                            for (y = yres; y-- > 0; ) {
514 >                                const COLRV     *cvp = (COLRV *)((char *)imap + dstart) +
515 >                                                        (ncomp+1L)*xres*syarr[y];
516 >                                dst = osum + (size_t)ncomp*xres*syarr[y];
517 >                                for (x = xres; x-- > 0; dst += ncomp, cvp += ncomp+1) {
518 >                                    const rmx_dtype     fe = cxponent[cvp[ncomp]];
519 >                                    for (i = ncomp; i--; )
520 >                                        dst[i] += cval[i]*(cvp[i]+(rmx_dtype).5)*fe;
521 >                                }
522 >                            }
523                          munmap(imap, maplen);
524 <                }                       /* write out accumulated column result */
524 >                }                       /* write accumulated column picture/matrix */
525                  sprintf(fbuf, out_spec, c);
526                  fout = open_output(fbuf, c);
527                  if (!fout)
# Line 492 | Line 545 | multi_process(void)
545                  odd = !odd;             /* go back & forth to milk page cache */
546          }
547          free(osum);
548 <        if (coff)                       /* children return here... */
548 >        free(syarr);
549 >        if (coff)                       /* child processes return here... */
550                  return(1);
551          c = 0;                          /* ...but parent waits for children */
552          while (++coff < nprocs) {
# Line 505 | Line 559 | multi_process(void)
559   writerr:
560          fprintf(stderr, "%s: write error\n", fbuf);
561          return(0);
508 #endif
562   }
563  
564 + #endif          /* ! Windows */
565 +
566   int
567   main(int argc, char *argv[])
568   {
569          int     a;
570  
571 +        gargc = argc;                   /* for header output */
572 +        gargv = argv;
573 +
574          for (a = 1; a < argc-1 && argv[a][0] == '-'; a++)
575                  switch (argv[a][1]) {
576                  case 'o':               /* output spec/format */
# Line 544 | Line 602 | badopt:                        fprintf(stderr, "%s: bad option: %s\n", argv
602          if ((argc-a < 1) | (argc-a > 2) || argv[a][0] == '-')
603                  goto userr;
604          in_spec = argv[a];
605 <        cmtx = rmx_load(argv[a+1], RMPnone);    /* may load from stdin */
605 >        cmtx = rmx_load(argv[a+1]);     /* loads from stdin if a+1==argc */
606          if (cmtx == NULL)
607                  return(1);              /* error reported */
608 +        if (nprocs > cmtx->ncols)
609 +                nprocs = cmtx->ncols;
610   #if defined(_WIN32) || defined(_WIN64)
611          if (nprocs > 1) {
612                  fprintf(stderr, "%s: warning - Windows only allows -N 1\n", argv[0]);
613                  nprocs = 1;
614          }
615   #else
556        if (nprocs > cmtx->ncols)
557                nprocs = cmtx->ncols;
616          if ((nprocs > 1) & !out_spec) {
617                  fprintf(stderr, "%s: multi-processing result cannot go to stdout\n",
618                                  argv[0]);

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)