# Thread: Image rotation (Bitwise operations?)

1. ## Image rotation (Bitwise operations?)

I am writing a 2d game engine out of SDL using the ada binding and found what seems to be useful code for image rotation (similar to rotozoom). The code itself, although well formatted, is completely uncommented. I, as I previously stated, am not well versed in the C language and therefore do not completely comprehend the necessity, if existent, of the bit-wise manipulation.

If someone could explain the reasoning behind this and answer the questions preceding the following snippets, in particular, it would be greatly appreciated.

Code:
```            newx = rotx >> 16;
newy = roty >> 16;```
What pointers, where?!
Code:
` *(Uint16 *) dp = *(Uint16 *) sp;`
I am assuming that bpp retains its assigned value after this IF statement, is this correct?
Code:
```       if((bpp = Surface->format->BytesPerPixel) == 3) {
....```

Code for the whole function...
Code:
```#include "SDL_Bilinear.h"

SDL_Surface *SDL_Rotate(SDL_Surface *Surface, double angle) {
double dcos = cos(angle);
double dsin = sin(angle);

int iWidth  = (int) ceil(ABS(Surface->h * dsin) + ABS(Surface->w * dcos));
int iHeight = (int) ceil(ABS(Surface->h * dcos) + ABS(Surface->w * dsin));

int centre_x = Surface->w << 15;
int centre_y = Surface->h << 15;
int dx = iWidth  >> 1;
int dy = iHeight >> 1;

int rotx, roty, newx, newy, x, y;
int ncos  = (int) (dcos * 65536.0f);
int nsin  = (int) (dsin * 65536.0f);
int srotx = (int) (-dx * ncos + dy * nsin) + centre_x;
int sroty = (int) (-dx * nsin - dy * ncos) + centre_y;

Uint8 *sp, *dp, bpp;
Uint16 destinationGap;
SDL_Surface *destination;

if((bpp = Surface->format->BytesPerPixel) == 3) {
return NULL;
}

if((destination = SDL_CreateRGBSurface(Surface->flags, iWidth, iHeight,
Surface->format->BitsPerPixel,
return NULL;
}

if(SDL_MUSTLOCK(Surface)) {
if(SDL_LockSurface(Surface) < 0) {
return NULL;
}
}
if(SDL_MUSTLOCK(destination)) {
if(SDL_LockSurface(destination) < 0) {
return NULL;
}
}

dp = (Uint8 *) destination->pixels;
destinationGap = destination->pitch - destination->w * bpp;

for(y = 0; y < iHeight; y++) {
rotx = srotx = srotx - nsin;
roty = sroty = sroty + ncos;
for(x = 0; x < iWidth; x++) {
newx = rotx >> 16;
newy = roty >> 16;
if(newx >= 0 && newx < Surface->w && newy >= 0 && newy < Surface->h) {
sp = (Uint8 *) Surface->pixels
+ (((int) newy) * Surface->pitch)
+ (((int) newx) * bpp);

switch(bpp) {
case 1:
*dp = *sp;
break;
case 2:
*(Uint16 *) dp = *(Uint16 *) sp;
break;
case 4:
*(Uint32 *) dp = *(Uint32 *) sp;
break;
default:
break;
}
}
rotx += ncos;
roty += nsin;
dp += bpp;
}
dp += destinationGap;
}

if(SDL_MUSTLOCK(Surface)) {
SDL_UnlockSurface(Surface);
}
if(SDL_MUSTLOCK(destination)) {
SDL_UnlockSurface(destination);
}

return destination;
}```
Thanks in advance (for scrolling at least)!

2. Looks like a fairly simple algorithm. The idea is to step across the source image at the given angle (determined by nsin and ncos), copying pixels to the destination. The bit shifting is used because the coordinates are being manipulated in 16.16 fixed point format. This avoids the need to keep track of an error term for precise Bresenham stepping, although at the expense of a tiny bit of accuracy.

EDIT: Come to think of it, precise, rational Bresenham stepping might involve enormous values in the ratio (since the sin/cos of an arbitrary angle won't necessarily be exactly representable as the ratio of two SMALL integers), which could lead to overflow. Fixed point is probably the best choice here.