[futurebasic] Re: [FB] Eradication of Slothness Request (Rotation)

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : January 2001 : Group Archive : Group : All Groups

From: Jay Reeve <jktr@...>
Date: Sun, 7 Jan 01 17:41:08 -0600
>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