--- ray/src/rt/data.c 1991/11/11 14:02:43 1.11 +++ ray/src/rt/data.c 1995/06/30 16:07:44 2.10 @@ -1,4 +1,4 @@ -/* Copyright (c) 1991 Regents of the University of California */ +/* Copyright (c) 1993 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -18,35 +18,46 @@ static char SCCSid[] = "$SunId$ LBL"; #include "data.h" + /* picture memory usage before warning */ +#ifndef PSIZWARN +#ifdef BIGMEM +#define PSIZWARN 3000000 +#else +#define PSIZWARN 1000000 +#endif +#endif -extern char *fgetword(); -extern double atof(); +#ifndef TABSIZ +#define TABSIZ 97 /* table size (prime) */ +#endif -extern char *libpath; /* library search path */ +#define hash(s) (shash(s)%TABSIZ) -static DATARRAY *dlist = NULL; /* data array list */ -static DATARRAY *plist = NULL; /* picture list */ +extern char *getlibpath(); /* library search path */ +static DATARRAY *dtab[TABSIZ]; /* data array list */ +static DATARRAY *ptab[TABSIZ]; /* picture list */ + + DATARRAY * getdata(dname) /* get data array dname */ char *dname; { - char word[64]; char *dfname; FILE *fp; int asize; register int i, j; register DATARRAY *dp; /* look for array in list */ - for (dp = dlist; dp != NULL; dp = dp->next) + for (dp = dtab[hash(dname)]; dp != NULL; dp = dp->next) if (!strcmp(dname, dp->name)) return(dp); /* found! */ /* * If we haven't loaded the data already, we will look - * for it in the directorys specified by the library path. + * for it in the directories specified by the library path. * * The file has the following format: * @@ -64,7 +75,7 @@ char *dname; * 0 0 ni p0i p1i .. pni */ - if ((dfname = getpath(dname, libpath, R_OK)) == NULL) { + if ((dfname = getpath(dname, getlibpath(), R_OK)) == NULL) { sprintf(errmsg, "cannot find data file \"%s\"", dname); error(USER, errmsg); } @@ -78,24 +89,20 @@ char *dname; error(SYSTEM, errmsg); } /* get dimensions */ - if (fgetword(word, sizeof(word), fp) == NULL || !isint(word)) + if (fgetval(fp, 'i', &dp->nd) <= 0) goto scanerr; - 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 (fgetword(word, sizeof(word), fp) == NULL || !isflt(word)) + if (fgetval(fp, 'd', &dp->dim[i].org) <= 0) goto scanerr; - dp->dim[i].org = atof(word); - if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word)) + if (fgetval(fp, 'd', &dp->dim[i].siz) <= 0) goto scanerr; - dp->dim[i].siz = atof(word); - if (fgetword(word, sizeof(word), fp) == NULL || !isint(word)) + if (fgetval(fp, 'i', &dp->dim[i].ne) <= 0) goto scanerr; - dp->dim[i].ne = atoi(word); if (dp->dim[i].ne < 2) goto scanerr; asize *= dp->dim[i].ne; @@ -103,12 +110,9 @@ char *dname; 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)) + for (j = 0; j < dp->dim[i].ne; j++) + if (fgetval(fp, 'd', &dp->dim[i].p[i]) <= 0) 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])) @@ -122,14 +126,13 @@ char *dname; if ((dp->arr = (DATATYPE *)malloc(asize*sizeof(DATATYPE))) == NULL) goto memerr; - for (i = 0; i < asize; i++) { - if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word)) + for (i = 0; i < asize; i++) + if (fgetval(fp, DATATY, &dp->arr[i]) <= 0) goto scanerr; - dp->arr[i] = atof(word); - } fclose(fp); - dp->next = dlist; - return(dlist = dp); + i = hash(dname); + dp->next = dtab[i]; + return(dtab[i] = dp); memerr: error(SYSTEM, "out of memory in getdata"); @@ -140,14 +143,13 @@ scanerr: } -static double inpaspect; /* aspect ratio of input picture */ - static -headaspect(s) /* check string for aspect ratio */ +headaspect(s, iap) /* check string for aspect ratio */ char *s; +double *iap; { if (isaspect(s)) - inpaspect *= aspectval(s); + *iap *= aspectval(s); } @@ -155,22 +157,22 @@ DATARRAY * getpict(pname) /* get picture pname */ char *pname; { - extern char *libpath; + double inpaspect; char *pfname; FILE *fp; COLOR *scanin; int sl, ns; - RESOLU inpres; + RESOLU inpres; FLOAT loc[2]; int y; register int x, i; register DATARRAY *pp; /* look for array in list */ - for (pp = plist; pp != NULL; pp = pp->next) + for (pp = ptab[hash(pname)]; pp != NULL; pp = pp->next) if (!strcmp(pname, pp->name)) return(pp); /* found! */ - if ((pfname = getpath(pname, libpath, R_OK)) == NULL) { + if ((pfname = getpath(pname, getlibpath(), R_OK)) == NULL) { sprintf(errmsg, "cannot find picture file \"%s\"", pname); error(USER, errmsg); } @@ -185,11 +187,23 @@ char *pname; sprintf(errmsg, "cannot open picture file \"%s\"", pfname); error(SYSTEM, errmsg); } +#ifdef MSDOS + setmode(fileno(fp), O_BINARY); +#endif /* get dimensions */ inpaspect = 1.0; - getheader(fp, headaspect); + getheader(fp, headaspect, &inpaspect); if (!fgetsresolu(&inpres, fp)) goto readerr; +#if PSIZWARN + /* check memory usage */ + i = 3*sizeof(DATATYPE)*inpres.xr*inpres.yr; + if (i > PSIZWARN) { + sprintf(errmsg, "picture file \"%s\" using %d bytes of memory", + pname, i); + error(WARNING, errmsg); + } +#endif for (i = 0; i < 3; i++) { pp[i].nd = 2; pp[i].dim[0].ne = inpres.yr; @@ -230,10 +244,11 @@ char *pname; } free((char *)scanin); fclose(fp); + i = hash(pname); pp[0].next = pp[1].next = - pp[2].next = plist; - return(plist = pp); + pp[2].next = ptab[i]; + return(ptab[i] = pp); memerr: error(SYSTEM, "out of memory in getpict"); @@ -246,57 +261,75 @@ readerr: freedata(dname) /* free memory associated with dname */ char *dname; { + DATARRAY head; + int hval, nents; register DATARRAY *dp, *dpl; register int i; - for (dpl = NULL, dp = dlist; dp != NULL; dpl = dp, dp = dp->next) - if (!strcmp(dname, dp->name)) { - if (dpl == NULL) - dlist = dp->next; - else + if (dname == NULL) { /* free all if NULL */ + hval = 0; nents = TABSIZ; + } else { + hval = hash(dname); nents = 1; + } + while (nents--) { + head.next = dtab[hval]; + dpl = &head; + while ((dp = dpl->next) != NULL) + if (dname == NULL || !strcmp(dname, dp->name)) { 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; - } + 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); + } else + dpl = dp; + dtab[hval++] = head.next; + } } freepict(pname) /* free memory associated with pname */ char *pname; { + DATARRAY head; + int hval, nents; register DATARRAY *pp, *ppl; - for (ppl = NULL, pp = plist; pp != NULL; ppl = pp, pp = pp->next) - if (!strcmp(pname, pp->name)) { - if (ppl == NULL) - plist = pp->next; - else + if (pname == NULL) { /* free all if NULL */ + hval = 0; nents = TABSIZ; + } else { + hval = hash(pname); nents = 1; + } + while (nents--) { + head.next = ptab[hval]; + ppl = &head; + while ((pp = ppl->next) != NULL) + if (pname == NULL || !strcmp(pname, pp->name)) { ppl->next = pp->next; - free((char *)pp[0].arr); - free((char *)pp[1].arr); - free((char *)pp[2].arr); - freestr(pp[0].name); - free((char *)pp); - return; - } + free((char *)pp[0].arr); + free((char *)pp[1].arr); + free((char *)pp[2].arr); + freestr(pp[0].name); + free((char *)pp); + } else + ppl = pp; + ptab[hval++] = head.next; + } } double datavalue(dp, pt) /* interpolate data value at a point */ register DATARRAY *dp; -double *pt; +double *pt; { DATARRAY sd; int asize; int lower, upper; register int i; - double x, y, y0, y1; + double x, y0, y1; /* set up dimensions for recursion */ sd.nd = dp->nd - 1; asize = 1; @@ -309,7 +342,7 @@ double *pt; /* 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); + x *= (double)(dp->dim[0].ne - 1); i = x; if (i < 0) i = 0; @@ -350,11 +383,10 @@ double *pt; * taper off harmonically to zero. */ if (x > i+2) - y = (2*y1-y0)/(x-i-1); - else if (x < i-1) - y = (2*y0-y1)/(i-x); - else - y = y0*((i+1)-x) + y1*(x-i); + return( (2*y1-y0)/(x-(i-1)) ); - return(y); + if (x < i-1) + return( (2*y0-y1)/(i-x) ); + + return( y0*((i+1)-x) + y1*(x-i) ); }