Path: utzoo!mnetor!uunet!husc6!rutgers!labrea!rocky!ali From: ali@rocky.STANFORD.EDU (Ali Ozer) Newsgroups: comp.sys.mac Subject: Re: image rotation Message-ID: <828@rocky.STANFORD.EDU> Date: 12 Dec 87 00:40:43 GMT References: <600@analog.UUCP> <22140@ucbvax.BERKELEY.EDU> Reply-To: ali@rocky.UUCP (Ali Ozer) Organization: Stanford University Computer Science Department Lines: 161 Keywords: CopyBits rotation bitmap MacTutor blitter In article ... oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster) writes: >In article <600@analog.UUCP> kim@analog.UUCP (Kim Helliwell) writes: >>I am interested in any information anyone may have on algorithms for >>rotating bitmaps by +/- 90 degrees. >The scheme I use is: divide the picture to be rotated into 8x8 pixel >blocks. (Pad the edges to make them come out exactly on block boundaries.) I've included (at the end of this article) the 8x8 rotation code, in assembly, written by Tomas Rokicki (rokicki@sushi.stanford.edu). It's lengthy, mainly because the loops are unrolled. It was written for the Amiga, but it's general enough such that with a little attention to how the parameters come in it should work on the Mac. And it's fast --- I use it to rotate 64x64 4 bit plane images. (But it's a CPU hog...) Also, when doing the rotation, no matter how large the bitmap you're rotating is, you only need ONE 8x8 temporary. Then you can do the rotation in the source area itself. Ali Ozer, ali@rocky.stanford.edu -------------------------------- /* Rotation code from Tomas Rokicki. ** If you use it, please leave the author's name intact! */ /* * This code flips an 8 x 8 rectangle to the right 90 degrees. * Note that the blitter could be up to 4 times faster (according * to my preliminary calculations), but it would probably also be * more complex, and this should be plenty fast. Also, for small * rectangles like 16 x 16, this will certainly be faster. */ /* * This subroutine takes four arguments, two for the source and * two for the destination. There is a pointer to the first byte * to be flipped, and the value to be added to the address for * each subsequent byte. */ flip(sp, sw, dp, dw) unsigned char *sp, *dp ; int sw, dw ; { /* 8(a5), 14(a5), 12(a5), 18(a5) */ #asm ; ; This subroutine actually flips the eight bytes in the lower byte ; of d0-d7, and sticks the results in the upper bytes of d0-d7, ; rotating their previous contents down. Don't let the length of ; it scare you; you might be able to discern a pattern in the ; instructions. It's really quite simple. ; movem.w reglist,-(sp) move.l 8(a5),a0 move.w 12(a5),a1 move.b (a0),d0 add.w a1,a0 move.b (a0),d1 add.w a1,a0 move.b (a0),d2 add.w a1,a0 move.b (a0),d3 add.w a1,a0 move.b (a0),d4 add.w a1,a0 move.b (a0),d5 add.w a1,a0 move.b (a0),d6 add.w a1,a0 move.b (a0),d7 roxr.b #1,d0 roxr.w #1,d0 roxr.w #1,d1 roxr.w #1,d0 roxr.w #1,d2 roxr.w #1,d0 roxr.w #1,d3 roxr.w #1,d0 roxr.w #1,d4 roxr.w #1,d0 roxr.w #1,d5 roxr.w #1,d0 roxr.w #1,d6 roxr.w #1,d0 roxr.w #1,d7 roxl.w #8,d0 roxr.b #1,d1 roxr.w #1,d1 roxr.w #1,d2 roxr.w #1,d1 roxr.w #1,d3 roxr.w #1,d1 roxr.w #1,d4 roxr.w #1,d1 roxr.w #1,d5 roxr.w #1,d1 roxr.w #1,d6 roxr.w #1,d1 roxr.w #1,d7 roxl.w #8,d1 roxr.b #1,d2 roxr.w #1,d2 roxr.w #1,d3 roxr.w #1,d2 roxr.w #1,d4 roxr.w #1,d2 roxr.w #1,d5 roxr.w #1,d2 roxr.w #1,d6 roxr.w #1,d2 roxr.w #1,d7 roxl.w #8,d2 roxr.b #1,d3 roxr.w #1,d3 roxr.w #1,d4 roxr.w #1,d3 roxr.w #1,d5 roxr.w #1,d3 roxr.w #1,d6 roxr.w #1,d3 roxr.w #1,d7 roxl.w #8,d3 roxr.b #1,d4 roxr.w #1,d4 roxr.w #1,d5 roxr.w #1,d4 roxr.w #1,d6 roxr.w #1,d4 roxr.w #1,d7 roxl.w #8,d4 roxr.b #1,d5 roxr.w #1,d5 roxr.w #1,d6 roxr.w #1,d5 roxr.w #1,d7 roxl.w #8,d5 roxr.b #1,d6 roxr.w #1,d6 roxr.w #1,d7 roxl.w #8,d6 roxr.b #1,d7 roxl.w #8,d7 move.l 14(a5),a0 move.w 18(a5),a1 move.b d7,(a0) add.w a1,a0 move.b d6,(a0) add.w a1,a0 move.b d5,(a0) add.w a1,a0 move.b d4,(a0) add.w a1,a0 move.b d3,(a0) add.w a1,a0 move.b d2,(a0) add.w a1,a0 move.b d1,(a0) add.w a1,a0 move.b d0,(a0) movem.w (sp)+,reglist reglist reg d0/d1/d2/d3/d4/d5/d6/d7/a0/a1 #endasm }