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

Comparing ray/src/util/rmtxop.c (file contents):
Revision 2.18 by greg, Tue Jan 19 23:32:00 2021 UTC vs.
Revision 2.42 by greg, Sat Apr 19 03:58:00 2025 UTC

# Line 5 | Line 5 | static const char RCSid[] = "$Id$";
5   * General component matrix operations.
6   */
7  
8 #include <stdlib.h>
8   #include <errno.h>
9   #include "rtio.h"
11 #include "resolu.h"
10   #include "rmatrix.h"
11   #include "platform.h"
12  
13 < #define MAXCOMP         16              /* #components we support */
13 > /* Preferred BSDF component:
14 >        none, transmission, reflection front (normal side), reflection back */
15 > typedef enum {RMPnone=-1, RMPtrans=0, RMPreflF, RMPreflB} RMPref;
16  
17 < /* unary matrix operation(s) */
17 > /* Unary matrix operation(s) */
18   typedef struct {
19        double          sca[MAXCOMP];           /* scalar coefficients */
19          double          cmat[MAXCOMP*MAXCOMP];  /* component transformation */
20 <        short           nsf;                    /* number of scalars */
20 >        double          sca[MAXCOMP];           /* scalar coefficients */
21 >        const char      *csym;                  /* symbolic coefs or file */
22          short           clen;                   /* number of coefficients */
23 +        short           nsf;                    /* number of scalars */
24          short           transpose;              /* do transpose? */
25   } RUNARYOP;
26  
27 < /* matrix input source and requested operation(s) */
27 > /* Matrix input source and requested operation(s) */
28   typedef struct {
29          const char      *inspec;                /* input specification */
30          RMPref          rmp;                    /* matrix preference */
# Line 35 | Line 36 | typedef struct {
36   int     verbose = 0;                    /* verbose reporting? */
37  
38   /* Load matrix */
39 < static int
39 > int
40   loadmatrix(ROPMAT *rop)
41   {
42 <        if (rop->mtx != NULL)
42 >        if (rop->mtx)                   /* already loaded? */
43                  return(0);
44 +                                        /* check for BSDF input */
45 +        if ((rop->inspec[0] != '!') & (rop->rmp != RMPnone)) {
46 +                const char      *sp = strrchr(rop->inspec, '.');
47 +                if (sp > rop->inspec && !strcasecmp(sp+1, "XML")) {
48 +                        CMATRIX *cm = rop->rmp==RMPtrans ? cm_loadBTDF(rop->inspec) :
49 +                                        cm_loadBRDF(rop->inspec, rop->rmp==RMPreflB) ;
50 +                        if (!cm)
51 +                                return(-1);
52 +                        rop->mtx = rmx_from_cmatrix(cm);
53 +                        cm_free(cm);
54 +                        if (!rop->mtx)
55 +                                return(-1);
56 +                        rop->mtx->dtype = DTascii;
57 +                        return(1);      /* loaded BSDF XML file */
58 +                }
59 +        }                               /* else load regular matrix */
60 +        rop->mtx = rmx_load(rop->inspec);
61  
62 <        rop->mtx = rmx_load(rop->inspec, rop->rmp);
63 <        if (rop->mtx == NULL) {
64 <                fputs(rop->inspec, stderr);
65 <                fputs(": cannot load matrix\n", stderr);
62 >        return(rop->mtx ? 1 : -1);
63 > }
64 >
65 > extern int      checksymbolic(ROPMAT *rop);
66 >
67 > /* Check/set transform based on a reference input file */
68 > int
69 > checkreffile(ROPMAT *rop)
70 > {
71 >        static const char       *curRF = NULL;
72 >        static RMATRIX          refm;
73 >        const int               nc = rop->mtx->ncomp;
74 >        int                     i;
75 >
76 >        if (!curRF || strcmp(rop->preop.csym, curRF)) {
77 >                FILE    *fp = fopen(rop->preop.csym, "rb");
78 >                if (!rmx_load_header(&refm, fp)) {
79 >                        fprintf(stderr, "%s: cannot read info header\n",
80 >                                        rop->preop.csym);
81 >                        curRF = NULL;
82 >                        if (fp) fclose(fp);
83 >                        return(-1);
84 >                }
85 >                fclose(fp);
86 >                curRF = rop->preop.csym;
87 >        }
88 >        if (refm.ncomp == 3) {
89 >                rop->preop.csym = (refm.dtype == DTxyze) ? "XYZ" : "RGB";
90 >                return(checksymbolic(rop));
91 >        }
92 >        if (refm.ncomp == 2) {
93 >                fprintf(stderr, "%s: cannot convert to 2 components\n",
94 >                                curRF);
95                  return(-1);
96          }
97 <        return(1);
97 >        if (refm.ncomp == 1) {
98 >                rop->preop.csym = "Y";          /* XXX big assumption */
99 >                return(checksymbolic(rop));
100 >        }
101 >        if (refm.ncomp == nc &&
102 >                        !memcmp(refm.wlpart, rop->mtx->wlpart, sizeof(refm.wlpart)))
103 >                return(0);                      /* nothing to do */
104 >
105 >        if ((nc <= 3) | (nc > MAXCSAMP) | (refm.ncomp > MAXCSAMP)) {
106 >                fprintf(stderr, "%s: cannot resample from %d to %d components\n",
107 >                                curRF, nc, refm.ncomp);
108 >                return(-1);
109 >        }
110 >        rop->preop.clen = refm.ncomp * nc;      /* compute spec to ref */
111 >
112 >        for (i = 0; i < nc; i++) {
113 >                SCOLOR  scstim, scresp;
114 >                int     j;
115 >                memset(scstim, 0, sizeof(COLORV)*nc);
116 >                scstim[i] = 1.f;
117 >                convertscolor(scresp, refm.ncomp, refm.wlpart[0], refm.wlpart[3],
118 >                                scstim, nc, rop->mtx->wlpart[0], rop->mtx->wlpart[3]);
119 >                for (j = refm.ncomp; j-- > 0; )
120 >                        rop->preop.cmat[j*nc + i] = scresp[j];
121 >        }
122 >        memcpy(rop->mtx->wlpart, refm.wlpart, sizeof(rop->mtx->wlpart));
123 >        return(0);
124   }
125  
126 + /* Compute conversion row from spectrum to one channel of RGB */
127 + void
128 + rgbrow(ROPMAT *rop, int r, int p)
129 + {
130 +        const int       nc = rop->mtx->ncomp;
131 +        const float *   wlp = rop->mtx->wlpart;
132 +        int             i;
133 +
134 +        for (i = nc; i--; ) {
135 +                int     nmEnd = wlp[0] + (wlp[3] - wlp[0])*i/nc;
136 +                int     nmStart = wlp[0] + (wlp[3] - wlp[0])*(i+1)/nc;
137 +                COLOR   crgb;
138 +                spec_rgb(crgb, nmStart, nmEnd);
139 +                rop->preop.cmat[r*nc+i] = crgb[p];
140 +        }
141 + }
142 +
143 + /* Compute conversion row from spectrum to one channel of XYZ */
144 + void
145 + xyzrow(ROPMAT *rop, int r, int p)
146 + {
147 +        const int       nc = rop->mtx->ncomp;
148 +        const float *   wlp = rop->mtx->wlpart;
149 +        int             i;
150 +
151 +        for (i = nc; i--; ) {
152 +                int     nmEnd = wlp[0] + (wlp[3] - wlp[0])*i/nc;
153 +                int     nmStart = wlp[0] + (wlp[3] - wlp[0])*(i+1)/nc;
154 +                COLOR   cxyz;
155 +                spec_cie(cxyz, nmStart, nmEnd);
156 +                rop->preop.cmat[r*nc+i] = cxyz[p];
157 +        }
158 + }
159 +
160 + /* Use the spectral sensitivity function to compute matrix coefficients */
161 + void
162 + sensrow(ROPMAT *rop, int r, double (*sf)(const SCOLOR sc, int ncs, const float wlpt[4]))
163 + {
164 +        const int       nc = rop->mtx->ncomp;
165 +        int             i;
166 +
167 +        for (i = nc; i--; ) {
168 +                SCOLOR  sclr;
169 +                memset(sclr, 0, sizeof(COLORV)*nc);
170 +                sclr[i] = 1.f;
171 +                rop->preop.cmat[r*nc+i] = (*sf)(sclr, nc, rop->mtx->wlpart);
172 +        }
173 + }
174 +
175 + /* Check/set symbolic transform */
176 + int
177 + checksymbolic(ROPMAT *rop)
178 + {
179 +        const int       nc = rop->mtx->ncomp;
180 +        const int       dt = rop->mtx->dtype;
181 +        double          cf = 1;
182 +        int             i, j;
183 +                                        /* check suffix => reference file */
184 +        if (strchr(rop->preop.csym, '.') > rop->preop.csym)
185 +                return(checkreffile(rop));
186 +
187 +        if (nc < 3) {
188 +                fprintf(stderr, "%s: -c '%s' requires at least 3 components\n",
189 +                                rop->inspec, rop->preop.csym);
190 +                return(-1);
191 +        }
192 +        rop->preop.clen = strlen(rop->preop.csym) * nc;
193 +        if (rop->preop.clen > MAXCOMP*MAXCOMP) {
194 +                fprintf(stderr, "%s: -c '%s' results in too many components\n",
195 +                                rop->inspec, rop->preop.csym);
196 +                return(-1);
197 +        }
198 +        for (j = 0; rop->preop.csym[j]; j++) {
199 +                int     comp = 0;
200 +                switch (rop->preop.csym[j]) {
201 +                case 'B':
202 +                case 'b':
203 +                        ++comp;
204 +                        /* fall through */
205 +                case 'G':
206 +                case 'g':
207 +                        ++comp;
208 +                        /* fall through */
209 +                case 'R':
210 +                case 'r':
211 +                        if (rop->preop.csym[j] <= 'Z')
212 +                                cf = 1./WHTEFFICACY;
213 +                        if (dt == DTxyze) {
214 +                                for (i = 3; i--; )
215 +                                        rop->preop.cmat[j*nc+i] = cf*xyz2rgbmat[comp][i];
216 +                        } else if (nc == 3)
217 +                                rop->preop.cmat[j*nc+comp] = 1.;
218 +                        else
219 +                                rgbrow(rop, j, comp);
220 +                        break;
221 +                case 'Z':
222 +                case 'z':
223 +                        ++comp;
224 +                        /* fall through */
225 +                case 'Y':
226 +                case 'y':
227 +                        ++comp;
228 +                        /* fall through */
229 +                case 'X':
230 +                case 'x':
231 +                        if ((rop->preop.csym[j] <= 'Z') & (dt != DTxyze))
232 +                                cf = WHTEFFICACY;
233 +                        if (dt == DTxyze) {
234 +                                rop->preop.cmat[j*nc+comp] = 1.;
235 +                        } else if (nc == 3) {
236 +                                for (i = 3; i--; )
237 +                                        rop->preop.cmat[j*nc+i] =
238 +                                                        rgb2xyzmat[comp][i];
239 +                        } else if (comp == CIEY)
240 +                                sensrow(rop, j, scolor2photopic);
241 +                        else
242 +                                xyzrow(rop, j, comp);
243 +
244 +                        for (i = nc*(cf != 1); i--; )
245 +                                rop->preop.cmat[j*nc+i] *= cf;
246 +                        break;
247 +                case 'S':               /* scotopic (il)luminance */
248 +                        cf = WHTSCOTOPIC;
249 +                        /* fall through */
250 +                case 's':
251 +                        sensrow(rop, j, scolor2scotopic);
252 +                        for (i = nc*(cf != 1); i--; )
253 +                                rop->preop.cmat[j*nc+i] *= cf;
254 +                        break;
255 +                case 'M':               /* melanopic (il)luminance */
256 +                        cf = WHTMELANOPIC;
257 +                        /* fall through */
258 +                case 'm':
259 +                        sensrow(rop, j, scolor2melanopic);
260 +                        for (i = nc*(cf != 1); i--; )
261 +                                rop->preop.cmat[j*nc+i] *= cf;
262 +                        break;
263 +                case 'A':               /* average component */
264 +                case 'a':
265 +                        for (i = nc; i--; )
266 +                                rop->preop.cmat[j*nc+i] = 1./(double)nc;
267 +                        break;
268 +                default:
269 +                        fprintf(stderr, "%s: -c '%c' unsupported\n",
270 +                                rop->inspec, rop->preop.csym[j]);
271 +                        return(-1);
272 +                }
273 +        }
274 +                                        /* return recommended output type */
275 +        if (!strcasecmp(rop->preop.csym, "XYZ")) {
276 +                if (dt <= DTspec)
277 +                        return(DTxyze);
278 +        } else if (!strcasecmp(rop->preop.csym, "RGB")) {
279 +                if (dt <= DTspec)
280 +                        return(DTrgbe);
281 +        } else if (dt == DTspec)
282 +                return(DTfloat);        /* probably not actual spectrum */
283 +        return(0);
284 + }
285 +
286   /* Get matrix and perform unary operations */
287 < static RMATRIX *
287 > RMATRIX *
288   loadop(ROPMAT *rop)
289   {
290 +        int     outtype = 0;
291          RMATRIX *mres;
292 <        int     i;
292 >        int     i, j;
293  
294          if (loadmatrix(rop) < 0)                /* make sure we're loaded */
295                  return(NULL);
296  
297 <        if (rop->preop.nsf > 0) {               /* apply scalar(s) */
298 <                if (rop->preop.clen > 0) {
299 <                        fputs("Options -s and -c are exclusive\n", stderr);
297 >        if (rop->preop.csym &&                  /* symbolic transform? */
298 >                        (outtype = checksymbolic(rop)) < 0)
299 >                goto failure;
300 >        if (rop->preop.clen > 0) {              /* apply component transform? */
301 >                if (rop->preop.clen % rop->mtx->ncomp) {
302 >                        fprintf(stderr, "%s: -c must have N x %d coefficients\n",
303 >                                        rop->inspec, rop->mtx->ncomp);
304                          goto failure;
305                  }
306 +                if (rop->preop.nsf > 0) {       /* scale transform, first */
307 +                        if (rop->preop.nsf == 1) {
308 +                                for (i = rop->preop.clen; i--; )
309 +                                        rop->preop.cmat[i] *= rop->preop.sca[0];
310 +                        } else if (rop->preop.nsf*rop->mtx->ncomp != rop->preop.clen) {
311 +                                fprintf(stderr, "%s: -s must have one or %d factors\n",
312 +                                                rop->inspec,
313 +                                                rop->preop.clen/rop->mtx->ncomp);
314 +                                goto failure;
315 +                        } else {
316 +                                for (i = rop->preop.nsf; i--; )
317 +                                        for (j = rop->mtx->ncomp; j--; )
318 +                                                rop->preop.cmat[i*rop->mtx->ncomp+j]
319 +                                                                *= rop->preop.sca[i];
320 +                        }
321 +                }
322 +                mres = rmx_transform(rop->mtx, rop->preop.clen/rop->mtx->ncomp,
323 +                                        rop->preop.cmat);
324 +                if (mres == NULL) {
325 +                        fprintf(stderr, "%s: matrix transform failed\n",
326 +                                                rop->inspec);
327 +                        goto failure;
328 +                }
329 +                if (verbose)
330 +                        fprintf(stderr, "%s: applied %d x %d transform%s\n",
331 +                                        rop->inspec, mres->ncomp,
332 +                                        rop->mtx->ncomp,
333 +                                        rop->preop.nsf ? " (* scalar)" : "");
334 +                rop->preop.nsf = 0;             /* now folded in */
335 +                if ((mres->ncomp > 3) & (mres->dtype <= DTspec))
336 +                        outtype = DTfloat;      /* probably not actual spectrum */
337 +                rmx_free(rop->mtx);
338 +                rop->mtx = mres;
339 +        }
340 +        if (rop->preop.nsf > 0) {               /* apply scalar(s)? */
341                  if (rop->preop.nsf == 1) {
342                          for (i = rop->mtx->ncomp; --i; )
343                                  rop->preop.sca[i] = rop->preop.sca[0];
# Line 86 | Line 359 | loadop(ROPMAT *rop)
359                          fputs(" )\n", stderr);
360                  }
361          }
362 <        if (rop->preop.clen > 0) {      /* apply transform */
363 <                if (rop->preop.clen % rop->mtx->ncomp) {
91 <                        fprintf(stderr, "%s: -c must have N x %d coefficients\n",
92 <                                        rop->inspec, rop->mtx->ncomp);
93 <                        goto failure;
94 <                }
95 <                mres = rmx_transform(rop->mtx, rop->preop.clen/rop->mtx->ncomp,
96 <                                        rop->preop.cmat);
97 <                if (mres == NULL) {
98 <                        fprintf(stderr, "%s: matrix transform failed\n",
99 <                                                rop->inspec);
100 <                        goto failure;
101 <                }
102 <                if (verbose)
103 <                        fprintf(stderr, "%s: applied %d x %d transform\n",
104 <                                        rop->inspec, mres->ncomp,
105 <                                        rop->mtx->ncomp);
106 <                rmx_free(rop->mtx);
107 <                rop->mtx = mres;
108 <        }
109 <        if (rop->preop.transpose) {     /* transpose matrix? */
110 <                mres = rmx_transpose(rop->mtx);
111 <                if (mres == NULL) {
362 >        if (rop->preop.transpose) {             /* transpose matrix? */
363 >                if (!rmx_transpose(rop->mtx)) {
364                          fputs(rop->inspec, stderr);
365                          fputs(": transpose failed\n", stderr);
366                          goto failure;
# Line 117 | Line 369 | loadop(ROPMAT *rop)
369                          fputs(rop->inspec, stderr);
370                          fputs(": transposed rows and columns\n", stderr);
371                  }
120                rmx_free(rop->mtx);
121                rop->mtx = mres;
372          }
373          mres = rop->mtx;
374          rop->mtx = NULL;
375 +        if (outtype)
376 +                mres->dtype = outtype;
377          return(mres);
378   failure:
379          rmx_free(rop->mtx);
# Line 129 | Line 381 | failure:
381   }
382  
383   /* Execute binary operation, free matrix arguments and return new result */
384 < static RMATRIX *
384 > RMATRIX *
385   binaryop(const char *inspec, RMATRIX *mleft, int op, RMATRIX *mright)
386   {
387          RMATRIX *mres = NULL;
# Line 206 | Line 458 | binaryop(const char *inspec, RMATRIX *mleft, int op, R
458   }
459  
460   /* Perform matrix operations from left to right */
461 < static RMATRIX *
461 > RMATRIX *
462   op_left2right(ROPMAT *mop)
463   {
464          RMATRIX *mleft = loadop(mop);
# Line 222 | Line 474 | op_left2right(ROPMAT *mop)
474   }
475  
476   /* Perform matrix operations from right to left */
477 < static RMATRIX *
477 > RMATRIX *
478   op_right2left(ROPMAT *mop)
479   {
480          RMATRIX *mright;
# Line 239 | Line 491 | op_right2left(ROPMAT *mop)
491          while (rpos-- > 0) {
492                  if (mright == NULL)
493                          break;
494 <                mright = binaryop(mop[rpos].inspec,
494 >                mright = binaryop(mop[rpos+1].inspec,
495                                  loadop(mop+rpos), mop[rpos].binop, mright);
496          }
497          return(mright);
# Line 251 | Line 503 | op_right2left(ROPMAT *mop)
503                                                  : (mop)->mtx->ncols)
504  
505   /* Should we prefer concatenating from rightmost matrix towards left? */
506 < static int
506 > int
507   prefer_right2left(ROPMAT *mop)
508   {
509          int     mri = 0;
# Line 278 | Line 530 | prefer_right2left(ROPMAT *mop)
530          return(t_ncols(mop+mri) < t_nrows(mop));
531   }
532  
533 < static int
533 > int
534   get_factors(double da[], int n, char *av[])
535   {
536          int     ac;
# Line 288 | Line 540 | get_factors(double da[], int n, char *av[])
540          return(ac);
541   }
542  
543 < static ROPMAT *
544 < grow_moparray(ROPMAT *mop, int n2alloc)
543 > ROPMAT *
544 > resize_moparr(ROPMAT *mop, int n2alloc)
545   {
546          int     nmats = 0;
547 +        int     i;
548  
549          while (mop[nmats++].binop)
550                  ;
551 +        for (i = nmats; i >= n2alloc; i--)
552 +                rmx_free(mop[i].mtx);
553          mop = (ROPMAT *)realloc(mop, n2alloc*sizeof(ROPMAT));
554          if (mop == NULL) {
555 <                fputs("Out of memory in grow_moparray()\n", stderr);
555 >                fputs("Out of memory in resize_moparr()\n", stderr);
556                  exit(1);
557          }
558          if (n2alloc > nmats)
# Line 309 | Line 564 | grow_moparray(ROPMAT *mop, int n2alloc)
564   int
565   main(int argc, char *argv[])
566   {
567 <        int     outfmt = DTfromHeader;
568 <        int     nall = 2;
569 <        ROPMAT  *mop = (ROPMAT *)calloc(nall, sizeof(ROPMAT));
570 <        int     nmats = 0;
571 <        RMATRIX *mres = NULL;
572 <        int     stdin_used = 0;
573 <        int     i;
567 >        int             outfmt = DTfromHeader;
568 >        const char      *defCsym = NULL;
569 >        int             nall = 2;
570 >        ROPMAT          *mop = (ROPMAT *)calloc(nall, sizeof(ROPMAT));
571 >        int             nmats = 0;
572 >        RMATRIX         *mres = NULL;
573 >        int             stdin_used = 0;
574 >        int             i;
575                                          /* get options and arguments */
576          for (i = 1; i < argc; i++) {
577                  if (argv[i][0] && !argv[i][1] &&
# Line 338 | Line 594 | main(int argc, char *argv[])
594                                  mop[nmats].inspec = stdin_name;
595                          } else
596                                  mop[nmats].inspec = argv[i];
597 +                        if (!mop[nmats].preop.csym)
598 +                                mop[nmats].preop.csym = defCsym;
599                          if (nmats > 0 && !mop[nmats-1].binop)
600                                  mop[nmats-1].binop = '.';
601                          nmats++;
# Line 373 | Line 631 | main(int argc, char *argv[])
631                                  i += mop[nmats].preop.nsf =
632                                          get_factors(mop[nmats].preop.sca,
633                                                          n, argv+i+1);
634 +                                if (mop[nmats].preop.nsf <= 0) {
635 +                                        fprintf(stderr, "%s: -s missing arguments\n",
636 +                                                        argv[0]);
637 +                                        goto userr;
638 +                                }
639                                  break;
640 +                        case 'C':
641 +                                if (!n || isflt(argv[i+1]))
642 +                                        goto userr;
643 +                                defCsym = mop[nmats].preop.csym = argv[++i];
644 +                                mop[nmats].preop.clen = 0;
645 +                                break;
646                          case 'c':
647 +                                if (n && !isflt(argv[i+1])) {
648 +                                        mop[nmats].preop.csym = argv[++i];
649 +                                        mop[nmats].preop.clen = 0;
650 +                                        break;
651 +                                }
652                                  if (n > MAXCOMP*MAXCOMP) n = MAXCOMP*MAXCOMP;
653                                  i += mop[nmats].preop.clen =
654                                          get_factors(mop[nmats].preop.cmat,
655                                                          n, argv+i+1);
656 +                                if (mop[nmats].preop.clen <= 0) {
657 +                                        fprintf(stderr, "%s: -c missing arguments\n",
658 +                                                        argv[0]);
659 +                                        goto userr;
660 +                                }
661 +                                mop[nmats].preop.csym = NULL;
662                                  break;
663                          case 'r':
664                                  if (argv[i][2] == 'f')
# Line 395 | Line 675 | main(int argc, char *argv[])
675                          }
676                  }
677                  if (nmats >= nall)
678 <                        mop = grow_moparray(mop, nall += 2);
678 >                        mop = resize_moparr(mop, nall += 2);
679          }
680          if (mop[0].inspec == NULL)      /* nothing to do? */
681                  goto userr;
# Line 415 | Line 695 | main(int argc, char *argv[])
695          mres = loadop(mop+nmats);
696          if (mres == NULL)
697                  return(1);
698 <                                        /* write result to stdout */
419 <        if (outfmt == DTfromHeader)
698 >        if ((outfmt == DTfromHeader) & (mres->dtype < DTspec))
699                  outfmt = mres->dtype;
700 <        if (outfmt != DTascii)
701 <                SET_FILE_BINARY(stdout);
702 <        newheader("RADIANCE", stdout);
703 <        printargs(argc, argv, stdout);
704 <        if (!rmx_write(mres, outfmt, stdout)) {
426 <                fprintf(stderr, "%s: error writing result matrix\n", argv[0]);
427 <                return(1);
700 >        if (outfmt == DTrgbe) {         /* check data type */
701 >                if (mres->ncomp > 3)
702 >                        outfmt = DTspec;
703 >                else if (mres->dtype == DTxyze)
704 >                        outfmt = DTxyze;
705          }
706 <        /* rmx_free(mres); free(mop); */
707 <        return(0);
706 > #if DTrmx_native==DTfloat
707 >        if (outfmt == DTdouble)
708 >                fprintf(stderr,
709 >                        "%s: warning - writing float result as double\n",
710 >                                argv[0]);
711 > #endif
712 >        newheader("RADIANCE", stdout);  /* write result to stdout */
713 >        printargs(argc, argv, stdout);
714 >        return(rmx_write(mres, outfmt, stdout) ? 0 : 1);
715   userr:
716          fprintf(stderr,
717 <        "Usage: %s [-v][-f[adfc][-t][-s sf .. | -c ce ..][-r[fb]] m1 [.+*/] .. > mres\n",
717 >        "Usage: %s [-v][-f{adfc}][-t][-s sf .. | -c ce ..][-rf|-rb] m1 [.+*/] .. > mres\n",
718                          argv[0]);
719          return(1);
720   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines