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 2.3 by greg, Mon Sep 21 12:07:42 1992 UTC vs.
Revision 2.17 by greg, Tue May 13 17:58:33 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1992 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  data.c - routines dealing with interpolated data.
9 *
10 *     6/4/86
6   */
7  
8 + #include "copyright.h"
9 +
10   #include  "standard.h"
11  
12   #include  "color.h"
# Line 18 | Line 15 | static char SCCSid[] = "$SunId$ LBL";
15  
16   #include  "data.h"
17  
18 +                                /* picture memory usage before warning */
19 + #ifndef PSIZWARN
20 + #ifdef BIGMEM
21 + #define PSIZWARN        5000000
22 + #else
23 + #define PSIZWARN        1500000
24 + #endif
25 + #endif
26  
27 < extern char  *fgetword();
27 > #ifndef TABSIZ
28 > #define TABSIZ          97              /* table size (prime) */
29 > #endif
30  
31 < extern char  *libpath;                  /* library search path */
31 > #define hash(s)         (shash(s)%TABSIZ)
32  
26 static DATARRAY  *dlist = NULL;         /* data array list */
33  
34 < static DATARRAY  *plist = NULL;         /* picture list */
34 > static DATARRAY  *dtab[TABSIZ];         /* data array list */
35  
36  
37   DATARRAY *
38   getdata(dname)                          /* get data array dname */
39   char  *dname;
40   {
35        char  word[64];
41          char  *dfname;
42          FILE  *fp;
43          int  asize;
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! */
45
50          /*
51           *      If we haven't loaded the data already, we will look
52 <         *  for it in the directorys specified by the library path.
52 >         *  for it in the directories specified by the library path.
53           *
54           *      The file has the following format:
55           *
# Line 63 | Line 67 | char  *dname;
67           *              0 0 ni p0i p1i .. pni
68           */
69  
70 <        if ((dfname = getpath(dname, libpath, R_OK)) == NULL) {
70 >        if ((dfname = getpath(dname, getrlibpath(), R_OK)) == NULL) {
71                  sprintf(errmsg, "cannot find data file \"%s\"", dname);
72                  error(USER, errmsg);
73          }
70        if ((dp = (DATARRAY *)malloc(sizeof(DATARRAY))) == NULL)
71                goto memerr;
72
73        dp->name = savestr(dname);
74
74          if ((fp = fopen(dfname, "r")) == NULL) {
75                  sprintf(errmsg, "cannot open data file \"%s\"", dfname);
76                  error(SYSTEM, errmsg);
77          }
78                                                          /* get dimensions */
79 <        if (fgetword(word, sizeof(word), fp) == NULL || !isint(word))
79 >        if (fgetval(fp, 'i', (char *)&asize) <= 0)
80                  goto scanerr;
81 <        dp->nd = atoi(word);
83 <        if (dp->nd <= 0 || dp->nd > MAXDDIM) {
81 >        if (asize <= 0 | asize > MAXDDIM) {
82                  sprintf(errmsg, "bad number of dimensions for \"%s\"", dname);
83                  error(USER, errmsg);
84          }
85 +        if ((dp = (DATARRAY *)malloc(sizeof(DATARRAY))) == NULL)
86 +                goto memerr;
87 +        dp->name = savestr(dname);
88 +        dp->type = DATATY;
89 +        dp->nd = asize;
90          asize = 1;
91          for (i = 0; i < dp->nd; i++) {
92 <                if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word))
92 >                if (fgetval(fp, DATATY, (char *)&dp->dim[i].org) <= 0)
93                          goto scanerr;
94 <                dp->dim[i].org = atof(word);
92 <                if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word))
94 >                if (fgetval(fp, DATATY, (char *)&dp->dim[i].siz) <= 0)
95                          goto scanerr;
96 <                dp->dim[i].siz = atof(word);
95 <                if (fgetword(word, sizeof(word), fp) == NULL || !isint(word))
96 >                if (fgetval(fp, 'i', (char *)&dp->dim[i].ne) <= 0)
97                          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));
102 >                        dp->dim[i].p = (DATATYPE *)
103 >                                        malloc(dp->dim[i].ne*sizeof(DATATYPE));
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))
106 >                        for (j = 0; j < dp->dim[i].ne; j++)
107 >                                if (fgetval(fp, DATATY,
108 >                                                (char *)&dp->dim[i].p[j]) <= 0)
109                                          goto scanerr;
109                                dp->dim[i].p[j] = atof(word);
110                        }
110                          for (j = 1; j < dp->dim[i].ne-1; j++)
111                                  if ((dp->dim[i].p[j-1] < dp->dim[i].p[j]) !=
112                                          (dp->dim[i].p[j] < dp->dim[i].p[j+1]))
# Line 118 | Line 117 | char  *dname;
117                  } else
118                          dp->dim[i].p = NULL;
119          }
120 <        if ((dp->arr = (DATATYPE *)malloc(asize*sizeof(DATATYPE))) == NULL)
120 >        if ((dp->arr.d = (DATATYPE *)malloc(asize*sizeof(DATATYPE))) == NULL)
121                  goto memerr;
122          
123 <        for (i = 0; i < asize; i++) {
124 <                if (fgetword(word, sizeof(word), fp) == NULL || !isflt(word))
123 >        for (i = 0; i < asize; i++)
124 >                if (fgetval(fp, DATATY, (char *)&dp->arr.d[i]) <= 0)
125                          goto scanerr;
127                dp->arr[i] = atof(word);
128        }
126          fclose(fp);
127 <        dp->next = dlist;
128 <        return(dlist = dp);
127 >        i = hash(dname);
128 >        dp->next = dtab[i];
129 >        return(dtab[i] = dp);
130  
131   memerr:
132          error(SYSTEM, "out of memory in getdata");
# Line 139 | Line 137 | scanerr:
137   }
138  
139  
140 < static double  inpaspect;               /* aspect ratio of input picture */
141 <
144 < static
145 < headaspect(s)                           /* check string for aspect ratio */
140 > static int
141 > headaspect(s, iap)                      /* check string for aspect ratio */
142   char  *s;
143 + double  *iap;
144   {
145 +        char    fmt[32];
146 +
147          if (isaspect(s))
148 <                inpaspect *= aspectval(s);
148 >                *iap *= aspectval(s);
149 >        else if (formatval(fmt, s) && !globmatch(PICFMT, fmt))
150 >                *iap = 0.0;
151 >        return(0);
152   }
153  
154  
# Line 154 | Line 156 | DATARRAY *
156   getpict(pname)                          /* get picture pname */
157   char  *pname;
158   {
159 <        extern char  *libpath;
159 >        double  inpaspect;
160          char  *pfname;
161          FILE  *fp;
162 <        COLOR  *scanin;
162 >        COLR  *scanin;
163          int  sl, ns;
164          RESOLU  inpres;
165          FLOAT  loc[2];
# Line 165 | Line 167 | char  *pname;
167          register int  x, i;
168          register DATARRAY  *pp;
169                                                  /* look for array in list */
170 <        for (pp = plist; pp != NULL; pp = pp->next)
170 >        for (pp = dtab[hash(pname)]; pp != NULL; pp = pp->next)
171                  if (!strcmp(pname, pp->name))
172                          return(pp);             /* found! */
173  
174 <        if ((pfname = getpath(pname, libpath, R_OK)) == NULL) {
174 >        if ((pfname = getpath(pname, getrlibpath(), R_OK)) == NULL) {
175                  sprintf(errmsg, "cannot find picture file \"%s\"", pname);
176                  error(USER, errmsg);
177          }
178 <        if ((pp = (DATARRAY *)calloc(3, sizeof(DATARRAY))) == NULL)
178 >        if ((pp = (DATARRAY *)malloc(3*sizeof(DATARRAY))) == NULL)
179                  goto memerr;
180  
181 <        pp[0].name =
180 <        pp[1].name =
181 <        pp[2].name = savestr(pname);
181 >        pp[0].name = savestr(pname);
182  
183          if ((fp = fopen(pfname, "r")) == NULL) {
184                  sprintf(errmsg, "cannot open picture file \"%s\"", pfname);
# Line 189 | Line 189 | char  *pname;
189   #endif
190                                                  /* get dimensions */
191          inpaspect = 1.0;
192 <        getheader(fp, headaspect);
193 <        if (!fgetsresolu(&inpres, fp))
192 >        getheader(fp, headaspect, (char *)&inpaspect);
193 >        if (inpaspect <= FTINY || !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;
195 >        pp[0].nd = 2;
196 >        pp[0].dim[0].ne = inpres.yr;
197 >        pp[0].dim[1].ne = inpres.xr;
198 >        pp[0].dim[0].org =
199 >        pp[0].dim[1].org = 0.0;
200 >        if (inpres.xr <= inpres.yr*inpaspect) {
201 >                pp[0].dim[0].siz = inpaspect *
202 >                                        (double)inpres.yr/inpres.xr;
203 >                pp[0].dim[1].siz = 1.0;
204 >        } else {
205 >                pp[0].dim[0].siz = 1.0;
206 >                pp[0].dim[1].siz = (double)inpres.xr/inpres.yr /
207 >                                        inpaspect;
208          }
209 <                                                        /* load picture */
210 <        sl = scanlen(&inpres);
209 >        pp[0].dim[0].p = pp[0].dim[1].p = NULL;
210 >        sl = scanlen(&inpres);                          /* allocate array */
211          ns = numscans(&inpres);
212 <        if ((scanin = (COLOR *)malloc(sl*sizeof(COLOR))) == NULL)
212 >        i = ns*sl*sizeof(COLR);
213 > #if PSIZWARN
214 >        if (i > PSIZWARN) {                             /* memory warning */
215 >                sprintf(errmsg, "picture file \"%s\" using %d bytes of memory",
216 >                                pname, i);
217 >                error(WARNING, errmsg);
218 >        }
219 > #endif
220 >        if ((pp[0].arr.c = (COLR *)malloc(i)) == NULL)
221                  goto memerr;
222 +                                                        /* load picture */
223 +        if ((scanin = (COLR *)malloc(sl*sizeof(COLR))) == NULL)
224 +                goto memerr;
225          for (y = 0; y < ns; y++) {
226 <                if (freadscan(scanin, sl, fp) < 0)
226 >                if (freadcolrs(scanin, sl, fp) < 0)
227                          goto readerr;
228                  for (x = 0; x < sl; x++) {
229                          pix2loc(loc, &inpres, x, y);
230                          i = (int)(loc[1]*inpres.yr)*inpres.xr +
231                                          (int)(loc[0]*inpres.xr);
232 <                        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);
232 >                        copycolr(pp[0].arr.c[i], scanin[x]);
233                  }
234          }
235 <        free((char *)scanin);
235 >        free((void *)scanin);
236          fclose(fp);
237 <        pp[0].next =
238 <        pp[1].next =
239 <        pp[2].next = plist;
240 <        return(plist = pp);
237 >        i = hash(pname);
238 >        pp[0].next = dtab[i];           /* link into picture list */
239 >        copystruct(&pp[1], &pp[0]);
240 >        copystruct(&pp[2], &pp[0]);
241 >        pp[0].type = RED;               /* differentiate RGB records */
242 >        pp[1].type = GRN;
243 >        pp[2].type = BLU;
244 >        return(dtab[i] = pp);
245  
246   memerr:
247          error(SYSTEM, "out of memory in getpict");
# Line 245 | Line 251 | readerr:
251   }
252  
253  
254 < freedata(dname)                 /* free memory associated with dname */
255 < char  *dname;
254 > void
255 > freedata(dta)                   /* release data array reference */
256 > DATARRAY  *dta;
257   {
258 <        register DATARRAY  *dp, *dpl;
258 >        DATARRAY  head;
259 >        int  hval, nents;
260 >        register DATARRAY  *dpl, *dp;
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 (dta == NULL) {                      /* free all if NULL */
264 >                hval = 0; nents = TABSIZ;
265 >        } else {
266 >                hval = hash(dta->name); nents = 1;
267 >        }
268 >        while (nents--) {
269 >                head.next = dtab[hval];
270 >                dpl = &head;
271 >                while ((dp = dpl->next) != NULL)
272 >                        if ((dta == NULL | dta == dp)) {
273                                  dpl->next = dp->next;
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 <                        return;
281 <                }
274 >                                if (dp->type == DATATY)
275 >                                        free((void *)dp->arr.d);
276 >                                else
277 >                                        free((void *)dp->arr.c);
278 >                                for (i = 0; i < dp->nd; i++)
279 >                                        if (dp->dim[i].p != NULL)
280 >                                                free((void *)dp->dim[i].p);
281 >                                freestr(dp->name);
282 >                                free((void *)dp);
283 >                        } else
284 >                                dpl = dp;
285 >                dtab[hval++] = head.next;
286 >        }
287   }
288  
289  
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
290   double
291   datavalue(dp, pt)               /* interpolate data value at a point */
292   register DATARRAY  *dp;
# Line 298 | Line 296 | double *pt;
296          int  asize;
297          int  lower, upper;
298          register int  i;
299 <        double  x, y, y0, y1;
299 >        double  x, 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;
301 >        if (dp->nd > 1) {
302 >                sd.name = dp->name;
303 >                sd.type = dp->type;
304 >                sd.nd = dp->nd - 1;
305 >                asize = 1;
306 >                for (i = 0; i < sd.nd; i++) {
307 >                        sd.dim[i].org = dp->dim[i+1].org;
308 >                        sd.dim[i].siz = dp->dim[i+1].siz;
309 >                        sd.dim[i].p = dp->dim[i+1].p;
310 >                        asize *= sd.dim[i].ne = dp->dim[i+1].ne;
311 >                }
312          }
313                                          /* get independent variable */
314          if (dp->dim[0].p == NULL) {             /* evenly spaced points */
315                  x = (pt[0] - dp->dim[0].org)/dp->dim[0].siz;
316 <                x = x * (dp->dim[0].ne - 1);
316 >                x *= (double)(dp->dim[0].ne - 1);
317                  i = x;
318                  if (i < 0)
319                          i = 0;
# Line 338 | Line 340 | double *pt;
340                                  (dp->dim[0].p[i+1] - dp->dim[0].p[i]);
341          }
342                                          /* get dependent variable */
343 <        if (dp->nd == 1) {
344 <                y0 = dp->arr[i];
345 <                y1 = dp->arr[i+1];
343 >        if (dp->nd > 1) {
344 >                if (dp->type == DATATY) {
345 >                        sd.arr.d = dp->arr.d + i*asize;
346 >                        y0 = datavalue(&sd, pt+1);
347 >                        sd.arr.d = dp->arr.d + (i+1)*asize;
348 >                        y1 = datavalue(&sd, pt+1);
349 >                } else {
350 >                        sd.arr.c = dp->arr.c + i*asize;
351 >                        y0 = datavalue(&sd, pt+1);
352 >                        sd.arr.c = dp->arr.c + (i+1)*asize;
353 >                        y1 = datavalue(&sd, pt+1);
354 >                }
355          } else {
356 <                sd.arr = &dp->arr[i*asize];
357 <                y0 = datavalue(&sd, pt+1);
358 <                sd.arr = &dp->arr[(i+1)*asize];
359 <                y1 = datavalue(&sd, pt+1);
356 >                if (dp->type == DATATY) {
357 >                        y0 = dp->arr.d[i];
358 >                        y1 = dp->arr.d[i+1];
359 >                } else {
360 >                        y0 = colrval(dp->arr.c[i],dp->type);
361 >                        y1 = colrval(dp->arr.c[i+1],dp->type);
362 >                }
363          }
364          /*
365           * Extrapolate as far as one division, then
366           * taper off harmonically to zero.
367           */
368          if (x > i+2)
369 <                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);
369 >                return( (2*y1-y0)/(x-(i-1)) );
370  
371 <        return(y);
371 >        if (x < i-1)
372 >                return( (2*y0-y1)/(i-x) );
373 >
374 >        return( y0*((i+1)-x) + y1*(x-i) );
375   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines