ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/data.c
Revision: 2.8
Committed: Thu Apr 14 04:50:27 1994 UTC (30 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +3 -4 lines
Log Message:
changed extern char *libpath to extern char *getlibpath()

File Contents

# Content
1 /* Copyright (c) 1993 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * data.c - routines dealing with interpolated data.
9 *
10 * 6/4/86
11 */
12
13 #include "standard.h"
14
15 #include "color.h"
16
17 #include "resolu.h"
18
19 #include "data.h"
20
21 /* picture memory usage before warning */
22 #ifndef PSIZWARN
23 #ifdef BIGMEM
24 #define PSIZWARN 3000000
25 #else
26 #define PSIZWARN 1000000
27 #endif
28 #endif
29
30 #ifndef TABSIZ
31 #define TABSIZ 97 /* table size (prime) */
32 #endif
33
34 #define hash(s) (shash(s)%TABSIZ)
35
36
37 extern char *fgetword();
38
39 extern char *getlibpath(); /* library search path */
40
41 static DATARRAY *dtab[TABSIZ]; /* data array list */
42
43 static DATARRAY *ptab[TABSIZ]; /* picture list */
44
45
46 DATARRAY *
47 getdata(dname) /* get data array dname */
48 char *dname;
49 {
50 char word[64];
51 char *dfname;
52 FILE *fp;
53 int asize;
54 register int i, j;
55 register DATARRAY *dp;
56 /* look for array in list */
57 for (dp = dtab[hash(dname)]; dp != NULL; dp = dp->next)
58 if (!strcmp(dname, dp->name))
59 return(dp); /* found! */
60
61 /*
62 * If we haven't loaded the data already, we will look
63 * for it in the directories specified by the library path.
64 *
65 * The file has the following format:
66 *
67 * N
68 * beg0 end0 n0
69 * beg1 end1 n1
70 * . . .
71 * begN endN nN
72 * data, later dimensions changing faster
73 * . . .
74 *
75 * For irregularly spaced points, the following can be
76 * substituted for begi endi ni:
77 *
78 * 0 0 ni p0i p1i .. pni
79 */
80
81 if ((dfname = getpath(dname, getlibpath(), R_OK)) == NULL) {
82 sprintf(errmsg, "cannot find data file \"%s\"", dname);
83 error(USER, errmsg);
84 }
85 if ((dp = (DATARRAY *)malloc(sizeof(DATARRAY))) == NULL)
86 goto memerr;
87
88 dp->name = savestr(dname);
89
90 if ((fp = fopen(dfname, "r")) == NULL) {
91 sprintf(errmsg, "cannot open data file \"%s\"", dfname);
92 error(SYSTEM, errmsg);
93 }
94 /* get dimensions */
95 if (fgetword(word, sizeof(word), fp) == NULL || !isint(word))
96 goto scanerr;
97 dp->nd = atoi(word);
98 if (dp->nd <= 0 || dp->nd > MAXDDIM) {
99 sprintf(errmsg, "bad number of dimensions for \"%s\"", dname);
100 error(USER, errmsg);
101 }
102 asize = 1;
103 for (i = 0; i < dp->nd; i++) {
104 if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word))
105 goto scanerr;
106 dp->dim[i].org = atof(word);
107 if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word))
108 goto scanerr;
109 dp->dim[i].siz = atof(word);
110 if (fgetword(word, sizeof(word), fp) == NULL || !isint(word))
111 goto scanerr;
112 dp->dim[i].ne = atoi(word);
113 if (dp->dim[i].ne < 2)
114 goto scanerr;
115 asize *= dp->dim[i].ne;
116 if ((dp->dim[i].siz -= dp->dim[i].org) == 0) {
117 dp->dim[i].p = (double *)malloc(dp->dim[i].ne*sizeof(double));
118 if (dp->dim[i].p == NULL)
119 goto memerr;
120 for (j = 0; j < dp->dim[i].ne; j++) {
121 if (fgetword(word, sizeof(word), fp) == NULL ||
122 !isflt(word))
123 goto scanerr;
124 dp->dim[i].p[j] = atof(word);
125 }
126 for (j = 1; j < dp->dim[i].ne-1; j++)
127 if ((dp->dim[i].p[j-1] < dp->dim[i].p[j]) !=
128 (dp->dim[i].p[j] < dp->dim[i].p[j+1]))
129 goto scanerr;
130 dp->dim[i].org = dp->dim[i].p[0];
131 dp->dim[i].siz = dp->dim[i].p[dp->dim[i].ne-1]
132 - dp->dim[i].p[0];
133 } else
134 dp->dim[i].p = NULL;
135 }
136 if ((dp->arr = (DATATYPE *)malloc(asize*sizeof(DATATYPE))) == NULL)
137 goto memerr;
138
139 for (i = 0; i < asize; i++) {
140 if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word))
141 goto scanerr;
142 dp->arr[i] = atof(word);
143 }
144 fclose(fp);
145 i = hash(dname);
146 dp->next = dtab[i];
147 return(dtab[i] = dp);
148
149 memerr:
150 error(SYSTEM, "out of memory in getdata");
151 scanerr:
152 sprintf(errmsg, "%s in data file \"%s\"",
153 feof(fp) ? "unexpected EOF" : "bad format", dfname);
154 error(USER, errmsg);
155 }
156
157
158 static
159 headaspect(s, iap) /* check string for aspect ratio */
160 char *s;
161 double *iap;
162 {
163 if (isaspect(s))
164 *iap *= aspectval(s);
165 }
166
167
168 DATARRAY *
169 getpict(pname) /* get picture pname */
170 char *pname;
171 {
172 double inpaspect;
173 char *pfname;
174 FILE *fp;
175 COLOR *scanin;
176 int sl, ns;
177 RESOLU inpres;
178 FLOAT loc[2];
179 int y;
180 register int x, i;
181 register DATARRAY *pp;
182 /* look for array in list */
183 for (pp = ptab[hash(pname)]; pp != NULL; pp = pp->next)
184 if (!strcmp(pname, pp->name))
185 return(pp); /* found! */
186
187 if ((pfname = getpath(pname, getlibpath(), R_OK)) == NULL) {
188 sprintf(errmsg, "cannot find picture file \"%s\"", pname);
189 error(USER, errmsg);
190 }
191 if ((pp = (DATARRAY *)calloc(3, sizeof(DATARRAY))) == NULL)
192 goto memerr;
193
194 pp[0].name =
195 pp[1].name =
196 pp[2].name = savestr(pname);
197
198 if ((fp = fopen(pfname, "r")) == NULL) {
199 sprintf(errmsg, "cannot open picture file \"%s\"", pfname);
200 error(SYSTEM, errmsg);
201 }
202 #ifdef MSDOS
203 setmode(fileno(fp), O_BINARY);
204 #endif
205 /* get dimensions */
206 inpaspect = 1.0;
207 getheader(fp, headaspect, &inpaspect);
208 if (!fgetsresolu(&inpres, fp))
209 goto readerr;
210 #if PSIZWARN
211 /* check memory usage */
212 i = 3*sizeof(DATATYPE)*inpres.xr*inpres.yr;
213 if (i > PSIZWARN) {
214 sprintf(errmsg, "picture file \"%s\" using %d bytes of memory",
215 pname, i);
216 error(WARNING, errmsg);
217 }
218 #endif
219 for (i = 0; i < 3; i++) {
220 pp[i].nd = 2;
221 pp[i].dim[0].ne = inpres.yr;
222 pp[i].dim[1].ne = inpres.xr;
223 pp[i].dim[0].org =
224 pp[i].dim[1].org = 0.0;
225 if (inpres.xr <= inpres.yr*inpaspect) {
226 pp[i].dim[0].siz = inpaspect *
227 (double)inpres.yr/inpres.xr;
228 pp[i].dim[1].siz = 1.0;
229 } else {
230 pp[i].dim[0].siz = 1.0;
231 pp[i].dim[1].siz = (double)inpres.xr/inpres.yr /
232 inpaspect;
233 }
234 pp[i].dim[0].p = pp[i].dim[1].p = NULL;
235 pp[i].arr = (DATATYPE *)
236 malloc(inpres.xr*inpres.yr*sizeof(DATATYPE));
237 if (pp[i].arr == NULL)
238 goto memerr;
239 }
240 /* load picture */
241 sl = scanlen(&inpres);
242 ns = numscans(&inpres);
243 if ((scanin = (COLOR *)malloc(sl*sizeof(COLOR))) == NULL)
244 goto memerr;
245 for (y = 0; y < ns; y++) {
246 if (freadscan(scanin, sl, fp) < 0)
247 goto readerr;
248 for (x = 0; x < sl; x++) {
249 pix2loc(loc, &inpres, x, y);
250 i = (int)(loc[1]*inpres.yr)*inpres.xr +
251 (int)(loc[0]*inpres.xr);
252 pp[0].arr[i] = colval(scanin[x],RED);
253 pp[1].arr[i] = colval(scanin[x],GRN);
254 pp[2].arr[i] = colval(scanin[x],BLU);
255 }
256 }
257 free((char *)scanin);
258 fclose(fp);
259 i = hash(pname);
260 pp[0].next =
261 pp[1].next =
262 pp[2].next = ptab[i];
263 return(ptab[i] = pp);
264
265 memerr:
266 error(SYSTEM, "out of memory in getpict");
267 readerr:
268 sprintf(errmsg, "bad picture file \"%s\"", pfname);
269 error(USER, errmsg);
270 }
271
272
273 freedata(dname) /* free memory associated with dname */
274 char *dname;
275 {
276 DATARRAY head;
277 int hval, nents;
278 register DATARRAY *dp, *dpl;
279 register int i;
280
281 if (dname == NULL) { /* free all if NULL */
282 hval = 0; nents = TABSIZ;
283 } else {
284 hval = hash(dname); nents = 1;
285 }
286 while (nents--) {
287 head.next = dtab[hval];
288 dpl = &head;
289 while ((dp = dpl->next) != NULL)
290 if (dname == NULL || !strcmp(dname, dp->name)) {
291 dpl->next = dp->next;
292 free((char *)dp->arr);
293 for (i = 0; i < dp->nd; i++)
294 if (dp->dim[i].p != NULL)
295 free((char *)dp->dim[i].p);
296 freestr(dp->name);
297 free((char *)dp);
298 } else
299 dpl = dp;
300 dtab[hval++] = head.next;
301 }
302 }
303
304
305 freepict(pname) /* free memory associated with pname */
306 char *pname;
307 {
308 DATARRAY head;
309 int hval, nents;
310 register DATARRAY *pp, *ppl;
311
312 if (pname == NULL) { /* free all if NULL */
313 hval = 0; nents = TABSIZ;
314 } else {
315 hval = hash(pname); nents = 1;
316 }
317 while (nents--) {
318 head.next = ptab[hval];
319 ppl = &head;
320 while ((pp = ppl->next) != NULL)
321 if (pname == NULL || !strcmp(pname, pp->name)) {
322 ppl->next = pp->next;
323 free((char *)pp[0].arr);
324 free((char *)pp[1].arr);
325 free((char *)pp[2].arr);
326 freestr(pp[0].name);
327 free((char *)pp);
328 } else
329 ppl = pp;
330 ptab[hval++] = head.next;
331 }
332 }
333
334
335 double
336 datavalue(dp, pt) /* interpolate data value at a point */
337 register DATARRAY *dp;
338 double *pt;
339 {
340 DATARRAY sd;
341 int asize;
342 int lower, upper;
343 register int i;
344 double x, y, y0, y1;
345 /* set up dimensions for recursion */
346 sd.nd = dp->nd - 1;
347 asize = 1;
348 for (i = 0; i < sd.nd; i++) {
349 sd.dim[i].org = dp->dim[i+1].org;
350 sd.dim[i].siz = dp->dim[i+1].siz;
351 sd.dim[i].p = dp->dim[i+1].p;
352 asize *= sd.dim[i].ne = dp->dim[i+1].ne;
353 }
354 /* get independent variable */
355 if (dp->dim[0].p == NULL) { /* evenly spaced points */
356 x = (pt[0] - dp->dim[0].org)/dp->dim[0].siz;
357 x = x * (dp->dim[0].ne - 1);
358 i = x;
359 if (i < 0)
360 i = 0;
361 else if (i > dp->dim[0].ne - 2)
362 i = dp->dim[0].ne - 2;
363 } else { /* unevenly spaced points */
364 if (dp->dim[0].siz > 0.0) {
365 lower = 0;
366 upper = dp->dim[0].ne;
367 } else {
368 lower = dp->dim[0].ne;
369 upper = 0;
370 }
371 do {
372 i = (lower + upper) >> 1;
373 if (pt[0] >= dp->dim[0].p[i])
374 lower = i;
375 else
376 upper = i;
377 } while (i != (lower + upper) >> 1);
378 if (i > dp->dim[0].ne - 2)
379 i = dp->dim[0].ne - 2;
380 x = i + (pt[0] - dp->dim[0].p[i]) /
381 (dp->dim[0].p[i+1] - dp->dim[0].p[i]);
382 }
383 /* get dependent variable */
384 if (dp->nd == 1) {
385 y0 = dp->arr[i];
386 y1 = dp->arr[i+1];
387 } else {
388 sd.arr = &dp->arr[i*asize];
389 y0 = datavalue(&sd, pt+1);
390 sd.arr = &dp->arr[(i+1)*asize];
391 y1 = datavalue(&sd, pt+1);
392 }
393 /*
394 * Extrapolate as far as one division, then
395 * taper off harmonically to zero.
396 */
397 if (x > i+2)
398 y = (2*y1-y0)/(x-i-1);
399 else if (x < i-1)
400 y = (2*y0-y1)/(i-x);
401 else
402 y = y0*((i+1)-x) + y1*(x-i);
403
404 return(y);
405 }