/*
* call-seq:
* flip(horz, vert) -> Surface
*
* Flips the source surface horizontally (if +horz+ is true), vertically
* (if +vert+ is true), or both (if both are true). This operation is
* non-destructive; the original image can be perfectly reconstructed by
* flipping the resultant image again.
*
* This operation does NOT require SDL_gfx.
*
* A similar effect can (supposedly) be achieved by giving X or Y zoom
* factors of -1 to #rotozoom (only if compiled with SDL_gfx 2.0.13 or
* greater). Your mileage may vary.
*/
VALUE rbgm_transform_flip(VALUE self, VALUE vhorz, VALUE vvert)
{
SDL_Surface *surf, *newsurf;
int xaxis, yaxis;
int loopx, loopy;
int pixsize, srcpitch, dstpitch;
Uint8 *srcpix, *dstpix;
xaxis = RTEST(vhorz);
yaxis = RTEST(vvert);
Data_Get_Struct(self,SDL_Surface,surf);
/* Borrowed from Pygame: */
newsurf = newsurf_fromsurf(surf, surf->w, surf->h);
if(!newsurf)
return Qnil;
pixsize = surf->format->BytesPerPixel;
srcpitch = surf->pitch;
dstpitch = newsurf->pitch;
SDL_LockSurface(newsurf);
srcpix = (Uint8*)surf->pixels;
dstpix = (Uint8*)newsurf->pixels;
if(!xaxis)
{
if(!yaxis)
{
for(loopy = 0; loopy < surf->h; ++loopy)
memcpy(dstpix+loopy*dstpitch, srcpix+loopy*srcpitch, surf->w*surf->format->BytesPerPixel);
}
else
{
for(loopy = 0; loopy < surf->h; ++loopy)
memcpy(dstpix+loopy*dstpitch, srcpix+(surf->h-1-loopy)*srcpitch, surf->w*surf->format->BytesPerPixel);
}
}
else /*if (xaxis)*/
{
if(yaxis)
{
switch(surf->format->BytesPerPixel)
{
case 1:
for(loopy = 0; loopy < surf->h; ++loopy) {
Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch);
Uint8* src = ((Uint8*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w - 1;
for(loopx = 0; loopx < surf->w; ++loopx)
*dst++ = *src--;
}break;
case 2:
for(loopy = 0; loopy < surf->h; ++loopy) {
Uint16* dst = (Uint16*)(dstpix+loopy*dstpitch);
Uint16* src = ((Uint16*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w - 1;
for(loopx = 0; loopx < surf->w; ++loopx)
*dst++ = *src--;
}break;
case 4:
for(loopy = 0; loopy < surf->h; ++loopy) {
Uint32* dst = (Uint32*)(dstpix+loopy*dstpitch);
Uint32* src = ((Uint32*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w - 1;
for(loopx = 0; loopx < surf->w; ++loopx)
*dst++ = *src--;
}break;
case 3:
for(loopy = 0; loopy < surf->h; ++loopy) {
Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch);
Uint8* src = ((Uint8*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w*3 - 3;
for(loopx = 0; loopx < surf->w; ++loopx)
{
dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2];
dst += 3;
src -= 3;
}
}break;
}
}
else
{
switch(surf->format->BytesPerPixel)
{
case 1:
for(loopy = 0; loopy < surf->h; ++loopy) {
Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch);
Uint8* src = ((Uint8*)(srcpix+loopy*srcpitch)) + surf->w - 1;
for(loopx = 0; loopx < surf->w; ++loopx)
*dst++ = *src--;
}break;
case 2:
for(loopy = 0; loopy < surf->h; ++loopy) {
Uint16* dst = (Uint16*)(dstpix+loopy*dstpitch);
Uint16* src = ((Uint16*)(srcpix+loopy*srcpitch)) + surf->w - 1;
for(loopx = 0; loopx < surf->w; ++loopx)
*dst++ = *src--;
}break;
case 4:
for(loopy = 0; loopy < surf->h; ++loopy) {
Uint32* dst = (Uint32*)(dstpix+loopy*dstpitch);
Uint32* src = ((Uint32*)(srcpix+loopy*srcpitch)) + surf->w - 1;
for(loopx = 0; loopx < surf->w; ++loopx)
*dst++ = *src--;
}break;
case 3:
for(loopy = 0; loopy < surf->h; ++loopy) {
Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch);
Uint8* src = ((Uint8*)(srcpix+loopy*srcpitch)) + surf->w*3 - 3;
for(loopx = 0; loopx < surf->w; ++loopx)
{
dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2];
dst += 3;
src -= 3;
}
}break;
}
}
}
SDL_UnlockSurface(newsurf);
/* Thanks, Pygame :) */
if(newsurf == NULL)
rb_raise(eSDLError,"Could not flip surface: %s",SDL_GetError());
return Data_Wrap_Struct(cSurface,0,SDL_FreeSurface,newsurf);
}