[futurebasic] Re: Slothness & (Rotation)

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

From: Robert Covington <artlythere@...>
Date: Sun, 7 Jan 2001 23:47:33 -0400
Robert Bob Gumptingham wrote:

>But I have been doing further testing. While the FN CubicBSpline does
>result in some overhead, the primary cycle wasters are the checks I am
>doing to make sure I don't go peeking and poking out of bounds. Comment
>these out, and the thing flies along.

Threadsters:

I combined the three channels into a onetime pass, computation wise.. don't know why I didn't see it earlier, probably fixated on the original port's approach before I changed that. Still slow, but now lots faster compared to the original.

Wiped out two out of bounds checks for the G and B channels. 
I think I  can apply an RP special byte computer for the pixel addresses and whack some more slothness.

One cool thing...my bilinear is near identical to Photoshop quality >:)

They seem to be using some half-pixel offset of the pixel centers though.

I will write Adobe for the source code of their bicubic rotation, to save time. Surely they will respond. <g>

But I stomp the venerable Graphic Converter's rotation routines for speed with no discernable difference in quality there either, at least for v3.8.2. Might have changed since.

We talking 18 seconds for GC, 2.5 for me on test image. :)

Wahooo, its another grand graphics day.  Below is altered current incarnation of the slothly bicubic.

Robert Covington

// FB 3

LOCAL FN CubicBSpline#(x as double)
DIM &&
DIM as single y, y2, y3, result

result=0

LONG IF x < 0
y = -x
Xelse
y = x
END IF

y2=y*y
y3=y2*y

Long if y <= 1.0
result = ( 2.0/3.0 + 0.5 * y3 - y2)
Xelse
LONG IF y <= 2.0 
result=1.0/6.0*(2-y)*(2-y)*(2-y)
END IF
END IF

END FN = result


LOCAL FN ArbitraryBicubisaurus(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 double cubsum, sumR,  sumG,  sumB
DIM  as long newIndex,val1, val2, val3, val4,index,imageval
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

FN Make_Progress_Wnd(_bicubic,"")

Cursor _watchCursor

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)

sumR = 0
sumG = 0
sumB = 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)
sumR = sumR + (PEEK(imageval+1))*cubsum
sumG = sumG + (PEEK(imageval+2))*cubsum
sumB = sumB + (PEEK(imageval+3))*cubsum
Next n
NEXT m

rr = INT(sumR)
gg = INT(sumG)
bb = INT(sumB)

Poke newIndex + 1, rr
Poke newIndex + 2, gg
Poke newIndex + 3, bb

END IF
END IF
NEXT xx
FN Update_Progress_Wnd( yy/tY)
NEXT yy

FN Close_Progress_Wnd
Cursor _arrowCursor

END FN