ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/data.c
Revision: 2.27
Committed: Tue Mar 30 16:13:01 2004 UTC (20 years, 1 month ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6
Changes since 2.26: +21 -14 lines
Log Message:
Continued ANSIfication. There are only bits and pieces left now.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.27 static const char RCSid[] = "$Id: data.c,v 2.26 2004/01/02 11:43:42 schorsch Exp $";
3 greg 1.1 #endif
4     /*
5     * data.c - routines dealing with interpolated data.
6     */
7    
8 greg 2.16 #include "copyright.h"
9 greg 2.22
10     #include <time.h>
11 greg 2.15
12 greg 2.25 #include "platform.h"
13 greg 1.1 #include "standard.h"
14     #include "color.h"
15 greg 1.11 #include "resolu.h"
16 schorsch 2.27 #include "view.h"
17 greg 1.1 #include "data.h"
18    
19 greg 2.7 /* picture memory usage before warning */
20     #ifndef PSIZWARN
21 greg 2.18 #ifdef SMLMEM
22     #define PSIZWARN 1500000
23     #else
24 gregl 2.13 #define PSIZWARN 5000000
25 greg 2.7 #endif
26     #endif
27 greg 1.1
28 greg 2.7 #ifndef TABSIZ
29 greg 2.6 #define TABSIZ 97 /* table size (prime) */
30 greg 2.7 #endif
31 greg 2.6
32     #define hash(s) (shash(s)%TABSIZ)
33    
34    
35     static DATARRAY *dtab[TABSIZ]; /* data array list */
36 greg 1.1
37 schorsch 2.26 static gethfunc headaspect;
38    
39 greg 1.1
40 schorsch 2.27 extern DATARRAY *
41     getdata( /* get data array dname */
42     char *dname
43     )
44 greg 1.1 {
45     char *dfname;
46     FILE *fp;
47     int asize;
48 greg 1.4 register int i, j;
49 greg 1.1 register DATARRAY *dp;
50     /* look for array in list */
51 greg 2.6 for (dp = dtab[hash(dname)]; dp != NULL; dp = dp->next)
52 greg 1.1 if (!strcmp(dname, dp->name))
53     return(dp); /* found! */
54     /*
55     * If we haven't loaded the data already, we will look
56 greg 2.5 * for it in the directories specified by the library path.
57 greg 1.1 *
58     * The file has the following format:
59     *
60 greg 1.4 * N
61 greg 1.1 * beg0 end0 n0
62     * beg1 end1 n1
63     * . . .
64 greg 1.4 * begN endN nN
65 greg 1.1 * data, later dimensions changing faster
66     * . . .
67     *
68 greg 1.4 * For irregularly spaced points, the following can be
69     * substituted for begi endi ni:
70     *
71 greg 1.6 * 0 0 ni p0i p1i .. pni
72 greg 1.1 */
73    
74 greg 2.17 if ((dfname = getpath(dname, getrlibpath(), R_OK)) == NULL) {
75 greg 1.1 sprintf(errmsg, "cannot find data file \"%s\"", dname);
76     error(USER, errmsg);
77     }
78     if ((fp = fopen(dfname, "r")) == NULL) {
79     sprintf(errmsg, "cannot open data file \"%s\"", dfname);
80     error(SYSTEM, errmsg);
81     }
82     /* get dimensions */
83 greg 2.15 if (fgetval(fp, 'i', (char *)&asize) <= 0)
84 greg 1.1 goto scanerr;
85 schorsch 2.24 if ((asize <= 0) | (asize > MAXDDIM)) {
86 greg 1.1 sprintf(errmsg, "bad number of dimensions for \"%s\"", dname);
87     error(USER, errmsg);
88     }
89 greg 2.12 if ((dp = (DATARRAY *)malloc(sizeof(DATARRAY))) == NULL)
90     goto memerr;
91     dp->name = savestr(dname);
92     dp->type = DATATY;
93     dp->nd = asize;
94 greg 1.1 asize = 1;
95     for (i = 0; i < dp->nd; i++) {
96 greg 2.15 if (fgetval(fp, DATATY, (char *)&dp->dim[i].org) <= 0)
97 greg 1.6 goto scanerr;
98 greg 2.15 if (fgetval(fp, DATATY, (char *)&dp->dim[i].siz) <= 0)
99 greg 1.10 goto scanerr;
100 greg 2.15 if (fgetval(fp, 'i', (char *)&dp->dim[i].ne) <= 0)
101 greg 1.10 goto scanerr;
102 greg 1.6 if (dp->dim[i].ne < 2)
103     goto scanerr;
104     asize *= dp->dim[i].ne;
105     if ((dp->dim[i].siz -= dp->dim[i].org) == 0) {
106 greg 2.12 dp->dim[i].p = (DATATYPE *)
107     malloc(dp->dim[i].ne*sizeof(DATATYPE));
108 greg 1.4 if (dp->dim[i].p == NULL)
109     goto memerr;
110 greg 2.10 for (j = 0; j < dp->dim[i].ne; j++)
111 greg 2.15 if (fgetval(fp, DATATY,
112     (char *)&dp->dim[i].p[j]) <= 0)
113 greg 1.4 goto scanerr;
114     for (j = 1; j < dp->dim[i].ne-1; j++)
115     if ((dp->dim[i].p[j-1] < dp->dim[i].p[j]) !=
116     (dp->dim[i].p[j] < dp->dim[i].p[j+1]))
117     goto scanerr;
118     dp->dim[i].org = dp->dim[i].p[0];
119     dp->dim[i].siz = dp->dim[i].p[dp->dim[i].ne-1]
120     - dp->dim[i].p[0];
121     } else
122 greg 1.6 dp->dim[i].p = NULL;
123 greg 1.1 }
124 greg 2.12 if ((dp->arr.d = (DATATYPE *)malloc(asize*sizeof(DATATYPE))) == NULL)
125 greg 1.1 goto memerr;
126    
127 greg 2.10 for (i = 0; i < asize; i++)
128 greg 2.15 if (fgetval(fp, DATATY, (char *)&dp->arr.d[i]) <= 0)
129 greg 1.1 goto scanerr;
130     fclose(fp);
131 greg 2.6 i = hash(dname);
132     dp->next = dtab[i];
133     return(dtab[i] = dp);
134 greg 1.1
135     memerr:
136     error(SYSTEM, "out of memory in getdata");
137     scanerr:
138     sprintf(errmsg, "%s in data file \"%s\"",
139     feof(fp) ? "unexpected EOF" : "bad format", dfname);
140     error(USER, errmsg);
141 schorsch 2.27 return NULL; /* pro forma return */
142 greg 1.1 }
143    
144    
145 greg 2.15 static int
146 schorsch 2.26 headaspect( /* check string for aspect ratio */
147     char *s,
148     void *iap
149     )
150 greg 1.5 {
151 gwlarson 2.14 char fmt[32];
152    
153 greg 1.5 if (isaspect(s))
154 schorsch 2.26 *(double*)iap *= aspectval(s);
155 greg 2.15 else if (formatval(fmt, s) && !globmatch(PICFMT, fmt))
156 schorsch 2.26 *(double*)iap = 0.0;
157 gwlarson 2.14 return(0);
158 greg 1.5 }
159    
160    
161 schorsch 2.27 extern DATARRAY *
162     getpict( /* get picture pname */
163     char *pname
164     )
165 greg 1.1 {
166 greg 2.4 double inpaspect;
167 greg 1.1 char *pfname;
168     FILE *fp;
169 greg 2.12 COLR *scanin;
170 greg 1.11 int sl, ns;
171 greg 2.3 RESOLU inpres;
172 schorsch 2.21 RREAL loc[2];
173 greg 1.11 int y;
174     register int x, i;
175 greg 1.1 register DATARRAY *pp;
176     /* look for array in list */
177 greg 2.12 for (pp = dtab[hash(pname)]; pp != NULL; pp = pp->next)
178 greg 1.1 if (!strcmp(pname, pp->name))
179     return(pp); /* found! */
180    
181 greg 2.17 if ((pfname = getpath(pname, getrlibpath(), R_OK)) == NULL) {
182 greg 1.1 sprintf(errmsg, "cannot find picture file \"%s\"", pname);
183     error(USER, errmsg);
184     }
185 greg 2.12 if ((pp = (DATARRAY *)malloc(3*sizeof(DATARRAY))) == NULL)
186 greg 1.1 goto memerr;
187    
188 greg 2.12 pp[0].name = savestr(pname);
189 greg 1.1
190     if ((fp = fopen(pfname, "r")) == NULL) {
191     sprintf(errmsg, "cannot open picture file \"%s\"", pfname);
192     error(SYSTEM, errmsg);
193     }
194 schorsch 2.19 SET_FILE_BINARY(fp);
195 greg 1.1 /* get dimensions */
196 greg 1.5 inpaspect = 1.0;
197 schorsch 2.26 getheader(fp, headaspect, &inpaspect);
198 gwlarson 2.14 if (inpaspect <= FTINY || !fgetsresolu(&inpres, fp))
199 greg 1.1 goto readerr;
200 greg 2.12 pp[0].nd = 2;
201     pp[0].dim[0].ne = inpres.yr;
202     pp[0].dim[1].ne = inpres.xr;
203     pp[0].dim[0].org =
204     pp[0].dim[1].org = 0.0;
205     if (inpres.xr <= inpres.yr*inpaspect) {
206     pp[0].dim[0].siz = inpaspect *
207     (double)inpres.yr/inpres.xr;
208     pp[0].dim[1].siz = 1.0;
209     } else {
210     pp[0].dim[0].siz = 1.0;
211     pp[0].dim[1].siz = (double)inpres.xr/inpres.yr /
212     inpaspect;
213     }
214     pp[0].dim[0].p = pp[0].dim[1].p = NULL;
215     sl = scanlen(&inpres); /* allocate array */
216     ns = numscans(&inpres);
217     i = ns*sl*sizeof(COLR);
218 greg 2.7 #if PSIZWARN
219 greg 2.12 if (i > PSIZWARN) { /* memory warning */
220 greg 2.7 sprintf(errmsg, "picture file \"%s\" using %d bytes of memory",
221     pname, i);
222     error(WARNING, errmsg);
223     }
224     #endif
225 greg 2.12 if ((pp[0].arr.c = (COLR *)malloc(i)) == NULL)
226     goto memerr;
227 greg 1.1 /* load picture */
228 greg 2.12 if ((scanin = (COLR *)malloc(sl*sizeof(COLR))) == NULL)
229 greg 1.1 goto memerr;
230 greg 1.11 for (y = 0; y < ns; y++) {
231 greg 2.12 if (freadcolrs(scanin, sl, fp) < 0)
232 greg 1.1 goto readerr;
233 greg 1.11 for (x = 0; x < sl; x++) {
234     pix2loc(loc, &inpres, x, y);
235     i = (int)(loc[1]*inpres.yr)*inpres.xr +
236     (int)(loc[0]*inpres.xr);
237 greg 2.12 copycolr(pp[0].arr.c[i], scanin[x]);
238 greg 1.11 }
239 greg 1.1 }
240 greg 2.15 free((void *)scanin);
241 greg 1.1 fclose(fp);
242 greg 2.6 i = hash(pname);
243 greg 2.12 pp[0].next = dtab[i]; /* link into picture list */
244 schorsch 2.23 pp[1] = pp[0];
245     pp[2] = pp[0];
246 greg 2.12 pp[0].type = RED; /* differentiate RGB records */
247     pp[1].type = GRN;
248     pp[2].type = BLU;
249     return(dtab[i] = pp);
250 greg 1.1
251     memerr:
252     error(SYSTEM, "out of memory in getpict");
253     readerr:
254     sprintf(errmsg, "bad picture file \"%s\"", pfname);
255     error(USER, errmsg);
256 schorsch 2.27 return NULL; /* pro forma return */
257 greg 1.1 }
258    
259    
260 schorsch 2.27 extern void
261     freedata( /* release data array reference */
262     DATARRAY *dta
263     )
264 greg 1.1 {
265 greg 2.5 DATARRAY head;
266 greg 2.6 int hval, nents;
267 greg 2.15 register DATARRAY *dpl, *dp;
268 greg 1.4 register int i;
269 greg 1.1
270 greg 2.15 if (dta == NULL) { /* free all if NULL */
271 greg 2.6 hval = 0; nents = TABSIZ;
272     } else {
273 greg 2.15 hval = hash(dta->name); nents = 1;
274 greg 2.6 }
275     while (nents--) {
276     head.next = dtab[hval];
277     dpl = &head;
278     while ((dp = dpl->next) != NULL)
279 schorsch 2.24 if ((dta == NULL) | (dta == dp)) {
280 greg 2.6 dpl->next = dp->next;
281 greg 2.12 if (dp->type == DATATY)
282 greg 2.15 free((void *)dp->arr.d);
283 greg 2.12 else
284 greg 2.15 free((void *)dp->arr.c);
285 greg 2.6 for (i = 0; i < dp->nd; i++)
286     if (dp->dim[i].p != NULL)
287 greg 2.15 free((void *)dp->dim[i].p);
288 greg 2.6 freestr(dp->name);
289 greg 2.15 free((void *)dp);
290 greg 2.6 } else
291     dpl = dp;
292     dtab[hval++] = head.next;
293     }
294 greg 1.1 }
295    
296    
297 schorsch 2.27 extern double
298     datavalue( /* interpolate data value at a point */
299     register DATARRAY *dp,
300     double *pt
301     )
302 greg 1.1 {
303     DATARRAY sd;
304     int asize;
305 greg 1.6 int lower, upper;
306 greg 1.1 register int i;
307 greg 2.9 double x, y0, y1;
308 greg 1.4 /* set up dimensions for recursion */
309 greg 2.12 if (dp->nd > 1) {
310     sd.name = dp->name;
311     sd.type = dp->type;
312     sd.nd = dp->nd - 1;
313     asize = 1;
314     for (i = 0; i < sd.nd; i++) {
315     sd.dim[i].org = dp->dim[i+1].org;
316     sd.dim[i].siz = dp->dim[i+1].siz;
317     sd.dim[i].p = dp->dim[i+1].p;
318     asize *= sd.dim[i].ne = dp->dim[i+1].ne;
319     }
320 greg 1.1 }
321 greg 1.4 /* get independent variable */
322     if (dp->dim[0].p == NULL) { /* evenly spaced points */
323     x = (pt[0] - dp->dim[0].org)/dp->dim[0].siz;
324 greg 2.9 x *= (double)(dp->dim[0].ne - 1);
325 greg 1.4 i = x;
326     if (i < 0)
327     i = 0;
328     else if (i > dp->dim[0].ne - 2)
329     i = dp->dim[0].ne - 2;
330     } else { /* unevenly spaced points */
331 greg 1.6 if (dp->dim[0].siz > 0.0) {
332     lower = 0;
333     upper = dp->dim[0].ne;
334     } else {
335     lower = dp->dim[0].ne;
336     upper = 0;
337     }
338     do {
339     i = (lower + upper) >> 1;
340     if (pt[0] >= dp->dim[0].p[i])
341     lower = i;
342 greg 1.8 else
343 greg 1.6 upper = i;
344     } while (i != (lower + upper) >> 1);
345 greg 1.8 if (i > dp->dim[0].ne - 2)
346 greg 1.4 i = dp->dim[0].ne - 2;
347     x = i + (pt[0] - dp->dim[0].p[i]) /
348     (dp->dim[0].p[i+1] - dp->dim[0].p[i]);
349     }
350     /* get dependent variable */
351 greg 2.12 if (dp->nd > 1) {
352     if (dp->type == DATATY) {
353     sd.arr.d = dp->arr.d + i*asize;
354     y0 = datavalue(&sd, pt+1);
355     sd.arr.d = dp->arr.d + (i+1)*asize;
356     y1 = datavalue(&sd, pt+1);
357     } else {
358     sd.arr.c = dp->arr.c + i*asize;
359     y0 = datavalue(&sd, pt+1);
360     sd.arr.c = dp->arr.c + (i+1)*asize;
361     y1 = datavalue(&sd, pt+1);
362     }
363 greg 1.1 } else {
364 greg 2.12 if (dp->type == DATATY) {
365     y0 = dp->arr.d[i];
366     y1 = dp->arr.d[i+1];
367     } else {
368     y0 = colrval(dp->arr.c[i],dp->type);
369     y1 = colrval(dp->arr.c[i+1],dp->type);
370     }
371 greg 1.1 }
372     /*
373     * Extrapolate as far as one division, then
374     * taper off harmonically to zero.
375     */
376     if (x > i+2)
377 greg 2.9 return( (2*y1-y0)/(x-(i-1)) );
378 greg 1.1
379 greg 2.9 if (x < i-1)
380     return( (2*y0-y1)/(i-x) );
381    
382     return( y0*((i+1)-x) + y1*(x-i) );
383 greg 1.1 }