ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/data.c
(Generate patch)

Comparing ray/src/rt/data.c (file contents):
Revision 1.1 by greg, Thu Feb 2 10:41:18 1989 UTC vs.
Revision 2.6 by greg, Sun Nov 22 10:47:51 1992 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines