ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/data.c
Revision: 2.3
Committed: Mon Sep 21 12:07:42 1992 UTC (31 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +9 -6 lines
Log Message:
Changes for PC port

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 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 #ifdef MSDOS
188 setmode(fileno(fp), O_BINARY);
189 #endif
190 /* get dimensions */
191 inpaspect = 1.0;
192 getheader(fp, headaspect);
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 register DATARRAY *dp, *dpl;
252 register int i;
253
254 for (dpl = NULL, dp = dlist; dp != NULL; dpl = dp, dp = dp->next)
255 if (!strcmp(dname, dp->name)) {
256 if (dpl == NULL)
257 dlist = dp->next;
258 else
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 return;
267 }
268 }
269
270
271 freepict(pname) /* free memory associated with pname */
272 char *pname;
273 {
274 register DATARRAY *pp, *ppl;
275
276 for (ppl = NULL, pp = plist; pp != NULL; ppl = pp, pp = pp->next)
277 if (!strcmp(pname, pp->name)) {
278 if (ppl == NULL)
279 plist = pp->next;
280 else
281 ppl->next = pp->next;
282 free((char *)pp[0].arr);
283 free((char *)pp[1].arr);
284 free((char *)pp[2].arr);
285 freestr(pp[0].name);
286 free((char *)pp);
287 return;
288 }
289 }
290
291
292 double
293 datavalue(dp, pt) /* interpolate data value at a point */
294 register DATARRAY *dp;
295 double *pt;
296 {
297 DATARRAY sd;
298 int asize;
299 int lower, upper;
300 register int i;
301 double x, y, y0, y1;
302 /* set up dimensions for recursion */
303 sd.nd = dp->nd - 1;
304 asize = 1;
305 for (i = 0; i < sd.nd; i++) {
306 sd.dim[i].org = dp->dim[i+1].org;
307 sd.dim[i].siz = dp->dim[i+1].siz;
308 sd.dim[i].p = dp->dim[i+1].p;
309 asize *= sd.dim[i].ne = dp->dim[i+1].ne;
310 }
311 /* get independent variable */
312 if (dp->dim[0].p == NULL) { /* evenly spaced points */
313 x = (pt[0] - dp->dim[0].org)/dp->dim[0].siz;
314 x = x * (dp->dim[0].ne - 1);
315 i = x;
316 if (i < 0)
317 i = 0;
318 else if (i > dp->dim[0].ne - 2)
319 i = dp->dim[0].ne - 2;
320 } else { /* unevenly spaced points */
321 if (dp->dim[0].siz > 0.0) {
322 lower = 0;
323 upper = dp->dim[0].ne;
324 } else {
325 lower = dp->dim[0].ne;
326 upper = 0;
327 }
328 do {
329 i = (lower + upper) >> 1;
330 if (pt[0] >= dp->dim[0].p[i])
331 lower = i;
332 else
333 upper = i;
334 } while (i != (lower + upper) >> 1);
335 if (i > dp->dim[0].ne - 2)
336 i = dp->dim[0].ne - 2;
337 x = i + (pt[0] - dp->dim[0].p[i]) /
338 (dp->dim[0].p[i+1] - dp->dim[0].p[i]);
339 }
340 /* get dependent variable */
341 if (dp->nd == 1) {
342 y0 = dp->arr[i];
343 y1 = dp->arr[i+1];
344 } else {
345 sd.arr = &dp->arr[i*asize];
346 y0 = datavalue(&sd, pt+1);
347 sd.arr = &dp->arr[(i+1)*asize];
348 y1 = datavalue(&sd, pt+1);
349 }
350 /*
351 * Extrapolate as far as one division, then
352 * taper off harmonically to zero.
353 */
354 if (x > i+2)
355 y = (2*y1-y0)/(x-i-1);
356 else if (x < i-1)
357 y = (2*y0-y1)/(i-x);
358 else
359 y = y0*((i+1)-x) + y1*(x-i);
360
361 return(y);
362 }