38 |
|
|
39 |
|
#define NEWMAP 01 /* need to recompute mapping */ |
40 |
|
#define NEWRGB 02 /* need to remap RGB values */ |
41 |
+ |
#define NEWHIST 04 /* clear histogram as well */ |
42 |
|
|
43 |
|
struct ODview *odView; /* our view list */ |
44 |
|
int odNViews; /* number of views in our list */ |
58 |
|
int nbytes, i, j, k, nextsamp, count, blockdiv; |
59 |
|
int res[2]; |
60 |
|
|
61 |
< |
if (odNViews) { /* deallocate view structures */ |
62 |
< |
for (i = 0; i < odNViews; i++) { |
61 |
> |
if (odNViews > 0) { /* deallocate view structures */ |
62 |
> |
for (i = odNViews; i--; ) { |
63 |
|
free((char *)odView[i].bmap); |
64 |
+ |
free((char *)odView[i].pmap); |
65 |
|
if (odView[i].emap != NULL) |
66 |
|
free((char *)odView[i].emap); |
67 |
|
} |
75 |
|
for (i = 1024; nbytes > i-8; i <<= 1) |
76 |
|
; |
77 |
|
n = (i-8)/SAMP32 * 32; |
78 |
< |
needmapping = NEWMAP; |
78 |
> |
needmapping = NEWHIST; |
79 |
|
} |
80 |
|
if (n != odS.nsamp) { /* (re)allocate sample array */ |
81 |
|
if (odS.nsamp) |
110 |
|
if (blockdiv < 8) blockdiv = 8; |
111 |
|
nextsamp = 0; count /= blockdiv*blockdiv; /* # blocks */ |
112 |
|
while (i--) { /* initialize each view */ |
111 |
– |
odView[i].emap = NULL; |
112 |
– |
odView[i].dmap = NULL; |
113 |
|
dev_auxview(i, res); |
114 |
|
odView[i].hhi = res[0]; |
115 |
|
odView[i].hlow = (res[0] + blockdiv/2) / blockdiv; |
117 |
|
odView[i].vhi = res[1]; |
118 |
|
odView[i].vlow = (res[1] + blockdiv/2) / blockdiv; |
119 |
|
if (odView[i].vlow < 1) odView[i].vlow = 1; |
120 |
+ |
odView[i].emap = NULL; |
121 |
+ |
odView[i].dmap = NULL; |
122 |
+ |
odView[i].pmap = (int4 *)calloc(FL4NELS(res[0]*res[1]), |
123 |
+ |
sizeof(int4)); |
124 |
+ |
if (odView[i].pmap == NULL) |
125 |
+ |
return(0); |
126 |
|
j = odView[i].hlow*odView[i].vlow; |
127 |
|
odView[i].bmap = (struct ODblock *)malloc( |
128 |
|
j * sizeof(struct ODblock)); |
131 |
|
DCHECK(count<=0 | nextsamp>=n, |
132 |
|
CONSISTENCY, "counter botch in odInit"); |
133 |
|
if (!i) count = j; |
134 |
< |
while (j--) { |
134 |
> |
while (j--) { /* initialize blocks & free lists */ |
135 |
> |
odView[i].bmap[j].pthresh = FHUGE; |
136 |
|
odView[i].bmap[j].first = k = nextsamp; |
137 |
|
nextsamp += odView[i].bmap[j].nsamp = |
138 |
|
(n - nextsamp)/count--; |
144 |
|
} |
145 |
|
} |
146 |
|
CLR4ALL(odS.redraw, odS.nsamp); /* clear redraw flags */ |
147 |
< |
for (i = odS.nsamp; i--; ) /* clear values */ |
147 |
> |
for (i = odS.nsamp; i--; ) { /* clear values */ |
148 |
|
odS.ip[i][0] = odS.ip[i][1] = -1; |
149 |
+ |
odS.brt[i] = TM_NOBRT; |
150 |
+ |
} |
151 |
+ |
needmapping |= NEWMAP; /* compute new map on update */ |
152 |
|
return(odS.nsamp); /* return number of samples */ |
153 |
|
} |
154 |
|
|
166 |
|
|
167 |
|
|
168 |
|
int |
169 |
< |
odAllocBlockSamp(vn, hl, vl) /* allocate sample from block */ |
170 |
< |
int vn, hl, vl; |
169 |
> |
odAllocBlockSamp(vn, hh, vh, prox) /* allocate sample from block */ |
170 |
> |
int vn, hh, vh; |
171 |
> |
double prox; |
172 |
|
{ |
173 |
|
int si[SAMPSPERBLOCK+SAMPSPERBLOCK/4]; |
174 |
+ |
int hl, vl; |
175 |
|
VIEW *vw; |
176 |
|
FVECT ro, rd; |
177 |
|
int res[2]; |
178 |
|
register struct ODblock *bp; |
179 |
< |
register int i; |
180 |
< |
|
179 |
> |
register int i, j; |
180 |
> |
/* get block */ |
181 |
> |
hl = hh*odView[vn].hlow/odView[vn].hhi; |
182 |
> |
vl = vh*odView[vn].vlow/odView[vn].vhi; |
183 |
|
bp = odView[vn].bmap + vl*odView[vn].hlow + hl; |
184 |
< |
if (bp->free != ENDFREE) { /* check free list first */ |
184 |
> |
if (prox > bp->pthresh) |
185 |
> |
return(-1); /* worse than free list occupants */ |
186 |
> |
/* check for duplicate pixel */ |
187 |
> |
if (CHK4(odView[vn].pmap, vh*odView[vn].hhi + hh)) |
188 |
> |
i = bp->first + bp->nsamp; |
189 |
> |
else |
190 |
> |
i = -1; |
191 |
> |
while (i-- > bp->first) |
192 |
> |
if (hh == odS.ip[i][0] && vh == odS.ip[i][1]) { /* found it! */ |
193 |
> |
/* search free list for it */ |
194 |
> |
if (i == bp->free) |
195 |
> |
break; /* special case */ |
196 |
> |
if (bp->free != ENDFREE) |
197 |
> |
for (j = bp->free; odS.nextfree(j) != ENDFREE; |
198 |
> |
j = odS.nextfree(j)) |
199 |
> |
if (odS.nextfree(j) == i) { |
200 |
> |
odS.nextfree(j) = |
201 |
> |
odS.nextfree(i); |
202 |
> |
bp->nused++; |
203 |
> |
goto gotit; |
204 |
> |
} |
205 |
> |
if (prox >= 0.999*odS.closeness(i)) |
206 |
> |
return(-1); /* previous sample is fine */ |
207 |
> |
goto gotit; |
208 |
> |
} |
209 |
> |
DCHECK(i>=-1, WARNING, "pixel in presence map not found in block"); |
210 |
> |
if (bp->free != ENDFREE) { /* allocate from free list */ |
211 |
|
i = bp->free; |
212 |
+ |
if (odS.ip[i][0] >= 0 & odS.ip[i][1] >= 0) |
213 |
+ |
CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi + |
214 |
+ |
odS.ip[i][0]); |
215 |
|
bp->free = odS.nextfree(i); |
216 |
|
bp->nused++; |
217 |
< |
return(i); |
217 |
> |
goto gotit; |
218 |
|
} |
219 |
|
DCHECK(bp->nsamp<=0, CONSISTENCY, |
220 |
|
"no available samples in odAllocBlockSamp"); |
226 |
|
for (i = bp->nsamp; i--; ) /* figure out which are worse */ |
227 |
|
si[i] = bp->first + i; |
228 |
|
qsort((char *)si, bp->nsamp, sizeof(int), sampcmp); |
229 |
< |
i = bp->nsamp*SFREEFRAC + .5; /* put them in a list */ |
229 |
> |
i = bp->nsamp*SFREEFRAC + .5; /* put them into free list */ |
230 |
> |
if (i >= bp->nsamp) i = bp->nsamp-1; /* paranoia */ |
231 |
> |
bp->pthresh = odS.closeness(si[i]); /* new proximity threshold */ |
232 |
|
while (--i > 0) { |
233 |
|
odS.nextfree(si[i]) = bp->free; |
234 |
|
bp->free = si[i]; |
235 |
|
bp->nused--; |
236 |
|
} |
237 |
< |
return(si[0]); /* return first free sample */ |
237 |
> |
i = si[0]; /* use worst sample */ |
238 |
> |
CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi + odS.ip[i][0]); |
239 |
> |
gotit: |
240 |
> |
odS.ip[i][0] = hh; |
241 |
> |
odS.ip[i][1] = vh; |
242 |
> |
odS.closeness(i) = prox; |
243 |
> |
SET4(odView[vn].pmap, vh*odView[vn].hhi + hh); |
244 |
> |
return(i); |
245 |
|
} |
246 |
|
|
247 |
|
|
250 |
|
FVECT d, p; |
251 |
|
{ |
252 |
|
FVECT disp; |
253 |
< |
double d0, d1, h, v; |
253 |
> |
double d0, d1, h, v, prox; |
254 |
|
register VIEW *vw; |
255 |
< |
int hl, vl, hh, vh; |
255 |
> |
int hh, vh; |
256 |
|
int res[2]; |
257 |
|
register int i, id; |
258 |
|
|
287 |
|
(1.+DEPTHEPS)*d0 < d1)) |
288 |
|
continue; /* occlusion error */ |
289 |
|
} |
238 |
– |
hl = hh*odView[i].hlow/res[0]; |
239 |
– |
vl = vh*odView[i].vlow/res[1]; |
240 |
– |
/* may duplicate samples */ |
241 |
– |
id = odAllocBlockSamp(i, hl, vl); |
242 |
– |
odS.ip[id][0] = hh; |
243 |
– |
odS.ip[id][1] = vh; |
290 |
|
if (p != NULL) { /* compute closeness (sin^2) */ |
291 |
|
d1 = DOT(disp, d); |
292 |
< |
odS.closeness(id) = 1. - d1*d1/DOT(disp,disp); |
292 |
> |
prox = 1. - d1*d1/DOT(disp,disp); |
293 |
|
} else |
294 |
< |
odS.closeness(id) = 0.; |
294 |
> |
prox = 0.; |
295 |
> |
/* allocate sample */ |
296 |
> |
id = odAllocBlockSamp(i, hh, vh, prox); |
297 |
> |
if (id < 0) |
298 |
> |
continue; /* not good enough */ |
299 |
|
/* convert color */ |
300 |
|
tmCvColrs(&odS.brt[id], odS.chr[id], c, 1); |
301 |
|
if (imm_mode | needmapping) /* if immediate mode */ |
307 |
|
} |
308 |
|
|
309 |
|
|
310 |
< |
odRemap() /* recompute tone mapping */ |
310 |
> |
odRemap(newhist) /* recompute tone mapping */ |
311 |
> |
int newhist; |
312 |
|
{ |
313 |
|
needmapping |= NEWMAP|NEWRGB; |
314 |
+ |
if (newhist) |
315 |
+ |
needmapping |= NEWHIST; |
316 |
|
} |
317 |
|
|
318 |
|
|
356 |
|
int i, j, hmin, hmax, vmin, vmax; |
357 |
|
register int k, l; |
358 |
|
|
306 |
– |
DCHECK(vn<0 | vn>=odNViews, CONSISTENCY, |
307 |
– |
"bad view number in odDepthMap"); |
359 |
|
if (dm == NULL) { /* free edge map */ |
360 |
+ |
if (vn<0 | vn>=odNViews) |
361 |
+ |
return; /* too late -- they're gone! */ |
362 |
|
if (odView[vn].emap != NULL) |
363 |
|
free((char *)odView[vn].emap); |
364 |
|
odView[vn].emap = NULL; |
365 |
|
odView[vn].dmap = NULL; |
366 |
|
return; |
367 |
|
} |
368 |
+ |
DCHECK(vn<0 | vn>=odNViews, CONSISTENCY, |
369 |
+ |
"bad view number in odDepthMap"); |
370 |
|
odView[vn].dmap = dm; /* initialize edge map */ |
371 |
|
if (odView[vn].emap == NULL) { |
372 |
|
odView[vn].emap = (int4 *)malloc( |
433 |
|
/* need to do some tone mapping? */ |
434 |
|
if (needmapping & NEWRGB) { |
435 |
|
if (needmapping & NEWMAP) { |
436 |
< |
tmClearHisto(); |
436 |
> |
if (needmapping & NEWHIST) |
437 |
> |
tmClearHisto(); |
438 |
|
if (tmAddHisto(odS.brt,odS.nsamp,1) != TM_E_OK) |
439 |
|
return; |
440 |
|
if (tmComputeMapping(0.,0.,0.) != TM_E_OK) |
448 |
|
needmapping = 0; /* reset flag */ |
449 |
|
} |
450 |
|
/* draw each block in view */ |
451 |
< |
for (i = odView[vn].hlow; i--; ) |
452 |
< |
for (j = odView[vn].vlow; j--; ) { |
451 |
> |
for (j = odView[vn].vlow; j--; ) |
452 |
> |
for (i = 0; i < odView[vn].hlow; i++) { |
453 |
|
/* get block */ |
454 |
|
bp = odView[vn].bmap + j*odView[vn].hlow + i; |
455 |
|
/* do quick, conservative flag check */ |