|
|
1.1 root 1: /****** routines for reading view2d files ******
2:
3: !!! Must be declared by calling program: !!!
4: double ts; starting time
5: double te; ending time
6: short timewarp; == -1 ts, te unused; avoids seeks if possible
7: == 0 ts, te set from file
8: == 1 ts set by calling program, te set from file
9: == 2 ts, te set by calling program
10:
11: another global, declared here in rd.c (with structure definition in view2d.h)
12: Rd2d rd;
13: short rd.pmin == global min pixel value
14: float rd.pmin == global max
15: short rd.u == global u value (origin)
16: short rd.v == global v value (exponent)
17: (the following are not set if timewarp==-1)
18: int rd.nfr == number of frames
19: double rd.ts == time of first frame in file
20: double rd.te == time of last frame in file
21:
22: if p is the pixel value and f is the corresponding user's function value,
23: f = (p-u) * 2**v p = u + f / 2**v
24: if p<(-BIG) then the function value is undefined, and the pixel is black
25:
26: rd2dh(fd,pny,pny)
27: int fd; (on input) a file descriptor open for read and seek
28: short *pnx, *pny; (on output) size of the images
29: Initializes the global variables ts, te, rd. Chooses global scale factor.
30: Skips forward through file to time>=ts.
31:
32: int
33: rd2di(ptime,p)
34: double *ptime; frame time
35: short p[]; nx by ny array of pixel values
36: Reads a frame of data.
37: Returns 0 upon EOF or time>te.
38:
39: rd2dj(j)
40: int j;
41: jumps to j frames forward (or back, if j<0)
42:
43: At Lynn's request, there used to be a warning message if "time" decreased.
44: Linda didn't like it, so I removed it.
45: */
46:
47:
48: #include <stdio.h>
49: #include "view2d.h"
50: extern short timewarp;
51: extern double ts, te;
52: Rd2d rd;
53:
54: Header hd;
55: Header2 hd2;
56: short filver; /* normally 3; old files may still be 2 */
57: double hdtime; /* set by rdhd() */
58: long frsiz; /* size of header and image */
59: int hdr_rd; /* are we part way through reading a header? */
60: #define MAXN 1025
61:
62: rd2dh(fd,pnx,pny) /* initialize */
63: int fd;
64: short *pnx, *pny;
65: {
66: long firstfr, imsiz;
67: int i, j;
68: float v2;
69: int hdsiz;
70: long Lseek();
71: double pow2();
72:
73: /* read first header */
74: rd.fd = fd;
75: filver = 0;
76: hdr_rd = 0;
77: if(rdhd()==0) error("empty input\n");
78: if(filver==3){ hdsiz = sizeof(hd); }
79: else{ hdsiz = sizeof(hd2); }
80: if( (hd.nx>MAXN) || (hd.ny>MAXN) ) error("nx,ny too big");
81: *pnx = hd.nx;
82: *pny = hd.ny;
83: rd.siz = hd.nx * hd.ny;
84: imsiz = rd.siz*sizeof(short);
85: frsiz = hdsiz+imsiz;
86: rd.ts = hdtime;
87: rd.u = hd.u;
88: rd.v = hd.v;
89: rd.fixuv = hd.fixuv;
90: rd.pmin = hd.pmin;
91: rd.pmax = hd.pmax;
92: if(timewarp>=0){
93: Lseek(fd,-frsiz,2);
94: rdhd();
95: rd.te = hdtime;
96: if (timewarp==0){ te = rd.te; ts = rd.ts; }
97: else if(timewarp==1){ te = rd.te; }
98: }
99:
100: /* locate first active header */
101: firstfr = 0;
102: if(timewarp>0){
103: Lseek(fd,firstfr,0);
104: rdhd();
105: while(hdtime<ts){
106: firstfr = Lseek(fd,imsiz,1);
107: if( rdhd() == 0 ) error("starting time is after EOF");
108: }
109: }
110:
111: /* get ready to start reading file */
112: if( (timewarp>=0) || (rd.fixuv!=1) ){
113: rd.nfr = Lseek(fd,0L,2)/frsiz;
114: Lseek(fd,firstfr,0);
115: }else if( rd.fixuv==1 ){
116: hdr_rd = 1; /* so that initial header needn't be reread */
117: }
118:
119: /* global scaling */
120: if(rd.fixuv!=1){
121: g_range();
122: Lseek(fd,firstfr,0);
123: }else{
124: v2 = pow2(rd.v);
125: rd.fmin = (rd.pmin-rd.u)*v2;
126: rd.fmax = (rd.pmax-rd.u)*v2;
127: }
128: }
129:
130:
131:
132: int /* returns 0 upon EOF */
133: rd2di(ptime,p) /* read an image */
134: double *ptime;
135: short p[];
136: {
137: short *q;
138: int shift;
139: int i, j, k;
140: int pmin=rd.pmin;
141: int pmax=rd.pmax;
142:
143: if(hdr_rd==1){ hdr_rd=0; }
144: else if(rdhd()==0) return(0);
145: if( (timewarp>=2) && (hdtime>te) ) return(0);
146: *ptime = hdtime;
147:
148: Read(rd.fd,p,rd.siz*sizeof(short));
149:
150: /* convert to global units */
151: if( (hd.u!=rd.u) || (hd.v!=rd.v) ){
152: shift = rd.v - hd.v;
153: if(shift>15){
154: for( i=rd.siz, q=p; i>0; i--, q++ ){
155: *q = rd.u;
156: }
157: }else if(shift>=0){
158: for(k=1; shift>0;){ shift--; k*=2; }
159: for( i=rd.siz, q=p; i>0; i--, q++ ){
160: if( *q < -BIG ) continue;
161: j = ((*q-hd.u)/k) + rd.u;
162: *q = (j<pmin)? pmin:
163: ((j>pmax)? pmax: j);
164: }
165: }else{ /* shift<0 */
166: for(k=1; shift<0;){ shift++; k*=2; }
167: for( i=rd.siz, q=p; i>0; i--, q++ ){
168: if( *q < -BIG ) continue;
169: j = ((*q-hd.u)*k) + rd.u;
170: *q = (j<pmin)? pmin:
171: ((j>pmax)? pmax: j);
172: }
173: }
174: }else{ /* hd.u=rd.u and hd.v==rd.v */
175: for( i=rd.siz, q=p; i>0; i--, q++ ){
176: if( *q < -BIG ) continue;
177: if( *q<rd.pmin ){ *q = rd.pmin; }
178: else if( *q>rd.pmax ){ *q = rd.pmax; }
179: }
180: }
181: return(1);
182: }
183:
184:
185: rd2dj(j)
186: int j;
187: {
188: long Lseek();
189: Lseek(rd.fd,j*frsiz,1);
190: }
191:
192:
193: int
194: rdhd() /* returns 0 upon EOF */
195: {
196: long Lseek();
197: char tm[16];
198:
199: if( filver==0 ){ /* get version number first time through */
200: if( EOFRead(rd.fd,&hd,sizeof(hd)) == 0 ) return(0);
201: if(hd.magic1!=MAGIC) error("bad magic number %o at start",hd.magic1);
202: filver = hd.ver;
203: if(filver==2){ Lseek(rd.fd,0L,0); }
204: else if(filver!=3){ error("bad version number %d",filver); }
205: }else if(filver==3){
206: if( EOFRead(rd.fd,&hd,sizeof(hd)) == 0 ) return(0);
207: }
208:
209: if(filver==2){
210: if( EOFRead(rd.fd,&hd2,sizeof(hd2)) == 0 ) return(0);
211: hd.magic1 = hd2.magic1;
212: hd.magic2 = hd2.magic2;
213: hd.ver = hd2.ver;
214: hd.nx = hd2.nx;
215: hd.ny = hd2.ny;
216: hd.u = hd2.u;
217: hd.v = hd2.v;
218: hd.fixuv = hd2.fixuv;
219: hd.pmin = hd2.pmin;
220: hd.pmax = hd2.pmax;
221: sprintf(hd.time, "%15.8g", (double)hd2.time);
222: }
223:
224: if(hd.magic1!=MAGIC){
225: fprintf(stderr,"bad magic number %o\n",hd.magic1);
226: fprintf(stderr,"file pointer now at %ld\n",Lseek(rd.fd,0L,1));
227: exit(2);
228: }
229: if(hd.ver!=filver){ error("inconsistent version number"); }
230: if(sscanf(hd.time,"%16E",&hdtime)!=1){
231: swab(hd.time,tm,16);
232: if(sscanf(tm,"%16E",&hdtime)!=1) error("can't parse time: %s",hd.time);
233: }
234: return(1);
235: }
236:
237:
238:
239: g_range()
240: { /* scan until last active header, updating range */
241: float gmin, gmax, v2;
242: double pow2();
243: f_range(&rd.fmin,&rd.fmax);
244: while( f_range(&gmin,&gmax) ){
245: if( rd.v > hd.v ){
246: rd.u = hd.u;
247: rd.v = hd.v;
248: }
249: if( gmin < rd.fmin ) rd.fmin = gmin;
250: if( gmax > rd.fmax ) rd.fmax = gmax;
251: }
252: g_rang2();
253: }
254:
255:
256: g_rang2()
257: { /* choose global scaling */
258: float gmin, gmax, v2;
259: double pow2();
260: gmax = (rd.fmax<0)?0:rd.fmax;
261: gmin = (rd.fmin>0)?0:rd.fmin;
262: v2 = pow2(rd.v);
263: if( (gmin < (-BIG-rd.u)*v2) || (gmax > (BIG-rd.u)*v2) ){
264: while( (gmax-gmin)/v2 >= 2*BIG-2 ){ rd.v++; v2 *= 2; }
265: rd.u = (short)(-(gmin+gmax)/(2*v2));
266: }
267: rd.pmin = rd.u + (short)(rd.fmin/v2);
268: rd.pmax = rd.u + (short)(rd.fmax/v2);
269: }
270:
271:
272: int
273: f_range ( pfmin, pfmax )
274: float *pfmin, *pfmax;
275: {
276: int i, j;
277: short p[MAXN], *q;
278: short pmin = BIG;
279: short pmax = -BIG;
280: double pow2();
281: float u2, v2;
282: if( rdhd()==0 ) return(0);
283: if( (timewarp>=2) && (hdtime>te) ) return(0);
284: u2 = hd.u;
285: v2 = pow2(hd.v);
286: for( i=hd.ny; i>0; i-- ){
287: Read(rd.fd,p,hd.nx*sizeof(short));
288: for( j=hd.nx, q=p; j>0; j--, q++ ){
289: if( *q < -BIG ) continue;
290: if( *q < pmin ){ pmin = *q; }
291: if( *q > pmax ){ pmax = *q; }
292: }
293: }
294: *pfmin = (pmin-u2)*v2;
295: *pfmax = (pmax-u2)*v2;
296: return(1);
297: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.