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.3 by greg, Tue Jul 8 16:39:41 2014 UTC vs.
Revision 2.8 by greg, Wed Aug 27 13:33:47 2014 UTC

# Line 12 | Line 12 | static const char RCSid[] = "$Id$";
12   #include "resolu.h"
13   #include "rmatrix.h"
14  
15 < typedef struct {
16 <        int     nrows, ncols, ncomp;
17 <        int     dtype;
18 < } DMINFO;
15 > static char     rmx_mismatch_warn[] = "WARNING: data type mismatch\n";
16  
17   /* Allocate a nr x nc matrix with n components */
18   RMATRIX *
# Line 30 | Line 27 | rmx_alloc(int nr, int nc, int n)
27          if (dnew == NULL)
28                  return(NULL);
29          dnew->nrows = nr; dnew->ncols = nc; dnew->ncomp = n;
30 +        dnew->dtype = DTdouble;
31 +        dnew->info = NULL;
32          return(dnew);
33   }
34  
35 + /* Free a RMATRIX array */
36 + void
37 + rmx_free(RMATRIX *rm)
38 + {
39 +        if (!rm) return;
40 +        if (rm->info)
41 +                free(rm->info);
42 +        free(rm);
43 + }
44 +
45 + /* Resolve data type based on two input types (returns 0 for mismatch) */
46 + int
47 + rmx_newtype(int dtyp1, int dtyp2)
48 + {
49 +        if ((dtyp1==DTxyze) | (dtyp1==DTrgbe) && dtyp1 != dtyp2)
50 +                return(0);
51 +        if (dtyp1 < dtyp2)
52 +                return(dtyp1);
53 +        return(dtyp2);
54 + }
55 +
56 + /* Append header information associated with matrix data */
57 + int
58 + rmx_addinfo(RMATRIX *rm, const char *info)
59 + {
60 +        if (!info || !*info)
61 +                return(0);
62 +        if (!rm->info) {
63 +                rm->info = (char *)malloc(strlen(info)+1);
64 +                if (rm->info) rm->info[0] = '\0';
65 +        } else
66 +                rm->info = (char *)realloc(rm->info,
67 +                                strlen(rm->info)+strlen(info)+1);
68 +        if (!rm->info)
69 +                return(0);
70 +        strcat(rm->info, info);
71 +        return(1);
72 + }
73 +
74   static int
75   get_dminfo(char *s, void *p)
76   {
77 <        DMINFO  *ip = (DMINFO *)p;
78 <        char    fmt[32];
77 >        RMATRIX *ip = (RMATRIX *)p;
78 >        char    fmt[64];
79          int     i;
80  
81 +        if (headidval(fmt, s))
82 +                return(0);
83          if (!strncmp(s, "NCOMP=", 6)) {
84                  ip->ncomp = atoi(s+6);
85                  return(0);
# Line 52 | Line 92 | get_dminfo(char *s, void *p)
92                  ip->ncols = atoi(s+6);
93                  return(0);
94          }
95 <        if (!formatval(fmt, s))
95 >        if (!formatval(fmt, s)) {
96 >                rmx_addinfo(ip, s);
97                  return(0);
98 +        }
99          for (i = 1; i < DTend; i++)
100                  if (!strcmp(fmt, cm_fmt_id[i])) {
101                          ip->dtype = i;
# Line 145 | Line 187 | RMATRIX *
187   rmx_load(const char *fname)
188   {
189          FILE            *fp = stdin;
190 <        DMINFO          dinfo;
190 >        RMATRIX         dinfo;
191          RMATRIX         *dnew;
192  
193          if (fname == NULL) {                    /* reading from stdin? */
194                  fname = "<stdin>";
195 + #ifdef _WIN32
196 +                _setmode(fileno(stdin), _O_BINARY);
197 + #endif
198          } else {
199                  const char      *sp = fname;    /* check suffix */
200                  while (*sp)
# Line 172 | Line 217 | rmx_load(const char *fname)
217          flockfile(fp);
218   #endif
219          dinfo.nrows = dinfo.ncols = dinfo.ncomp = 0;
220 <        dinfo.dtype = DTascii;
220 >        dinfo.dtype = DTascii;                  /* assumed w/o FORMAT */
221 >        dinfo.info = NULL;
222          if (getheader(fp, get_dminfo, &dinfo) < 0) {
223                  fclose(fp);
224                  return(NULL);
225          }
226 <        if ((dinfo.dtype == DTrgbe) | (dinfo.dtype == DTxyze)) {
226 >        if ((dinfo.nrows <= 0) | (dinfo.ncols <= 0)) {
227                  if (!fscnresolu(&dinfo.ncols, &dinfo.nrows, fp)) {
228                          fclose(fp);
229                          return(NULL);
230                  }
231 <                dinfo.ncomp = 3;
231 >                if (dinfo.ncomp <= 0)
232 >                        dinfo.ncomp = 3;
233 >                else if ((dinfo.dtype == DTrgbe) | (dinfo.dtype == DTxyze) &&
234 >                                dinfo.ncomp != 3) {
235 >                        fclose(fp);
236 >                        return(NULL);
237 >                }
238          }
239          dnew = rmx_alloc(dinfo.nrows, dinfo.ncols, dinfo.ncomp);
240          if (dnew == NULL) {
241                  fclose(fp);
242                  return(NULL);
243          }
244 +        dnew->info = dinfo.info;
245          switch (dinfo.dtype) {
246          case DTascii:
247                  if (!rmx_load_ascii(dnew, fp))
# Line 197 | Line 250 | rmx_load(const char *fname)
250          case DTfloat:
251                  if (!rmx_load_float(dnew, fp))
252                          goto loaderr;
253 +                dnew->dtype = DTfloat;
254                  break;
255          case DTdouble:
256                  if (!rmx_load_double(dnew, fp))
257                          goto loaderr;
258 +                dnew->dtype = DTdouble;
259                  break;
260          case DTrgbe:
261          case DTxyze:
262                  if (!rmx_load_rgbe(dnew, fp))
263                          goto loaderr;
264 +                dnew->dtype = dinfo.dtype;
265                  break;
266          default:
267                  goto loaderr;
# Line 299 | Line 355 | rmx_write_rgbe(const RMATRIX *rm, FILE *fp)
355          return(1);
356   }
357  
358 < /* Write matrix to file type indicated by dt */
358 > /* Write matrix to file type indicated by dtype */
359   long
360   rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
361   {
# Line 309 | Line 365 | rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
365          if ((rm == NULL) | (fp == NULL))
366                  return(0);
367                                                  /* complete header */
368 +        if (rm->info)
369 +                fputs(rm->info, fp);
370 +        if (dtype == DTfromHeader)
371 +                dtype = rm->dtype;
372 +        else if ((dtype == DTrgbe) & (rm->dtype == DTxyze))
373 +                dtype = DTxyze;
374 +        else if ((dtype = DTxyze) & (rm->dtype == DTrgbe))
375 +                dtype = DTrgbe;
376          if ((dtype != DTrgbe) & (dtype != DTxyze)) {
377                  fprintf(fp, "NROWS=%d\n", rm->nrows);
378                  fprintf(fp, "NCOLS=%d\n", rm->ncols);
# Line 377 | Line 441 | rmx_copy(const RMATRIX *rm)
441          dnew = rmx_alloc(rm->nrows, rm->ncols, rm->ncomp);
442          if (dnew == NULL)
443                  return(NULL);
444 +        rmx_addinfo(dnew, rm->info);
445 +        dnew->dtype = rm->dtype;
446          memcpy(dnew->mtx, rm->mtx,
447                  sizeof(rm->mtx[0])*rm->ncomp*rm->nrows*rm->ncols);
448          return(dnew);
# Line 394 | Line 460 | rmx_transpose(const RMATRIX *rm)
460          dnew = rmx_alloc(rm->ncols, rm->nrows, rm->ncomp);
461          if (dnew == NULL)
462                  return(NULL);
463 +        if (rm->info) {
464 +                rmx_addinfo(dnew, rm->info);
465 +                rmx_addinfo(dnew, "Transposed rows and columns\n");
466 +        }
467 +        dnew->dtype = rm->dtype;
468          for (i = dnew->nrows; i--; )
469              for (j = dnew->ncols; j--; )
470                  for (k = dnew->ncomp; k--; )
# Line 414 | Line 485 | rmx_multiply(const RMATRIX *m1, const RMATRIX *m2)
485          mres = rmx_alloc(m1->nrows, m2->ncols, m1->ncomp);
486          if (mres == NULL)
487                  return(NULL);
488 +        i = rmx_newtype(m1->dtype, m2->dtype);
489 +        if (i)
490 +                mres->dtype = i;
491 +        else
492 +                rmx_addinfo(mres, rmx_mismatch_warn);
493          for (i = mres->nrows; i--; )
494              for (j = mres->ncols; j--; )
495 <                for (h = m1->ncols; h--; ) {
495 >                for (k = mres->ncomp; k--; ) {
496                      long double d = 0;
497 <                    for (k = mres->ncomp; k--; )
497 >                    for (h = m1->ncols; h--; )
498                          d += (long double)rmx_lval(m1,i,h,k) *
499                                  (long double)rmx_lval(m2,h,j,k);
500                      rmx_lval(mres,i,j,k) = (double)d;
# Line 446 | Line 522 | rmx_sum(RMATRIX *msum, const RMATRIX *madd, const doub
522                          mysf[k] = 1;
523                  sf = mysf;
524          }
525 +        i = rmx_newtype(msum->dtype, madd->dtype);
526 +        if (i)
527 +                msum->dtype = i;
528 +        else
529 +                rmx_addinfo(msum, rmx_mismatch_warn);
530          for (i = msum->nrows; i--; )
531              for (j = msum->ncols; j--; )
532                  for (k = msum->ncomp; k--; )
# Line 483 | Line 564 | rmx_transform(const RMATRIX *msrc, int n, const double
564          dnew = rmx_alloc(msrc->nrows, msrc->ncols, n);
565          if (dnew == NULL)
566                  return(NULL);
567 +        dnew->dtype = msrc->dtype;
568          for (i = dnew->nrows; i--; )
569              for (j = dnew->ncols; j--; )
570                  for (kd = dnew->ncomp; kd--; ) {
# Line 506 | Line 588 | rmx_from_cmatrix(const CMATRIX *cm)
588          dnew = rmx_alloc(cm->nrows, cm->ncols, 3);
589          if (dnew == NULL)
590                  return(NULL);
591 +        dnew->dtype = DTfloat;
592          for (i = dnew->nrows; i--; )
593              for (j = dnew->ncols; j--; ) {
594                  const COLORV    *cv = cm_lval(cm,i,j);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines