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

Comparing ray/src/util/rmatrix.c (file contents):
Revision 2.60 by greg, Tue Nov 21 01:30:20 2023 UTC vs.
Revision 2.64 by greg, Tue Nov 28 16:19:31 2023 UTC

# Line 302 | Line 302 | rmx_load_spec(RMATRIX *rm, FILE *fp)
302          return(1);
303   }
304  
305 + /* Read matrix header from input stream (cannot be XML) */
306 + int
307 + rmx_load_header(RMATRIX *rm, FILE *fp)
308 + {
309 +        if (!rm | !fp)
310 +                return(0);
311 +        if (rm->info) {                         /* clear state */
312 +                free(rm->info);
313 +                rm->info = NULL;
314 +        }
315 +        if (rm->mtx) {                          /* ...and data */
316 + #ifdef MAP_FILE
317 +                if (rm->mapped) {
318 +                        munmap(rm->mapped, mapped_size(rm));
319 +                        rm->mapped = NULL;
320 +                } else
321 + #endif
322 +                        free(rm->mtx);
323 +                rm->mtx = NULL;
324 +        }
325 +        if (rm->nrows | rm->ncols | !rm->dtype) {
326 +                rm->nrows = rm->ncols = 0;
327 +                rm->ncomp = 3;
328 +                setcolor(rm->cexp, 1.f, 1.f, 1.f);
329 +                memcpy(rm->wlpart, WLPART, sizeof(rm->wlpart));
330 +                rm->swapin = 0;
331 +        }
332 +        SET_FILE_BINARY(fp);
333 +        rm->dtype = DTascii;                    /* assumed w/o FORMAT */
334 +        if (getheader(fp, get_dminfo, rm) < 0) {
335 +                fputs("Unrecognized matrix format\n", stderr);
336 +                return(0);
337 +        }
338 +                                                /* resolution string? */
339 +        if ((rm->nrows <= 0) | (rm->ncols <= 0)) {
340 +                if (!fscnresolu(&rm->ncols, &rm->nrows, fp))
341 +                        return(0);
342 +                if ((rm->dtype == DTrgbe) | (rm->dtype == DTxyze) &&
343 +                                rm->ncomp != 3)
344 +                        return(0);
345 +        }
346 +        return(1);
347 + }
348 +
349 + /* Allocate & load post-header data from stream given type set in rm->dtype */
350 + int
351 + rmx_load_data(RMATRIX *rm, FILE *fp)
352 + {
353 +        switch (rm->dtype) {
354 +        case DTascii:
355 +                SET_FILE_TEXT(fp);
356 +                return(rmx_load_ascii(rm, fp));
357 +        case DTfloat:
358 +                return(rmx_load_float(rm, fp));
359 +        case DTdouble:
360 +                return(rmx_load_double(rm, fp));
361 +        case DTrgbe:
362 +        case DTxyze:
363 +                return(rmx_load_rgbe(rm, fp));
364 +        case DTspec:
365 +                return(rmx_load_spec(rm, fp));
366 +        default:
367 +                fputs("Unsupported data type in rmx_loaddata()\n", stderr);
368 +        }
369 +        return(0);
370 + }
371 +
372   /* Load matrix from supported file type */
373   RMATRIX *
374   rmx_load(const char *inspec, RMPref rmp)
375   {
376          FILE            *fp;
377          RMATRIX         *dnew;
378 +        int             ok;
379  
380          if (!inspec)
381                  inspec = stdin_name;
382          else if (!*inspec)
383                  return(NULL);
384 <        if (inspec == stdin_name) {             /* reading from stdin? */
384 >        if (inspec == stdin_name)               /* reading from stdin? */
385                  fp = stdin;
386 <        } else if (inspec[0] == '!') {
387 <                if (!(fp = popen(inspec+1, "r")))
388 <                        return(NULL);
321 <        } else {
386 >        else if (inspec[0] == '!')
387 >                fp = popen(inspec+1, "r");
388 >        else {
389                  const char      *sp = inspec;   /* check suffix */
390                  while (*sp)
391                          ++sp;
# Line 332 | Line 399 | rmx_load(const char *inspec, RMPref rmp)
399                          dnew = rmx_from_cmatrix(cm);
400                          cm_free(cm);
401                          dnew->dtype = DTascii;
402 <                        return(dnew);
403 <                }
404 <                                                /* else open it ourselves */
338 <                if (!(fp = fopen(inspec, "r")))
339 <                        return(NULL);
402 >                        return(dnew);           /* return here */
403 >                }                               /* else open it ourselves */
404 >                fp = fopen(inspec, "r");
405          }
406 <        SET_FILE_BINARY(fp);
406 >        if (!fp)
407 >                return(NULL);
408   #ifdef getc_unlocked
409          flockfile(fp);
410   #endif
411 <        if (!(dnew = rmx_new(0,0,3))) {
412 <                fclose(fp);
411 >                                                /* load header info */
412 >        if (!rmx_load_header(dnew = rmx_new(0,0,3), fp)) {
413 >                fprintf(stderr, "Bad header in: %s\n", inspec);
414 >                if (inspec[0] == '!') pclose(fp);
415 >                else fclose(fp);
416 >                rmx_free(dnew);
417                  return(NULL);
418          }
419 <        dnew->dtype = DTascii;                  /* assumed w/o FORMAT */
420 <        if (getheader(fp, get_dminfo, dnew) < 0) {
421 <                fclose(fp);
352 <                return(NULL);
353 <        }
354 <        if ((dnew->nrows <= 0) | (dnew->ncols <= 0)) {
355 <                if (!fscnresolu(&dnew->ncols, &dnew->nrows, fp)) {
356 <                        fclose(fp);
357 <                        return(NULL);
358 <                }
359 <                if ((dnew->dtype == DTrgbe) | (dnew->dtype == DTxyze) &&
360 <                                dnew->ncomp != 3) {
361 <                        fclose(fp);
362 <                        return(NULL);
363 <                }
364 <        }
365 <        switch (dnew->dtype) {
366 <        case DTascii:
367 <                SET_FILE_TEXT(fp);
368 <                if (!rmx_load_ascii(dnew, fp))
369 <                        goto loaderr;
370 <                dnew->dtype = DTascii;          /* should leave double? */
371 <                break;
372 <        case DTfloat:
373 <                if (!rmx_load_float(dnew, fp))
374 <                        goto loaderr;
375 <                dnew->dtype = DTfloat;
376 <                break;
377 <        case DTdouble:
378 <                if (!rmx_load_double(dnew, fp))
379 <                        goto loaderr;
380 <                dnew->dtype = DTdouble;
381 <                break;
382 <        case DTrgbe:
383 <        case DTxyze:
384 <                if (!rmx_load_rgbe(dnew, fp))
385 <                        goto loaderr;
386 <                break;
387 <        case DTspec:
388 <                if (!rmx_load_spec(dnew, fp))
389 <                        goto loaderr;
390 <                break;
391 <        default:
392 <                goto loaderr;
393 <        }
394 <        if (fp != stdin) {
419 >        ok = rmx_load_data(dnew, fp);           /* allocate & load data */
420 >
421 >        if (fp != stdin) {                      /* close input stream */
422                  if (inspec[0] == '!')
423                          pclose(fp);
424                  else
# Line 401 | Line 428 | rmx_load(const char *inspec, RMPref rmp)
428          else
429                  funlockfile(fp);
430   #endif
431 +        if (!ok) {                              /* load failure? */
432 +                fprintf(stderr, "Error loading data from: %s\n", inspec);
433 +                rmx_free(dnew);
434 +                return(NULL);
435 +        }
436                                                  /* undo exposure? */
437          if ((dnew->cexp[0] != 1.f) |
438                          (dnew->cexp[1] != 1.f) | (dnew->cexp[2] != 1.f)) {
# Line 409 | Line 441 | rmx_load(const char *inspec, RMPref rmp)
441                  cmlt[0] = 1./dnew->cexp[0];
442                  cmlt[1] = 1./dnew->cexp[1];
443                  cmlt[2] = 1./dnew->cexp[2];
444 <                if (dnew->ncomp > MAXCSAMP)
445 <                        goto loaderr;
444 >                if (dnew->ncomp > MAXCSAMP) {
445 >                        fprintf(stderr, "Excess spectral components in: %s\n",
446 >                                        inspec);
447 >                        rmx_free(dnew);
448 >                        return(NULL);
449 >                }
450                  for (i = dnew->ncomp; i-- > 3; )
451                          cmlt[i] = cmlt[1];
452                  rmx_scale(dnew, cmlt);
453                  setcolor(dnew->cexp, 1.f, 1.f, 1.f);
454          }
455          return(dnew);
420 loaderr:                                        /* should report error? */
421        if (inspec[0] == '!')
422                pclose(fp);
423        else
424                fclose(fp);
425        rmx_free(dnew);
426        return(NULL);
456   }
457  
458   static int
# Line 436 | Line 465 | rmx_write_ascii(const RMATRIX *rm, FILE *fp)
465  
466          for (i = 0; i < rm->nrows; i++) {
467              for (j = 0; j < rm->ncols; j++) {
468 <                const double    *dp = rmx_lval(rm,i,j);
468 >                const double    *dp = rmx_val(rm,i,j);
469                  for (k = 0; k < rm->ncomp; k++)
470                      fprintf(fp, fmt, dp[k]);
471                  fputc('\t', fp);
# Line 458 | Line 487 | rmx_write_float(const RMATRIX *rm, FILE *fp)
487          }
488          for (i = 0; i < rm->nrows; i++)
489              for (j = 0; j < rm->ncols; j++) {
490 <                const double    *dp = rmx_lval(rm,i,j);
490 >                const double    *dp = rmx_val(rm,i,j);
491                  for (k = rm->ncomp; k--; )
492                      val[k] = (float)dp[k];
493                  if (putbinary(val, sizeof(float), rm->ncomp, fp) != rm->ncomp)
# Line 473 | Line 502 | rmx_write_double(const RMATRIX *rm, FILE *fp)
502          int     i;
503  
504          for (i = 0; i < rm->nrows; i++)
505 <                if (putbinary(rmx_lval(rm,i,0), sizeof(double)*rm->ncomp,
505 >                if (putbinary(rmx_val(rm,i,0), sizeof(double)*rm->ncomp,
506                                          rm->ncols, fp) != rm->ncols)
507                          return(0);
508          return(1);
# Line 489 | Line 518 | rmx_write_rgbe(const RMATRIX *rm, FILE *fp)
518                  return(0);
519          for (i = 0; i < rm->nrows; i++) {
520              for (j = rm->ncols; j--; ) {
521 <                const double    *dp = rmx_lval(rm,i,j);
521 >                const double    *dp = rmx_val(rm,i,j);
522                  if (rm->ncomp == 1)
523                          setcolr(scan[j], dp[0], dp[0], dp[0]);
524                  else
# Line 507 | Line 536 | rmx_write_rgbe(const RMATRIX *rm, FILE *fp)
536   static int
537   rmx_write_spec(const RMATRIX *rm, FILE *fp)
538   {
510        int     prevNCSAMP = NCSAMP;
539          uby8    *scan = (uby8 *)malloc((rm->ncomp+1)*rm->ncols);
540          int     ok = 1;
541          SCOLOR  scol;
# Line 515 | Line 543 | rmx_write_spec(const RMATRIX *rm, FILE *fp)
543  
544          if (!scan)
545                  return(0);
518        NCSAMP = rm->ncomp;             /* XXX: kosher? */
546          for (i = 0; i < rm->nrows; i++) {
547              for (j = rm->ncols; j--; ) {
548 <                const double    *dp = rmx_lval(rm,i,j);
549 <                for (k = NCSAMP; k--; )
548 >                const double    *dp = rmx_val(rm,i,j);
549 >                for (k = rm->ncomp; k--; )
550                          scol[k] = dp[k];
551 <                scolor2scolr(scan+j*(NCSAMP+1), scol, NCSAMP);
551 >                scolor2scolr(scan+j*(rm->ncomp+1), scol, rm->ncomp);
552              }
553 <            if (fwritescolrs(scan, rm->ncols, fp) < 0) {
553 >            if (fwritescolrs(scan, rm->ncomp, rm->ncols, fp) < 0) {
554                  ok = 0;
555                  break;
556              }
557          }
558          free(scan);
532        NCSAMP = prevNCSAMP;
559          return(ok);
560   }
561  
# Line 561 | Line 587 | rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
587   #ifdef getc_unlocked
588          flockfile(fp);
589   #endif
590 <                                                /* complete header */
565 <        if (rm->info)
590 >        if (rm->info)                           /* complete header */
591                  fputs(rm->info, fp);
592          if (dtype == DTfromHeader)
593                  dtype = rm->dtype;
# Line 578 | Line 603 | rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
603          else if (rm->cexp[GRN] != 1.f)
604                  fputexpos(rm->cexp[GRN], fp);
605          if ((dtype != DTrgbe) & (dtype != DTxyze)) {
606 <                if (dtype == DTspec) {
582 <                        if (rm->ncomp < 3)
583 <                                return(0);      /* bad # components */
584 <                        fputwlsplit(rm->wlpart, fp);
585 <                } else {
606 >                if (dtype != DTspec) {
607                          fprintf(fp, "NROWS=%d\n", rm->nrows);
608                          fprintf(fp, "NCOLS=%d\n", rm->ncols);
609 <                }
609 >                } else if (rm->ncomp < 3)
610 >                        return(0);              /* bad # components */
611                  fputncomp(rm->ncomp, fp);
612 +                if (dtype == DTspec || (rm->ncomp > 3 &&
613 +                                memcmp(rm->wlpart, WLPART, sizeof(WLPART))))
614 +                        fputwlsplit(rm->wlpart, fp);
615          } else if ((rm->ncomp != 3) & (rm->ncomp != 1))
616                  return(0);                      /* wrong # components */
617          if ((dtype == DTfloat) | (dtype == DTdouble))
618                  fputendian(fp);                 /* important to record */
619          fputformat(cm_fmt_id[dtype], fp);
620 <        fputc('\n', fp);
620 >        fputc('\n', fp);                        /* end of header */
621          switch (dtype) {                        /* write data */
622          case DTascii:
623                  ok = rmx_write_ascii(rm, fp);
# Line 619 | Line 644 | rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
644   #ifdef getc_unlocked
645          funlockfile(fp);
646   #endif
647 +        if (!ok) fputs("Error writing matrix\n", stderr);
648          return(ok);
649   }
650  
# Line 688 | Line 714 | rmx_transpose(const RMATRIX *rm)
714          memcpy(dnew->wlpart, rm->wlpart, sizeof(dnew->wlpart));
715          for (j = dnew->ncols; j--; )
716              for (i = dnew->nrows; i--; )
717 <                memcpy(rmx_lval(dnew,i,j), rmx_lval(rm,j,i),
717 >                memcpy(rmx_lval(dnew,i,j), rmx_val(rm,j,i),
718                                  sizeof(double)*dnew->ncomp);
719          return(dnew);
720   }
# Line 715 | Line 741 | rmx_multiply(const RMATRIX *m1, const RMATRIX *m2)
741                  for (k = mres->ncomp; k--; ) {
742                      double      d = 0;
743                      for (h = m1->ncols; h--; )
744 <                        d += rmx_lval(m1,i,h)[k] * rmx_lval(m2,h,j)[k];
744 >                        d += rmx_val(m1,i,h)[k] * rmx_val(m2,h,j)[k];
745                      rmx_lval(mres,i,j)[k] = d;
746                  }
747          return(mres);
# Line 742 | Line 768 | rmx_elemult(RMATRIX *m1, const RMATRIX *m2, int divide
768                  if (divide) {
769                      double      d;
770                      if (m2->ncomp == 1) {
771 <                        d = rmx_lval(m2,i,j)[0];
771 >                        d = rmx_val(m2,i,j)[0];
772                          if (d == 0) {
773                              ++zeroDivides;
774                              for (k = m1->ncomp; k--; )
# Line 754 | Line 780 | rmx_elemult(RMATRIX *m1, const RMATRIX *m2, int divide
780                          }
781                      } else
782                          for (k = m1->ncomp; k--; ) {
783 <                            d = rmx_lval(m2,i,j)[k];
783 >                            d = rmx_val(m2,i,j)[k];
784                              if (d == 0) {
785                                  ++zeroDivides;
786                                  rmx_lval(m1,i,j)[k] = 0;
# Line 763 | Line 789 | rmx_elemult(RMATRIX *m1, const RMATRIX *m2, int divide
789                          }
790                  } else {
791                      if (m2->ncomp == 1) {
792 <                        const double    d = rmx_lval(m2,i,j)[0];
792 >                        const double    d = rmx_val(m2,i,j)[0];
793                          for (k = m1->ncomp; k--; )
794                              rmx_lval(m1,i,j)[k] *= d;
795                      } else
796                          for (k = m1->ncomp; k--; )
797 <                            rmx_lval(m1,i,j)[k] *= rmx_lval(m2,i,j)[k];
797 >                            rmx_lval(m1,i,j)[k] *= rmx_val(m2,i,j)[k];
798                  }
799          if (zeroDivides) {
800                  rmx_addinfo(m1, "WARNING: zero divide(s) corrupted results\n");
# Line 804 | Line 830 | rmx_sum(RMATRIX *msum, const RMATRIX *madd, const doub
830                  rmx_addinfo(msum, rmx_mismatch_warn);
831          for (i = msum->nrows; i--; )
832              for (j = msum->ncols; j--; ) {
833 <                const double    *da = rmx_lval(madd,i,j);
833 >                const double    *da = rmx_val(madd,i,j);
834                  double          *ds = rmx_lval(msum,i,j);
835                  for (k = msum->ncomp; k--; )
836                       ds[k] += sf[k] * da[k];
# Line 856 | Line 882 | rmx_transform(const RMATRIX *msrc, int n, const double
882          dnew->dtype = msrc->dtype;
883          for (i = dnew->nrows; i--; )
884              for (j = dnew->ncols; j--; ) {
885 <                const double    *ds = rmx_lval(msrc,i,j);
885 >                const double    *ds = rmx_val(msrc,i,j);
886                  for (kd = dnew->ncomp; kd--; ) {
887                      double      d = 0;
888                      for (ks = msrc->ncomp; ks--; )
# Line 905 | Line 931 | cm_from_rmatrix(const RMATRIX *rm)
931                  return(NULL);
932          for (i = cnew->nrows; i--; )
933              for (j = cnew->ncols; j--; ) {
934 <                const double    *dp = rmx_lval(rm,i,j);
934 >                const double    *dp = rmx_val(rm,i,j);
935                  COLORV          *cv = cm_lval(cnew,i,j);
936                  switch (rm->ncomp) {
937                  case 3:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines