--- ray/src/util/cmatrix.c 2022/04/27 01:31:56 2.35 +++ ray/src/util/cmatrix.c 2025/04/19 17:12:59 2.41 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: cmatrix.c,v 2.35 2022/04/27 01:31:56 greg Exp $"; +static const char RCSid[] = "$Id: cmatrix.c,v 2.41 2025/04/19 17:12:59 greg Exp $"; #endif /* * Color matrix routines. @@ -15,17 +15,6 @@ static const char RCSid[] = "$Id: cmatrix.c,v 2.35 202 #include "paths.h" #include "resolu.h" -const char stdin_name[] = ""; - -const char *cm_fmt_id[] = { - "unknown", COLRFMT, CIEFMT, - "float", "ascii", "double" - }; - -const int cm_elem_size[] = { - 0, 4, 4, 3*sizeof(float), 0, 3*sizeof(double) - }; - /* Allocate a color coefficient matrix */ CMATRIX * cm_alloc(int nrows, int ncols) @@ -96,7 +85,7 @@ get_cminfo(char *s, void *p) char fmt[MAXFMTLEN]; int i; - if (!strncmp(s, "NCOMP=", 6) && atoi(s+6) != 3) { + if (isncomp(s) && ncompval(s) != 3) { ip->err = "unexpected # components (must be 3)"; return(-1); } @@ -177,18 +166,14 @@ cm_getheader(int *dt, int *nr, int *nc, int *swp, COLO /* Allocate and load image data into matrix */ static CMATRIX * -cm_load_rgbe(FILE *fp, int nrows, int ncols, COLOR scale) +cm_load_rgbe(FILE *fp, int nrows, int ncols) { - int doscale; CMATRIX *cm; COLORV *mp; /* header already loaded */ cm = cm_alloc(nrows, ncols); if (!cm) return(NULL); - doscale = (scale[0] < .99) | (scale[0] > 1.01) | - (scale[1] < .99) | (scale[1] > 1.01) | - (scale[2] < .99) | (scale[2] > 1.01) ; mp = cm->cmem; while (nrows--) { if (freadscan((COLOR *)mp, ncols, fp) < 0) { @@ -196,15 +181,7 @@ cm_load_rgbe(FILE *fp, int nrows, int ncols, COLOR sca cm_free(cm); return(NULL); } - if (doscale) { - int i = ncols; - while (i--) { - *mp++ *= scale[0]; - *mp++ *= scale[1]; - *mp++ *= scale[2]; - } - } else - mp += 3*ncols; + mp += 3*ncols; } /* caller closes stream */ return(cm); } @@ -214,7 +191,7 @@ CMATRIX * cm_load(const char *inspec, int nrows, int ncols, int dtype) { const int ROWINC = 2048; - int rowsOK = (dtype == DTascii) | (nrows > 0); + int dimsOK = (dtype == DTascii) | (nrows > 0) && ncols; int swap = 0; FILE *fp; COLOR scale; @@ -241,13 +218,14 @@ cm_load(const char *inspec, int nrows, int ncols, int #endif if (dtype != DTascii) SET_FILE_BINARY(fp); /* doesn't really work */ - if (!dtype | !rowsOK | !ncols) { /* expecting header? */ + if (!dtype | !dimsOK) { /* expecting header? */ char *err = cm_getheader(&dtype, &nrows, &ncols, &swap, scale, fp); if (err) error(USER, err); - rowsOK = (nrows > 0); + dimsOK = ncols > 0 && ( nrows > 0 || + (dtype != DTrgbe) & (dtype != DTxyze) ); } - if (!rowsOK | !ncols && !fscnresolu(&ncols, &nrows, fp)) + if (!dimsOK && !fscnresolu(&ncols, &nrows, fp)) error(USER, "unspecified matrix size"); switch (dtype) { case DTascii: @@ -256,7 +234,7 @@ cm_load(const char *inspec, int nrows, int ncols, int break; case DTrgbe: case DTxyze: - cm = cm_load_rgbe(fp, nrows, ncols, scale); + cm = cm_load_rgbe(fp, nrows, ncols); goto cleanup; default: error(USER, "unexpected data type in cm_load()"); @@ -393,6 +371,17 @@ cleanup: else funlockfile(fp); #endif + if ((scale[0] < .99) | (scale[0] > 1.01) | + (scale[1] < .99) | (scale[1] > 1.01) | + (scale[2] < .99) | (scale[2] > 1.01)) { + size_t n = (size_t)ncols*nrows; + COLORV *mp = cm->cmem; + while (n--) { /* apply exposure scaling */ + *mp++ *= scale[0]; + *mp++ *= scale[1]; + *mp++ *= scale[2]; + } + } return(cm); EOFerror: sprintf(errmsg, "unexpected EOF reading %s", inspec); @@ -495,6 +484,9 @@ cm_write(const CMATRIX *cm, int dtype, FILE *fp) if (!cm) return(0); +#ifdef getc_unlocked + flockfile(fp); +#endif mp = cm->cmem; switch (dtype) { case DTascii: @@ -546,5 +538,8 @@ cm_write(const CMATRIX *cm, int dtype, FILE *fp) fputs("Unsupported data type in cm_write()!\n", stderr); return(0); } +#ifdef getc_unlocked + funlockfile(fp); +#endif return(fflush(fp) == 0); }