ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pinterp.c
Revision: 1.7
Committed: Tue Jan 2 17:22:07 1990 UTC (34 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.6: +20 -3 lines
Log Message:
Added comments and fixed small comparison error.

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 'x': /* x resolution */
55 check(2,1);
56 ourview.hresolu = atoi(argv[++i]);
57 break;
58 case 'y': /* y resolution */
59 check(2,1);
60 ourview.vresolu = atoi(argv[++i]);
61 break;
62 case 'v': /* view */
63 switch (argv[i][2]) {
64 case 't': /* type */
65 check(4,0);
66 ourview.type = argv[i][3];
67 break;
68 case 'p': /* point */
69 check(3,3);
70 ourview.vp[0] = atof(argv[++i]);
71 ourview.vp[1] = atof(argv[++i]);
72 ourview.vp[2] = atof(argv[++i]);
73 break;
74 case 'd': /* direction */
75 check(3,3);
76 ourview.vdir[0] = atof(argv[++i]);
77 ourview.vdir[1] = atof(argv[++i]);
78 ourview.vdir[2] = atof(argv[++i]);
79 break;
80 case 'u': /* up */
81 check(3,3);
82 ourview.vup[0] = atof(argv[++i]);
83 ourview.vup[1] = atof(argv[++i]);
84 ourview.vup[2] = atof(argv[++i]);
85 break;
86 case 'h': /* horizontal */
87 check(3,1);
88 ourview.horiz = atof(argv[++i]);
89 break;
90 case 'v': /* vertical */
91 check(3,1);
92 ourview.vert = atof(argv[++i]);
93 break;
94 case 'f': /* file */
95 check(3,1);
96 gotvfile = viewfile(argv[++i], &ourview);
97 if (gotvfile < 0) {
98 perror(argv[i]);
99 exit(1);
100 } else if (gotvfile == 0) {
101 fprintf(stderr, "%s: bad view file\n",
102 argv[i]);
103 exit(1);
104 }
105 break;
106 default:
107 goto badopt;
108 }
109 break;
110 default:
111 badopt:
112 fprintf(stderr, "%s: unknown option '%s'\n",
113 progname, argv[i]);
114 exit(1);
115 }
116 /* check arguments */
117 if (argc-i < 2 || (argc-i)%2) {
118 fprintf(stderr, "Usage: %s [view args] pfile zfile ..\n",
119 progname);
120 exit(1);
121 }
122 /* set view */
123 if (err = setview(&ourview)) {
124 fprintf(stderr, "%s: %s\n", progname, err);
125 exit(1);
126 }
127 /* allocate frame */
128 ourpict = (COLR *)calloc(ourview.hresolu*ourview.vresolu,sizeof(COLR));
129 ourzbuf = (float *)calloc(ourview.hresolu*ourview.vresolu,sizeof(float));
130 if (ourpict == NULL || ourzbuf == NULL) {
131 perror(progname);
132 exit(1);
133 }
134 /* get input */
135 for ( ; i < argc; i += 2)
136 addpicture(argv[i], argv[i+1]);
137 /* fill in spaces */
138 fillpicture();
139 /* add to header */
140 printargs(argc, argv, stdout);
141 if (gotvfile) {
142 printf(VIEWSTR);
143 fprintview(&ourview, stdout);
144 printf("\n");
145 }
146 printf("\n");
147 /* write output */
148 writepicture();
149
150 exit(0);
151 #undef check
152 }
153
154
155 headline(s) /* process header string */
156 char *s;
157 {
158 static char *altname[] = {"rview","rpict","pinterp",VIEWSTR,NULL};
159 register char **an;
160
161 printf("\t%s", s);
162
163 for (an = altname; *an != NULL; an++)
164 if (!strncmp(*an, s, strlen(*an))) {
165 if (sscanview(&theirview, s+strlen(*an)) == 0)
166 gotview++;
167 break;
168 }
169 }
170
171
172 addpicture(pfile, zfile) /* add picture to output */
173 char *pfile, *zfile;
174 {
175 FILE *pfp, *zfp;
176 COLR *scanin;
177 float *zin;
178 char *err;
179 int xres, yres;
180 int y;
181 /* open input files */
182 if ((pfp = fopen(pfile, "r")) == NULL) {
183 perror(pfile);
184 exit(1);
185 }
186 if ((zfp = fopen(zfile, "r")) == NULL) {
187 perror(zfile);
188 exit(1);
189 }
190 /* get header and view */
191 printf("%s:\n", pfile);
192 gotview = 0;
193 getheader(pfp, headline);
194 if (!gotview || fgetresolu(&xres, &yres, pfp) != (YMAJOR|YDECR)) {
195 fprintf(stderr, "%s: picture view error\n", pfile);
196 exit(1);
197 }
198 theirview.hresolu = xres;
199 theirview.vresolu = yres;
200 if (err = setview(&theirview)) {
201 fprintf(stderr, "%s: %s\n", pfile, err);
202 exit(1);
203 }
204 /* compute transformation */
205 pixform(theirs2ours, &theirview, &ourview);
206 /* allocate scanlines */
207 scanin = (COLR *)malloc(xres*sizeof(COLR));
208 zin = (float *)malloc(xres*sizeof(float));
209 if (scanin == NULL || zin == NULL) {
210 perror(progname);
211 exit(1);
212 }
213 /* load image */
214 for (y = yres-1; y >= 0; y--) {
215 if (freadcolrs(scanin, xres, pfp) < 0) {
216 fprintf(stderr, "%s: read error\n", pfile);
217 exit(1);
218 }
219 if (fread(zin, sizeof(float), xres, zfp) < xres) {
220 fprintf(stderr, "%s: read error\n", zfile);
221 exit(1);
222 }
223 addscanline(y, scanin, zin);
224 }
225 /* clean up */
226 free((char *)scanin);
227 free((char *)zin);
228 fclose(pfp);
229 fclose(zfp);
230 }
231
232
233 pixform(xfmat, vw1, vw2) /* compute view1 to view2 matrix */
234 register double xfmat[4][4];
235 register VIEW *vw1, *vw2;
236 {
237 double m4t[4][4];
238
239 setident4(xfmat);
240 xfmat[0][0] = vw1->vhinc[0];
241 xfmat[0][1] = vw1->vhinc[1];
242 xfmat[0][2] = vw1->vhinc[2];
243 xfmat[1][0] = vw1->vvinc[0];
244 xfmat[1][1] = vw1->vvinc[1];
245 xfmat[1][2] = vw1->vvinc[2];
246 xfmat[2][0] = vw1->vdir[0];
247 xfmat[2][1] = vw1->vdir[1];
248 xfmat[2][2] = vw1->vdir[2];
249 xfmat[3][0] = vw1->vp[0];
250 xfmat[3][1] = vw1->vp[1];
251 xfmat[3][2] = vw1->vp[2];
252 setident4(m4t);
253 m4t[0][0] = vw2->vhinc[0]/vw2->vhn2;
254 m4t[1][0] = vw2->vhinc[1]/vw2->vhn2;
255 m4t[2][0] = vw2->vhinc[2]/vw2->vhn2;
256 m4t[3][0] = -DOT(vw2->vp,vw2->vhinc)/vw2->vhn2;
257 m4t[0][1] = vw2->vvinc[0]/vw2->vvn2;
258 m4t[1][1] = vw2->vvinc[1]/vw2->vvn2;
259 m4t[2][1] = vw2->vvinc[2]/vw2->vvn2;
260 m4t[3][1] = -DOT(vw2->vp,vw2->vvinc)/vw2->vvn2;
261 m4t[0][2] = vw2->vdir[0];
262 m4t[1][2] = vw2->vdir[1];
263 m4t[2][2] = vw2->vdir[2];
264 m4t[3][2] = -DOT(vw2->vp,vw2->vdir);
265 multmat4(xfmat, xfmat, m4t);
266 }
267
268
269 addscanline(y, pline, zline) /* add scanline to output */
270 int y;
271 COLR *pline;
272 float *zline;
273 {
274 extern double sqrt();
275 double pos[3];
276 register int x;
277 register int xpos, ypos;
278
279 for (x = 0; x < theirview.hresolu; x++) {
280 pos[0] = x - .5*(theirview.hresolu-1);
281 pos[1] = y - .5*(theirview.vresolu-1);
282 pos[2] = zline[x];
283 if (theirview.type == VT_PER) {
284 pos[2] /= sqrt( 1.
285 + pos[0]*pos[0]*theirview.vhn2
286 + pos[1]*pos[1]*theirview.vvn2 );
287 pos[0] *= pos[2];
288 pos[1] *= pos[2];
289 }
290 multp3(pos, pos, theirs2ours);
291 if (pos[2] <= 0.0)
292 continue;
293 if (ourview.type == VT_PER) {
294 pos[0] /= pos[2];
295 pos[1] /= pos[2];
296 }
297 pos[0] += .5*ourview.hresolu;
298 pos[1] += .5*ourview.vresolu;
299 if (pos[0] < 0 || pos[0] >= ourview.hresolu
300 || pos[1] < 0 || pos[1] >= ourview.vresolu)
301 continue;
302 /* check current value at pos */
303 xpos = pos[0];
304 ypos = pos[1];
305 if (zscan(ypos)[xpos] <= 0.0
306 || zscan(ypos)[xpos] - pos[2]
307 > zeps*zscan(ypos)[xpos]) {
308 zscan(ypos)[xpos] = pos[2];
309 copycolr(pscan(ypos)[xpos], pline[x]);
310 }
311 }
312 }
313
314
315 fillpicture() /* fill in empty spaces */
316 {
317 int *yback, xback;
318 int y;
319 COLR pfill;
320 register int x, i;
321 /* get back buffer */
322 yback = (int *)malloc(ourview.hresolu*sizeof(int));
323 if (yback == NULL) {
324 perror(progname);
325 return;
326 }
327 for (x = 0; x < ourview.hresolu; x++)
328 yback[x] = -2;
329 /*
330 * Xback and yback are the pixel locations of suitable
331 * background values in each direction.
332 * A value of -2 means unassigned, and -1 means
333 * that there is no suitable background in this direction.
334 */
335 /* fill image */
336 for (y = 0; y < ourview.vresolu; y++) {
337 xback = -2;
338 for (x = 0; x < ourview.hresolu; x++)
339 if (zscan(y)[x] <= 0.0) { /* empty pixel */
340 /*
341 * First, find background from above or below.
342 * (farthest assigned pixel)
343 */
344 if (yback[x] == -2) {
345 for (i = y+1; i < ourview.vresolu; i++)
346 if (zscan(i)[x] > 0.0)
347 break;
348 if (i < ourview.vresolu
349 && (y <= 0 || zscan(y-1)[x] < zscan(i)[x]))
350 yback[x] = i;
351 else
352 yback[x] = y-1;
353 }
354 /*
355 * Next, find background from left or right.
356 */
357 if (xback == -2) {
358 for (i = x+1; x < ourview.hresolu; i++)
359 if (zscan(y)[i] > 0.0)
360 break;
361 if (i < ourview.hresolu
362 && (x <= 0 || zscan(y)[x-1] < zscan(y)[i]))
363 xback = i;
364 else
365 xback = x-1;
366 }
367 if (xback < 0 && yback[x] < 0)
368 continue; /* no background */
369 /*
370 * Compare, and use the background that is
371 * farther, unless one of them is next to us.
372 */
373 if (yback[x] < 0 || ABS(x-xback) <= 1
374 || ( ABS(y-yback[x]) > 1
375 && zscan(yback[x])[x] < zscan(y)[xback] ))
376 copycolr(pscan(y)[x],pscan(y)[xback]);
377 else
378 copycolr(pscan(y)[x],pscan(yback[x])[x]);
379 } else { /* full pixel */
380 yback[x] = -2;
381 xback = -2;
382 }
383 }
384 free((char *)yback);
385 }
386
387
388 writepicture() /* write out picture */
389 {
390 int y;
391
392 fputresolu(YMAJOR|YDECR, ourview.hresolu, ourview.vresolu, stdout);
393 for (y = ourview.vresolu-1; y >= 0; y--)
394 if (fwritecolrs(pscan(y), ourview.hresolu, stdout) < 0) {
395 perror(progname);
396 exit(1);
397 }
398 }