// 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;