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 */ |
74 |
|
for (i = 1024; nbytes > i-8; i <<= 1) |
75 |
|
; |
76 |
|
n = (i-8)/SAMP32 * 32; |
77 |
< |
needmapping = NEWMAP; |
77 |
> |
needmapping = NEWHIST; |
78 |
|
} |
79 |
|
if (n != odS.nsamp) { /* (re)allocate sample array */ |
80 |
|
if (odS.nsamp) |
126 |
|
DCHECK(count<=0 | nextsamp>=n, |
127 |
|
CONSISTENCY, "counter botch in odInit"); |
128 |
|
if (!i) count = j; |
129 |
< |
while (j--) { |
129 |
> |
while (j--) { /* initialize blocks & free lists */ |
130 |
> |
odView[i].bmap[j].pthresh = FHUGE; |
131 |
|
odView[i].bmap[j].first = k = nextsamp; |
132 |
|
nextsamp += odView[i].bmap[j].nsamp = |
133 |
|
(n - nextsamp)/count--; |
139 |
|
} |
140 |
|
} |
141 |
|
CLR4ALL(odS.redraw, odS.nsamp); /* clear redraw flags */ |
142 |
< |
for (i = odS.nsamp; i--; ) /* clear values */ |
142 |
> |
for (i = odS.nsamp; i--; ) { /* clear values */ |
143 |
|
odS.ip[i][0] = odS.ip[i][1] = -1; |
144 |
+ |
odS.brt[i] = TM_NOBRT; |
145 |
+ |
} |
146 |
+ |
needmapping |= NEWMAP; /* compute new map on update */ |
147 |
|
return(odS.nsamp); /* return number of samples */ |
148 |
|
} |
149 |
|
|
161 |
|
|
162 |
|
|
163 |
|
int |
164 |
< |
odAllocBlockSamp(vn, hl, vl) /* allocate sample from block */ |
165 |
< |
int vn, hl, vl; |
164 |
> |
odAllocBlockSamp(vn, hh, vh, prox) /* allocate sample from block */ |
165 |
> |
int vn, hh, vh; |
166 |
> |
double prox; |
167 |
|
{ |
168 |
|
int si[SAMPSPERBLOCK+SAMPSPERBLOCK/4]; |
169 |
+ |
int hl, vl; |
170 |
|
VIEW *vw; |
171 |
|
FVECT ro, rd; |
172 |
|
int res[2]; |
173 |
|
register struct ODblock *bp; |
174 |
< |
register int i; |
175 |
< |
|
174 |
> |
register int i, j; |
175 |
> |
/* get block */ |
176 |
> |
hl = hh*odView[vn].hlow/odView[vn].hhi; |
177 |
> |
vl = vh*odView[vn].vlow/odView[vn].vhi; |
178 |
|
bp = odView[vn].bmap + vl*odView[vn].hlow + hl; |
179 |
< |
if (bp->free != ENDFREE) { /* check free list first */ |
179 |
> |
if (prox > bp->pthresh) |
180 |
> |
return(-1); /* worse than free list occupants */ |
181 |
> |
/* check for duplicate pixel */ |
182 |
> |
for (i = bp->first+bp->nsamp; i-- > bp->first; ) |
183 |
> |
if (hh == odS.ip[i][0] && vh == odS.ip[i][1]) { /* found it! */ |
184 |
> |
/* search free list for it */ |
185 |
> |
if (i == bp->free) |
186 |
> |
break; /* special case */ |
187 |
> |
if (bp->free != ENDFREE) |
188 |
> |
for (j = bp->free; odS.nextfree(j) != ENDFREE; |
189 |
> |
j = odS.nextfree(j)) |
190 |
> |
if (odS.nextfree(j) == i) { |
191 |
> |
odS.nextfree(j) = |
192 |
> |
odS.nextfree(i); |
193 |
> |
bp->nused++; |
194 |
> |
goto gotit; |
195 |
> |
} |
196 |
> |
if (prox >= 0.999*odS.closeness(i)) |
197 |
> |
return(-1); /* previous sample is fine */ |
198 |
> |
goto gotit; |
199 |
> |
} |
200 |
> |
if (bp->free != ENDFREE) { /* allocate from free list */ |
201 |
|
i = bp->free; |
202 |
|
bp->free = odS.nextfree(i); |
203 |
|
bp->nused++; |
204 |
< |
return(i); |
204 |
> |
goto gotit; |
205 |
|
} |
206 |
|
DCHECK(bp->nsamp<=0, CONSISTENCY, |
207 |
|
"no available samples in odAllocBlockSamp"); |
213 |
|
for (i = bp->nsamp; i--; ) /* figure out which are worse */ |
214 |
|
si[i] = bp->first + i; |
215 |
|
qsort((char *)si, bp->nsamp, sizeof(int), sampcmp); |
216 |
< |
i = bp->nsamp*SFREEFRAC + .5; /* put them in a list */ |
216 |
> |
i = bp->nsamp*SFREEFRAC + .5; /* put them into free list */ |
217 |
> |
if (i >= bp->nsamp) i = bp->nsamp-1; /* paranoia */ |
218 |
> |
bp->pthresh = odS.closeness(si[i]); /* new proximity threshold */ |
219 |
|
while (--i > 0) { |
220 |
|
odS.nextfree(si[i]) = bp->free; |
221 |
|
bp->free = si[i]; |
222 |
|
bp->nused--; |
223 |
|
} |
224 |
< |
return(si[0]); /* return first free sample */ |
224 |
> |
i = si[0]; /* use worst sample */ |
225 |
> |
gotit: |
226 |
> |
odS.ip[i][0] = hh; |
227 |
> |
odS.ip[i][1] = vh; |
228 |
> |
odS.closeness(i) = prox; |
229 |
> |
return(i); |
230 |
|
} |
231 |
|
|
232 |
|
|
235 |
|
FVECT d, p; |
236 |
|
{ |
237 |
|
FVECT disp; |
238 |
< |
double d0, d1, h, v; |
238 |
> |
double d0, d1, h, v, prox; |
239 |
|
register VIEW *vw; |
240 |
< |
int hl, vl, hh, vh; |
240 |
> |
int hh, vh; |
241 |
|
int res[2]; |
242 |
|
register int i, id; |
243 |
|
|
272 |
|
(1.+DEPTHEPS)*d0 < d1)) |
273 |
|
continue; /* occlusion error */ |
274 |
|
} |
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; |
275 |
|
if (p != NULL) { /* compute closeness (sin^2) */ |
276 |
|
d1 = DOT(disp, d); |
277 |
< |
odS.closeness(id) = 1. - d1*d1/DOT(disp,disp); |
277 |
> |
prox = 1. - d1*d1/DOT(disp,disp); |
278 |
|
} else |
279 |
< |
odS.closeness(id) = 0.; |
279 |
> |
prox = 0.; |
280 |
> |
/* allocate sample */ |
281 |
> |
id = odAllocBlockSamp(i, hh, vh, prox); |
282 |
> |
if (id < 0) |
283 |
> |
continue; /* not good enough */ |
284 |
|
/* convert color */ |
285 |
|
tmCvColrs(&odS.brt[id], odS.chr[id], c, 1); |
286 |
|
if (imm_mode | needmapping) /* if immediate mode */ |
292 |
|
} |
293 |
|
|
294 |
|
|
295 |
< |
odRemap() /* recompute tone mapping */ |
295 |
> |
odRemap(newhist) /* recompute tone mapping */ |
296 |
> |
int newhist; |
297 |
|
{ |
298 |
|
needmapping |= NEWMAP|NEWRGB; |
299 |
+ |
if (newhist) |
300 |
+ |
needmapping |= NEWHIST; |
301 |
|
} |
302 |
|
|
303 |
|
|
341 |
|
int i, j, hmin, hmax, vmin, vmax; |
342 |
|
register int k, l; |
343 |
|
|
306 |
– |
DCHECK(vn<0 | vn>=odNViews, CONSISTENCY, |
307 |
– |
"bad view number in odDepthMap"); |
344 |
|
if (dm == NULL) { /* free edge map */ |
345 |
+ |
if (vn<0 | vn>=odNViews) |
346 |
+ |
return; /* too late -- they're gone! */ |
347 |
|
if (odView[vn].emap != NULL) |
348 |
|
free((char *)odView[vn].emap); |
349 |
|
odView[vn].emap = NULL; |
350 |
|
odView[vn].dmap = NULL; |
351 |
|
return; |
352 |
|
} |
353 |
+ |
DCHECK(vn<0 | vn>=odNViews, CONSISTENCY, |
354 |
+ |
"bad view number in odDepthMap"); |
355 |
|
odView[vn].dmap = dm; /* initialize edge map */ |
356 |
|
if (odView[vn].emap == NULL) { |
357 |
|
odView[vn].emap = (int4 *)malloc( |
418 |
|
/* need to do some tone mapping? */ |
419 |
|
if (needmapping & NEWRGB) { |
420 |
|
if (needmapping & NEWMAP) { |
421 |
< |
tmClearHisto(); |
421 |
> |
if (needmapping & NEWHIST) |
422 |
> |
tmClearHisto(); |
423 |
|
if (tmAddHisto(odS.brt,odS.nsamp,1) != TM_E_OK) |
424 |
|
return; |
425 |
|
if (tmComputeMapping(0.,0.,0.) != TM_E_OK) |
433 |
|
needmapping = 0; /* reset flag */ |
434 |
|
} |
435 |
|
/* draw each block in view */ |
436 |
< |
for (i = odView[vn].hlow; i--; ) |
437 |
< |
for (j = odView[vn].vlow; j--; ) { |
436 |
> |
for (j = odView[vn].vlow; j--; ) |
437 |
> |
for (i = 0; i < odView[vn].hlow; i++) { |
438 |
|
/* get block */ |
439 |
|
bp = odView[vn].bmap + j*odView[vn].hlow + i; |
440 |
|
/* do quick, conservative flag check */ |