Difference between revisions of "Vertically invert a surface in SDL"
Jump to navigation
Jump to search
Line 1: | Line 1: | ||
− | This code flips an <code>SDL_Surface</code> | + | This code vertically flips the content of an <code>SDL_Surface</code>. It operates by first copying out the first row of the image, then overwriting the first with the last, then the last with the second, the second with the next to last, the next to last with the third, and so on. After this shuffling has been completed, the top half of the image is already correct, and the bottom half begins one row too late. At this point, a single <code>memmove</code> corrects that shift, and the row copied out at the beginning of the process is put back. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<nowiki> | <nowiki> |
Revision as of 03:36, 1 June 2005
This code vertically flips the content of an SDL_Surface
. It operates by first copying out the first row of the image, then overwriting the first with the last, then the last with the second, the second with the next to last, the next to last with the third, and so on. After this shuffling has been completed, the top half of the image is already correct, and the bottom half begins one row too late. At this point, a single memmove
corrects that shift, and the row copied out at the beginning of the process is put back.
#define SDL_LOCKIFMUST(s) (SDL_MUSTLOCK(s) ? SDL_LockSurface(s) : 0) #define SDL_UNLOCKIFMUST(s) { if(SDL_MUSTLOCK(s)) SDL_UnlockSurface(s); } int invert_surface_vertical(SDL_Surface *surface) { Uint8 *t; register Uint8 *a, *b; Uint8 *last; register Uint16 pitch; if( SDL_LOCKIFMUST(surface) < 0 ) return -2; /* do nothing unless at least two lines */ if(surface->h < 2) { SDL_UNLOCKIFMUST(surface); return 0; } /* get a place to store a line */ pitch = surface->pitch; t = (Uint8*)malloc(pitch); if(t == NULL) { SDL_UNLOCKIFMUST(surface); return -2; } /* get first line; it's about to be trampled */ memcpy(t,surface->pixels,pitch); /* now, shuffle the rest so it's almost correct */ a = (Uint8*)surface->pixels; last = a + pitch * (surface->h - 1); b = last; while(a < b) { memcpy(a,b,pitch); a += pitch; memcpy(b,a,pitch); b -= pitch; } /* in this shuffled state, the bottom slice is too far down */ memmove( b, b+pitch, last-b ); /* now we can put back that first row--in the last place */ memcpy(last,t,pitch); /* everything is in the right place; close up. */ free(t); SDL_UNLOCKIFMUST(surface); return 0; }