--- ray/src/util/rmatrix.c 2023/12/01 02:05:00 2.67 +++ ray/src/util/rmatrix.c 2023/12/11 19:00:22 2.75 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rmatrix.c,v 2.67 2023/12/01 02:05:00 greg Exp $"; +static const char RCSid[] = "$Id: rmatrix.c,v 2.75 2023/12/11 19:00:22 greg Exp $"; #endif /* * General matrix operations. @@ -31,14 +31,16 @@ rmx_new(int nr, int nc, int n) return(NULL); dnew = (RMATRIX *)calloc(1, sizeof(RMATRIX)); - if (dnew) { - dnew->dtype = DTdouble; - dnew->nrows = nr; - dnew->ncols = nc; - dnew->ncomp = n; - setcolor(dnew->cexp, 1.f, 1.f, 1.f); - memcpy(dnew->wlpart, WLPART, sizeof(dnew->wlpart)); - } + if (!dnew) + return(NULL); + + dnew->dtype = DTdouble; + dnew->nrows = nr; + dnew->ncols = nc; + dnew->ncomp = n; + setcolor(dnew->cexp, 1.f, 1.f, 1.f); + memcpy(dnew->wlpart, WLPART, sizeof(dnew->wlpart)); + return(dnew); } @@ -292,15 +294,13 @@ rmx_load_header(RMATRIX *rm, FILE *fp) fputs("Unrecognized matrix format\n", stderr); return(0); } - /* resolution string? */ - if ((rm->nrows <= 0) | (rm->ncols <= 0)) { - if (!fscnresolu(&rm->ncols, &rm->nrows, fp)) - return(0); - if ((rm->dtype == DTrgbe) | (rm->dtype == DTxyze) && - rm->ncomp != 3) - return(0); - } - if (rm->dtype == DTascii) /* set input type (WINDOWS) */ + if ((rm->dtype == DTrgbe) | (rm->dtype == DTxyze) && + rm->ncomp != 3) + return(0); + if (rm->ncols <= 0 && /* resolution string? */ + !fscnresolu(&rm->ncols, &rm->nrows, fp)) + return(0); + if (rm->dtype == DTascii) /* set file type (WINDOWS) */ SET_FILE_TEXT(fp); else SET_FILE_BINARY(fp); @@ -374,14 +374,15 @@ rmx_load(const char *inspec, RMPref rmp) fp = stdin; else if (inspec[0] == '!') fp = popen(inspec+1, "r"); - else if (rmp != RMPnone) { + else { const char *sp = inspec; /* check suffix */ while (*sp) ++sp; while (sp > inspec && sp[-1] != '.') --sp; if (!strcasecmp(sp, "XML")) { /* assume it's a BSDF */ - CMATRIX *cm = rmp==RMPtrans ? cm_loadBTDF(inspec) : + CMATRIX *cm = rmp==RMPnone ? (CMATRIX *)NULL : + rmp==RMPtrans ? cm_loadBTDF(inspec) : cm_loadBRDF(inspec, rmp==RMPreflB) ; if (!cm) return(NULL); @@ -449,7 +450,7 @@ rmx_write_ascii(const double *dp, int nc, int len, FIL { while (len-- > 0) { int k = nc; - while (nc-- > 0) + while (k-- > 0) fprintf(fp, " %.7e", *dp++); fputc('\t', fp); } @@ -527,7 +528,7 @@ findCIEprims(const char *info) int rmx_write_header(const RMATRIX *rm, int dtype, FILE *fp) { - if (!rm | !fp || !rm->mtx) + if (!rm | !fp || rm->ncols <= 0) return(0); if (rm->info) fputs(rm->info, fp); @@ -538,8 +539,12 @@ rmx_write_header(const RMATRIX *rm, int dtype, FILE *f dtype = DTxyze; else if ((dtype == DTxyze) & (rm->dtype == DTrgbe)) dtype = DTrgbe; + if ((dtype < DTspec) & (rm->ncomp > 3)) + dtype = DTspec; + else if ((dtype == DTspec) & (rm->ncomp <= 3)) + return(0); - if (dtype == DTascii) /* set output type (WINDOWS) */ + if (dtype == DTascii) /* set file type (WINDOWS) */ SET_FILE_TEXT(fp); else SET_FILE_BINARY(fp); @@ -549,15 +554,16 @@ rmx_write_header(const RMATRIX *rm, int dtype, FILE *f fputcolcor(rm->cexp, fp); else if (rm->cexp[GRN] != 1.f) fputexpos(rm->cexp[GRN], fp); - if ((dtype != DTrgbe) & (dtype != DTxyze)) { - if (dtype != DTspec) { + /* matrix size? */ + if ((dtype > DTspec) | (rm->nrows <= 0)) { + if (rm->nrows > 0) fprintf(fp, "NROWS=%d\n", rm->nrows); - fprintf(fp, "NCOLS=%d\n", rm->ncols); - } else if (rm->ncomp < 3) - return(0); /* bad # components */ + fprintf(fp, "NCOLS=%d\n", rm->ncols); + } + if (dtype >= DTspec) { /* # components & split? */ fputncomp(rm->ncomp, fp); - if (dtype == DTspec || (rm->ncomp > 3 && - memcmp(rm->wlpart, WLPART, sizeof(WLPART)))) + if (rm->ncomp > 3 && + memcmp(rm->wlpart, WLPART, sizeof(WLPART))) fputwlsplit(rm->wlpart, fp); } else if ((rm->ncomp != 3) & (rm->ncomp != 1)) return(0); /* wrong # components */ @@ -565,7 +571,7 @@ rmx_write_header(const RMATRIX *rm, int dtype, FILE *f fputendian(fp); /* important to record */ fputformat(cm_fmt_id[dtype], fp); fputc('\n', fp); /* end of header */ - if (dtype <= DTspec) + if ((dtype <= DTspec) & (rm->nrows > 0)) fprtresolu(rm->ncols, rm->nrows, fp); return(dtype); } @@ -639,23 +645,53 @@ rmx_identity(const int dim, const int n) return(rid); } -/* Duplicate the given matrix */ +/* Duplicate the given matrix (may be unallocated) */ RMATRIX * rmx_copy(const RMATRIX *rm) { RMATRIX *dnew; - if (!rm || !rm->mtx) + if (!rm) return(NULL); - dnew = rmx_alloc(rm->nrows, rm->ncols, rm->ncomp); + dnew = rmx_new(rm->nrows, rm->ncols, rm->ncomp); if (!dnew) return(NULL); + if (rm->mtx) { + if (!rmx_prepare(dnew)) { + rmx_free(dnew); + return(NULL); + } + memcpy(dnew->mtx, rm->mtx, array_size(dnew)); + } rmx_addinfo(dnew, rm->info); dnew->dtype = rm->dtype; copycolor(dnew->cexp, rm->cexp); memcpy(dnew->wlpart, rm->wlpart, sizeof(dnew->wlpart)); - memcpy(dnew->mtx, rm->mtx, array_size(dnew)); return(dnew); +} + +/* Replace data in first matrix with data from second */ +int +rmx_transfer_data(RMATRIX *rdst, RMATRIX *rsrc, int dometa) +{ + if (!rdst | !rsrc || (rdst->nrows != rsrc->nrows) | + (rdst->ncols != rsrc->ncols) | + (rdst->ncomp != rsrc->ncomp)) + return(0); + + if (dometa) { /* transfer everything? */ + rmx_reset(rdst); + *rdst = *rsrc; + rsrc->info = NULL; rsrc->mapped = NULL; rsrc->mtx = NULL; + return(1); + } + if (rdst->mapped) + return(0); /* XXX can't handle this case */ + /* just matrix data -- leave metadata */ + if (rdst->mtx) free(rdst->mtx); + rdst->mtx = rsrc->mtx; + rsrc->mtx = NULL; + return(1); } /* Allocate and assign transposed matrix */