home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1991 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)data.c 2.2 12/19/91 LBL";
- #endif
-
- /*
- * data.c - routines dealing with interpolated data.
- *
- * 6/4/86
- */
-
- #include "standard.h"
-
- #include "color.h"
-
- #include "resolu.h"
-
- #include "data.h"
-
-
- extern char *fgetword();
-
- extern char *libpath; /* library search path */
-
- static DATARRAY *dlist = NULL; /* data array list */
-
- static DATARRAY *plist = NULL; /* 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)
- 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.
- *
- * The file has the following format:
- *
- * 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, 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))
- 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))
- goto scanerr;
- 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 (fgetword(word, sizeof(word), fp) == NULL || !isflt(word))
- goto scanerr;
- dp->arr[i] = atof(word);
- }
- fclose(fp);
- dp->next = dlist;
- return(dlist = dp);
-
- memerr:
- error(SYSTEM, "out of memory in getdata");
- scanerr:
- sprintf(errmsg, "%s in data file \"%s\"",
- feof(fp) ? "unexpected EOF" : "bad format", dfname);
- error(USER, errmsg);
- }
-
-
- 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;
- {
- extern char *libpath;
- char *pfname;
- FILE *fp;
- COLOR *scanin;
- int sl, ns;
- 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)
- if (!strcmp(pname, pp->name))
- return(pp); /* found! */
-
- if ((pfname = getpath(pname, libpath, R_OK)) == NULL) {
- sprintf(errmsg, "cannot find picture file \"%s\"", pname);
- error(USER, errmsg);
- }
- if ((pp = (DATARRAY *)calloc(3, sizeof(DATARRAY))) == NULL)
- goto memerr;
-
- pp[0].name =
- pp[1].name =
- pp[2].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
- /* get dimensions */
- inpaspect = 1.0;
- getheader(fp, headaspect);
- if (!fgetsresolu(&inpres, fp))
- goto readerr;
- 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;
- }
- /* load picture */
- sl = scanlen(&inpres);
- ns = numscans(&inpres);
- if ((scanin = (COLOR *)malloc(sl*sizeof(COLOR))) == NULL)
- goto memerr;
- for (y = 0; y < ns; y++) {
- if (freadscan(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);
- }
- }
- free((char *)scanin);
- fclose(fp);
- pp[0].next =
- pp[1].next =
- pp[2].next = plist;
- return(plist = pp);
-
- memerr:
- error(SYSTEM, "out of memory in getpict");
- readerr:
- sprintf(errmsg, "bad picture file \"%s\"", pfname);
- error(USER, errmsg);
- }
-
-
- 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)) {
- if (dpl == NULL)
- dlist = dp->next;
- 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;
- }
- }
-
-
- freepict(pname) /* free memory associated with pname */
- char *pname;
- {
- 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
- 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;
- }
- }
-
-
- 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;
- /* 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;
- }
- /* 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];
- } else {
- sd.arr = &dp->arr[i*asize];
- y0 = datavalue(&sd, pt+1);
- sd.arr = &dp->arr[(i+1)*asize];
- y1 = datavalue(&sd, pt+1);
- }
- /*
- * 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(y);
- }
-