ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/data.c
Revision: 2.5
Committed: Sun Nov 22 10:02:57 1992 UTC (31 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +19 -17 lines
Log Message:
added global freeing routines

File Contents

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