--- ray/src/rt/data.c 1994/04/14 04:50:27 2.8 +++ ray/src/rt/data.c 2009/05/12 16:37:53 2.29 @@ -1,29 +1,28 @@ -/* Copyright (c) 1993 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: data.c,v 2.29 2009/05/12 16:37:53 greg Exp $"; #endif - /* * data.c - routines dealing with interpolated data. - * - * 6/4/86 */ -#include "standard.h" +#include "copyright.h" -#include "color.h" +#include +#include "platform.h" +#include "paths.h" +#include "standard.h" +#include "color.h" #include "resolu.h" - +#include "view.h" #include "data.h" /* picture memory usage before warning */ #ifndef PSIZWARN -#ifdef BIGMEM +#ifdef SMLMEM #define PSIZWARN 3000000 #else -#define PSIZWARN 1000000 +#define PSIZWARN 10000000 #endif #endif @@ -34,20 +33,16 @@ static char SCCSid[] = "$SunId$ LBL"; #define hash(s) (shash(s)%TABSIZ) -extern char *fgetword(); - -extern char *getlibpath(); /* library search path */ - static DATARRAY *dtab[TABSIZ]; /* data array list */ -static DATARRAY *ptab[TABSIZ]; /* picture list */ +static gethfunc headaspect; -DATARRAY * -getdata(dname) /* get data array dname */ -char *dname; +extern DATARRAY * +getdata( /* get data array dname */ + char *dname +) { - char word[64]; char *dfname; FILE *fp; int asize; @@ -57,7 +52,6 @@ char *dname; 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 directories specified by the library path. @@ -78,51 +72,46 @@ char *dname; * 0 0 ni p0i p1i .. pni */ - if ((dfname = getpath(dname, getlibpath(), R_OK)) == NULL) { + if ((dfname = getpath(dname, getrlibpath(), R_OK)) == NULL) { sprintf(errmsg, "cannot find data file \"%s\"", dname); error(USER, errmsg); } - if ((dp = (DATARRAY *)malloc(sizeof(DATARRAY))) == NULL) - goto memerr; - - dp->name = savestr(dname); - if ((fp = fopen(dfname, "r")) == NULL) { sprintf(errmsg, "cannot open data file \"%s\"", dfname); error(SYSTEM, errmsg); } /* get dimensions */ - if (fgetword(word, sizeof(word), fp) == NULL || !isint(word)) + if (fgetval(fp, 'i', (char *)&asize) <= 0) goto scanerr; - dp->nd = atoi(word); - if (dp->nd <= 0 || dp->nd > MAXDDIM) { + if ((asize <= 0) | (asize > MAXDDIM)) { sprintf(errmsg, "bad number of dimensions for \"%s\"", dname); error(USER, errmsg); } + if ((dp = (DATARRAY *)malloc(sizeof(DATARRAY))) == NULL) + goto memerr; + dp->name = savestr(dname); + dp->type = DATATY; + dp->nd = asize; asize = 1; for (i = 0; i < dp->nd; i++) { - if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word)) + if (fgetval(fp, DATATY, (char *)&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, DATATY, (char *)&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', (char *)&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; if ((dp->dim[i].siz -= dp->dim[i].org) == 0) { - dp->dim[i].p = (double *)malloc(dp->dim[i].ne*sizeof(double)); + dp->dim[i].p = (DATATYPE *) + malloc(dp->dim[i].ne*sizeof(DATATYPE)); 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, DATATY, + (char *)&dp->dim[i].p[j]) <= 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])) @@ -133,14 +122,12 @@ char *dname; } else dp->dim[i].p = NULL; } - if ((dp->arr = (DATATYPE *)malloc(asize*sizeof(DATATYPE))) == NULL) + if ((dp->arr.d = (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, (char *)&dp->arr.d[i]) <= 0) goto scanerr; - dp->arr[i] = atof(word); - } fclose(fp); i = hash(dname); dp->next = dtab[i]; @@ -152,149 +139,155 @@ scanerr: sprintf(errmsg, "%s in data file \"%s\"", feof(fp) ? "unexpected EOF" : "bad format", dfname); error(USER, errmsg); + return NULL; /* pro forma return */ } -static -headaspect(s, iap) /* check string for aspect ratio */ -char *s; -double *iap; +static int +headaspect( /* check string for aspect ratio */ + char *s, + void *iap +) { + char fmt[32]; + if (isaspect(s)) - *iap *= aspectval(s); + *(double*)iap *= aspectval(s); + else if (formatval(fmt, s) && !globmatch(PICFMT, fmt)) + *(double*)iap = 0.0; + return(0); } -DATARRAY * -getpict(pname) /* get picture pname */ -char *pname; +extern DATARRAY * +getpict( /* get picture pname */ + char *pname +) { double inpaspect; char *pfname; FILE *fp; - COLOR *scanin; + COLR *scanin; int sl, ns; RESOLU inpres; - FLOAT loc[2]; + RREAL loc[2]; int y; register int x, i; register DATARRAY *pp; /* look for array in list */ - for (pp = ptab[hash(pname)]; pp != NULL; pp = pp->next) + for (pp = dtab[hash(pname)]; pp != NULL; pp = pp->next) if (!strcmp(pname, pp->name)) return(pp); /* found! */ - if ((pfname = getpath(pname, getlibpath(), R_OK)) == NULL) { + if ((pfname = getpath(pname, getrlibpath(), R_OK)) == NULL) { sprintf(errmsg, "cannot find picture file \"%s\"", pname); error(USER, errmsg); } - if ((pp = (DATARRAY *)calloc(3, sizeof(DATARRAY))) == NULL) + if ((pp = (DATARRAY *)malloc(3*sizeof(DATARRAY))) == NULL) goto memerr; - pp[0].name = - pp[1].name = - pp[2].name = savestr(pname); + pp[0].name = savestr(pname); if ((fp = fopen(pfname, "r")) == NULL) { sprintf(errmsg, "cannot open picture file \"%s\"", pfname); error(SYSTEM, errmsg); } -#ifdef MSDOS - setmode(fileno(fp), O_BINARY); -#endif + SET_FILE_BINARY(fp); /* get dimensions */ inpaspect = 1.0; getheader(fp, headaspect, &inpaspect); - if (!fgetsresolu(&inpres, fp)) + if (inpaspect <= FTINY || !fgetsresolu(&inpres, fp)) goto readerr; + pp[0].nd = 2; + pp[0].dim[0].ne = inpres.yr; + pp[0].dim[1].ne = inpres.xr; + pp[0].dim[0].org = + pp[0].dim[1].org = 0.0; + if (inpres.xr <= inpres.yr*inpaspect) { + pp[0].dim[0].siz = inpaspect * + (double)inpres.yr/inpres.xr; + pp[0].dim[1].siz = 1.0; + } else { + pp[0].dim[0].siz = 1.0; + pp[0].dim[1].siz = (double)inpres.xr/inpres.yr / + inpaspect; + } + pp[0].dim[0].p = pp[0].dim[1].p = NULL; + sl = scanlen(&inpres); /* allocate array */ + ns = numscans(&inpres); + i = ns*sl*sizeof(COLR); #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); + if (i > PSIZWARN) { /* memory warning */ + sprintf(errmsg, "picture file \"%s\" using %.1f MB of memory", + pname, i*(1.0/(1024*1024))); error(WARNING, errmsg); } #endif - for (i = 0; i < 3; i++) { - pp[i].nd = 2; - pp[i].dim[0].ne = inpres.yr; - pp[i].dim[1].ne = inpres.xr; - pp[i].dim[0].org = - pp[i].dim[1].org = 0.0; - if (inpres.xr <= inpres.yr*inpaspect) { - pp[i].dim[0].siz = inpaspect * - (double)inpres.yr/inpres.xr; - pp[i].dim[1].siz = 1.0; - } else { - pp[i].dim[0].siz = 1.0; - pp[i].dim[1].siz = (double)inpres.xr/inpres.yr / - inpaspect; - } - pp[i].dim[0].p = pp[i].dim[1].p = NULL; - pp[i].arr = (DATATYPE *) - malloc(inpres.xr*inpres.yr*sizeof(DATATYPE)); - if (pp[i].arr == NULL) - goto memerr; - } + if ((pp[0].arr.c = (COLR *)malloc(i)) == NULL) + goto memerr; /* load picture */ - sl = scanlen(&inpres); - ns = numscans(&inpres); - if ((scanin = (COLOR *)malloc(sl*sizeof(COLOR))) == NULL) + if ((scanin = (COLR *)malloc(sl*sizeof(COLR))) == NULL) goto memerr; for (y = 0; y < ns; y++) { - if (freadscan(scanin, sl, fp) < 0) + if (freadcolrs(scanin, sl, fp) < 0) goto readerr; for (x = 0; x < sl; x++) { pix2loc(loc, &inpres, x, y); i = (int)(loc[1]*inpres.yr)*inpres.xr + (int)(loc[0]*inpres.xr); - pp[0].arr[i] = colval(scanin[x],RED); - pp[1].arr[i] = colval(scanin[x],GRN); - pp[2].arr[i] = colval(scanin[x],BLU); + copycolr(pp[0].arr.c[i], scanin[x]); } } - free((char *)scanin); + free((void *)scanin); fclose(fp); i = hash(pname); - pp[0].next = - pp[1].next = - pp[2].next = ptab[i]; - return(ptab[i] = pp); + pp[0].next = dtab[i]; /* link into picture list */ + pp[1] = pp[0]; + pp[2] = pp[0]; + pp[0].type = RED; /* differentiate RGB records */ + pp[1].type = GRN; + pp[2].type = BLU; + return(dtab[i] = pp); memerr: error(SYSTEM, "out of memory in getpict"); readerr: sprintf(errmsg, "bad picture file \"%s\"", pfname); error(USER, errmsg); + return NULL; /* pro forma return */ } -freedata(dname) /* free memory associated with dname */ -char *dname; +extern void +freedata( /* release data array reference */ + DATARRAY *dta +) { DATARRAY head; int hval, nents; - register DATARRAY *dp, *dpl; + register DATARRAY *dpl, *dp; register int i; - if (dname == NULL) { /* free all if NULL */ + if (dta == NULL) { /* free all if NULL */ hval = 0; nents = TABSIZ; } else { - hval = hash(dname); nents = 1; + hval = hash(dta->name); nents = 1; } while (nents--) { head.next = dtab[hval]; dpl = &head; while ((dp = dpl->next) != NULL) - if (dname == NULL || !strcmp(dname, dp->name)) { + if ((dta == NULL) | (dta == dp)) { dpl->next = dp->next; - free((char *)dp->arr); + if (dp->type == DATATY) + free((void *)dp->arr.d); + else + free((void *)dp->arr.c); for (i = 0; i < dp->nd; i++) if (dp->dim[i].p != NULL) - free((char *)dp->dim[i].p); + free((void *)dp->dim[i].p); freestr(dp->name); - free((char *)dp); + free((void *)dp); } else dpl = dp; dtab[hval++] = head.next; @@ -302,59 +295,34 @@ char *dname; } -freepict(pname) /* free memory associated with pname */ -char *pname; +extern double +datavalue( /* interpolate data value at a point */ + register DATARRAY *dp, + double *pt +) { - DATARRAY head; - int hval, nents; - register DATARRAY *pp, *ppl; - - 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); - } else - ppl = pp; - ptab[hval++] = head.next; - } -} - - -double -datavalue(dp, pt) /* interpolate data value at a point */ -register DATARRAY *dp; -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; - 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; + if (dp->nd > 1) { + sd.name = dp->name; + sd.type = dp->type; + 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; + } } /* 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; @@ -381,25 +349,36 @@ double *pt; (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]; + if (dp->nd > 1) { + if (dp->type == DATATY) { + sd.arr.d = dp->arr.d + i*asize; + y0 = datavalue(&sd, pt+1); + sd.arr.d = dp->arr.d + (i+1)*asize; + y1 = datavalue(&sd, pt+1); + } else { + sd.arr.c = dp->arr.c + i*asize; + y0 = datavalue(&sd, pt+1); + sd.arr.c = dp->arr.c + (i+1)*asize; + y1 = datavalue(&sd, pt+1); + } } else { - sd.arr = &dp->arr[i*asize]; - y0 = datavalue(&sd, pt+1); - sd.arr = &dp->arr[(i+1)*asize]; - y1 = datavalue(&sd, pt+1); + if (dp->type == DATATY) { + y0 = dp->arr.d[i]; + y1 = dp->arr.d[i+1]; + } else { + y0 = colrval(dp->arr.c[i],dp->type); + y1 = colrval(dp->arr.c[i+1],dp->type); + } } /* * Extrapolate as far as one division, then * 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) ); }