38 |
|
VIEW vwprev = STDVIEW; /* previous view */ |
39 |
|
int fnprev; /* frame number for previous view */ |
40 |
|
|
41 |
– |
char *progname; /* global argv[0] */ |
42 |
– |
|
41 |
|
typedef struct { |
42 |
|
VIEW *vp; /* view pointer */ |
43 |
|
int gotview; /* got view parameters? */ |
50 |
|
headline(char *s, void *p) |
51 |
|
{ |
52 |
|
IMGHEAD *ip = (IMGHEAD *)p; |
53 |
< |
char fmt[32]; |
53 |
> |
char fmt[MAXFMTLEN]; |
54 |
|
|
55 |
|
if (isview(s)) { |
56 |
|
ip->gotview += (sscanview(ip->vp, s) > 0); |
109 |
|
exprev = ih.ev; |
110 |
|
if (!fgetsresolu(&rs, fp)) |
111 |
|
goto readerr; |
112 |
+ |
if (rs.rt != PIXSTANDARD) { |
113 |
+ |
sprintf(errmsg, "unsupported orientation in picture \"%s\"", fname); |
114 |
+ |
error(USER, errmsg); |
115 |
+ |
} |
116 |
|
if (!imres.xr) { /* allocate buffers */ |
117 |
|
imres = rs; |
118 |
|
imsum = (COLOR *)ecalloc(imres.xr*imres.yr, sizeof(COLOR)); |
130 |
|
goto readerr; |
131 |
|
fclose(fp); |
132 |
|
sprintf(fname, zbfspec, fno); /* load depth buffer */ |
133 |
< |
if ((fd = open(fname, O_RDONLY)) < 0) { |
133 |
> |
if ((fd = open_float_depth(fname, (long)rs.xr*rs.yr)) < 0) { |
134 |
|
sprintf(errmsg, "cannot open depth buffer \"%s\"", fname); |
135 |
|
error(SYSTEM, errmsg); |
136 |
|
} |
148 |
|
/* Interpolate between two image pixels */ |
149 |
|
/* XXX skipping expensive ray vector calculations for now */ |
150 |
|
static void |
151 |
< |
interp_pixel(COLOR con, const VIEW *vwn, int xn, int yn, double zn, |
152 |
< |
double pos, int xp, int yp) |
151 |
> |
interp_pixel(COLOR con, const VIEW *vwn, int xn, int yn, double zval, |
152 |
> |
double pos, int xp, int yp, int interpOK) |
153 |
|
{ |
154 |
|
const int hres = scanlen(&imres); |
155 |
|
RREAL ipos; |
156 |
|
FVECT wprev, wcoor, rdir; |
157 |
|
int np, xd, yd, nd; |
158 |
|
COLOR cpr; |
159 |
< |
double sf, zval; |
159 |
> |
double sf; |
160 |
|
/* check if off image */ |
161 |
|
if ((xp < 0) | (xp >= hres)) |
162 |
|
return; |
166 |
|
xd = (1.-pos)*xp + pos*xn + .5; |
167 |
|
yd = (1.-pos)*yp + pos*yn + .5; |
168 |
|
nd = yd*hres + xd; |
169 |
< |
/* check interpolated depth */ |
170 |
< |
zval = (1.-pos)*zprev[np] + pos*zn; |
169 |
> |
/* check depth */ |
170 |
> |
if (interpOK) |
171 |
> |
zval = (1.-pos)*zprev[np] + pos*zval; |
172 |
|
if (zval >= zbuf[nd]) |
173 |
|
return; |
174 |
< |
copycolor(imbuf[nd], con); /* assign interpolated color */ |
174 |
> |
zbuf[nd] = zval; /* assign new depth */ |
175 |
> |
copycolor(imbuf[nd], con); /* assign new color */ |
176 |
> |
if (!interpOK) |
177 |
> |
return; |
178 |
|
scalecolor(imbuf[nd], pos); |
179 |
|
sf = (1.-pos)/exprev; |
180 |
|
colr_color(cpr, imprev[np]); |
181 |
|
scalecolor(cpr, sf); |
182 |
|
addcolor(imbuf[nd], cpr); |
177 |
– |
zbuf[nd] = zval; /* assign new depth */ |
183 |
|
} |
184 |
|
|
185 |
|
|
205 |
|
} |
206 |
|
|
207 |
|
|
208 |
< |
/* Fill in missing pixels from immediate neighbors */ |
208 |
> |
/* Expand foreground pixels to mitigate aliasing/fill errors */ |
209 |
|
static void |
210 |
|
fill_missing(void) |
211 |
|
{ |
212 |
|
int n, m; |
213 |
|
|
214 |
|
for (n = imres.xr*imres.yr; n--; ) |
215 |
< |
if (zbuf[n] >= .9*FHUGE && |
211 |
< |
zbuf[m = neigh_zmin(zbuf,n)] < .9*FHUGE) |
215 |
> |
if (zbuf[n] > 1.25*zbuf[m = neigh_zmin(zbuf,n)]) |
216 |
|
copycolor(imbuf[n], imbuf[m]); |
217 |
|
} |
218 |
|
|
262 |
|
error(USER, err); |
263 |
|
if (!fgetsresolu(&rs, fpimg)) |
264 |
|
goto readerr; |
265 |
+ |
if (rs.rt != PIXSTANDARD) { |
266 |
+ |
sprintf(errmsg, "unsupported orientation in picture \"%s\"", fname); |
267 |
+ |
error(USER, errmsg); |
268 |
+ |
} |
269 |
|
if ((rs.xr != imres.xr) | (rs.yr != imres.yr)) { |
270 |
|
sprintf(errmsg, "resolution mismatch for picture \"%s\"", fname); |
271 |
|
error(USER, errmsg); |
319 |
|
scalecolor(cval, sf); |
320 |
|
interp_pixel(cval, &fvw, h, n, zscan[h], fpos, |
321 |
|
h + (int)mscan[3*h] - 32768, |
322 |
< |
n - (int)mscan[3*h+1] + 32768); |
322 |
> |
n - (int)mscan[3*h+1] + 32768, |
323 |
> |
mscan[3*h+2]); |
324 |
|
} |
325 |
|
} |
326 |
|
/* fill in missing pixels */ |
389 |
|
{ |
390 |
|
double fstart, fend, fstep, fcur; |
391 |
|
|
392 |
< |
progname = argv[0]; |
392 |
> |
fixargv0(argv[0]); /* sets global progname */ |
393 |
|
SET_DEFAULT_BINARY(); |
394 |
|
if (argc != 5) |
395 |
|
goto userr; |
396 |
< |
/* get frame range */ |
397 |
< |
switch (sscanf(argv[1], "%lf,%lf", &fstart, &fend)) { |
396 |
> |
/* get frame range & sampling */ |
397 |
> |
switch (sscanf(argv[1], "%lf,%lf/%d", &fstart, &fend, &nsamps)) { |
398 |
|
case 1: |
399 |
|
fend = fstart; |
400 |
+ |
nsamps = 0; |
401 |
|
break; |
402 |
|
case 2: |
403 |
+ |
nsamps = 0; |
404 |
+ |
/* fall through */ |
405 |
+ |
case 3: |
406 |
|
if (fend < fstart) |
407 |
|
goto userr; |
408 |
+ |
if (fend <= fstart+FTINY) |
409 |
+ |
nsamps = 0; |
410 |
|
break; |
411 |
|
default: |
412 |
|
goto userr; |
413 |
|
} |
414 |
|
if (fstart < 1) |
415 |
|
goto userr; |
416 |
< |
hdrspec = argv[2]; |
417 |
< |
zbfspec = argv[3]; |
403 |
< |
mvospec = argv[4]; |
404 |
< |
nsamps = (fend - fstart)*12.; |
416 |
> |
if (nsamps <= 0) |
417 |
> |
nsamps = (fend - fstart)*17.; |
418 |
|
if (nsamps) { |
419 |
+ |
if (nsamps > 100) nsamps = 100; |
420 |
|
fstep = (fend - fstart)/nsamps; |
421 |
|
} else { |
422 |
|
fstep = 1.; |
423 |
|
fstart -= .5; |
424 |
|
nsamps = 1; |
425 |
|
} |
426 |
+ |
hdrspec = argv[2]; |
427 |
+ |
zbfspec = argv[3]; |
428 |
+ |
mvospec = argv[4]; |
429 |
|
/* load and filter each subframe */ |
430 |
|
for (fcur = fstart + .5*fstep; fcur <= fend; fcur += fstep) |
431 |
|
addframe(fcur); |
437 |
|
write_average(stdout); |
438 |
|
return(fflush(stdout) == EOF); |
439 |
|
userr: |
440 |
< |
fprintf(stderr, "Usage: %s f0,f1 HDRspec ZBUFspec MVOspec\n", progname); |
440 |
> |
fprintf(stderr, "Usage: %s f0,f1[/n] HDRspec ZBUFspec MVOspec\n", progname); |
441 |
|
return(1); |
442 |
|
} |