Thread: Image rotation (Bitwise operations?)

  1. #1
    Registered User
    Join Date
    May 2009
    Location
    Look in your attic, I am there...
    Posts
    92

    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.

    Bit-shifting instead of typecasting?
    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,
                                               Surface->format->Rmask,
                                               Surface->format->Gmask,
                                               Surface->format->Bmask,
                                               Surface->format->Amask)) == NULL) {
            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. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    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.
    Last edited by brewbuck; 05-29-2009 at 12:47 PM.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem reading tiff image files?
    By compz in forum C++ Programming
    Replies: 9
    Last Post: 10-30-2009, 04:17 AM
  2. bitwise operations with double
    By henry_kay in forum C Programming
    Replies: 2
    Last Post: 10-03-2007, 04:57 AM
  3. Image rotation - doesn't always work
    By ulillillia in forum C Programming
    Replies: 12
    Last Post: 05-03-2007, 12:46 PM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. Image rotation using intel image processing
    By sunis in forum Windows Programming
    Replies: 1
    Last Post: 11-18-2002, 02:40 AM

Tags for this Thread