--- ray/src/rt/data.c 1989/02/02 10:41:18 1.1 +++ ray/src/rt/data.c 1991/07/22 13:02:24 1.10 @@ -1,4 +1,4 @@ -/* Copyright (c) 1986 Regents of the University of California */ +/* Copyright (c) 1991 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -17,6 +17,9 @@ static char SCCSid[] = "$SunId$ LBL"; #include "data.h" +extern char *fgetword(); +extern double atof(); + extern char *libpath; /* library search path */ static DATARRAY *dlist = NULL; /* data array list */ @@ -28,10 +31,11 @@ DATARRAY * getdata(dname) /* get data array dname */ char *dname; { + char word[64]; char *dfname; FILE *fp; int asize; - register int i; + register int i, j; register DATARRAY *dp; /* look for array in list */ for (dp = dlist; dp != NULL; dp = dp->next) @@ -44,16 +48,21 @@ char *dname; * * The file has the following format: * - * #dimensions + * N * beg0 end0 n0 * beg1 end1 n1 * . . . + * begN endN nN * data, later dimensions changing faster * . . . * + * For irregularly spaced points, the following can be + * substituted for begi endi ni: + * + * 0 0 ni p0i p1i .. pni */ - if ((dfname = getpath(dname, libpath)) == NULL) { + if ((dfname = getpath(dname, libpath, R_OK)) == NULL) { sprintf(errmsg, "cannot find data file \"%s\"", dname); error(USER, errmsg); } @@ -67,28 +76,55 @@ char *dname; error(SYSTEM, errmsg); } /* get dimensions */ - if (fscanf(fp, "%d", &dp->nd) != 1) + if (fgetword(word, sizeof(word), fp) == NULL || !isint(word)) goto scanerr; - if (dp->nd <= 0 || dp->nd > MAXDIM) { + dp->nd = atoi(word); + if (dp->nd <= 0 || dp->nd > MAXDDIM) { sprintf(errmsg, "bad number of dimensions for \"%s\"", dname); error(USER, errmsg); } asize = 1; for (i = 0; i < dp->nd; i++) { - if (fscanf(fp, "%lf %lf %d", - &dp->dim[i].org, &dp->dim[i].siz, - &dp->dim[i].ne) != 3) + if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word)) goto scanerr; - dp->dim[i].siz -= dp->dim[i].org; + dp->dim[i].org = atof(word); + if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word)) + goto scanerr; + dp->dim[i].siz = atof(word); + if (fgetword(word, sizeof(word), fp) == NULL || !isint(word)) + goto scanerr; + dp->dim[i].ne = atoi(word); + if (dp->dim[i].ne < 2) + goto scanerr; asize *= dp->dim[i].ne; + if ((dp->dim[i].siz -= dp->dim[i].org) == 0) { + dp->dim[i].p = (double *)malloc(dp->dim[i].ne*sizeof(double)); + if (dp->dim[i].p == NULL) + goto memerr; + for (j = 0; j < dp->dim[i].ne; j++) { + if (fgetword(word, sizeof(word), fp) == NULL || + !isflt(word)) + goto scanerr; + dp->dim[i].p[j] = atof(word); + } + for (j = 1; j < dp->dim[i].ne-1; j++) + if ((dp->dim[i].p[j-1] < dp->dim[i].p[j]) != + (dp->dim[i].p[j] < dp->dim[i].p[j+1])) + goto scanerr; + dp->dim[i].org = dp->dim[i].p[0]; + dp->dim[i].siz = dp->dim[i].p[dp->dim[i].ne-1] + - dp->dim[i].p[0]; + } else + dp->dim[i].p = NULL; } if ((dp->arr = (DATATYPE *)malloc(asize*sizeof(DATATYPE))) == NULL) goto memerr; - for (i = 0; i < asize; i++) - if (fscanf(fp, DSCANF, &dp->arr[i]) != 1) + for (i = 0; i < asize; i++) { + if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word)) goto scanerr; - + dp->arr[i] = atof(word); + } fclose(fp); dp->next = dlist; return(dlist = dp); @@ -102,6 +138,17 @@ scanerr: } +static double inpaspect; /* aspect ratio of input picture */ + +static +headaspect(s) /* check string for aspect ratio */ +char *s; +{ + if (isaspect(s)) + inpaspect *= aspectval(s); +} + + DATARRAY * getpict(pname) /* get picture pname */ char *pname; @@ -119,7 +166,7 @@ char *pname; if (!strcmp(pname, pp->name)) return(pp); /* found! */ - if ((pfname = getpath(pname, libpath)) == NULL) { + if ((pfname = getpath(pname, libpath, R_OK)) == NULL) { sprintf(errmsg, "cannot find picture file \"%s\"", pname); error(USER, errmsg); } @@ -135,22 +182,24 @@ char *pname; error(SYSTEM, errmsg); } /* get dimensions */ - getheader(fp, NULL); - if (fscanf(fp, "-Y %d +X %d\n", &height, &width) != 2) + inpaspect = 1.0; + getheader(fp, headaspect); + if (fgetresolu(&width, &height, fp) != (YMAJOR|YDECR)) goto readerr; for (i = 0; i < 3; i++) { pp[i].nd = 2; - pp[i].dim[0].ne = width; - pp[i].dim[1].ne = height; + pp[i].dim[0].ne = height; + pp[i].dim[1].ne = width; pp[i].dim[0].org = pp[i].dim[1].org = 0.0; - if (width <= height) { - pp[i].dim[0].siz = 1.0; - pp[i].dim[1].siz = (double)height/width; - } else { - pp[i].dim[0].siz = (double)width/height; + if (width <= height*inpaspect) { + pp[i].dim[0].siz = inpaspect*(double)height/width; pp[i].dim[1].siz = 1.0; + } else { + pp[i].dim[0].siz = 1.0; + pp[i].dim[1].siz = (double)width/height/inpaspect; } + pp[i].dim[0].p = pp[i].dim[1].p = NULL; pp[i].arr = (DATATYPE *)malloc(width*height*sizeof(DATATYPE)); if (pp[i].arr == NULL) goto memerr; @@ -163,7 +212,7 @@ char *pname; goto readerr; for (x = 0; x < width; x++) for (i = 0; i < 3; i++) - pp[i].arr[x*height+y] = colval(scanin[x],i); + pp[i].arr[y*width+x] = colval(scanin[x],i); } free((char *)scanin); fclose(fp); @@ -184,6 +233,7 @@ freedata(dname) /* free memory associated with dname char *dname; { register DATARRAY *dp, *dpl; + register int i; for (dpl = NULL, dp = dlist; dp != NULL; dpl = dp, dp = dp->next) if (!strcmp(dname, dp->name)) { @@ -192,6 +242,9 @@ char *dname; else dpl->next = dp->next; free((char *)dp->arr); + for (i = 0; i < dp->nd; i++) + if (dp->dim[i].p != NULL) + free((char *)dp->dim[i].p); freestr(dp->name); free((char *)dp); return; @@ -227,27 +280,48 @@ double *pt; { DATARRAY sd; int asize; + int lower, upper; register int i; double x, y, y0, y1; - + /* set up dimensions for recursion */ sd.nd = dp->nd - 1; asize = 1; for (i = 0; i < sd.nd; i++) { sd.dim[i].org = dp->dim[i+1].org; sd.dim[i].siz = dp->dim[i+1].siz; + sd.dim[i].p = dp->dim[i+1].p; asize *= sd.dim[i].ne = dp->dim[i+1].ne; } - - x = (pt[0] - dp->dim[0].org)/dp->dim[0].siz; - - x *= dp->dim[0].ne - 1; - - i = x; - if (i < 0) - i = 0; - else if (i > dp->dim[0].ne - 2) - i = dp->dim[0].ne - 2; - + /* get independent variable */ + if (dp->dim[0].p == NULL) { /* evenly spaced points */ + x = (pt[0] - dp->dim[0].org)/dp->dim[0].siz; + x = x * (dp->dim[0].ne - 1); + i = x; + if (i < 0) + i = 0; + else if (i > dp->dim[0].ne - 2) + i = dp->dim[0].ne - 2; + } else { /* unevenly spaced points */ + if (dp->dim[0].siz > 0.0) { + lower = 0; + upper = dp->dim[0].ne; + } else { + lower = dp->dim[0].ne; + upper = 0; + } + do { + i = (lower + upper) >> 1; + if (pt[0] >= dp->dim[0].p[i]) + lower = i; + else + upper = i; + } while (i != (lower + upper) >> 1); + if (i > dp->dim[0].ne - 2) + i = dp->dim[0].ne - 2; + x = i + (pt[0] - dp->dim[0].p[i]) / + (dp->dim[0].p[i+1] - dp->dim[0].p[i]); + } + /* get dependent variable */ if (dp->nd == 1) { y0 = dp->arr[i]; y1 = dp->arr[i+1]; @@ -257,7 +331,6 @@ double *pt; sd.arr = &dp->arr[(i+1)*asize]; y1 = datavalue(&sd, pt+1); } - /* * Extrapolate as far as one division, then * taper off harmonically to zero.