ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/data.c
Revision: 2.2
Committed: Thu Dec 19 14:54:58 1991 UTC (32 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +0 -1 lines
Log Message:
removed atof() declarations for NeXT

File Contents

# Content
1 /* Copyright (c) 1991 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 directorys 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 double inpaspect; /* aspect ratio of input picture */
143
144 static
145 headaspect(s) /* check string for aspect ratio */
146 char *s;
147 {
148 if (isaspect(s))
149 inpaspect *= aspectval(s);
150 }
151
152
153 DATARRAY *
154 getpict(pname) /* get picture pname */
155 char *pname;
156 {
157 extern char *libpath;
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 /* get dimensions */
188 inpaspect = 1.0;
189 getheader(fp, headaspect);
190 if (!fgetsresolu(&inpres, fp))
191 goto readerr;
192 for (i = 0; i < 3; i++) {
193 pp[i].nd = 2;
194 pp[i].dim[0].ne = inpres.yr;
195 pp[i].dim[1].ne = inpres.xr;
196 pp[i].dim[0].org =
197 pp[i].dim[1].org = 0.0;
198 if (inpres.xr <= inpres.yr*inpaspect) {
199 pp[i].dim[0].siz = inpaspect *
200 (double)inpres.yr/inpres.xr;
201 pp[i].dim[1].siz = 1.0;
202 } else {
203 pp[i].dim[0].siz = 1.0;
204 pp[i].dim[1].siz = (double)inpres.xr/inpres.yr /
205 inpaspect;
206 }
207 pp[i].dim[0].p = pp[i].dim[1].p = NULL;
208 pp[i].arr = (DATATYPE *)
209 malloc(inpres.xr*inpres.yr*sizeof(DATATYPE));
210 if (pp[i].arr == NULL)
211 goto memerr;
212 }
213 /* load picture */
214 sl = scanlen(&inpres);
215 ns = numscans(&inpres);
216 if ((scanin = (COLOR *)malloc(sl*sizeof(COLOR))) == NULL)
217 goto memerr;
218 for (y = 0; y < ns; y++) {
219 if (freadscan(scanin, sl, fp) < 0)
220 goto readerr;
221 for (x = 0; x < sl; x++) {
222 pix2loc(loc, &inpres, x, y);
223 i = (int)(loc[1]*inpres.yr)*inpres.xr +
224 (int)(loc[0]*inpres.xr);
225 pp[0].arr[i] = colval(scanin[x],RED);
226 pp[1].arr[i] = colval(scanin[x],GRN);
227 pp[2].arr[i] = colval(scanin[x],BLU);
228 }
229 }
230 free((char *)scanin);
231 fclose(fp);
232 pp[0].next =
233 pp[1].next =
234 pp[2].next = plist;
235 return(plist = pp);
236
237 memerr:
238 error(SYSTEM, "out of memory in getpict");
239 readerr:
240 sprintf(errmsg, "bad picture file \"%s\"", pfname);
241 error(USER, errmsg);
242 }
243
244
245 freedata(dname) /* free memory associated with dname */
246 char *dname;
247 {
248 register DATARRAY *dp, *dpl;
249 register int i;
250
251 for (dpl = NULL, dp = dlist; dp != NULL; dpl = dp, dp = dp->next)
252 if (!strcmp(dname, dp->name)) {
253 if (dpl == NULL)
254 dlist = dp->next;
255 else
256 dpl->next = dp->next;
257 free((char *)dp->arr);
258 for (i = 0; i < dp->nd; i++)
259 if (dp->dim[i].p != NULL)
260 free((char *)dp->dim[i].p);
261 freestr(dp->name);
262 free((char *)dp);
263 return;
264 }
265 }
266
267
268 freepict(pname) /* free memory associated with pname */
269 char *pname;
270 {
271 register DATARRAY *pp, *ppl;
272
273 for (ppl = NULL, pp = plist; pp != NULL; ppl = pp, pp = pp->next)
274 if (!strcmp(pname, pp->name)) {
275 if (ppl == NULL)
276 plist = pp->next;
277 else
278 ppl->next = pp->next;
279 free((char *)pp[0].arr);
280 free((char *)pp[1].arr);
281 free((char *)pp[2].arr);
282 freestr(pp[0].name);
283 free((char *)pp);
284 return;
285 }
286 }
287
288
289 double
290 datavalue(dp, pt) /* interpolate data value at a point */
291 register DATARRAY *dp;
292 double *pt;
293 {
294 DATARRAY sd;
295 int asize;
296 int lower, upper;
297 register int i;
298 double x, y, y0, y1;
299 /* set up dimensions for recursion */
300 sd.nd = dp->nd - 1;
301 asize = 1;
302 for (i = 0; i < sd.nd; i++) {
303 sd.dim[i].org = dp->dim[i+1].org;
304 sd.dim[i].siz = dp->dim[i+1].siz;
305 sd.dim[i].p = dp->dim[i+1].p;
306 asize *= sd.dim[i].ne = dp->dim[i+1].ne;
307 }
308 /* get independent variable */
309 if (dp->dim[0].p == NULL) { /* evenly spaced points */
310 x = (pt[0] - dp->dim[0].org)/dp->dim[0].siz;
311 x = x * (dp->dim[0].ne - 1);
312 i = x;
313 if (i < 0)
314 i = 0;
315 else if (i > dp->dim[0].ne - 2)
316 i = dp->dim[0].ne - 2;
317 } else { /* unevenly spaced points */
318 if (dp->dim[0].siz > 0.0) {
319 lower = 0;
320 upper = dp->dim[0].ne;
321 } else {
322 lower = dp->dim[0].ne;
323 upper = 0;
324 }
325 do {
326 i = (lower + upper) >> 1;
327 if (pt[0] >= dp->dim[0].p[i])
328 lower = i;
329 else
330 upper = i;
331 } while (i != (lower + upper) >> 1);
332 if (i > dp->dim[0].ne - 2)
333 i = dp->dim[0].ne - 2;
334 x = i + (pt[0] - dp->dim[0].p[i]) /
335 (dp->dim[0].p[i+1] - dp->dim[0].p[i]);
336 }
337 /* get dependent variable */
338 if (dp->nd == 1) {
339 y0 = dp->arr[i];
340 y1 = dp->arr[i+1];
341 } else {
342 sd.arr = &dp->arr[i*asize];
343 y0 = datavalue(&sd, pt+1);
344 sd.arr = &dp->arr[(i+1)*asize];
345 y1 = datavalue(&sd, pt+1);
346 }
347 /*
348 * Extrapolate as far as one division, then
349 * taper off harmonically to zero.
350 */
351 if (x > i+2)
352 y = (2*y1-y0)/(x-i-1);
353 else if (x < i-1)
354 y = (2*y0-y1)/(i-x);
355 else
356 y = y0*((i+1)-x) + y1*(x-i);
357
358 return(y);
359 }