home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
RADIANCE
/
SRC
/
RT
/
DATA.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-07
|
9KB
|
363 lines
/* 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);
}