>Anyway, the Bicubic anti-aliasing is dreadfully slow, since you are doing >3 operations per pixel , for the R G and B , for 16 pixels at a time, PER >pixel rotated. I integrated some part of it into the ArbitraryBicubic FN >to avoid FN call overhead, but it didn't help much. > Robert, I tried to do an integer implementation of your FN CubicBSpline(). I have no way to test it, and may have screwed up the math a little, but I'm guessing if you can work out any bugs I introduced, it will be significantly faster and plenty accurate for what you are doing. I used a factor of 1024 (1<<10) for calculations in FN CubicBSpline(). Let me know if what I did is unclear, or if you run into problems. 0"0 =J= a y " LOCAL FN CubicBSpline(xx as double) DIM as long x,y, y2, y3, result x = xx * 1024 result=0 LONG IF x < 0 y = -x Xelse y = x END IF y2=(y>>10)*y y3=(y2>>10)*y Long if y <= 1024 //result = ( 2.0/3.0 + 0.5 * y3 - y2) result = ( 2048 + 3*y3/2 - 3*y2)/3 Xelse LONG IF y <= 2048 result=(4*y3-2*y2-2*y+8)/6 END IF END IF END FN = result '~' '~BICUBIC Interpolation '~' LOCAL FN ArbitraryBicubic(angle as double) DIM && DIM as double a,b,xsize,ysize DIM as double newfX, newfY DIM as double sinTheta, cosTheta, rads,Xmid, Ymid, DIM as long newIndex,imageval,sum, cubsum DIM @tmpWorld as long, @tmpDevice as long DIM as INT yy,xx,newX,newY,m,n, Xmid, Ymid DIM as int rr,gg,bb DIM tX as int DIM tY as int DIm as int offsetX, offsetY angle = -angle rads = 3.141592/180*angle sinTheta = sin(rads) cosTheta = cos(rads) xsize = gRect.right-gRect.left ysize = gRect.bottom-gRect.top Xmid = .5*xsize Ymid = .5*ysize tX = gRect.right-1 tY = gRect.bottom-1 FOR yy = 0 TO tY FOR xx = 0 TO tX newfX = (xx-Xmid)*cosTheta - (yy-Ymid)*sinTheta +Xmid newX = newfX newfY = (xx-Xmid)*sinTheta + (yy-Ymid)*cosTheta +Ymid newY = newfY LONG IF newX <= tX AND newX >= 0 LONG IF newY <= tY AND newY >= 0 a = newfX-newX b = newfY-newY newIndex = gBaseAddr + (yy * gRowBytes) + (xx*4) a = abs(a) b = Abs(b) sum = 0 FOR m = -1 TO 2 FOR n = -1 TO 2 LONG IF ((newx+m >= 0) AND (newx+m <= xsize-1)) LONG IF ((newy+n >=0) AND (newy+n <= ysize-1)) imageval = gCopyAddr + ((newy+n) * gCopyBytes) + ((newx+m)*4) XElse imageval = gCopyAddr + (newy * gCopyBytes) + (newx*4) END IF XElse imageval = gCopyAddr + ((newy+m) * gCopyBytes) + (newx*4) END IF cubsum = (FN CubicBSpline(-a+m)*FN CubicBSpline(-b+n))>>10 sum = sum + (PEEK(imageval+1))*cubsum Next n NEXT m rr = sum>>10 sum = 0 FOR m = -1 TO 2 FOR n = -1 TO 2 LONG IF ((newx+m >= 0) AND (newx+m <= xsize-1)) LONG IF ((newy+n >=0) AND (newy+n <= ysize-1)) imageval = gCopyAddr + ((newy+n) * gCopyBytes) + ((newx+m)*4) XElse imageval = gCopyAddr + (newy * gCopyBytes) + (newx*4) END IF XElse imageval = gCopyAddr + ((newy+m) * gCopyBytes) + (newx*4) END IF cubsum = (FN CubicBSpline(-a+m)*FN CubicBSpline(-b+n))>>10 sum = sum + (PEEK(imageval+1))*cubsum Next n NEXT m gg = sum>>10 sum = 0 FOR m = -1 TO 2 FOR n = -1 TO 2 LONG IF ((newx+m >= 0) AND (newx+m <= xsize-1)) LONG IF ((newy+n >=0) AND (newy+n <= ysize-1)) imageval = gCopyAddr + ((newy+n) * gCopyBytes) + ((newx+m)*4) XElse imageval = gCopyAddr + (newy * gCopyBytes) + (newx*4) END IF XElse imageval = gCopyAddr + ((newy+m) * gCopyBytes) + (newx*4) END IF cubsum = (FN CubicBSpline(-a+m)*FN CubicBSpline(-b+n))>>10 sum = sum + (PEEK(imageval+1))*cubsum Next n NEXT m bb = sum>>10 Poke newIndex + 1, rr Poke newIndex + 2, gg Poke newIndex + 3, bb END IF END IF NEXT xx NEXT yy END FN