--- ray/src/util/cmatrix.c 2014/01/20 21:29:04 2.1 +++ ray/src/util/cmatrix.c 2014/05/29 17:28:09 2.4 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: cmatrix.c,v 2.1 2014/01/20 21:29:04 greg Exp $"; +static const char RCSid[] = "$Id: cmatrix.c,v 2.4 2014/05/29 17:28:09 greg Exp $"; #endif /* * Color matrix routines. @@ -11,7 +11,17 @@ static const char RCSid[] = "$Id: cmatrix.c,v 2.1 2014 #include "standard.h" #include "cmatrix.h" #include "platform.h" +#include "resolu.h" +const char *cm_fmt_id[] = { + "unknown", "ascii", "float", "double", + COLRFMT, CIEFMT + }; + +const int cm_elem_size[] = { + 0, 0, 3*sizeof(float), 3*sizeof(double), 4, 4 + }; + /* Allocate a color coefficient matrix */ CMATRIX * cm_alloc(int nrows, int ncols) @@ -21,7 +31,7 @@ cm_alloc(int nrows, int ncols) if ((nrows <= 0) | (ncols <= 0)) error(USER, "attempt to create empty matrix"); cm = (CMATRIX *)malloc(sizeof(CMATRIX) + - 3*sizeof(COLORV)*(nrows*ncols - 1)); + sizeof(COLOR)*(nrows*ncols - 1)); if (cm == NULL) error(SYSTEM, "out of memory in cm_alloc()"); cm->nrows = nrows; @@ -40,7 +50,7 @@ cm_resize(CMATRIX *cm, int nrows) return(NULL); } cm = (CMATRIX *)realloc(cm, sizeof(CMATRIX) + - 3*sizeof(COLORV)*(nrows*cm->ncols - 1)); + sizeof(COLOR)*(nrows*cm->ncols - 1)); if (cm == NULL) error(SYSTEM, "out of memory in cm_resize()"); cm->nrows = nrows; @@ -51,19 +61,13 @@ static int getDT(char *s, void *p) { char fmt[32]; + int i; - if (formatval(fmt, s)) { - if (!strcmp(fmt, "ascii")) - *((int *)p) = DTascii; - else if (!strcmp(fmt, "float")) - *((int *)p) = DTfloat; - else if (!strcmp(fmt, "double")) - *((int *)p) = DTdouble; - else if (!strcmp(fmt, COLRFMT)) - *((int *)p) = DTrgbe; - else if (!strcmp(fmt, CIEFMT)) - *((int *)p) = DTxyze; - } + if (!formatval(fmt, s)) + return(0); + for (i = 1; i < DTend; i++) + if (!strcmp(fmt, cm_fmt_id[i])) + *((int *)p) = i; return(0); } @@ -165,12 +169,11 @@ cm_load(const char *fname, int nrows, int ncols, int d break; } } else { /* read binary file */ - if (sizeof(COLORV) == (dtype==DTfloat ? sizeof(float) : - sizeof(double))) { + if (sizeof(COLOR) == cm_elem_size[dtype]) { int nread = 0; do { /* read all we can */ nread += fread(cm->cmem + 3*nread, - 3*sizeof(COLORV), + sizeof(COLOR), cm->nrows*cm->ncols - nread, fp); if (nrows <= 0) { /* unknown length */ @@ -312,34 +315,84 @@ cm_multiply(const CMATRIX *cm1, const CMATRIX *cm2) for (dr = 0; dr < cmr->nrows; dr++) for (dc = 0; dc < cmr->ncols; dc++) { COLORV *dp = cm_lval(cmr,dr,dc); + double res[3]; dp[0] = dp[1] = dp[2] = 0; if (rowcheck != NULL && !rowcheck[dr]) continue; if (colcheck != NULL && !colcheck[dc]) continue; + res[0] = res[1] = res[2] = 0; for (i = 0; i < cm1->ncols; i++) { const COLORV *cp1 = cm_lval(cm1,dr,i); const COLORV *cp2 = cm_lval(cm2,i,dc); - dp[0] += cp1[0] * cp2[0]; - dp[1] += cp1[1] * cp2[1]; - dp[2] += cp1[2] * cp2[2]; + res[0] += cp1[0] * cp2[0]; + res[1] += cp1[1] * cp2[1]; + res[2] += cp1[2] * cp2[2]; } + copycolor(dp, res); } if (rowcheck != NULL) free(rowcheck); if (colcheck != NULL) free(colcheck); return(cmr); } -/* print out matrix as ASCII text -- no header */ -void -cm_print(const CMATRIX *cm, FILE *fp) +/* write out matrix to file (precede by resolution string if picture) */ +int +cm_write(const CMATRIX *cm, int dtype, FILE *fp) { - int r, c; - const COLORV *mp = cm->cmem; - - for (r = 0; r < cm->nrows; r++) { - for (c = 0; c < cm->ncols; c++, mp += 3) - fprintf(fp, "\t%.6e %.6e %.6e", mp[0], mp[1], mp[2]); - fputc('\n', fp); + static const char tabEOL[2] = {'\t','\n'}; + const COLORV *mp = cm->cmem; + int r, c; + + switch (dtype) { + case DTascii: + for (r = 0; r < cm->nrows; r++) + for (c = 0; c < cm->ncols; c++, mp += 3) + fprintf(fp, "%.6e %.6e %.6e%c", + mp[0], mp[1], mp[2], + tabEOL[c >= cm->ncols-1]); + break; + case DTfloat: + case DTdouble: + if (sizeof(COLOR) == cm_elem_size[dtype]) { + r = cm->ncols*cm->nrows; + while (r > 0) { + c = fwrite(mp, sizeof(COLOR), r, fp); + if (c <= 0) + return(0); + mp += 3*c; + r -= c; + } + } else if (dtype == DTdouble) { + double dc[3]; + r = cm->ncols*cm->nrows; + while (r--) { + copycolor(dc, mp); + if (fwrite(dc, sizeof(double), 3, fp) != 3) + return(0); + mp += 3; + } + } else /* dtype == DTfloat */ { + float fc[3]; + r = cm->ncols*cm->nrows; + while (r--) { + copycolor(fc, mp); + if (fwrite(fc, sizeof(float), 3, fp) != 3) + return(0); + mp += 3; + } + } + break; + case DTrgbe: + case DTxyze: + fprtresolu(cm->ncols, cm->nrows, fp); + for (r = 0; r < cm->nrows; r++, mp += 3*cm->ncols) + if (fwritescan((COLOR *)mp, cm->ncols, fp) < 0) + return(0); + break; + default: + fputs("Unsupported data type in cm_write()!\n", stderr); + return(0); } + return(fflush(fp) == 0); }