| 31 |  | return(NULL); | 
| 32 |  |  | 
| 33 |  | dnew = (RMATRIX *)calloc(1, sizeof(RMATRIX)); | 
| 34 | < | if (dnew) { | 
| 35 | < | dnew->dtype = DTdouble; | 
| 36 | < | dnew->nrows = nr; | 
| 37 | < | dnew->ncols = nc; | 
| 38 | < | dnew->ncomp = n; | 
| 39 | < | setcolor(dnew->cexp, 1.f, 1.f, 1.f); | 
| 40 | < | memcpy(dnew->wlpart, WLPART, sizeof(dnew->wlpart)); | 
| 41 | < | } | 
| 34 | > | if (!dnew) | 
| 35 | > | return(NULL); | 
| 36 | > |  | 
| 37 | > | dnew->dtype = DTdouble; | 
| 38 | > | dnew->nrows = nr; | 
| 39 | > | dnew->ncols = nc; | 
| 40 | > | dnew->ncomp = n; | 
| 41 | > | setcolor(dnew->cexp, 1.f, 1.f, 1.f); | 
| 42 | > | memcpy(dnew->wlpart, WLPART, sizeof(dnew->wlpart)); | 
| 43 | > |  | 
| 44 |  | return(dnew); | 
| 45 |  | } | 
| 46 |  |  | 
| 294 |  | fputs("Unrecognized matrix format\n", stderr); | 
| 295 |  | return(0); | 
| 296 |  | } | 
| 297 | < | /* resolution string? */ | 
| 298 | < | if ((rm->nrows <= 0) | (rm->ncols <= 0)) { | 
| 299 | < | if (!fscnresolu(&rm->ncols, &rm->nrows, fp)) | 
| 300 | < | return(0); | 
| 301 | < | if ((rm->dtype == DTrgbe) | (rm->dtype == DTxyze) && | 
| 302 | < | rm->ncomp != 3) | 
| 303 | < | return(0); | 
| 302 | < | } | 
| 303 | < | if (rm->dtype == DTascii)               /* set input type (WINDOWS) */ | 
| 297 | > | if ((rm->dtype == DTrgbe) | (rm->dtype == DTxyze) && | 
| 298 | > | rm->ncomp != 3) | 
| 299 | > | return(0); | 
| 300 | > | if (rm->ncols <= 0 &&                   /* resolution string? */ | 
| 301 | > | !fscnresolu(&rm->ncols, &rm->nrows, fp)) | 
| 302 | > | return(0); | 
| 303 | > | if (rm->dtype == DTascii)               /* set file type (WINDOWS) */ | 
| 304 |  | SET_FILE_TEXT(fp); | 
| 305 |  | else | 
| 306 |  | SET_FILE_BINARY(fp); | 
| 374 |  | fp = stdin; | 
| 375 |  | else if (inspec[0] == '!') | 
| 376 |  | fp = popen(inspec+1, "r"); | 
| 377 | < | else if (rmp != RMPnone) { | 
| 377 | > | else { | 
| 378 |  | const char      *sp = inspec;   /* check suffix */ | 
| 379 |  | while (*sp) | 
| 380 |  | ++sp; | 
| 381 |  | while (sp > inspec && sp[-1] != '.') | 
| 382 |  | --sp; | 
| 383 |  | if (!strcasecmp(sp, "XML")) {   /* assume it's a BSDF */ | 
| 384 | < | CMATRIX *cm = rmp==RMPtrans ? cm_loadBTDF(inspec) : | 
| 384 | > | CMATRIX *cm = rmp==RMPnone ? (CMATRIX *)NULL : | 
| 385 | > | rmp==RMPtrans ? cm_loadBTDF(inspec) : | 
| 386 |  | cm_loadBRDF(inspec, rmp==RMPreflB) ; | 
| 387 |  | if (!cm) | 
| 388 |  | return(NULL); | 
| 528 |  | int | 
| 529 |  | rmx_write_header(const RMATRIX *rm, int dtype, FILE *fp) | 
| 530 |  | { | 
| 531 | < | if (!rm | !fp || !rm->mtx) | 
| 531 | > | if (!rm | !fp || rm->ncols <= 0) | 
| 532 |  | return(0); | 
| 533 |  | if (rm->info) | 
| 534 |  | fputs(rm->info, fp); | 
| 539 |  | dtype = DTxyze; | 
| 540 |  | else if ((dtype == DTxyze) & (rm->dtype == DTrgbe)) | 
| 541 |  | dtype = DTrgbe; | 
| 542 | + | if ((dtype == DTspec) & (rm->ncomp < 3)) | 
| 543 | + | return(0); | 
| 544 |  |  | 
| 545 | < | if (dtype == DTascii)                   /* set output type (WINDOWS) */ | 
| 545 | > | if (dtype == DTascii)                   /* set file type (WINDOWS) */ | 
| 546 |  | SET_FILE_TEXT(fp); | 
| 547 |  | else | 
| 548 |  | SET_FILE_BINARY(fp); | 
| 552 |  | fputcolcor(rm->cexp, fp); | 
| 553 |  | else if (rm->cexp[GRN] != 1.f) | 
| 554 |  | fputexpos(rm->cexp[GRN], fp); | 
| 555 | < | if ((dtype != DTrgbe) & (dtype != DTxyze)) { | 
| 556 | < | if (dtype != DTspec) { | 
| 555 | > | /* matrix size? */ | 
| 556 | > | if ((dtype > DTspec) | (rm->nrows <= 0)) { | 
| 557 | > | if (rm->nrows > 0) | 
| 558 |  | fprintf(fp, "NROWS=%d\n", rm->nrows); | 
| 559 | < | fprintf(fp, "NCOLS=%d\n", rm->ncols); | 
| 560 | < | } else if (rm->ncomp < 3) | 
| 561 | < | return(0);              /* bad # components */ | 
| 559 | > | fprintf(fp, "NCOLS=%d\n", rm->ncols); | 
| 560 | > | } | 
| 561 | > | if (dtype >= DTspec) {                  /* # components & split? */ | 
| 562 |  | fputncomp(rm->ncomp, fp); | 
| 563 |  | if (dtype == DTspec || (rm->ncomp > 3 && | 
| 564 |  | memcmp(rm->wlpart, WLPART, sizeof(WLPART)))) | 
| 569 |  | fputendian(fp);                 /* important to record */ | 
| 570 |  | fputformat(cm_fmt_id[dtype], fp); | 
| 571 |  | fputc('\n', fp);                        /* end of header */ | 
| 572 | < | if (dtype <= DTspec) | 
| 572 | > | if ((dtype <= DTspec) & (rm->nrows > 0)) | 
| 573 |  | fprtresolu(rm->ncols, rm->nrows, fp); | 
| 574 |  | return(dtype); | 
| 575 |  | } | 
| 643 |  | return(rid); | 
| 644 |  | } | 
| 645 |  |  | 
| 646 | < | /* Duplicate the given matrix */ | 
| 646 | > | /* Duplicate the given matrix (may be unallocated) */ | 
| 647 |  | RMATRIX * | 
| 648 |  | rmx_copy(const RMATRIX *rm) | 
| 649 |  | { | 
| 650 |  | RMATRIX *dnew; | 
| 651 |  |  | 
| 652 | < | if (!rm || !rm->mtx) | 
| 652 | > | if (!rm) | 
| 653 |  | return(NULL); | 
| 654 | < | dnew = rmx_alloc(rm->nrows, rm->ncols, rm->ncomp); | 
| 654 | > | dnew = rmx_new(rm->nrows, rm->ncols, rm->ncomp); | 
| 655 |  | if (!dnew) | 
| 656 |  | return(NULL); | 
| 657 | + | if (rm->mtx) { | 
| 658 | + | if (!rmx_prepare(dnew)) { | 
| 659 | + | rmx_free(dnew); | 
| 660 | + | return(NULL); | 
| 661 | + | } | 
| 662 | + | memcpy(dnew->mtx, rm->mtx, array_size(dnew)); | 
| 663 | + | } | 
| 664 |  | rmx_addinfo(dnew, rm->info); | 
| 665 |  | dnew->dtype = rm->dtype; | 
| 666 |  | copycolor(dnew->cexp, rm->cexp); | 
| 667 |  | memcpy(dnew->wlpart, rm->wlpart, sizeof(dnew->wlpart)); | 
| 657 | – | memcpy(dnew->mtx, rm->mtx, array_size(dnew)); | 
| 668 |  | return(dnew); | 
| 669 |  | } | 
| 670 |  |  |