| 50 |
|
scolor_out(col, primp, rp->rcol); |
| 51 |
|
return SetPixel(x, y, col, zv); |
| 52 |
|
default: |
| 53 |
< |
error(INTERNAL, "missing color space type in SetPixel()"); |
| 53 |
> |
error(INTERNAL, "botched color space type in SetPixel()"); |
| 54 |
|
} |
| 55 |
|
return false; |
| 56 |
|
} |
| 79 |
|
case RDTrgb: |
| 80 |
|
primp = pr ? pr : stdprims; |
| 81 |
|
break; |
| 82 |
< |
default: // RDTscolr | RDTscolor |
| 82 |
> |
case RDTscolr: |
| 83 |
> |
case RDTscolor: |
| 84 |
|
primp = NULL; |
| 85 |
|
break; |
| 86 |
+ |
default: |
| 87 |
+ |
error(INTERNAL, "botched color space type in SetColorSpace()"); |
| 88 |
|
} |
| 89 |
|
dtyp = RDTnewCT(dtyp, cs); |
| 87 |
– |
if (primp) |
| 88 |
– |
xyz2myrgbmat[0][0] = 0; |
| 90 |
|
return true; |
| 91 |
|
} |
| 92 |
|
|
| 139 |
|
RpictSimulManager::RtCall(RAY *r, void *cd) |
| 140 |
|
{ |
| 141 |
|
RpictSimulManager * rsp = (RpictSimulManager *)cd; |
| 142 |
< |
const int ty = r->rno / rsp->TWidth(); |
| 143 |
< |
const int tx = r->rno - (RNUMBER)ty*rsp->TWidth(); |
| 142 |
> |
const int ty = (r->rno-1) / rsp->TWidth(); |
| 143 |
> |
const int tx = r->rno-1 - (RNUMBER)ty*rsp->TWidth(); |
| 144 |
|
|
| 145 |
|
if (ty >= rsp->THeight()) { |
| 146 |
|
error(INTERNAL, "bad pixel calculation position in RtCall()"); |
| 228 |
|
for (i = (dlim > FTINY)*3; i--; ) |
| 229 |
|
rodir[1][i] *= dlim; |
| 230 |
|
|
| 231 |
< |
return EnqueueRay(rodir[0], rodir[1], (RNUMBER)y*TWidth()+x); |
| 231 |
> |
return EnqueueRay(rodir[0], rodir[1], (RNUMBER)y*TWidth()+x+1); |
| 232 |
|
} |
| 233 |
|
|
| 234 |
|
// Check if neighbor differences are below pixel sampling threshold |
| 262 |
|
|
| 263 |
|
// Fill an interior square patch with interpolated values |
| 264 |
|
void |
| 265 |
< |
RpictSimulManager::FillSquare(int x, int y, const int noff[4][2]) |
| 265 |
> |
RpictSimulManager::FillSquare(const int x, const int y, const int noff[4][2]) |
| 266 |
|
{ |
| 267 |
|
SCOLOR pval[4]; |
| 268 |
|
float dist[4]; |
| 272 |
|
pacc.GetPixel(x+noff[i][0], y+noff[i][1], pval[i], &dist[i]); |
| 273 |
|
|
| 274 |
|
i = abs(noff[1][0]-noff[0][0]); |
| 275 |
< |
j = abs(noff[1][1]-noff[0][1]); |
| 276 |
< |
const int slen = i > j ? i : j; |
| 276 |
< |
const double sf = 1./slen; |
| 275 |
> |
j = abs(noff[1][1]-noff[0][1]); // i==j for diamond fill |
| 276 |
> |
const int slen = (i > j) ? i : j; |
| 277 |
|
const bool spectr = (pacc.NC() > 3); |
| 278 |
< |
for (i = 0; i <= slen; i++) { // bilinear interpolant |
| 279 |
< |
const double c1 = i*sf; |
| 280 |
< |
for (j = 0; j <= slen; j++) { |
| 281 |
< |
const double c2 = j*sf; |
| 278 |
> |
for (i = slen+1 + (i==j)*slen; i--; ) { |
| 279 |
> |
const double c1 = (i>slen ? i-slen-.5 : (double)i)/slen; |
| 280 |
> |
for (j = slen + (i<=slen); j--; ) { |
| 281 |
> |
const double c2 = (j + (i>slen)*.5)/slen; |
| 282 |
|
const int px = int(x + (1.-c1)*(1.-c2)*noff[0][0] + |
| 283 |
|
c1*(1.-c2)*noff[1][0] + |
| 284 |
|
(1.-c1)*c2*noff[2][0] + |
| 331 |
|
SetQuincunx(ABitMap2 *bmp2, int noff[4][2], const int spc, const bool odd) |
| 332 |
|
{ |
| 333 |
|
for (int y = 0; y < bmp2->Height(); y += spc>>1) |
| 334 |
< |
for (int x = odd*(spc>>1); x < bmp2->Width(); x += spc) |
| 334 |
> |
for (int x = (odd^(y&1))*(spc>>1); x < bmp2->Width(); x += spc) |
| 335 |
|
bmp2->Set(x, y); |
| 336 |
|
// order neighbors CCW |
| 337 |
|
if (odd) { |
| 359 |
|
int sp2 = ceil(log2((TWidth()>THeight() ? TWidth() : THeight()) - 1.)); |
| 360 |
|
int layer = 0; |
| 361 |
|
int x, y; |
| 362 |
< |
fprintf(stderr, "Rendering %dx%d tile with psample=%d, maxdiff=%.3f ...\n", |
| 363 |
< |
TWidth(), THeight(), psample, maxdiff); |
| 362 |
> |
// fprintf(stderr, "Rendering %dx%d tile with psample=%d, maxdiff=%.3f ...\n", |
| 363 |
> |
// TWidth(), THeight(), psample, maxdiff); |
| 364 |
|
while (sp2 > 0) { |
| 365 |
|
ABitMap2 sampMap(TWidth(), THeight()); |
| 366 |
|
int noff[4][2]; |
| 370 |
|
sampMap -= doneSamples; // avoid resampling pixels |
| 371 |
|
// Are we into adaptive sampling realm? |
| 372 |
|
if (noff[0][0]*noff[0][0] + noff[0][1]*noff[0][1] < psample*psample) { |
| 373 |
< |
if (FlushQueue() < 0) // need results to check threshold |
| 373 |
> |
if (FlushQueue() < 0) // need results to check thresholds |
| 374 |
|
return false; |
| 375 |
|
ABitMap2 fillMap = sampMap; |
| 376 |
|
for (x = y = 0; sampMap.Find(&x, &y); x++) |
| 378 |
|
sampMap.Reset(x, y); |
| 379 |
|
// spread sampling to neighbors... |
| 380 |
|
const ABitMap2 origSampMap = sampMap; |
| 381 |
< |
for (int yoff = -(1<<(sp2-1)); |
| 382 |
< |
yoff <= 1<<(sp2-1); yoff += 1<<sp2) |
| 383 |
< |
for (int xoff = -(1<<(sp2-1)); |
| 384 |
< |
xoff <= 1<<(sp2-1); xoff += 1<<sp2) { |
| 381 |
> |
for (x = 4; x--; ) { |
| 382 |
|
ABitMap2 stamp = origSampMap; |
| 383 |
< |
stamp.Shift(xoff, yoff); |
| 383 |
> |
stamp.Shift(noff[x][0], noff[x][1]); |
| 384 |
|
sampMap |= stamp; |
| 385 |
|
} // ...but don't resample what's done |
| 386 |
|
sampMap -= doneSamples; |
| 394 |
|
if (!ComputePixel(x, y)) |
| 395 |
|
return false; |
| 396 |
|
doneSamples |= sampMap; // samples now done or at least queued |
| 397 |
< |
fprintf(stderr, "Sampled %ld pixels at (sp2,layer)=(%d,%d)\n", |
| 398 |
< |
(long)sampMap.SumTotal(), sp2, layer); |
| 399 |
< |
fprintf(stderr, "\t%ld pixels (%.3f%%) completed (+%ld in process)\n", |
| 400 |
< |
(long)doneMap.SumTotal(), 100.*doneMap.SumTotal()/doneMap.Width()/doneMap.Height(), |
| 401 |
< |
(long)(doneSamples.SumTotal()-doneMap.SumTotal())); |
| 397 |
> |
// fprintf(stderr, "Sampled %ld pixels at (sp2,layer)=(%d,%d)\n", |
| 398 |
> |
// (long)sampMap.SumTotal(), sp2, layer); |
| 399 |
> |
// fprintf(stderr, "\t%ld pixels (%.3f%%) completed (+%ld in process)\n", |
| 400 |
> |
// (long)doneMap.SumTotal(), 100.*doneMap.SumTotal()/doneMap.Width()/doneMap.Height(), |
| 401 |
> |
// (long)(doneSamples.SumTotal()-doneMap.SumTotal())); |
| 402 |
|
sp2 -= layer++ & 1; // next denser sampling |
| 403 |
|
} |
| 404 |
|
if (FlushQueue() < 0) // make sure we got everyone |
| 471 |
|
return SetTile(tile) && RenderRect(); |
| 472 |
|
} |
| 473 |
|
|
| 474 |
+ |
// Back to float color with 16-bit depth |
| 475 |
+ |
bool |
| 476 |
+ |
RpictSimulManager::RenderTile(COLORV *rp, int ystride, short *dp, const int *tile) |
| 477 |
+ |
{ |
| 478 |
+ |
if (!rp | (GetWidth() <= 0) | (GetHeight() <= 0) | !vw.type) |
| 479 |
+ |
return false; |
| 480 |
+ |
if (!ystride) // contiguous rows? |
| 481 |
+ |
ystride = TWidth(); |
| 482 |
+ |
pacc.Init(rp, ystride, dp); |
| 483 |
+ |
if (prims == xyzprims) |
| 484 |
+ |
pacc.SetColorSpace(RDTxyz); |
| 485 |
+ |
else if (prims) |
| 486 |
+ |
pacc.SetColorSpace(RDTrgb, prims); |
| 487 |
+ |
|
| 488 |
+ |
return SetTile(tile) && RenderRect(); |
| 489 |
+ |
} |
| 490 |
+ |
|
| 491 |
|
// Allocate a new render bar |
| 492 |
|
void |
| 493 |
|
RpictSimulManager::NewBar(int ht) |
| 518 |
|
|
| 519 |
|
// Shift render bar area the specified amount down the frame |
| 520 |
|
bool |
| 521 |
< |
RpictSimulManager::LowerBar(int v) |
| 521 |
> |
RpictSimulManager::LowerBar(int v, int ytop) |
| 522 |
|
{ |
| 509 |
– |
if (v <= 0) return !v; |
| 523 |
|
if (!barPix | !barDepth | (v > THeight()) | !tvw.type) |
| 524 |
|
return false; |
| 525 |
< |
tvw.voff -= double(v)/GetHeight(); |
| 526 |
< |
ptvw.voff -= double(v)/GetHeight(); |
| 525 |
> |
if (v <= 0) return !v; |
| 526 |
> |
if ((ytop -= v) <= 0) |
| 527 |
> |
return true; |
| 528 |
> |
tvw.voff -= double(v)/THeight(); |
| 529 |
> |
ptvw.voff -= double(v)/THeight(); |
| 530 |
|
if (v == THeight()) { |
| 531 |
|
doneMap.ClearBitMap(); |
| 532 |
|
return true; |
| 537 |
|
sizeof(COLORV)*NC*TWidth()*(THeight()-v)); |
| 538 |
|
memmove(barDepth, barDepth + TWidth()*v, |
| 539 |
|
sizeof(float)*TWidth()*(THeight()-v)); |
| 540 |
+ |
if (ytop < THeight()) { // mark what we won't do as finished |
| 541 |
+ |
doneMap.ClearRect(0, 0, TWidth(), THeight()-ytop, true); |
| 542 |
+ |
memset(barPix, 0, sizeof(COLORV)*NC*TWidth()*(THeight()-ytop)); |
| 543 |
+ |
memset(barDepth, 0, sizeof(float)*TWidth()*(THeight()-ytop)); |
| 544 |
+ |
} |
| 545 |
|
return true; |
| 546 |
|
} |
| 547 |
|
|
| 583 |
|
} |
| 584 |
|
int lastOut = ytop; // render down frame |
| 585 |
|
while (ytop > 0) { |
| 586 |
< |
if (ytop < THeight()) // mark what we won't do as finished |
| 566 |
< |
doneMap.ClearRect(0, 0, TWidth(), THeight()-ytop, true); |
| 586 |
> |
// fprintf(stderr, "At y=%d, source drawing %s...\n", ytop, parr ? "ON" : "OFF"); |
| 587 |
|
if (prCB) |
| 588 |
|
(*prCB)(100.*(GetHeight()-ytop)/GetHeight()); |
| 589 |
|
if (!RenderRect()) // render this bar |
| 625 |
|
error(SYSTEM, "cannot write SCOLOR output"); |
| 626 |
|
break; |
| 627 |
|
default: |
| 628 |
< |
error(INTERNAL, "missing output color type in RenderBelow()"); |
| 628 |
> |
error(INTERNAL, "botched output color type in RenderBelow()"); |
| 629 |
|
break; |
| 630 |
|
} |
| 631 |
|
bpos += pacc.NC()*TWidth(); |
| 634 |
|
if (fflush(pfp) == EOF || (dfp && fflush(dfp) == EOF)) |
| 635 |
|
error(SYSTEM, "output write error"); |
| 636 |
|
// advance down the frame |
| 637 |
< |
if (lastOut > 0 && !LowerBar(vstep)) |
| 637 |
> |
if (lastOut > 0 && !LowerBar(vstep, ytop)) |
| 638 |
|
return false; |
| 639 |
|
ytop -= vstep; |
| 640 |
|
} |
| 649 |
|
* Render and write a frame to the named file |
| 650 |
|
* Include any header lines set prior to call |
| 651 |
|
* Picture file must not already exist |
| 652 |
< |
* Picture to stdout if pfname==NULL |
| 653 |
< |
* Depth written to a command if dfname[0]=='!' |
| 652 |
> |
* Write pixels to stdout if !pfname |
| 653 |
> |
* Write depth to a command if dfname[0]=='!' |
| 654 |
|
*/ |
| 655 |
|
RenderDataType |
| 656 |
|
RpictSimulManager::RenderFrame(const char *pfname, RenderDataType dt, const char *dfname) |
| 660 |
|
FILE * dfp = NULL; |
| 661 |
|
|
| 662 |
|
if (!RDTcolorT(dt)) |
| 663 |
< |
error(INTERNAL, "missing pixel output type in RenderFrame()"); |
| 663 |
> |
error(INTERNAL, "botched color output type in RenderFrame()"); |
| 664 |
|
if (NCSAMP == 3) { |
| 665 |
|
if (RDTcolorT(dt) == RDTscolr) |
| 666 |
|
dt = RDTnewCT(dt, prims==xyzprims ? RDTxyze : RDTrgbe); |
| 696 |
|
if (frameNo > 0) |
| 697 |
|
fprintf(pfp, "FRAME=%d\n", frameNo); |
| 698 |
|
double pasp = viewaspect(&vw) * GetWidth() / GetHeight(); |
| 699 |
< |
if (!FABSEQ(pasp, 1.0)) |
| 699 |
> |
if ((0.99 > pasp) | (pasp > 1.01)) |
| 700 |
|
fputaspect(pasp, pfp); |
| 701 |
|
fputnow(pfp); |
| 702 |
|
switch (RDTcolorT(dt)) { // set primaries and picture format |