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.23 by greg, Tue Aug 30 14:54:08 2016 UTC vs.
Revision 2.35 by greg, Wed Aug 14 18:20:02 2019 UTC

# Line 9 | Line 9 | static const char RCSid[] = "$Id$";
9   #include <stdlib.h>
10   #include <string.h>
11   #include <fcntl.h>
12 + #include <errno.h>
13   #include "rtio.h"
14   #include "platform.h"
15   #include "resolu.h"
# Line 27 | Line 28 | rmx_alloc(int nr, int nc, int n)
28                  return(NULL);
29          dnew = (RMATRIX *)malloc(sizeof(RMATRIX)-sizeof(dnew->mtx) +
30                                          sizeof(dnew->mtx[0])*(n*nr*nc));
31 <        if (dnew == NULL)
31 >        if (!dnew)
32                  return(NULL);
33          dnew->nrows = nr; dnew->ncols = nc; dnew->ncomp = n;
34          dnew->dtype = DTdouble;
# Line 62 | Line 63 | rmx_newtype(int dtyp1, int dtyp2)
63   int
64   rmx_addinfo(RMATRIX *rm, const char *info)
65   {
66 <        if (!info || !*info)
66 >        if (!rm || !info || !*info)
67                  return(0);
68          if (!rm->info) {
69                  rm->info = (char *)malloc(strlen(info)+1);
# Line 80 | Line 81 | static int
81   get_dminfo(char *s, void *p)
82   {
83          RMATRIX *ip = (RMATRIX *)p;
84 <        char    fmt[64];
84 >        char    fmt[MAXFMTLEN];
85          int     i;
86  
87          if (headidval(fmt, s))
# Line 97 | Line 98 | get_dminfo(char *s, void *p)
98                  ip->ncols = atoi(s+6);
99                  return(0);
100          }
101 +        if ((i = isbigendian(s)) >= 0) {
102 +                ip->swapin = (nativebigendian() != i);
103 +                return(0);
104 +        }
105          if (!formatval(fmt, s)) {
106                  rmx_addinfo(ip, s);
107                  return(0);
# Line 136 | Line 141 | rmx_load_float(RMATRIX *rm, FILE *fp)
141              for (j = 0; j < rm->ncols; j++) {
142                  if (getbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
143                      return(0);
144 +                if (rm->swapin)
145 +                    swap32((char *)val, rm->ncomp);
146                  for (k = rm->ncomp; k--; )
147                       rmx_lval(rm,i,j,k) = val[k];
148              }
# Line 145 | Line 152 | rmx_load_float(RMATRIX *rm, FILE *fp)
152   static int
153   rmx_load_double(RMATRIX *rm, FILE *fp)
154   {
155 <        int     i, j, k;
149 <        double  val[100];
155 >        int     i, j;
156  
151        if (rm->ncomp > 100) {
152                fputs("Unsupported # components in rmx_load_double()\n", stderr);
153                exit(1);
154        }
157          for (i = 0; i < rm->nrows; i++)
158              for (j = 0; j < rm->ncols; j++) {
159 <                if (getbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
159 >                if (getbinary(&rmx_lval(rm,i,j,0), sizeof(double), rm->ncomp, fp) != rm->ncomp)
160                      return(0);
161 <                for (k = rm->ncomp; k--; )
162 <                     rmx_lval(rm,i,j,k) = val[k];
161 >                if (rm->swapin)
162 >                    swap64((char *)&rmx_lval(rm,i,j,0), rm->ncomp);
163              }
164          return(1);
165   }
# Line 168 | Line 170 | rmx_load_rgbe(RMATRIX *rm, FILE *fp)
170          COLOR   *scan = (COLOR *)malloc(sizeof(COLOR)*rm->ncols);
171          int     i, j;
172  
173 <        if (scan == NULL)
173 >        if (!scan)
174                  return(0);
175          for (i = 0; i < rm->nrows; i++) {
176              if (freadscan(scan, rm->ncols, fp) < 0) {
# Line 193 | Line 195 | rmx_load(const char *inspec)
195          RMATRIX         dinfo;
196          RMATRIX         *dnew;
197  
198 <        if (inspec == NULL) {                   /* reading from stdin? */
198 >        if (!inspec) {                          /* reading from stdin? */
199                  inspec = "<stdin>";
200                  SET_FILE_BINARY(stdin);
201          } else if (inspec[0] == '!') {
202 <                if ((fp = popen(inspec+1, "r")) == NULL)
202 >                if (!(fp = popen(inspec+1, "r")))
203                          return(NULL);
204                  SET_FILE_BINARY(stdin);
205          } else {
# Line 208 | Line 210 | rmx_load(const char *inspec)
210                          --sp;
211                  if (!strcasecmp(sp, "XML")) {   /* assume it's a BSDF */
212                          CMATRIX *cm = cm_loadBTDF((char *)inspec);
213 <                        if (cm == NULL)
213 >                        if (!cm)
214                                  return(NULL);
215                          dnew = rmx_from_cmatrix(cm);
216                          cm_free(cm);
# Line 216 | Line 218 | rmx_load(const char *inspec)
218                          return(dnew);
219                  }
220                                                  /* else open it ourselves */
221 <                if ((fp = fopen(inspec, "rb")) == NULL)
221 >                if (!(fp = fopen(inspec, "rb")))
222                          return(NULL);
223          }
224   #ifdef getc_unlocked
# Line 224 | Line 226 | rmx_load(const char *inspec)
226   #endif
227          dinfo.nrows = dinfo.ncols = dinfo.ncomp = 0;
228          dinfo.dtype = DTascii;                  /* assumed w/o FORMAT */
229 +        dinfo.swapin = 0;
230          dinfo.info = NULL;
231          if (getheader(fp, get_dminfo, &dinfo) < 0) {
232                  fclose(fp);
# Line 243 | Line 246 | rmx_load(const char *inspec)
246                  }
247          }
248          dnew = rmx_alloc(dinfo.nrows, dinfo.ncols, dinfo.ncomp);
249 <        if (dnew == NULL) {
249 >        if (!dnew) {
250                  fclose(fp);
251                  return(NULL);
252          }
# Line 256 | Line 259 | rmx_load(const char *inspec)
259                  dnew->dtype = DTascii;          /* should leave double? */
260                  break;
261          case DTfloat:
262 +                dnew->swapin = dinfo.swapin;
263                  if (!rmx_load_float(dnew, fp))
264                          goto loaderr;
265                  dnew->dtype = DTfloat;
266                  break;
267          case DTdouble:
268 +                dnew->swapin = dinfo.swapin;
269                  if (!rmx_load_double(dnew, fp))
270                          goto loaderr;
271                  dnew->dtype = DTdouble;
# Line 297 | Line 302 | loaderr:                                       /* should report error? */
302   static int
303   rmx_write_ascii(const RMATRIX *rm, FILE *fp)
304   {
305 +        const char      *fmt = (rm->dtype == DTfloat) ? " %.7e" :
306 +                        (rm->dtype == DTrgbe) | (rm->dtype == DTxyze) ? " %.3e" :
307 +                                " %.15e" ;
308          int     i, j, k;
309  
310          for (i = 0; i < rm->nrows; i++) {
311              for (j = 0; j < rm->ncols; j++) {
312                  for (k = 0; k < rm->ncomp; k++)
313 <                    fprintf(fp, " %.15e", rmx_lval(rm,i,j,k));
313 >                    fprintf(fp, fmt, rmx_lval(rm,i,j,k));
314                  fputc('\t', fp);
315              }
316              fputc('\n', fp);
# Line 333 | Line 341 | rmx_write_float(const RMATRIX *rm, FILE *fp)
341   static int
342   rmx_write_double(const RMATRIX *rm, FILE *fp)
343   {
344 <        int     i, j, k;
337 <        double  val[100];
344 >        int     i, j;
345  
339        if (rm->ncomp > 100) {
340                fputs("Unsupported # components in rmx_write_double()\n", stderr);
341                exit(1);
342        }
346          for (i = 0; i < rm->nrows; i++)
347 <            for (j = 0; j < rm->ncols; j++) {
348 <                for (k = rm->ncomp; k--; )
346 <                    val[k] = rmx_lval(rm,i,j,k);
347 <                if (putbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
347 >            for (j = 0; j < rm->ncols; j++)
348 >                if (putbinary(&rmx_lval(rm,i,j,0), sizeof(double), rm->ncomp, fp) != rm->ncomp)
349                          return(0);
349            }
350          return(1);
351   }
352  
353   static int
354   rmx_write_rgbe(const RMATRIX *rm, FILE *fp)
355   {
356 <        COLOR   *scan = (COLOR *)malloc(sizeof(COLOR)*rm->ncols);
356 >        COLR    *scan = (COLR *)malloc(sizeof(COLR)*rm->ncols);
357          int     i, j;
358  
359 <        if (scan == NULL)
359 >        if (!scan)
360                  return(0);
361          for (i = 0; i < rm->nrows; i++) {
362              for (j = rm->ncols; j--; )
363 <                setcolor(scan[j],       rmx_lval(rm,i,j,0),
363 >                setcolr(scan[j],        rmx_lval(rm,i,j,0),
364                                          rmx_lval(rm,i,j,1),
365                                          rmx_lval(rm,i,j,2)      );
366 <            if (fwritescan(scan, rm->ncols, fp) < 0) {
366 >            if (fwritecolrs(scan, rm->ncols, fp) < 0) {
367                  free(scan);
368                  return(0);
369              }
# Line 379 | Line 379 | rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
379          RMATRIX *mydm = NULL;
380          int     ok = 1;
381  
382 <        if ((rm == NULL) | (fp == NULL))
382 >        if (!rm | !fp)
383                  return(0);
384   #ifdef getc_unlocked
385          flockfile(fp);
# Line 403 | Line 403 | rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
403                          return(0);
404                  cmtx[0] = cmtx[1] = cmtx[2] = 1;
405                  mydm = rmx_transform(rm, 3, cmtx);
406 <                if (mydm == NULL)
406 >                if (!mydm)
407                          return(0);
408                  rm = mydm;
409          }
410 +        if ((dtype == DTfloat) | (dtype == DTdouble))
411 +                fputendian(fp);                 /* important to record */
412          fputformat((char *)cm_fmt_id[dtype], fp);
413          fputc('\n', fp);
414          switch (dtype) {                        /* write data */
# Line 431 | Line 433 | rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
433   #ifdef getc_unlocked
434          funlockfile(fp);
435   #endif
436 <        rmx_free(mydm);
436 >        if (mydm)
437 >                rmx_free(mydm);
438          return(ok);
439   }
440  
# Line 442 | Line 445 | rmx_identity(const int dim, const int n)
445          RMATRIX *rid = rmx_alloc(dim, dim, n);
446          int     i, k;
447  
448 <        if (rid == NULL)
448 >        if (!rid)
449                  return(NULL);
450          memset(rid->mtx, 0, sizeof(rid->mtx[0])*n*dim*dim);
451          for (i = dim; i--; )
# Line 457 | Line 460 | rmx_copy(const RMATRIX *rm)
460   {
461          RMATRIX *dnew;
462  
463 <        if (rm == NULL)
463 >        if (!rm)
464                  return(NULL);
465          dnew = rmx_alloc(rm->nrows, rm->ncols, rm->ncomp);
466 <        if (dnew == NULL)
466 >        if (!dnew)
467                  return(NULL);
468          rmx_addinfo(dnew, rm->info);
469          dnew->dtype = rm->dtype;
# Line 476 | Line 479 | rmx_transpose(const RMATRIX *rm)
479          RMATRIX *dnew;
480          int     i, j, k;
481  
482 <        if (rm == NULL)
482 >        if (!rm)
483                  return(0);
484 +        if ((rm->nrows == 1) | (rm->ncols == 1)) {
485 +                dnew = rmx_copy(rm);
486 +                if (!dnew)
487 +                        return(NULL);
488 +                dnew->nrows = rm->ncols;
489 +                dnew->ncols = rm->nrows;
490 +                return(dnew);
491 +        }
492          dnew = rmx_alloc(rm->ncols, rm->nrows, rm->ncomp);
493 <        if (dnew == NULL)
493 >        if (!dnew)
494                  return(NULL);
495          if (rm->info) {
496                  rmx_addinfo(dnew, rm->info);
# Line 500 | Line 511 | rmx_multiply(const RMATRIX *m1, const RMATRIX *m2)
511          RMATRIX *mres;
512          int     i, j, k, h;
513  
514 <        if ((m1 == NULL) | (m2 == NULL) ||
504 <                        (m1->ncomp != m2->ncomp) | (m1->ncols != m2->nrows))
514 >        if (!m1 | !m2 || (m1->ncomp != m2->ncomp) | (m1->ncols != m2->nrows))
515                  return(NULL);
516          mres = rmx_alloc(m1->nrows, m2->ncols, m1->ncomp);
517 <        if (mres == NULL)
517 >        if (!mres)
518                  return(NULL);
519          i = rmx_newtype(m1->dtype, m2->dtype);
520          if (i)
# Line 516 | Line 526 | rmx_multiply(const RMATRIX *m1, const RMATRIX *m2)
526                  for (k = mres->ncomp; k--; ) {
527                      long double d = 0;
528                      for (h = m1->ncols; h--; )
529 <                        d += (long double)rmx_lval(m1,i,h,k) *
520 <                                (long double)rmx_lval(m2,h,j,k);
529 >                        d += rmx_lval(m1,i,h,k) * rmx_lval(m2,h,j,k);
530                      rmx_lval(mres,i,j,k) = (double)d;
531                  }
532          return(mres);
533   }
534  
535 + /* Element-wise multiplication (or division) of m2 into m1 */
536 + int
537 + rmx_elemult(RMATRIX *m1, const RMATRIX *m2, int divide)
538 + {
539 +        int     zeroDivides = 0;
540 +        int     i, j, k;
541 +
542 +        if (!m1 | !m2 || (m1->ncols != m2->ncols) | (m1->nrows != m2->nrows))
543 +                return(0);
544 +        if ((m2->ncomp > 1) & (m2->ncomp != m1->ncomp))
545 +                return(0);
546 +        i = rmx_newtype(m1->dtype, m2->dtype);
547 +        if (i)
548 +                m1->dtype = i;
549 +        else
550 +                rmx_addinfo(m1, rmx_mismatch_warn);
551 +        for (i = m1->nrows; i--; )
552 +            for (j = m1->ncols; j--; )
553 +                if (divide) {
554 +                    double      d;
555 +                    if (m2->ncomp == 1) {
556 +                        d = rmx_lval(m2,i,j,0);
557 +                        if (d == 0) {
558 +                            ++zeroDivides;
559 +                            for (k = m1->ncomp; k--; )
560 +                                rmx_lval(m1,i,j,k) = 0;
561 +                        } else {
562 +                            d = 1./d;
563 +                            for (k = m1->ncomp; k--; )
564 +                                rmx_lval(m1,i,j,k) *= d;
565 +                        }
566 +                    } else
567 +                        for (k = m1->ncomp; k--; ) {
568 +                            d = rmx_lval(m2,i,j,k);
569 +                            if (d == 0) {
570 +                                ++zeroDivides;
571 +                                rmx_lval(m1,i,j,k) = 0;
572 +                            } else
573 +                                rmx_lval(m1,i,j,k) /= d;
574 +                        }
575 +                } else {
576 +                    if (m2->ncomp == 1) {
577 +                        const double    d = rmx_lval(m2,i,j,0);
578 +                        for (k = m1->ncomp; k--; )
579 +                            rmx_lval(m1,i,j,k) *= d;
580 +                    } else
581 +                        for (k = m1->ncomp; k--; )
582 +                            rmx_lval(m1,i,j,k) *= rmx_lval(m2,i,j,k);
583 +                }
584 +        if (zeroDivides) {
585 +                rmx_addinfo(m1, "WARNING: zero divide(s) corrupted results\n");
586 +                errno = ERANGE;
587 +        }
588 +        return(1);
589 + }
590 +
591   /* Sum second matrix into first, applying scale factor beforehand */
592   int
593   rmx_sum(RMATRIX *msum, const RMATRIX *madd, const double sf[])
# Line 530 | Line 595 | rmx_sum(RMATRIX *msum, const RMATRIX *madd, const doub
595          double  *mysf = NULL;
596          int     i, j, k;
597  
598 <        if ((msum == NULL) | (madd == NULL) ||
598 >        if (!msum | !madd ||
599                          (msum->nrows != madd->nrows) |
600                          (msum->ncols != madd->ncols) |
601                          (msum->ncomp != madd->ncomp))
602                  return(0);
603 <        if (sf == NULL) {
603 >        if (!sf) {
604                  mysf = (double *)malloc(sizeof(double)*msum->ncomp);
605 <                if (mysf == NULL)
605 >                if (!mysf)
606                          return(0);
607                  for (k = msum->ncomp; k--; )
608                          mysf[k] = 1;
# Line 552 | Line 617 | rmx_sum(RMATRIX *msum, const RMATRIX *madd, const doub
617              for (j = msum->ncols; j--; )
618                  for (k = msum->ncomp; k--; )
619                       rmx_lval(msum,i,j,k) += sf[k] * rmx_lval(madd,i,j,k);
620 <
621 <        free(mysf);
620 >        if (mysf)
621 >                free(mysf);
622          return(1);
623   }
624  
# Line 563 | Line 628 | rmx_scale(RMATRIX *rm, const double sf[])
628   {
629          int     i, j, k;
630  
631 <        if ((rm == NULL) | (sf == NULL))
631 >        if (!rm | !sf)
632                  return(0);
633          for (i = rm->nrows; i--; )
634              for (j = rm->ncols; j--; )
635                  for (k = rm->ncomp; k--; )
636                      rmx_lval(rm,i,j,k) *= sf[k];
637  
638 +        if (rm->info)
639 +                rmx_addinfo(rm, "Applied scalar\n");
640          return(1);
641   }
642  
# Line 580 | Line 647 | rmx_transform(const RMATRIX *msrc, int n, const double
647          int     i, j, ks, kd;
648          RMATRIX *dnew;
649  
650 <        if ((msrc == NULL) | (n <= 0) | (cmat == NULL))
650 >        if (!msrc | (n <= 0) | !cmat)
651                  return(NULL);
652          dnew = rmx_alloc(msrc->nrows, msrc->ncols, n);
653 <        if (dnew == NULL)
653 >        if (!dnew)
654                  return(NULL);
655 +        if (msrc->info) {
656 +                char    buf[128];
657 +                sprintf(buf, "Applied %dx%d matrix transform\n",
658 +                                dnew->ncomp, msrc->ncomp);
659 +                rmx_addinfo(dnew, msrc->info);
660 +                rmx_addinfo(dnew, buf);
661 +        }
662          dnew->dtype = msrc->dtype;
663          for (i = dnew->nrows; i--; )
664              for (j = dnew->ncols; j--; )
# Line 604 | Line 678 | rmx_from_cmatrix(const CMATRIX *cm)
678          int     i, j;
679          RMATRIX *dnew;
680  
681 <        if (cm == NULL)
681 >        if (!cm)
682                  return(NULL);
683          dnew = rmx_alloc(cm->nrows, cm->ncols, 3);
684 <        if (dnew == NULL)
684 >        if (!dnew)
685                  return(NULL);
686          dnew->dtype = DTfloat;
687          for (i = dnew->nrows; i--; )
# Line 627 | Line 701 | cm_from_rmatrix(const RMATRIX *rm)
701          int     i, j;
702          CMATRIX *cnew;
703  
704 <        if (rm == NULL || rm->ncomp != 3)
704 >        if (!rm || rm->ncomp != 3)
705                  return(NULL);
706          cnew = cm_alloc(rm->nrows, rm->ncols);
707 <        if (cnew == NULL)
707 >        if (!cnew)
708                  return(NULL);
709          for (i = cnew->nrows; i--; )
710              for (j = cnew->ncols; j--; ) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines