ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pinterp.c
Revision: 1.5
Committed: Fri Dec 22 10:08:33 1989 UTC (34 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +68 -14 lines
Log Message:
Changed calls to rayview() and pixelview() to matrix transform

File Contents

# Content
1 #ifndef lint
2 static char SCCSid[] = "$SunId$ LBL";
3 #endif
4
5 /*
6 * Interpolate and extrapolate pictures with different view parameters.
7 *
8 * Greg Ward 09Dec89
9 */
10
11 #include "standard.h"
12
13 #include "view.h"
14
15 #include "color.h"
16
17 #define pscan(y) (ourpict+(y)*ourview.hresolu)
18 #define zscan(y) (ourzbuf+(y)*ourview.hresolu)
19
20 #define ABS(x) ((x)>0?(x):-(x))
21
22 VIEW ourview = STDVIEW(512); /* desired view */
23
24 double zeps = 0.001; /* allowed z epsilon */
25
26 COLR *ourpict; /* output picture */
27 float *ourzbuf; /* corresponding z-buffer */
28
29 char *progname;
30
31 VIEW theirview = STDVIEW(512); /* input view */
32 int gotview; /* got input view? */
33
34 double theirs2ours[4][4]; /* transformation matrix */
35
36
37 main(argc, argv) /* interpolate pictures */
38 int argc;
39 char *argv[];
40 {
41 #define check(olen,narg) if (argv[i][olen] || narg >= argc-i) goto badopt
42 int gotvfile = 0;
43 char *err;
44 int i;
45
46 progname = argv[0];
47
48 for (i = 1; i < argc && argv[i][0] == '-'; i++)
49 switch (argv[i][1]) {
50 case 't': /* threshold */
51 check(2,1);
52 zeps = atof(argv[++i]);
53 break;
54 case 'v': /* view */
55 switch (argv[i][2]) {
56 case 't': /* type */
57 check(4,0);
58 ourview.type = argv[i][3];
59 break;
60 case 'p': /* point */
61 check(3,3);
62 ourview.vp[0] = atof(argv[++i]);
63 ourview.vp[1] = atof(argv[++i]);
64 ourview.vp[2] = atof(argv[++i]);
65 break;
66 case 'd': /* direction */
67 check(3,3);
68 ourview.vdir[0] = atof(argv[++i]);
69 ourview.vdir[1] = atof(argv[++i]);
70 ourview.vdir[2] = atof(argv[++i]);
71 break;
72 case 'u': /* up */
73 check(3,3);
74 ourview.vup[0] = atof(argv[++i]);
75 ourview.vup[1] = atof(argv[++i]);
76 ourview.vup[2] = atof(argv[++i]);
77 break;
78 case 'h': /* horizontal */
79 check(3,1);
80 ourview.horiz = atof(argv[++i]);
81 break;
82 case 'v': /* vertical */
83 check(3,1);
84 ourview.vert = atof(argv[++i]);
85 break;
86 case 'f': /* file */
87 check(3,1);
88 gotvfile = viewfile(argv[++i], &ourview);
89 if (gotvfile < 0) {
90 perror(argv[i]);
91 exit(1);
92 } else if (gotvfile == 0) {
93 fprintf(stderr, "%s: bad view file\n",
94 argv[i]);
95 exit(1);
96 }
97 break;
98 default:
99 goto badopt;
100 }
101 break;
102 default:
103 badopt:
104 fprintf(stderr, "%s: unknown option '%s'\n",
105 progname, argv[i]);
106 exit(1);
107 }
108 /* check arguments */
109 if (argc-i < 2 || (argc-i)%2) {
110 fprintf(stderr, "Usage: %s [view args] pfile zfile ..\n",
111 progname);
112 exit(1);
113 }
114 /* set view */
115 if (err = setview(&ourview)) {
116 fprintf(stderr, "%s: %s\n", progname, err);
117 exit(1);
118 }
119 /* allocate frame */
120 ourpict = (COLR *)calloc(ourview.hresolu*ourview.vresolu,sizeof(COLR));
121 ourzbuf = (float *)calloc(ourview.hresolu*ourview.vresolu,sizeof(float));
122 if (ourpict == NULL || ourzbuf == NULL) {
123 perror(progname);
124 exit(1);
125 }
126 /* get input */
127 for ( ; i < argc; i += 2)
128 addpicture(argv[i], argv[i+1]);
129 /* fill in spaces */
130 fillpicture();
131 /* add to header */
132 printargs(argc, argv, stdout);
133 if (gotvfile) {
134 printf(VIEWSTR);
135 fprintview(&ourview, stdout);
136 printf("\n");
137 }
138 printf("\n");
139 /* write output */
140 writepicture();
141
142 exit(0);
143 #undef check
144 }
145
146
147 headline(s) /* process header string */
148 char *s;
149 {
150 static char *altname[] = {"rview","rpict","pinterp",VIEWSTR,NULL};
151 register char **an;
152
153 printf("\t%s", s);
154
155 for (an = altname; *an != NULL; an++)
156 if (!strncmp(*an, s, strlen(*an))) {
157 if (sscanview(&theirview, s+strlen(*an)) == 0)
158 gotview++;
159 break;
160 }
161 }
162
163
164 addpicture(pfile, zfile) /* add picture to output */
165 char *pfile, *zfile;
166 {
167 FILE *pfp, *zfp;
168 COLR *scanin;
169 float *zin;
170 char *err;
171 int xres, yres;
172 int y;
173 /* open input files */
174 if ((pfp = fopen(pfile, "r")) == NULL) {
175 perror(pfile);
176 exit(1);
177 }
178 if ((zfp = fopen(zfile, "r")) == NULL) {
179 perror(zfile);
180 exit(1);
181 }
182 /* get header and view */
183 printf("%s:\n", pfile);
184 gotview = 0;
185 getheader(pfp, headline);
186 if (!gotview || fgetresolu(&xres, &yres, pfp) != (YMAJOR|YDECR)) {
187 fprintf(stderr, "%s: picture view error\n", pfile);
188 exit(1);
189 }
190 theirview.hresolu = xres;
191 theirview.vresolu = yres;
192 if (err = setview(&theirview)) {
193 fprintf(stderr, "%s: %s\n", pfile, err);
194 exit(1);
195 }
196 /* compute transformation */
197 pixform(theirs2ours, &theirview, &ourview);
198 /* allocate scanlines */
199 scanin = (COLR *)malloc(xres*sizeof(COLR));
200 zin = (float *)malloc(xres*sizeof(float));
201 if (scanin == NULL || zin == NULL) {
202 perror(progname);
203 exit(1);
204 }
205 /* load image */
206 for (y = yres-1; y >= 0; y--) {
207 if (freadcolrs(scanin, xres, pfp) < 0) {
208 fprintf(stderr, "%s: read error\n", pfile);
209 exit(1);
210 }
211 if (fread(zin, sizeof(float), xres, zfp) < xres) {
212 fprintf(stderr, "%s: read error\n", zfile);
213 exit(1);
214 }
215 addscanline(y, scanin, zin);
216 }
217 /* clean up */
218 free((char *)scanin);
219 free((char *)zin);
220 fclose(pfp);
221 fclose(zfp);
222 }
223
224
225 pixform(xfmat, vw1, vw2) /* compute view1 to view2 matrix */
226 register double xfmat[4][4];
227 register VIEW *vw1, *vw2;
228 {
229 double m4t[4][4];
230
231 setident4(xfmat);
232 xfmat[0][0] = vw1->vhinc[0];
233 xfmat[0][1] = vw1->vhinc[1];
234 xfmat[0][2] = vw1->vhinc[2];
235 xfmat[1][0] = vw1->vvinc[0];
236 xfmat[1][1] = vw1->vvinc[1];
237 xfmat[1][2] = vw1->vvinc[2];
238 xfmat[2][0] = vw1->vdir[0];
239 xfmat[2][1] = vw1->vdir[1];
240 xfmat[2][2] = vw1->vdir[2];
241 xfmat[3][0] = vw1->vp[0];
242 xfmat[3][1] = vw1->vp[1];
243 xfmat[3][2] = vw1->vp[2];
244 setident4(m4t);
245 m4t[0][0] = vw2->vhinc[0]/vw2->vhn2;
246 m4t[1][0] = vw2->vhinc[1]/vw2->vhn2;
247 m4t[2][0] = vw2->vhinc[2]/vw2->vhn2;
248 m4t[3][0] = -DOT(vw2->vp,vw2->vhinc)/vw2->vhn2;
249 m4t[0][1] = vw2->vvinc[0]/vw2->vvn2;
250 m4t[1][1] = vw2->vvinc[1]/vw2->vvn2;
251 m4t[2][1] = vw2->vvinc[2]/vw2->vvn2;
252 m4t[3][1] = -DOT(vw2->vp,vw2->vvinc)/vw2->vvn2;
253 m4t[0][2] = vw2->vdir[0];
254 m4t[1][2] = vw2->vdir[1];
255 m4t[2][2] = vw2->vdir[2];
256 m4t[3][2] = -DOT(vw2->vp,vw2->vdir);
257 multmat4(xfmat, xfmat, m4t);
258 }
259
260
261 addscanline(y, pline, zline) /* add scanline to output */
262 int y;
263 COLR *pline;
264 float *zline;
265 {
266 extern double sqrt();
267 double pos[3];
268 register int x;
269 register int xpos, ypos;
270
271 for (x = 0; x < theirview.hresolu; x++) {
272 pos[0] = x - .5*(theirview.hresolu-1);
273 pos[1] = y - .5*(theirview.vresolu-1);
274 pos[2] = zline[x];
275 if (theirview.type == VT_PER) {
276 pos[2] /= sqrt( 1.
277 + pos[0]*pos[0]*theirview.vhn2
278 + pos[1]*pos[1]*theirview.vvn2 );
279 pos[0] *= pos[2];
280 pos[1] *= pos[2];
281 }
282 multp3(pos, pos, theirs2ours);
283 if (pos[2] <= 0.0)
284 continue;
285 if (ourview.type == VT_PER) {
286 pos[0] /= pos[2];
287 pos[1] /= pos[2];
288 }
289 pos[0] += .5*ourview.hresolu;
290 pos[1] += .5*ourview.vresolu;
291 if (pos[0] < 0 || pos[0] > ourview.hresolu
292 || pos[1] < 0 || pos[1] > ourview.vresolu)
293 continue;
294 /* check current value at pos */
295 xpos = pos[0];
296 ypos = pos[1];
297 if (zscan(ypos)[xpos] <= 0.0
298 || zscan(ypos)[xpos] - pos[2]
299 > zeps*zscan(ypos)[xpos]) {
300 zscan(ypos)[xpos] = pos[2];
301 copycolr(pscan(ypos)[xpos], pline[x]);
302 }
303 }
304 }
305
306
307 fillpicture() /* fill in empty spaces */
308 {
309 int *yback, xback;
310 int y;
311 COLR pfill;
312 register int x, i;
313 /* get back buffer */
314 yback = (int *)malloc(ourview.hresolu*sizeof(int));
315 if (yback == NULL) {
316 perror(progname);
317 return;
318 }
319 for (x = 0; x < ourview.hresolu; x++)
320 yback[x] = -2;
321 /* fill image */
322 for (y = 0; y < ourview.vresolu; y++) {
323 xback = -2;
324 for (x = 0; x < ourview.hresolu; x++)
325 if (zscan(y)[x] <= 0.0) { /* empty pixel */
326 if (yback[x] == -2) {
327 for (i = y+1; i < ourview.vresolu; i++)
328 if (zscan(i)[x] > 0.0)
329 break;
330 if (i < ourview.vresolu
331 && (y <= 0 || zscan(y-1)[x] < zscan(i)[x]))
332 yback[x] = i;
333 else
334 yback[x] = y-1;
335 }
336 if (xback == -2) {
337 for (i = x+1; x < ourview.hresolu; i++)
338 if (zscan(y)[i] > 0.0)
339 break;
340 if (i < ourview.hresolu
341 && (x <= 0 || zscan(y)[x-1] < zscan(y)[i]))
342 xback = i;
343 else
344 xback = x-1;
345 }
346 if (xback < 0 && yback[x] < 0)
347 continue;
348 if (yback[x] < 0 || ABS(x-xback) <= 1
349 || ( ABS(y-yback[x]) > 1
350 && zscan(yback[x])[x] < zscan(y)[xback] ))
351 copycolr(pscan(y)[x],pscan(y)[xback]);
352 else
353 copycolr(pscan(y)[x],pscan(yback[x])[x]);
354 } else { /* full pixel */
355 yback[x] = -2;
356 xback = -2;
357 }
358 }
359 free((char *)yback);
360 }
361
362
363 writepicture() /* write out picture */
364 {
365 int y;
366
367 fputresolu(YMAJOR|YDECR, ourview.hresolu, ourview.vresolu, stdout);
368 for (y = ourview.vresolu-1; y >= 0; y--)
369 if (fwritecolrs(pscan(y), ourview.hresolu, stdout) < 0) {
370 perror(progname);
371 exit(1);
372 }
373 }