rendered paste body// methods to extract ready filtered pixels from bitmap in clamped or repeated style
procedure getPixel32_bilinear_clamp(aDib : TosaCustomDIB; x, y : Single; var result : TosaRGB32);
var
f0, f1, f2, f3 : Single;
ix, iy, iy2 : Integer;
fx, fy : Single;
sc1, sc2 : posaScanline32;
rc : TosaRGB32;
c1, c2, c3, c4 : TosaRGB32;
begin
// extract fractional and int
fx := Frac(y);
fy := Frac(x);
ix := Trunc(x);
iy := Trunc(y);
// calculate weights
f0 := (1-fx) * (1-fy);
f1 := (1-fx) * fy;
f2 := fx * fy;
f3 := fx * (1-fy);
// default "background" color
rc := oclWhite;
if ix >= aDib.Width - 1 then
begin
if ix < aDib.Width then
begin
// pixel is on / very near egde
iy2 := iy+1;
Wrap(iy, aDib.Height-1);
Wrap(iy2, aDib.Height-1);
sc1 := aDib.Scanline[iy];
sc2 := aDib.Scanline[iy2];
result.r := Round(f0 * sc1[ix].r + f1 * rc.r + f2 * rc.r + f3 * sc2[ix].r);
result.g := Round(f0 * sc1[ix].g + f1 * rc.g + f2 * rc.g + f3 * sc2[ix].g);
result.b := Round(f0 * sc1[ix].b + f1 * rc.b + f2 * rc.b + f3 * sc2[ix].b);
exit;
end
else
begin
// pixel is outside egde
result := oclWhite;
exit;
end;
end
else if ix < 0 then
begin
if ix+1 = 0 then
begin
iy2 := iy+1;
Wrap(iy, aDib.Height-1);
Wrap(iy2, aDib.Height-1);
sc1 := aDib.Scanline[iy];
sc2 := aDib.Scanline[iy2];
rc := oclWhite;
result.r := Round(f0 * sc1[ix+1].r + f1 * rc.r + f2 * rc.r + f3 * sc2[ix+1].r);
result.g := Round(f0 * sc1[ix+1].g + f1 * rc.g + f2 * rc.g + f3 * sc2[ix+1].g);
result.b := Round(f0 * sc1[ix+1].b + f1 * rc.b + f2 * rc.b + f3 * sc2[ix+1].b);
exit;
end;
result := oclWhite;
exit;
end
else if iy > aDib.Height - 2 then
begin
if iy < aDib.Height then
begin
sc1 := aDib.Scanline[iy];
result.r := Round(f0 * sc1[ix].r + f1 * sc1[ix+1].r + f2 * rc.r + f3 * rc.r);
result.g := Round(f0 * sc1[ix].g + f1 * sc1[ix+1].g + f2 * rc.g + f3 * rc.g);
result.b := Round(f0 * sc1[ix].b + f1 * sc1[ix+1].b + f2 * rc.b + f3 * rc.b);
exit;
end;
result := oclWhite;
exit;
end
else if iy < 0 then
begin
if iy + 1 = 0 then
begin
rc := oclWhite;
sc1 := aDib.Scanline[0];
c1 := rc;
c2 := rc;
c3 := sc1[ix+1];
c4 := sc1[ix];
result.r := Round(f0 * c1.r + f1 * c2.r + f2 * c3.r + f3 * c4.r);
result.g := Round(f0 * c1.g + f1 * c2.g + f2 * c3.g + f3 * c4.g);
result.b := Round(f0 * c1.b + f1 * c2.b + f2 * c3.b + f3 * c4.b);
exit;
end;
result := oclWhite;
exit;
end;
// wrap iy2 based on iy's relation to height
if iy + 1 > aDib.Height - 1 then iy2 := 0 else iy2 := iy + 1;
// setup scanlinepointers
sc1 := aDib.Scanline[iy];
sc2 := aDib.Scanline[iy2];
// calculated interpolated
result.r := Round(f0 * sc1[ix].r + f1 * sc1[ix+1].r + f2 * sc2[ix+1].r + f3 * sc2[ix].r);
result.g := Round(f0 * sc1[ix].g + f1 * sc1[ix+1].g + f2 * sc2[ix+1].g + f3 * sc2[ix].g);
result.b := Round(f0 * sc1[ix].b + f1 * sc1[ix+1].b + f2 * sc2[ix+1].b + f3 * sc2[ix].b);
end;
procedure getPixel32_bilinear_wrap(aDib : TosaCustomDIB; x, y : Single; var result : TosaRGB32);
var
f0, f1, f2, f3 : Single;
ix, iy : Integer;
ix2, iy2 : Integer;
fx, fy : Single;
sc1, sc2 : posaScanline32;
begin
// THIS METHOD HAS BEEN OPTMIZED FOR AND THEREFOR
// VARIABLES MAY NOT CONTAIN THE VALUE INTENDED TO
// AT ANY TIME. SEPARATION OF BLOCKS MEANS A LOT
// in the wrap x/y section temp was replaced with the intvar iy
// wrap X coordinates
iy := aDib.Width-1;
if x > iy then
while x > iy do
x := x - iy
else if x < 0 then
while x < 0 do
x := x + iy;
// wrap Y coordinates
iy := aDib.Height-1;
if y > iy then
while y > iy do
y := y - iy
else if y < 0 then
while y < 0 do
y := y + iy;
// extract fractional and int
fx := Frac(y);
fy := Frac(x);
ix := trunc(x);
iy := trunc(y);
// wrap the interpolator contribotur coordinates
// OPT : Tried to optmize for branch prediction failure
iy2 := iy+1;
if iy+1 > aDib.Height - 1 then iy2 := 0;
ix2 := ix+1;
if ix+1 > aDib.Width - 1 then ix2 := 0;
// calulate weights
f0 := (1-fx) * (1-fy);
f3 := fx * (1-fy);
f1 := (1-fx) * fy;
f2 := fx * fy;
// setup scanlinepointers
sc1 := aDib.Scanline[iy];
sc2 := aDib.Scanline[iy2];
// calculated interpolated pixelsums
result.r := Round(f0 * sc1[ix].r + f1 * sc1[ix2].r + f2 * sc2[ix2].r + f3 * sc2[ix].r);
result.g := Round(f0 * sc1[ix].g + f1 * sc1[ix2].g + f2 * sc2[ix2].g + f3 * sc2[ix].g);
result.b := Round(f0 * sc1[ix].b + f1 * sc1[ix2].b + f2 * sc2[ix2].b + f3 * sc2[ix].b);
end;