ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/data.c
Revision: 2.10
Committed: Fri Jun 30 16:07:44 1995 UTC (28 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.9: +8 -20 lines
Log Message:
added comments to data files using new fgetval() function

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