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.21 by greg, Thu Aug 18 00:52:48 2016 UTC

# Line 9 | Line 9 | static const char RCSid[] = "$Id$";
9   #include <stdlib.h>
10   #include <string.h>
11   #include <fcntl.h>
12 + #include "rtio.h"
13 + #include "platform.h"
14   #include "resolu.h"
15 + #include "paths.h"
16   #include "rmatrix.h"
17  
18 < typedef struct {
16 <        int     nrows, ncols, ncomp;
17 <        int     dtype;
18 < } DMINFO;
18 > static char     rmx_mismatch_warn[] = "WARNING: data type mismatch\n";
19  
20   /* Allocate a nr x nc matrix with n components */
21   RMATRIX *
# Line 30 | Line 30 | rmx_alloc(int nr, int nc, int n)
30          if (dnew == NULL)
31                  return(NULL);
32          dnew->nrows = nr; dnew->ncols = nc; dnew->ncomp = n;
33 +        dnew->dtype = DTdouble;
34 +        dnew->info = NULL;
35          return(dnew);
36   }
37  
38 + /* Free a RMATRIX array */
39 + void
40 + rmx_free(RMATRIX *rm)
41 + {
42 +        if (!rm) return;
43 +        if (rm->info)
44 +                free(rm->info);
45 +        free(rm);
46 + }
47 +
48 + /* Resolve data type based on two input types (returns 0 for mismatch) */
49 + int
50 + rmx_newtype(int dtyp1, int dtyp2)
51 + {
52 +        if ((dtyp1==DTxyze) | (dtyp1==DTrgbe) |
53 +                        (dtyp2==DTxyze) | (dtyp2==DTrgbe)
54 +                        && dtyp1 != dtyp2)
55 +                return(0);
56 +        if (dtyp1 < dtyp2)
57 +                return(dtyp1);
58 +        return(dtyp2);
59 + }
60 +
61 + /* Append header information associated with matrix data */
62 + int
63 + rmx_addinfo(RMATRIX *rm, const char *info)
64 + {
65 +        if (!info || !*info)
66 +                return(0);
67 +        if (!rm->info) {
68 +                rm->info = (char *)malloc(strlen(info)+1);
69 +                if (rm->info) rm->info[0] = '\0';
70 +        } else
71 +                rm->info = (char *)realloc(rm->info,
72 +                                strlen(rm->info)+strlen(info)+1);
73 +        if (!rm->info)
74 +                return(0);
75 +        strcat(rm->info, info);
76 +        return(1);
77 + }
78 +
79   static int
80   get_dminfo(char *s, void *p)
81   {
82 <        DMINFO  *ip = (DMINFO *)p;
83 <        char    fmt[32];
82 >        RMATRIX *ip = (RMATRIX *)p;
83 >        char    fmt[64];
84          int     i;
85  
86 +        if (headidval(fmt, s))
87 +                return(0);
88          if (!strncmp(s, "NCOMP=", 6)) {
89                  ip->ncomp = atoi(s+6);
90                  return(0);
# Line 52 | Line 97 | get_dminfo(char *s, void *p)
97                  ip->ncols = atoi(s+6);
98                  return(0);
99          }
100 <        if (!formatval(fmt, s))
100 >        if (!formatval(fmt, s)) {
101 >                rmx_addinfo(ip, s);
102                  return(0);
103 +        }
104          for (i = 1; i < DTend; i++)
105                  if (!strcmp(fmt, cm_fmt_id[i])) {
106                          ip->dtype = i;
# Line 66 | Line 113 | static int
113   rmx_load_ascii(RMATRIX *rm, FILE *fp)
114   {
115          int     i, j, k;
116 < #ifdef _WIN32
70 <        _setmode(fileno(fp), _O_TEXT);
71 < #endif
116 >
117          for (i = 0; i < rm->nrows; i++)
118              for (j = 0; j < rm->ncols; j++)
119                  for (k = 0; k < rm->ncomp; k++)
# Line 89 | Line 134 | rmx_load_float(RMATRIX *rm, FILE *fp)
134          }
135          for (i = 0; i < rm->nrows; i++)
136              for (j = 0; j < rm->ncols; j++) {
137 <                if (fread(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
137 >                if (getbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
138                      return(0);
139                  for (k = rm->ncomp; k--; )
140                       rmx_lval(rm,i,j,k) = val[k];
# Line 109 | Line 154 | rmx_load_double(RMATRIX *rm, FILE *fp)
154          }
155          for (i = 0; i < rm->nrows; i++)
156              for (j = 0; j < rm->ncols; j++) {
157 <                if (fread(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
157 >                if (getbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
158                      return(0);
159                  for (k = rm->ncomp; k--; )
160                       rmx_lval(rm,i,j,k) = val[k];
# Line 142 | Line 187 | rmx_load_rgbe(RMATRIX *rm, FILE *fp)
187  
188   /* Load matrix from supported file type */
189   RMATRIX *
190 < rmx_load(const char *fname)
190 > rmx_load(const char *inspec)
191   {
192          FILE            *fp = stdin;
193 <        DMINFO          dinfo;
193 >        RMATRIX         dinfo;
194          RMATRIX         *dnew;
195  
196 <        if (fname == NULL) {                    /* reading from stdin? */
197 <                fname = "<stdin>";
196 >        if (inspec == NULL) {                   /* reading from stdin? */
197 >                inspec = "<stdin>";
198 > #if defined(_WIN32) || defined(_WIN64)
199 >                _setmode(fileno(stdin), _O_BINARY);
200 > #endif
201 >        } else if (inspec[0] == '!') {
202 >                if ((fp = popen(inspec+1, "r")) == NULL)
203 >                        return(NULL);
204 > #if defined(_WIN32) || defined(_WIN64)
205 >                _setmode(fileno(fp), _O_BINARY);
206 > #endif
207          } else {
208 <                const char      *sp = fname;    /* check suffix */
208 >                const char      *sp = inspec;   /* check suffix */
209                  while (*sp)
210                          ++sp;
211 <                while (sp > fname && sp[-1] != '.')
211 >                while (sp > inspec && sp[-1] != '.')
212                          --sp;
213                  if (!strcasecmp(sp, "XML")) {   /* assume it's a BSDF */
214 <                        CMATRIX *cm = cm_loadBTDF((char *)fname);
214 >                        CMATRIX *cm = cm_loadBTDF((char *)inspec);
215                          if (cm == NULL)
216                                  return(NULL);
217                          dnew = rmx_from_cmatrix(cm);
218                          cm_free(cm);
219 +                        dnew->dtype = DTascii;
220                          return(dnew);
221                  }
222                                                  /* else open it ourselves */
223 <                if ((fp = fopen(fname, "rb")) == NULL)
223 >                if ((fp = fopen(inspec, "rb")) == NULL)
224                          return(NULL);
225          }
226   #ifdef getc_unlocked
227          flockfile(fp);
228   #endif
229          dinfo.nrows = dinfo.ncols = dinfo.ncomp = 0;
230 <        dinfo.dtype = DTascii;
230 >        dinfo.dtype = DTascii;                  /* assumed w/o FORMAT */
231 >        dinfo.info = NULL;
232          if (getheader(fp, get_dminfo, &dinfo) < 0) {
233                  fclose(fp);
234                  return(NULL);
235          }
236 <        if ((dinfo.dtype == DTrgbe) | (dinfo.dtype == DTxyze)) {
236 >        if ((dinfo.nrows <= 0) | (dinfo.ncols <= 0)) {
237                  if (!fscnresolu(&dinfo.ncols, &dinfo.nrows, fp)) {
238                          fclose(fp);
239                          return(NULL);
240                  }
241 <                dinfo.ncomp = 3;
241 >                if (dinfo.ncomp <= 0)
242 >                        dinfo.ncomp = 3;
243 >                else if ((dinfo.dtype == DTrgbe) | (dinfo.dtype == DTxyze) &&
244 >                                dinfo.ncomp != 3) {
245 >                        fclose(fp);
246 >                        return(NULL);
247 >                }
248          }
249          dnew = rmx_alloc(dinfo.nrows, dinfo.ncols, dinfo.ncomp);
250          if (dnew == NULL) {
251                  fclose(fp);
252                  return(NULL);
253          }
254 +        dnew->info = dinfo.info;
255          switch (dinfo.dtype) {
256          case DTascii:
257 + #if defined(_WIN32) || defined(_WIN64)
258 +                _setmode(fileno(fp), _O_TEXT);
259 + #endif
260                  if (!rmx_load_ascii(dnew, fp))
261                          goto loaderr;
262 +                dnew->dtype = DTascii;          /* should leave double? */
263                  break;
264          case DTfloat:
265                  if (!rmx_load_float(dnew, fp))
266                          goto loaderr;
267 +                dnew->dtype = DTfloat;
268                  break;
269          case DTdouble:
270                  if (!rmx_load_double(dnew, fp))
271                          goto loaderr;
272 +                dnew->dtype = DTdouble;
273                  break;
274          case DTrgbe:
275          case DTxyze:
276                  if (!rmx_load_rgbe(dnew, fp))
277                          goto loaderr;
278 +                dnew->dtype = dinfo.dtype;
279                  break;
280          default:
281                  goto loaderr;
282          }
283 <        if (fp != stdin)
284 <                fclose(fp);
283 >        if (fp != stdin) {
284 >                if (inspec[0] == '!')
285 >                        pclose(fp);
286 >                else
287 >                        fclose(fp);
288 >        }
289 > #ifdef getc_unlocked
290 >        else
291 >                funlockfile(fp);
292 > #endif
293          return(dnew);
294   loaderr:                                        /* should report error? */
295 <        fclose(fp);
295 >        if (inspec[0] == '!')
296 >                pclose(fp);
297 >        else
298 >                fclose(fp);
299          rmx_free(dnew);
300          return(NULL);
301   }
# Line 223 | Line 304 | static int
304   rmx_write_ascii(const RMATRIX *rm, FILE *fp)
305   {
306          int     i, j, k;
307 < #ifdef _WIN32
227 <        _setmode(fileno(fp), _O_TEXT);
228 < #endif
307 >
308          for (i = 0; i < rm->nrows; i++) {
309              for (j = 0; j < rm->ncols; j++) {
310                  for (k = 0; k < rm->ncomp; k++)
# Line 251 | Line 330 | rmx_write_float(const RMATRIX *rm, FILE *fp)
330              for (j = 0; j < rm->ncols; j++) {
331                  for (k = rm->ncomp; k--; )
332                      val[k] = (float)rmx_lval(rm,i,j,k);
333 <                if (fwrite(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
333 >                if (putbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
334                          return(0);
335              }
336          return(1);
# Line 271 | Line 350 | rmx_write_double(const RMATRIX *rm, FILE *fp)
350              for (j = 0; j < rm->ncols; j++) {
351                  for (k = rm->ncomp; k--; )
352                      val[k] = rmx_lval(rm,i,j,k);
353 <                if (fwrite(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
353 >                if (putbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp)
354                          return(0);
355              }
356          return(1);
# Line 299 | Line 378 | rmx_write_rgbe(const RMATRIX *rm, FILE *fp)
378          return(1);
379   }
380  
381 < /* Write matrix to file type indicated by dt */
382 < long
381 > /* Write matrix to file type indicated by dtype */
382 > int
383   rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
384   {
385          RMATRIX *mydm = NULL;
# Line 308 | Line 387 | rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
387  
388          if ((rm == NULL) | (fp == NULL))
389                  return(0);
390 + #ifdef getc_unlocked
391 +        flockfile(fp);
392 + #endif
393                                                  /* complete header */
394 +        if (rm->info)
395 +                fputs(rm->info, fp);
396 +        if (dtype == DTfromHeader)
397 +                dtype = rm->dtype;
398 +        else if ((dtype == DTrgbe) & (rm->dtype == DTxyze))
399 +                dtype = DTxyze;
400 +        else if ((dtype == DTxyze) & (rm->dtype == DTrgbe))
401 +                dtype = DTrgbe;
402          if ((dtype != DTrgbe) & (dtype != DTxyze)) {
403                  fprintf(fp, "NROWS=%d\n", rm->nrows);
404                  fprintf(fp, "NCOLS=%d\n", rm->ncols);
# Line 344 | Line 434 | rmx_write(const RMATRIX *rm, int dtype, FILE *fp)
434                  return(0);
435          }
436          ok &= (fflush(fp) == 0);
437 + #ifdef getc_unlocked
438 +        funlockfile(fp);
439 + #endif
440          rmx_free(mydm);
441 <        return(ftell(fp) * ok);         /* return # bytes written */
441 >        return(ok);
442   }
443  
444   /* Allocate and assign square identity matrix with n components */
# Line 353 | Line 446 | RMATRIX *
446   rmx_identity(const int dim, const int n)
447   {
448          RMATRIX *rid = rmx_alloc(dim, dim, n);
449 <        int     i;
449 >        int     i, k;
450  
451          if (rid == NULL)
452                  return(NULL);
453 <        memset(rid->mtx, 0, sizeof(rid->mtx[0])*dim*dim);
453 >        memset(rid->mtx, 0, sizeof(rid->mtx[0])*n*dim*dim);
454          for (i = dim; i--; )
455 <                rmx_lval(rid,i,i,0) = 1;
456 <        for (i = n; --i; )
364 <                memcpy(rid->mtx+i*(dim*dim), rid->mtx,
365 <                                sizeof(rid->mtx[0])*dim*dim);
455 >            for (k = n; k--; )
456 >                rmx_lval(rid,i,i,k) = 1;
457          return(rid);
458   }
459  
# Line 377 | Line 468 | rmx_copy(const RMATRIX *rm)
468          dnew = rmx_alloc(rm->nrows, rm->ncols, rm->ncomp);
469          if (dnew == NULL)
470                  return(NULL);
471 +        rmx_addinfo(dnew, rm->info);
472 +        dnew->dtype = rm->dtype;
473          memcpy(dnew->mtx, rm->mtx,
474                  sizeof(rm->mtx[0])*rm->ncomp*rm->nrows*rm->ncols);
475          return(dnew);
# Line 394 | Line 487 | rmx_transpose(const RMATRIX *rm)
487          dnew = rmx_alloc(rm->ncols, rm->nrows, rm->ncomp);
488          if (dnew == NULL)
489                  return(NULL);
490 +        if (rm->info) {
491 +                rmx_addinfo(dnew, rm->info);
492 +                rmx_addinfo(dnew, "Transposed rows and columns\n");
493 +        }
494 +        dnew->dtype = rm->dtype;
495          for (i = dnew->nrows; i--; )
496              for (j = dnew->ncols; j--; )
497                  for (k = dnew->ncomp; k--; )
# Line 414 | Line 512 | rmx_multiply(const RMATRIX *m1, const RMATRIX *m2)
512          mres = rmx_alloc(m1->nrows, m2->ncols, m1->ncomp);
513          if (mres == NULL)
514                  return(NULL);
515 +        i = rmx_newtype(m1->dtype, m2->dtype);
516 +        if (i)
517 +                mres->dtype = i;
518 +        else
519 +                rmx_addinfo(mres, rmx_mismatch_warn);
520          for (i = mres->nrows; i--; )
521              for (j = mres->ncols; j--; )
522 <                for (h = m1->ncols; h--; ) {
522 >                for (k = mres->ncomp; k--; ) {
523                      long double d = 0;
524 <                    for (k = mres->ncomp; k--; )
525 <                        d += (long double)rmx_lval(m1,i,h,k) *
423 <                                (long double)rmx_lval(m2,h,j,k);
524 >                    for (h = m1->ncols; h--; )
525 >                        d += rmx_lval(m1,i,h,k) * rmx_lval(m2,h,j,k);
526                      rmx_lval(mres,i,j,k) = (double)d;
527                  }
528          return(mres);
# Line 446 | Line 548 | rmx_sum(RMATRIX *msum, const RMATRIX *madd, const doub
548                          mysf[k] = 1;
549                  sf = mysf;
550          }
551 +        i = rmx_newtype(msum->dtype, madd->dtype);
552 +        if (i)
553 +                msum->dtype = i;
554 +        else
555 +                rmx_addinfo(msum, rmx_mismatch_warn);
556          for (i = msum->nrows; i--; )
557              for (j = msum->ncols; j--; )
558                  for (k = msum->ncomp; k--; )
# Line 483 | Line 590 | rmx_transform(const RMATRIX *msrc, int n, const double
590          dnew = rmx_alloc(msrc->nrows, msrc->ncols, n);
591          if (dnew == NULL)
592                  return(NULL);
593 +        dnew->dtype = msrc->dtype;
594          for (i = dnew->nrows; i--; )
595              for (j = dnew->ncols; j--; )
596                  for (kd = dnew->ncomp; kd--; ) {
# Line 506 | Line 614 | rmx_from_cmatrix(const CMATRIX *cm)
614          dnew = rmx_alloc(cm->nrows, cm->ncols, 3);
615          if (dnew == NULL)
616                  return(NULL);
617 +        dnew->dtype = DTfloat;
618          for (i = dnew->nrows; i--; )
619              for (j = dnew->ncols; j--; ) {
620                  const COLORV    *cv = cm_lval(cm,i,j);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines