ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/data.c
Revision: 1.11
Committed: Mon Nov 11 14:02:43 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.10: +30 -16 lines
Log Message:
Improved handling of scanline ordering

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