9 |
|
* Created by Greg Ward on 07/11/2024. |
10 |
|
*/ |
11 |
|
|
12 |
+ |
#define DEBUG 1 // XXX temporary! |
13 |
+ |
|
14 |
|
#include <ctype.h> |
15 |
|
#include "platform.h" |
16 |
|
#include "RpictSimulManager.h" |
198 |
|
bool |
199 |
|
RpictSimulManager::ComputePixel(int x, int y) |
200 |
|
{ |
201 |
+ |
DCHECK(doneMap.OffBitMap(x,y), |
202 |
+ |
CONSISTENCY, "illegal pixel index in ComputPixel()"); |
203 |
|
int i; |
204 |
|
FVECT rodir[2]; |
205 |
|
double hpos = (x+pixjitter())/TWidth(); |
236 |
|
|
237 |
|
// Check if neighbor differences are below pixel sampling threshold |
238 |
|
bool |
239 |
< |
RpictSimulManager::BelowSampThresh(int x, int y, const int noff[4][2]) const |
239 |
> |
RpictSimulManager::BelowSampThresh(const int x, const int y, const int noff[4][2]) const |
240 |
|
{ |
241 |
|
SCOLOR pval[4]; |
242 |
|
float dist[4]; |
243 |
|
int i, j; |
244 |
|
|
245 |
|
for (i = 4; i--; ) { // get pixels from tile store |
246 |
< |
int px = x + noff[i][0]; |
247 |
< |
int py = y + noff[i][1]; |
246 |
> |
const int px = x + noff[i][0]; |
247 |
> |
const int py = y + noff[i][1]; |
248 |
|
if (!doneMap.Check(px, py) || |
249 |
|
!pacc.GetPixel(px, py, pval[i], &dist[i])) |
250 |
|
return false; |
251 |
|
} |
252 |
< |
const bool spectr = (pacc.NC() > 3); |
253 |
< |
for (i = 4; --i; ) // do pairwise comparisons |
254 |
< |
for (j = i; j--; ) { |
255 |
< |
if (pacc.DepthType() && |
252 |
< |
(dist[i] - dist[j] > maxdiff*dist[j]) | |
252 |
> |
// do pairwise comparisons |
253 |
> |
for (i = (pacc.DepthType() != RDTnone)*4; --i > 0; ) |
254 |
> |
for (j = i; j--; ) |
255 |
> |
if ((dist[i] - dist[j] > maxdiff*dist[j]) | |
256 |
|
(dist[j] - dist[i] > maxdiff*dist[i])) |
257 |
|
return false; |
258 |
< |
if (spectr ? sbigsdiff(pval[i], pval[j], maxdiff) : |
259 |
< |
bigdiff(pval[i], pval[j], maxdiff)) |
258 |
> |
if (pacc.NC() > 3) { |
259 |
> |
for (i = 4; --i; ) |
260 |
> |
for (j = i; j--; ) |
261 |
> |
if (sbigsdiff(pval[i], pval[j], maxdiff)) |
262 |
|
return false; |
263 |
< |
} |
264 |
< |
return true; // linear interpolation OK |
263 |
> |
} else { |
264 |
> |
for (i = 4; --i; ) |
265 |
> |
for (j = i; j--; ) |
266 |
> |
if (bigdiff(pval[i], pval[j], maxdiff)) |
267 |
> |
return false; |
268 |
> |
} |
269 |
> |
return true; |
270 |
|
} |
271 |
|
|
272 |
|
// Fill an interior square patch with interpolated values |
277 |
|
float dist[4]; |
278 |
|
int i, j; |
279 |
|
// assumes 4 corners are valid! |
280 |
< |
for (i = 4; i--; ) |
280 |
> |
for (i = 4; i--; ) { |
281 |
> |
DCHECK(!doneMap.Check(x+noff[i][0], y+noff[i][1]), |
282 |
> |
CONSISTENCY, "inclusion of bad pixel in FillSquare()"); |
283 |
|
pacc.GetPixel(x+noff[i][0], y+noff[i][1], pval[i], &dist[i]); |
284 |
< |
|
284 |
> |
} |
285 |
|
i = abs(noff[1][0]-noff[0][0]); |
286 |
|
j = abs(noff[1][1]-noff[0][1]); // i==j for diamond fill |
287 |
|
const int slen = (i > j) ? i : j; |
390 |
|
SetQuincunx(&sampMap, noff, 1<<sp2, layer&1, x0, y0); |
391 |
|
sampMap -= doneSamples; // avoid resampling pixels |
392 |
|
// Are we into adaptive sampling realm? |
393 |
< |
if (noff[0][0]*noff[0][0] + noff[0][1]*noff[0][1] < 4*psample*psample) { |
393 |
> |
if (noff[0][0]*noff[0][0] + noff[0][1]*noff[0][1] < psample*psample) { |
394 |
|
if (FlushQueue() < 0) // need results to check thresholds |
395 |
|
return false; |
396 |
|
ABitMap2 fillMap = sampMap; |
401 |
|
const ABitMap2 origSampMap = sampMap; |
402 |
|
for (x = 4; x--; ) { |
403 |
|
ABitMap2 stamp = origSampMap; |
404 |
< |
stamp.Shift(noff[x][0], noff[x][1]); |
404 |
> |
stamp.Shift(noff[x][0] + noff[(x+1)&3][0], |
405 |
> |
noff[x][1] + noff[(x+1)&3][1]); |
406 |
|
sampMap |= stamp; |
407 |
|
} // ...but don't resample what's done |
408 |
|
sampMap -= doneSamples; |
409 |
|
// interpolate smooth regions |
410 |
|
fillMap -= sampMap; |
411 |
+ |
fillMap -= doneSamples; |
412 |
|
for (x = y = 0; fillMap.Find(&x, &y); x++) |
413 |
|
FillSquare(x, y, noff); |
414 |
|
doneSamples |= doneMap; |
423 |
|
return false; |
424 |
|
x = y = 0; |
425 |
|
if (doneMap.Find(&x, &y, false)) { |
426 |
< |
sprintf(errmsg, "missed %ld tile pixels, e.g. (%d,%d)", |
427 |
< |
(long)doneMap.Width()*doneMap.Height() - |
428 |
< |
doneMap.SumTotal(), x, y); |
426 |
> |
sprintf(errmsg, "missed %.4f%% of pixels in rectangle\n", |
427 |
> |
100. - 100.*doneMap.SumTotal() / |
428 |
> |
doneMap.Width() / doneMap.Height()); |
429 |
|
error(WARNING, errmsg); |
430 |
|
} |
431 |
|
if ((prCB != NULL) & (barPix == NULL)) |
452 |
|
else if (prims) |
453 |
|
pacc.SetColorSpace(RDTrgb, prims); |
454 |
|
|
455 |
< |
int x0=0, y0=0; |
442 |
< |
if (tile) { |
443 |
< |
x0 = -tile[0]*TWidth(); |
444 |
< |
y0 = -tile[1]*THeight(); |
445 |
< |
} |
446 |
< |
return SetTile(tile) && RenderRect(x0, y0); |
455 |
> |
return SetTile(tile) && RenderRect(); |
456 |
|
} |
457 |
|
|
458 |
|
// Same but store as common-exponent COLR or SCOLR |
469 |
|
else if (prims) |
470 |
|
pacc.SetColorSpace(RDTrgbe, prims); |
471 |
|
|
472 |
< |
int x0=0, y0=0; |
464 |
< |
if (tile) { |
465 |
< |
x0 = -tile[0]*TWidth(); |
466 |
< |
y0 = -tile[1]*THeight(); |
467 |
< |
} |
468 |
< |
return SetTile(tile) && RenderRect(x0, y0); |
472 |
> |
return SetTile(tile) && RenderRect(); |
473 |
|
} |
474 |
|
|
475 |
|
// Same but also use 16-bit encoded depth buffer |
486 |
|
else if (prims) |
487 |
|
pacc.SetColorSpace(RDTrgbe, prims); |
488 |
|
|
489 |
< |
int x0=0, y0=0; |
486 |
< |
if (tile) { |
487 |
< |
x0 = -tile[0]*TWidth(); |
488 |
< |
y0 = -tile[1]*THeight(); |
489 |
< |
} |
490 |
< |
return SetTile(tile) && RenderRect(x0, y0); |
489 |
> |
return SetTile(tile) && RenderRect(); |
490 |
|
} |
491 |
|
|
492 |
|
// Back to float color with 16-bit depth |
503 |
|
else if (prims) |
504 |
|
pacc.SetColorSpace(RDTrgb, prims); |
505 |
|
|
506 |
< |
int x0=0, y0=0; |
508 |
< |
if (tile) { |
509 |
< |
x0 = -tile[0]*TWidth(); |
510 |
< |
y0 = -tile[1]*THeight(); |
511 |
< |
} |
512 |
< |
return SetTile(tile) && RenderRect(x0, y0); |
506 |
> |
return SetTile(tile) && RenderRect(); |
507 |
|
} |
508 |
|
|
509 |
|
// Allocate a new render bar |
555 |
|
sizeof(COLORV)*NC*TWidth()*(THeight()-v)); |
556 |
|
memmove(barDepth, barDepth + TWidth()*v, |
557 |
|
sizeof(float)*TWidth()*(THeight()-v)); |
558 |
< |
if (ytop < THeight()) { // mark what we won't do as finished |
558 |
> |
if (ytop < THeight()) // mark what we won't do as finished |
559 |
|
doneMap.ClearRect(0, 0, TWidth(), THeight()-ytop, true); |
566 |
– |
memset(barPix, 0, sizeof(COLORV)*NC*TWidth()*(THeight()-ytop)); |
567 |
– |
memset(barDepth, 0, sizeof(float)*TWidth()*(THeight()-ytop)); |
568 |
– |
} |
560 |
|
return true; |
561 |
|
} |
562 |
|
|
579 |
|
cropview(&ptvw, 0., double(ytop-THeight())/GetHeight(), |
580 |
|
1., double(ytop)/GetHeight())) |
581 |
|
ptvw.type = 0; |
582 |
< |
// set up spectral sampling |
582 |
> |
// update spectral sampling |
583 |
|
if (setspectrsamp(CNDX, WLPART) <= 0) { |
584 |
|
error(USER, "unsupported spectral sampling"); |
585 |
|
return false; |
666 |
|
{ |
667 |
|
pdfp[0] = pdfp[1] = NULL; |
668 |
|
if (!RDTcolorT(dt)) |
669 |
< |
error(INTERNAL, "botched color output type in NewOutput()"); |
669 |
> |
error(INTERNAL, "missing color output type in NewOutput()"); |
670 |
|
if (NCSAMP == 3) { |
671 |
|
if (RDTcolorT(dt) == RDTscolr) |
672 |
|
dt = RDTnewCT(dt, prims==xyzprims ? RDTxyze : RDTrgbe); |
688 |
|
sprintf(errmsg, "cannot open picture file '%s'", pfname); |
689 |
|
error(SYSTEM, errmsg); |
690 |
|
} |
691 |
< |
return RDTnone; // expected in parallel sequence |
691 |
> |
return RDTnone; // may be expected in sequence run |
692 |
|
} |
693 |
|
if (fd == 1) |
694 |
|
pdfp[0] = stdout; |
743 |
|
fputendian(pdfp[0]); |
744 |
|
fputformat("float", pdfp[0]); |
745 |
|
break; |
746 |
< |
default:; |
746 |
> |
default:; // pro forma - caught this above |
747 |
|
} |
748 |
< |
fputc('\n', pdfp[0]); // flush picture header + resolution |
748 |
> |
fputc('\n', pdfp[0]); // flush picture header |
749 |
|
if (fflush(pdfp[0]) == EOF) { |
750 |
|
sprintf(errmsg, "cannot write header to picture '%s'", pfname); |
751 |
|
error(SYSTEM, errmsg); |
805 |
|
if (RDTdepthT(dt) == RDTdshort) |
806 |
|
fprtresolu(GetWidth(), GetHeight(), pdfp[1]); |
807 |
|
|
808 |
< |
const int bheight = (psample > 1) ? int(4*psample+.99) : 8; |
808 |
> |
const int bheight = (psample > 1) ? int(8*psample+.99) : 16; |
809 |
|
const int vstep = bheight >> (psample > 1); |
810 |
|
|
811 |
|
NewBar(bheight); // render frame if we can |
1168 |
|
fclose(pdfp[0]); fclose(pdfp[1]); |
1169 |
|
return RDTnone; |
1170 |
|
} |
1171 |
< |
int bheight = (psample > 1) ? int(4*psample+.99) : 8; |
1171 |
> |
int bheight = (psample > 1) ? int(8*psample+.99) : 16; |
1172 |
|
if (bheight > GetHeight()-doneScans) |
1173 |
|
bheight = GetHeight()-doneScans; |
1174 |
|
int vstep = bheight >> (psample > 1); |