From: giwoong.kim Date: Fri, 24 Aug 2012 12:11:56 +0000 (+0900) Subject: [Title] upgrade SDL_rotozoom X-Git-Tag: TizenStudio_2.0_p2.3~1312^2~81 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=77a3a0ed56315f22f7ec58e483f839865b057228;p=sdk%2Femulator%2Fqemu.git [Title] upgrade SDL_rotozoom [Type] feature [Module] Emulator / sdl [Priority] major [Jira#] [Redmine#] [Problem] [Cause] [Solution] sdl_gfx 2.0.24 [TestCase] --- diff --git a/tizen/src/Makefile.tizen b/tizen/src/Makefile.tizen index 1dabb65..42e129f 100755 --- a/tizen/src/Makefile.tizen +++ b/tizen/src/Makefile.tizen @@ -64,7 +64,7 @@ obj-y += emulator.o emul_state.o option.o maru_err_table.o # maru display obj-y += maru_display.o maru_shm.o ifndef CONFIG_DARWIN -obj-y += maru_sdl.o sdl_rotate.o maru_finger.o +obj-y += maru_sdl.o SDL_rotozoom.o maru_finger.o endif # sdb diff --git a/tizen/src/sdl_rotate.c b/tizen/src/SDL_rotozoom.c similarity index 70% rename from tizen/src/sdl_rotate.c rename to tizen/src/SDL_rotozoom.c index e268c97..3831236 100644 --- a/tizen/src/sdl_rotate.c +++ b/tizen/src/SDL_rotozoom.c @@ -1,11 +1,31 @@ -/* - * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library. - * Modifications by Hyunjun Son(hj79.son@samsung.com) - * - * This work is licensed under the terms of the GNU GPL version 2. - * See the COPYING file in the top-level directory. - * - */ +/* + +SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces + +Copyright (C) 2001-2012 Andreas Schiffler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. + +Andreas Schiffler -- aschiffler at ferzkopp dot net + +*/ #ifdef WIN32 #include @@ -14,9 +34,7 @@ #include #include -#include "sdl_rotate.h" - -#if 1 +#include "SDL_rotozoom.h" /* ---- Internally used structures */ @@ -37,58 +55,47 @@ typedef struct tColorY { Uint8 y; } tColorY; -/*! +/*! \brief Returns maximum of two numbers a and b. */ #define MAX(a,b) (((a) > (b)) ? (a) : (b)) -/*! +/*! \brief Number of guard rows added to destination surfaces. This is a simple but effective workaround for observed issues. These rows allocate extra memory and are then hidden from the surface. -Rows are added to the end of destination surfaces when they are allocated. -This catches any potential overflows which seem to happen with +Rows are added to the end of destination surfaces when they are allocated. +This catches any potential overflows which seem to happen with just the right src image dimensions and scale/rotation and can lead to a situation where the program can segfault. */ -#define GUARD_ROWS (0) +#define GUARD_ROWS (2) /*! \brief Lower limit of absolute zoom factor or rotation degrees. */ #define VALUE_LIMIT 0.001 -Uint32 _colorkey(SDL_Surface *src); -int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory); -int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory); -int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth); -int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy); -void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth); -void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy); -void _rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy, - int *dstwidth, int *dstheight, - double *canglezoom, double *sanglezoom); - /*! \brief Returns colorkey info for a surface */ -Uint32 _colorkey(SDL_Surface *src) +static Uint32 _colorkey(SDL_Surface *src) { - Uint32 key = 0; + Uint32 key = 0; #if (SDL_MINOR_VERSION == 3) - SDL_GetColorKey(src, &key); + SDL_GetColorKey(src, &key); #else - if (src) - { - key = src->format->colorkey; + if (src) + { + key = src->format->colorkey; } #endif - return key; + return key; } -/*! +/*! \brief Internal 32 bit integer-factor averaging Shrinker. Shrinks 32 bit RGBA/ABGR 'src' surface to 'dst' surface. @@ -103,7 +110,7 @@ Assumes dst surface was allocated with the correct dimensions. \return 0 for success or -1 for error. */ -int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) +static int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) { int x, y, dx, dy, sgap, dgap, ra, ga, ba, aa; int n_average; @@ -142,7 +149,7 @@ int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int fa aa += sp->a; sp++; - } + } /* src dx loop */ sp = (tColorRGBA *)((Uint8*)sp + (src->pitch - 4*factorx)); // next y } @@ -158,26 +165,26 @@ int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int fa dp->a = aa/n_average; /* - * Advance destination pointer + * Advance destination pointer */ dp++; - } + } /* dst x loop */ /* next box-y */ sp = (tColorRGBA *)((Uint8*)osp + src->pitch*factory); /* - * Advance destination pointers + * Advance destination pointers */ dp = (tColorRGBA *) ((Uint8 *) dp + dgap); - } + } /* dst y loop */ return (0); } -/*! +/*! \brief Internal 8 bit integer-factor averaging shrinker. Shrinks 8bit Y 'src' surface to 'dst' surface. @@ -192,7 +199,7 @@ Assumes dst surface was allocated with the correct dimensions. \return 0 for success or -1 for error. */ -int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) +static int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) { int x, y, dx, dy, sgap, dgap, a; int n_average; @@ -215,7 +222,7 @@ int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int facto dp = (Uint8 *) dst->pixels; dgap = dst->pitch - dst->w; - for (y = 0; y < dst->h; y++) { + for (y = 0; y < dst->h; y++) { osp=sp; for (x = 0; x < dst->w; x++) { @@ -226,13 +233,13 @@ int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int facto for (dy=0; dy < factory; dy++) { for (dx=0; dx < factorx; dx++) { a += (*sp); - /* next x */ + /* next x */ sp++; - } - /* end src dx loop */ + } + /* end src dx loop */ /* next y */ - sp = (Uint8 *)((Uint8*)sp + (src->pitch - factorx)); - } + sp = (Uint8 *)((Uint8*)sp + (src->pitch - factorx)); + } /* end src dy loop */ /* next box-x */ @@ -242,26 +249,26 @@ int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int facto *dp = a/n_average; /* - * Advance destination pointer + * Advance destination pointer */ dp++; - } + } /* end dst x loop */ /* next box-y */ sp = (Uint8 *)((Uint8*)osp + src->pitch*factory); /* - * Advance destination pointers + * Advance destination pointers */ dp = (Uint8 *)((Uint8 *)dp + dgap); - } + } /* end dst y loop */ return (0); } -/*! +/*! \brief Internal 32 bit Zoomer with optional anti-aliasing by bilinear interpolation. Zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface. @@ -276,32 +283,15 @@ Assumes dst surface was allocated with the correct dimensions. \return 0 for success or -1 for error. */ -int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth) +static int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth) { - int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, lx, ly; - tColorRGBA *c00, *c01, *c10, *c11, *cswap; + int x, y, sx, sy, ssx, ssy, *sax, *say, *csax, *csay, *salast, csx, csy, ex, ey, cx, cy, sstep, sstepx, sstepy; + tColorRGBA *c00, *c01, *c10, *c11; tColorRGBA *sp, *csp, *dp; - int dgap; - - /* - * Variable setup - */ - if (smooth) { - /* - * For interpolation: assume source dimension is one pixel - */ - /* - * smaller to avoid overflow on right and bottom edge. - */ - sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w); - sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h); - } else { - sx = (int) (65536.0 * (float) src->w / (float) dst->w); - sy = (int) (65536.0 * (float) src->h / (float) dst->h); - } + int spixelgap, spixelw, spixelh, dgap, t1, t2; /* - * Allocate memory for row increments + * Allocate memory for row/column increments */ if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) { return (-1); @@ -312,73 +302,104 @@ int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, } /* - * Precalculate row increments + * Precalculate row increments */ - sp = csp = (tColorRGBA *) src->pixels; - dp = (tColorRGBA *) dst->pixels; + spixelw = (src->w - 1); + spixelh = (src->h - 1); + if (smooth) { + sx = (int) (65536.0 * (float) spixelw / (float) (dst->w - 1)); + sy = (int) (65536.0 * (float) spixelh / (float) (dst->h - 1)); + } else { + sx = (int) (65536.0 * (float) (src->w) / (float) (dst->w)); + sy = (int) (65536.0 * (float) (src->h) / (float) (dst->h)); + } - if (flipx) csp += (src->w-1); - if (flipy) csp += (src->pitch*(src->h-1)); + /* Maximum scaled source size */ + ssx = (src->w << 16) - 1; + ssy = (src->h << 16) - 1; + /* Precalculate horizontal row increments */ csx = 0; csax = sax; for (x = 0; x <= dst->w; x++) { *csax = csx; csax++; - csx &= 0xffff; csx += sx; + + /* Guard from overflows */ + if (csx > ssx) { + csx = ssx; + } } + + /* Precalculate vertical row increments */ csy = 0; csay = say; for (y = 0; y <= dst->h; y++) { *csay = csy; csay++; - csy &= 0xffff; csy += sy; + + /* Guard from overflows */ + if (csy > ssy) { + csy = ssy; + } } + sp = (tColorRGBA *) src->pixels; + dp = (tColorRGBA *) dst->pixels; dgap = dst->pitch - dst->w * 4; + spixelgap = src->pitch/4; + + if (flipx) sp += spixelw; + if (flipy) sp += (spixelgap * spixelh); /* - * Switch between interpolating and non-interpolating code + * Switch between interpolating and non-interpolating code */ if (smooth) { /* - * Interpolating Zoom + * Interpolating Zoom */ - - /* - * Scan destination - */ - ly = 0; csay = say; for (y = 0; y < dst->h; y++) { - /* - * Setup color source pointers - */ - c00 = csp; - c01 = csp; - c01++; - c10 = (tColorRGBA *) ((Uint8 *) csp + src->pitch); - c11 = c10; - c11++; + csp = sp; csax = sax; - if (flipx) { - cswap = c00; c00=c01; c01=cswap; - cswap = c10; c10=c11; c11=cswap; - } - if (flipy) { - cswap = c00; c00=c10; c10=cswap; - cswap = c01; c01=c11; c11=cswap; - } - lx = 0; for (x = 0; x < dst->w; x++) { /* - * Interpolate colors + * Setup color source pointers */ ex = (*csax & 0xffff); ey = (*csay & 0xffff); + cx = (*csax >> 16); + cy = (*csay >> 16); + sstepx = cx < spixelw; + sstepy = cy < spixelh; + c00 = sp; + c01 = sp; + c10 = sp; + if (sstepy) { + if (flipy) { + c10 -= spixelgap; + } else { + c10 += spixelgap; + } + } + c11 = c10; + if (sstepx) { + if (flipx) { + c01--; + c11--; + } else { + c01++; + c11++; + } + } + + /* + * Draw and interpolate colors + */ t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; dp->r = (((t2 - t1) * ey) >> 16) + t1; @@ -390,85 +411,89 @@ int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, dp->b = (((t2 - t1) * ey) >> 16) + t1; t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; - dp->a = (((t2 - t1) * ey) >> 16) + t1; - + dp->a = (((t2 - t1) * ey) >> 16) + t1; /* - * Advance source pointers + * Advance source pointer x */ - csax++; - sstep = (*csax >> 16); - lx += sstep; - if (lx >= src->w) sstep = 0; - if (flipx) sstep = -sstep; - c00 += sstep; - c01 += sstep; - c10 += sstep; - c11 += sstep; + salast = csax; + csax++; + sstep = (*csax >> 16) - (*salast >> 16); + if (flipx) { + sp -= sstep; + } else { + sp += sstep; + } + /* - * Advance destination pointer + * Advance destination pointer x */ dp++; } /* - * Advance source pointer + * Advance source pointer y */ + salast = csay; csay++; - sstep = (*csay >> 16); - ly += sstep; - if (ly >= src->h) sstep = 0; - sstep *= src->pitch; - if (flipy) sstep = -sstep; - csp = (tColorRGBA *) ((Uint8 *) csp + sstep); + sstep = (*csay >> 16) - (*salast >> 16); + sstep *= spixelgap; + if (flipy) { + sp = csp - sstep; + } else { + sp = csp + sstep; + } /* - * Advance destination pointers + * Advance destination pointer y */ dp = (tColorRGBA *) ((Uint8 *) dp + dgap); } } else { - /* - * Non-Interpolating Zoom - */ - + * Non-Interpolating Zoom + */ csay = say; for (y = 0; y < dst->h; y++) { - sp = csp; + csp = sp; csax = sax; for (x = 0; x < dst->w; x++) { /* - * Draw + * Draw */ *dp = *sp; + /* - * Advance source pointers + * Advance source pointer x */ - csax++; - sstep = (*csax >> 16); + salast = csax; + csax++; + sstep = (*csax >> 16) - (*salast >> 16); if (flipx) sstep = -sstep; sp += sstep; + /* - * Advance destination pointer + * Advance destination pointer x */ dp++; } /* - * Advance source pointer + * Advance source pointer y */ + salast = csay; csay++; - sstep = (*csay >> 16) * src->pitch; - if (flipy) sstep = -sstep; - csp = (tColorRGBA *) ((Uint8 *) csp + sstep); + sstep = (*csay >> 16) - (*salast >> 16); + sstep *= spixelgap; + if (flipy) sstep = -sstep; + sp = csp + sstep; /* - * Advance destination pointers + * Advance destination pointer y */ dp = (tColorRGBA *) ((Uint8 *) dp + dgap); } } /* - * Remove temp arrays + * Remove temp arrays */ free(sax); free(say); @@ -476,7 +501,7 @@ int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, return (0); } -/*! +/*! \brief Internal 8 bit Zoomer without smoothing. @@ -491,7 +516,7 @@ Assumes dst surface was allocated with the correct dimensions. \return 0 for success or -1 for error. */ -int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) +static int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) { int x, y; Uint32 *sax, *say, *csax, *csay; @@ -500,7 +525,7 @@ int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) int dgap; /* - * Allocate memory for row increments + * Allocate memory for row increments */ if ((sax = (Uint32 *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) { return (-1); @@ -511,7 +536,7 @@ int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) } /* - * Pointer setup + * Pointer setup */ sp = csp = (Uint8 *) src->pixels; dp = (Uint8 *) dst->pixels; @@ -521,7 +546,7 @@ int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) if (flipy) csp = ( (Uint8*)csp + src->pitch*(src->h-1) ); /* - * Precalculate row increments + * Precalculate row increments */ csx = 0; csax = sax; @@ -532,6 +557,7 @@ int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) csx -= dst->w; (*csax)++; } + (*csax) = (*csax) * (flipx ? -1 : 1); csax++; } csy = 0; @@ -543,11 +569,12 @@ int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) csy -= dst->h; (*csay)++; } + (*csay) = (*csay) * (flipy ? -1 : 1); csay++; } /* - * Draw + * Draw */ csay = say; for (y = 0; y < dst->h; y++) { @@ -555,33 +582,33 @@ int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) sp = csp; for (x = 0; x < dst->w; x++) { /* - * Draw + * Draw */ *dp = *sp; /* - * Advance source pointers + * Advance source pointers */ - sp += (*csax) * (flipx ? -1 : 1); + sp += (*csax); csax++; /* - * Advance destination pointer + * Advance destination pointer */ dp++; } /* - * Advance source pointer (for row) + * Advance source pointer (for row) */ - csp += ((*csay) * src->pitch) * (flipy ? -1 : 1); + csp += ((*csay) * src->pitch); csay++; /* - * Advance destination pointers + * Advance destination pointers */ dp += dgap; } /* - * Remove temp arrays + * Remove temp arrays */ free(sax); free(say); @@ -589,10 +616,10 @@ int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) return (0); } -/*! +/*! \brief Internal 32 bit rotozoomer with optional anti-aliasing. -Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control +Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control parameters by scanning the destination surface and applying optionally anti-aliasing by bilinear interpolation. Assumes src and dst surfaces are of 32 bit depth. @@ -608,7 +635,7 @@ Assumes dst surface was allocated with the correct dimensions. \param flipy Flag indicating vertical mirroring should be applied. \param smooth Flag indicating anti-aliasing should be used. */ -void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) +static void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) { int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; tColorRGBA c00, c01, c10, c11, cswap; @@ -616,7 +643,7 @@ void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int gap; /* - * Variable setup + * Variable setup */ xd = ((src->w - dst->w) << 15); yd = ((src->h - dst->h) << 15); @@ -628,7 +655,7 @@ void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, gap = dst->pitch - dst->w * 4; /* - * Switch between interpolating and non-interpolating code + * Switch between interpolating and non-interpolating code */ if (smooth) { for (y = 0; y < dst->h; y++) { @@ -638,15 +665,16 @@ void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, for (x = 0; x < dst->w; x++) { dx = (sdx >> 16); dy = (sdy >> 16); - if ((dx > -1) && (dy > -1) && (dx < src->w) && (dy < src->h)) { - if (flipx) dx = sw - dx; - if (flipy) dy = sh - dy; - sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + if (flipx) dx = sw - dx; + if (flipy) dy = sh - dy; + if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) { + sp = (tColorRGBA *)src->pixels;; + sp += ((src->pitch/4) * dy); sp += dx; c00 = *sp; sp += 1; c01 = *sp; - sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + sp += (src->pitch/4); c11 = *sp; sp -= 1; c10 = *sp; @@ -659,7 +687,7 @@ void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, cswap = c01; c01=c11; c11=cswap; } /* - * Interpolate colors + * Interpolate colors */ ex = (sdx & 0xffff); ey = (sdy & 0xffff); @@ -710,7 +738,7 @@ void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, \brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing. -Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control +Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control parameters by scanning the destination surface. Assumes src and dst surfaces are of 8 bit depth. Assumes dst surface was allocated with the correct dimensions. @@ -724,14 +752,14 @@ Assumes dst surface was allocated with the correct dimensions. \param flipx Flag indicating horizontal mirroring should be applied. \param flipy Flag indicating vertical mirroring should be applied. */ -void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy) +static void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy) { int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh; tColorY *pc, *sp; int gap; /* - * Variable setup + * Variable setup */ xd = ((src->w - dst->w) << 15); yd = ((src->h - dst->h) << 15); @@ -742,11 +770,11 @@ void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int pc = (tColorY*) dst->pixels; gap = dst->pitch - dst->w; /* - * Clear surface to colorkey + * Clear surface to colorkey */ - memset(pc, (unsigned char) (_colorkey(src) & 0xff), dst->pitch * dst->h); + memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h); /* - * Iterate through destination surface + * Iterate through destination surface */ for (y = 0; y < dst->h; y++) { dy = cy - y; @@ -769,12 +797,11 @@ void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int pc += gap; } } -#endif /*! \brief Rotates a 32 bit surface in increments of 90 degrees. -Specialized 90 degree rotator which rotates a 'src' surface in 90 degree +Specialized 90 degree rotator which rotates a 'src' surface in 90 degree increments clockwise returning a new surface. Faster than rotozoomer since not scanning or interpolation takes place. Input surface must be 32 bit. (code contributed by J. Schiller, improved by C. Allport and A. Schiffler) @@ -784,7 +811,7 @@ not scanning or interpolation takes place. Input surface must be 32 bit. \returns The new, rotated surface; or NULL for surfaces with incorrect input format. */ -SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns) +SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns) { int row, col, newWidth, newHeight; int bpp, src_ipr, dst_ipr; @@ -804,8 +831,8 @@ SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns) newHeight = (numClockwiseTurns % 2) ? (src->w) : (src->h); dst = SDL_CreateRGBSurface( src->flags, newWidth, newHeight, src->format->BitsPerPixel, src->format->Rmask, - src->format->Gmask, - src->format->Bmask, + src->format->Gmask, + src->format->Bmask, src->format->Amask); if(!dst) { return NULL; @@ -824,74 +851,74 @@ SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns) dst_ipr = dst->pitch / bpp; switch(numClockwiseTurns) { - case 0: /* Make a copy of the surface */ - { - /* Unfortunately SDL_BlitSurface cannot be used to make a copy of the surface - since it does not preserve alpha. */ - - if (src->pitch == dst->pitch) { - /* If the pitch is the same for both surfaces, the memory can be copied all at once. */ - memcpy(dst->pixels, src->pixels, (src->h * src->pitch)); - } - else - { - /* If the pitch differs, copy each row separately */ - srcBuf = (Uint32*)(src->pixels); - dstBuf = (Uint32*)(dst->pixels); - for (row = 0; row < src->h; row++) { - memcpy(dstBuf, srcBuf, dst->w * bpp); - srcBuf += src_ipr; - dstBuf += dst_ipr; - } /* end for(col) */ - } /* end for(row) */ + case 0: /* Make a copy of the surface */ + { + /* Unfortunately SDL_BlitSurface cannot be used to make a copy of the surface + since it does not preserve alpha. */ + + if (src->pitch == dst->pitch) { + /* If the pitch is the same for both surfaces, the memory can be copied all at once. */ + memcpy(dst->pixels, src->pixels, (src->h * src->pitch)); } - break; - - /* rotate clockwise */ - case 1: /* rotated 90 degrees clockwise */ - { - for (row = 0; row < src->h; ++row) { - srcBuf = (Uint32*)(src->pixels) + (row * src_ipr); - dstBuf = (Uint32*)(dst->pixels) + (dst->w - row - 1); - for (col = 0; col < src->w; ++col) { - *dstBuf = *srcBuf; - ++srcBuf; - dstBuf += dst_ipr; - } - /* end for(col) */ - } - /* end for(row) */ - } - break; - - case 2: /* rotated 180 degrees clockwise */ - { - for (row = 0; row < src->h; ++row) { - srcBuf = (Uint32*)(src->pixels) + (row * src_ipr); - dstBuf = (Uint32*)(dst->pixels) + ((dst->h - row - 1) * dst_ipr) + (dst->w - 1); - for (col = 0; col < src->w; ++col) { - *dstBuf = *srcBuf; - ++srcBuf; - --dstBuf; - } - } - } - break; - - case 3: - { - for (row = 0; row < src->h; ++row) { - srcBuf = (Uint32*)(src->pixels) + (row * src_ipr); - dstBuf = (Uint32*)(dst->pixels) + row + ((dst->h - 1) * dst_ipr); - for (col = 0; col < src->w; ++col) { - *dstBuf = *srcBuf; - ++srcBuf; - dstBuf -= dst_ipr; - } - } - } - break; - } + else + { + /* If the pitch differs, copy each row separately */ + srcBuf = (Uint32*)(src->pixels); + dstBuf = (Uint32*)(dst->pixels); + for (row = 0; row < src->h; row++) { + memcpy(dstBuf, srcBuf, dst->w * bpp); + srcBuf += src_ipr; + dstBuf += dst_ipr; + } /* end for(col) */ + } /* end for(row) */ + } + break; + + /* rotate clockwise */ + case 1: /* rotated 90 degrees clockwise */ + { + for (row = 0; row < src->h; ++row) { + srcBuf = (Uint32*)(src->pixels) + (row * src_ipr); + dstBuf = (Uint32*)(dst->pixels) + (dst->w - row - 1); + for (col = 0; col < src->w; ++col) { + *dstBuf = *srcBuf; + ++srcBuf; + dstBuf += dst_ipr; + } + /* end for(col) */ + } + /* end for(row) */ + } + break; + + case 2: /* rotated 180 degrees clockwise */ + { + for (row = 0; row < src->h; ++row) { + srcBuf = (Uint32*)(src->pixels) + (row * src_ipr); + dstBuf = (Uint32*)(dst->pixels) + ((dst->h - row - 1) * dst_ipr) + (dst->w - 1); + for (col = 0; col < src->w; ++col) { + *dstBuf = *srcBuf; + ++srcBuf; + --dstBuf; + } + } + } + break; + + case 3: + { + for (row = 0; row < src->h; ++row) { + srcBuf = (Uint32*)(src->pixels) + (row * src_ipr); + dstBuf = (Uint32*)(dst->pixels) + row + ((dst->h - 1) * dst_ipr); + for (col = 0; col < src->w; ++col) { + *dstBuf = *srcBuf; + ++srcBuf; + dstBuf -= dst_ipr; + } + } + } + break; + } /* end switch */ if (SDL_MUSTLOCK(src)) { @@ -905,9 +932,8 @@ SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns) } -#if 1 /*! -\brief Internal target surface sizing function for rotozooms with trig result return. +\brief Internal target surface sizing function for rotozooms with trig result return. \param width The source surface width. \param height The source surface height. @@ -920,24 +946,24 @@ SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns) \param sanglezoom The cosine of the angle adjusted by the zoom factor. */ -void _rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy, - int *dstwidth, int *dstheight, - double *canglezoom, double *sanglezoom) +static void _rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy, + int *dstwidth, int *dstheight, + double *canglezoom, double *sanglezoom) { double x, y, cx, cy, sx, sy; double radangle; int dstwidthhalf, dstheighthalf; /* - * Determine destination width and height by rotating a centered source box + * Determine destination width and height by rotating a centered source box */ radangle = angle * (M_PI / 180.0); *sanglezoom = sin(radangle); *canglezoom = cos(radangle); *sanglezoom *= zoomx; *canglezoom *= zoomx; - x = width / 2; - y = height / 2; + x = (double)(width / 2); + y = (double)(height / 2); cx = *canglezoom * x; cy = *canglezoom * y; sx = *sanglezoom * x; @@ -951,8 +977,8 @@ void _rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, *dstheight = 2 * dstheighthalf; } -/*! -\brief Returns the size of the resulting target surface for a rotozoomSurfaceXY() call. +/*! +\brief Returns the size of the resulting target surface for a rotozoomSurfaceXY() call. \param width The source surface width. \param height The source surface height. @@ -969,8 +995,8 @@ void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, do _rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); } -/*! -\brief Returns the size of the resulting target surface for a rotozoomSurface() call. +/*! +\brief Returns the size of the resulting target surface for a rotozoomSurface() call. \param width The source surface width. \param height The source surface height. @@ -987,7 +1013,7 @@ void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int * } /*! -\brief Rotates and zooms a surface and optional anti-aliasing. +\brief Rotates and zooms a surface and optional anti-aliasing. Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. 'angle' is the rotation in degrees and 'zoom' a scaling factor. If 'smooth' is set @@ -1007,7 +1033,7 @@ SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int s } /*! -\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. +\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. Rotates and zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface. 'angle' is the rotation in degrees, 'zoomx and 'zoomy' scaling factors. If 'smooth' is set @@ -1037,7 +1063,7 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do int colorKeyAvailable = 0; /* - * Sanity check + * Sanity check */ if (src == NULL) return (NULL); @@ -1049,21 +1075,21 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do colorKeyAvailable = 1; } /* - * Determine if source surface is 32bit or 8bit + * Determine if source surface is 32bit or 8bit */ is32bit = (src->format->BitsPerPixel == 32); if ((is32bit) || (src->format->BitsPerPixel == 8)) { /* - * Use source surface 'as is' + * Use source surface 'as is' */ rz_src = src; src_converted = 0; } else { /* - * New source surface is 32bit with a defined RGBA ordering + * New source surface is 32bit with a defined RGBA ordering */ rz_src = - SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, + SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 #else @@ -1082,7 +1108,7 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do } /* - * Sanity check zoom factor + * Sanity check zoom factor */ flipx = (zoomx<0.0); if (flipx) zoomx=-zoomx; @@ -1093,22 +1119,22 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do zoominv = 65536.0 / (zoomx * zoomx); /* - * Check if we have a rotozoom or just a zoom + * Check if we have a rotozoom or just a zoom */ if (fabs(angle) > VALUE_LIMIT) { /* - * Angle!=0: full rotozoom + * Angle!=0: full rotozoom */ /* - * ----------------------- + * ----------------------- */ /* Determine target size */ _rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom); /* - * Calculate target factors from sin/cos and zoom + * Calculate target factors from sin/cos and zoom */ sanglezoominv = sanglezoom; canglezoominv = canglezoom; @@ -1120,12 +1146,12 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do dstheighthalf = dstheight / 2; /* - * Alloc space to completely contain the rotated surface + * Alloc space to completely contain the rotated surface */ rz_dst = NULL; if (is32bit) { /* - * Target surface is 32bit with source RGBA/ABGR ordering + * Target surface is 32bit with source RGBA/ABGR ordering */ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32, @@ -1133,11 +1159,18 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do rz_src->format->Bmask, rz_src->format->Amask); } else { /* - * Target surface is 8bit + * Target surface is 8bit */ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); } + /* Check target */ + if (rz_dst == NULL) + return NULL; + + /* Adjust for guard rows */ + rz_dst->h = dstheight; + if (colorKeyAvailable == 1){ colorkey = SDL_MapRGB(rz_dst->format, r, g, b); @@ -1145,38 +1178,38 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do } /* - * Lock source surface + * Lock source surface */ if (SDL_MUSTLOCK(rz_src)) { SDL_LockSurface(rz_src); } /* - * Check which kind of surface we have + * Check which kind of surface we have */ if (is32bit) { /* - * Call the 32bit transformation routine to do the rotation (using alpha) + * Call the 32bit transformation routine to do the rotation (using alpha) */ _transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf, - (int) (sanglezoominv), (int) (canglezoominv), + (int) (sanglezoominv), (int) (canglezoominv), flipx, flipy, smooth); /* - * Turn on source-alpha support + * Turn on source-alpha support */ SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); } else { /* - * Copy palette and colorkey info + * Copy palette and colorkey info */ for (i = 0; i < rz_src->format->palette->ncolors; i++) { rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; } rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; /* - * Call the 8bit transformation routine to do the rotation + * Call the 8bit transformation routine to do the rotation */ transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf, (int) (sanglezoominv), (int) (canglezoominv), @@ -1184,7 +1217,7 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); } /* - * Unlock source surface + * Unlock source surface */ if (SDL_MUSTLOCK(rz_src)) { SDL_UnlockSurface(rz_src); @@ -1193,10 +1226,10 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do } else { /* - * Angle=0: Just a zoom + * Angle=0: Just a zoom */ /* - * -------------------- + * -------------------- */ /* @@ -1205,12 +1238,12 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); /* - * Alloc space to completely contain the zoomed surface + * Alloc space to completely contain the zoomed surface */ rz_dst = NULL; if (is32bit) { /* - * Target surface is 32bit with source RGBA/ABGR ordering + * Target surface is 32bit with source RGBA/ABGR ordering */ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32, @@ -1218,11 +1251,18 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do rz_src->format->Bmask, rz_src->format->Amask); } else { /* - * Target surface is 8bit + * Target surface is 8bit */ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); } + /* Check target */ + if (rz_dst == NULL) + return NULL; + + /* Adjust for guard rows */ + rz_dst->h = dstheight; + if (colorKeyAvailable == 1){ colorkey = SDL_MapRGB(rz_dst->format, r, g, b); @@ -1230,41 +1270,44 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do } /* - * Lock source surface + * Lock source surface */ if (SDL_MUSTLOCK(rz_src)) { SDL_LockSurface(rz_src); } /* - * Check which kind of surface we have + * Check which kind of surface we have */ if (is32bit) { /* - * Call the 32bit transformation routine to do the zooming (using alpha) + * Call the 32bit transformation routine to do the zooming (using alpha) */ _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth); + /* - * Turn on source-alpha support + * Turn on source-alpha support */ SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); } else { /* - * Copy palette and colorkey info + * Copy palette and colorkey info */ for (i = 0; i < rz_src->format->palette->ncolors; i++) { rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; } rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + /* - * Call the 8bit transformation routine to do the zooming + * Call the 8bit transformation routine to do the zooming */ _zoomSurfaceY(rz_src, rz_dst, flipx, flipy); SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); } + /* - * Unlock source surface + * Unlock source surface */ if (SDL_MUSTLOCK(rz_src)) { SDL_UnlockSurface(rz_src); @@ -1272,16 +1315,15 @@ SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, do } /* - * Cleanup temp surface + * Cleanup temp surface */ if (src_converted) { SDL_FreeSurface(rz_src); } /* - * Return destination surface + * Return destination surface */ - rz_dst->h -= GUARD_ROWS; return (rz_dst); } @@ -1300,7 +1342,7 @@ The minimum size of the target surface is 1. The input factors can be positive o void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight) { /* - * Make zoom factors positive + * Make zoom factors positive */ int flipx, flipy; flipx = (zoomx<0.0); @@ -1309,7 +1351,7 @@ void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dst if (flipy) zoomy = -zoomy; /* - * Sanity check zoom factors + * Sanity check zoom factors */ if (zoomx < VALUE_LIMIT) { zoomx = VALUE_LIMIT; @@ -1319,10 +1361,10 @@ void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dst } /* - * Calculate target size + * Calculate target size */ - *dstwidth = (int) ((double) width * zoomx); - *dstheight = (int) ((double) height * zoomy); + *dstwidth = (int) floor(((double) width * zoomx) + 0.5); + *dstheight = (int) floor(((double) height * zoomy) + 0.5); if (*dstwidth < 1) { *dstwidth = 1; } @@ -1331,7 +1373,7 @@ void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dst } } -/*! +/*! \brief Zoom a surface by independent horizontal and vertical factors with optional smoothing. Zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface. @@ -1357,33 +1399,36 @@ SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smoo int flipx, flipy; /* - * Sanity check + * Sanity check */ if (src == NULL) return (NULL); /* - * Determine if source surface is 32bit or 8bit + * Determine if source surface is 32bit or 8bit */ is32bit = (src->format->BitsPerPixel == 32); if ((is32bit) || (src->format->BitsPerPixel == 8)) { /* - * Use source surface 'as is' + * Use source surface 'as is' */ rz_src = src; src_converted = 0; } else { /* - * New source surface is 32bit with a defined RGBA ordering + * New source surface is 32bit with a defined RGBA ordering */ rz_src = - SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, + SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 #else 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff #endif ); + if (rz_src == NULL) { + return NULL; + } SDL_BlitSurface(src, NULL, rz_src, NULL); src_converted = 1; is32bit = 1; @@ -1398,12 +1443,12 @@ SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smoo zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); /* - * Alloc space to completely contain the zoomed surface + * Alloc space to completely contain the zoomed surface */ rz_dst = NULL; if (is32bit) { /* - * Target surface is 32bit with source RGBA/ABGR ordering + * Target surface is 32bit with source RGBA/ABGR ordering */ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32, @@ -1411,66 +1456,79 @@ SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smoo rz_src->format->Bmask, rz_src->format->Amask); } else { /* - * Target surface is 8bit + * Target surface is 8bit */ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); } + /* Check target */ + if (rz_dst == NULL) { + /* + * Cleanup temp surface + */ + if (src_converted) { + SDL_FreeSurface(rz_src); + } + return NULL; + } + + /* Adjust for guard rows */ + rz_dst->h = dstheight; + /* - * Lock source surface + * Lock source surface */ if (SDL_MUSTLOCK(rz_src)) { SDL_LockSurface(rz_src); } /* - * Check which kind of surface we have + * Check which kind of surface we have */ if (is32bit) { /* - * Call the 32bit transformation routine to do the zooming (using alpha) + * Call the 32bit transformation routine to do the zooming (using alpha) */ _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth); /* - * Turn on source-alpha support + * Turn on source-alpha support */ SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); } else { /* - * Copy palette and colorkey info + * Copy palette and colorkey info */ for (i = 0; i < rz_src->format->palette->ncolors; i++) { rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; } rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; /* - * Call the 8bit transformation routine to do the zooming + * Call the 8bit transformation routine to do the zooming */ _zoomSurfaceY(rz_src, rz_dst, flipx, flipy); SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); } /* - * Unlock source surface + * Unlock source surface */ if (SDL_MUSTLOCK(rz_src)) { SDL_UnlockSurface(rz_src); } /* - * Cleanup temp surface + * Cleanup temp surface */ if (src_converted) { SDL_FreeSurface(rz_src); } /* - * Return destination surface + * Return destination surface */ - rz_dst->h -= GUARD_ROWS; return (rz_dst); } -/*! +/*! \brief Shrink a surface by an integer ratio using averaging. Shrinks a 32bit or 8bit 'src' surface to a newly created 'dst' surface. @@ -1486,47 +1544,65 @@ The input surface is not modified. The output surface is newly allocated. \return The new, shrunken surface. */ +/*@null@*/ SDL_Surface *shrinkSurface(SDL_Surface *src, int factorx, int factory) { + int result; SDL_Surface *rz_src; - SDL_Surface *rz_dst; + SDL_Surface *rz_dst = NULL; int dstwidth, dstheight; int is32bit; int i, src_converted; + int haveError = 0; /* - * Sanity check + * Sanity check */ - if (src == NULL) + if (src == NULL) { return (NULL); + } /* - * Determine if source surface is 32bit or 8bit + * Determine if source surface is 32bit or 8bit */ is32bit = (src->format->BitsPerPixel == 32); if ((is32bit) || (src->format->BitsPerPixel == 8)) { /* - * Use source surface 'as is' + * Use source surface 'as is' */ rz_src = src; src_converted = 0; } else { /* - * New source surface is 32bit with a defined RGBA ordering + * New source surface is 32bit with a defined RGBA ordering */ - rz_src = - SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, + rz_src = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 #else 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff #endif ); + if (rz_src==NULL) { + haveError = 1; + goto exitShrinkSurface; + } + SDL_BlitSurface(src, NULL, rz_src, NULL); src_converted = 1; is32bit = 1; } + /* + * Lock the surface + */ + if (SDL_MUSTLOCK(rz_src)) { + if (SDL_LockSurface(rz_src) < 0) { + haveError = 1; + goto exitShrinkSurface; + } + } + /* Get size for target */ dstwidth=rz_src->w/factorx; while (dstwidth*factorx>rz_src->w) { dstwidth--; } @@ -1537,10 +1613,9 @@ SDL_Surface *shrinkSurface(SDL_Surface *src, int factorx, int factory) * Alloc space to completely contain the shrunken surface * (with added guard rows) */ - rz_dst = NULL; - if (is32bit) { + if (is32bit==1) { /* - * Target surface is 32bit with source RGBA/ABGR ordering + * Target surface is 32bit with source RGBA/ABGR ordering */ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32, @@ -1548,63 +1623,95 @@ SDL_Surface *shrinkSurface(SDL_Surface *src, int factorx, int factory) rz_src->format->Bmask, rz_src->format->Amask); } else { /* - * Target surface is 8bit + * Target surface is 8bit */ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); } - /* - * Lock source surface - */ - if (SDL_MUSTLOCK(rz_src)) { - SDL_LockSurface(rz_src); + /* Check target */ + if (rz_dst == NULL) { + haveError = 1; + goto exitShrinkSurface; } + /* Adjust for guard rows */ + rz_dst->h = dstheight; + /* - * Check which kind of surface we have + * Check which kind of surface we have */ - if (is32bit) { + if (is32bit==1) { /* - * Call the 32bit transformation routine to do the shrinking (using alpha) + * Call the 32bit transformation routine to do the shrinking (using alpha) */ - _shrinkSurfaceRGBA(rz_src, rz_dst, factorx, factory); + result = _shrinkSurfaceRGBA(rz_src, rz_dst, factorx, factory); + if ((result!=0) || (rz_dst==NULL)) { + haveError = 1; + goto exitShrinkSurface; + } + /* - * Turn on source-alpha support + * Turn on source-alpha support */ - SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + result = SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + if (result!=0) { + haveError = 1; + goto exitShrinkSurface; + } } else { /* - * Copy palette and colorkey info + * Copy palette and colorkey info */ for (i = 0; i < rz_src->format->palette->ncolors; i++) { rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; } rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; /* - * Call the 8bit transformation routine to do the shrinking + * Call the 8bit transformation routine to do the shrinking */ - _shrinkSurfaceY(rz_src, rz_dst, factorx, factory); - SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); - } + result = _shrinkSurfaceY(rz_src, rz_dst, factorx, factory); + if (result!=0) { + haveError = 1; + goto exitShrinkSurface; + } - /* - * Unlock source surface - */ - if (SDL_MUSTLOCK(rz_src)) { - SDL_UnlockSurface(rz_src); + /* + * Set colorkey on target + */ + result = SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); + if (result!=0) { + haveError = 1; + goto exitShrinkSurface; + } } - /* - * Cleanup temp surface - */ - if (src_converted) { - SDL_FreeSurface(rz_src); +exitShrinkSurface: + if (rz_src!=NULL) { + /* + * Unlock source surface + */ + if (SDL_MUSTLOCK(rz_src)) { + SDL_UnlockSurface(rz_src); + } + + /* + * Cleanup temp surface + */ + if (src_converted==1) { + SDL_FreeSurface(rz_src); + } } + /* Check error state; maybe need to cleanup destination */ + if (haveError==1) { + if (rz_dst!=NULL) { + SDL_FreeSurface(rz_dst); + } + rz_dst=NULL; + } + /* - * Return destination surface + * Return destination surface */ - rz_dst->h -= GUARD_ROWS; return (rz_dst); } -#endif diff --git a/tizen/src/SDL_rotozoom.h b/tizen/src/SDL_rotozoom.h new file mode 100644 index 0000000..80b31f1 --- /dev/null +++ b/tizen/src/SDL_rotozoom.h @@ -0,0 +1,123 @@ +/* + +SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces + +Copyright (C) 2001-2012 Andreas Schiffler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. + +Andreas Schiffler -- aschiffler at ferzkopp dot net + +*/ + +#ifndef _SDL_rotozoom_h +#define _SDL_rotozoom_h + +#include + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef M_PI +#define M_PI 3.141592654 +#endif + +#include "SDL.h" + + /* ---- Defines */ + + /*! + \brief Disable anti-aliasing (no smoothing). + */ +#define SMOOTHING_OFF 0 + + /*! + \brief Enable anti-aliasing (smoothing). + */ +#define SMOOTHING_ON 1 + + /* ---- Function Prototypes */ + +#ifdef _MSC_VER +# if defined(DLL_EXPORT) && !defined(LIBSDL_GFX_DLL_IMPORT) +# define SDL_ROTOZOOM_SCOPE __declspec(dllexport) +# else +# ifdef LIBSDL_GFX_DLL_IMPORT +# define SDL_ROTOZOOM_SCOPE __declspec(dllimport) +# endif +# endif +#endif +#ifndef SDL_ROTOZOOM_SCOPE +# define SDL_ROTOZOOM_SCOPE extern +#endif + + /* + + Rotozoom functions + + */ + + SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth); + + SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurfaceXY + (SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth); + + + SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, + int *dstheight); + + SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSizeXY + (int width, int height, double angle, double zoomx, double zoomy, + int *dstwidth, int *dstheight); + + /* + + Zooming functions + + */ + + SDL_ROTOZOOM_SCOPE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth); + + SDL_ROTOZOOM_SCOPE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight); + + /* + + Shrinking functions + + */ + + SDL_ROTOZOOM_SCOPE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory); + + /* + + Specialized rotation functions + + */ + + SDL_ROTOZOOM_SCOPE SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns); + + /* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* _SDL_rotozoom_h */ diff --git a/tizen/src/maru_sdl.c b/tizen/src/maru_sdl.c index 21cbaaa..3ca6385 100644 --- a/tizen/src/maru_sdl.c +++ b/tizen/src/maru_sdl.c @@ -33,7 +33,7 @@ #include "console.h" #include "maru_sdl.h" #include "emul_state.h" -#include "sdl_rotate.h" +#include "SDL_rotozoom.h" #include "maru_sdl_rotozoom.h" #include "maru_finger.h" #include "hw/maru_pm.h" diff --git a/tizen/src/sdl_rotate.h b/tizen/src/sdl_rotate.h deleted file mode 100644 index 4611690..0000000 --- a/tizen/src/sdl_rotate.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library. - * Modifications by Hyunjun Son(hj79.son@samsung.com) - * - * This work is licensed under the terms of the GNU GPL version 2. - * See the COPYING file in the top-level directory. - * - */ - -#ifndef _SDL_rotate_h -#define _SDL_rotate_h - -#include -#include - -/* ---- Prototypes */ - -#ifdef WIN32 -# ifdef DLL_EXPORT -# define SDL_ROTOZOOM_SCOPE __declspec(dllexport) -# else -# ifdef LIBSDL_GFX_DLL_IMPORT -# define SDL_ROTOZOOM_SCOPE __declspec(dllimport) -# endif -# endif -#endif -#ifndef SDL_ROTOZOOM_SCOPE -# define SDL_ROTOZOOM_SCOPE extern -#endif - -/* - - rotozoomSurface() - - Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. - 'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1 - then the destination 32bit surface is anti-aliased. If the surface is not 8bit - or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. - - */ - -SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth); - -SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurfaceXY -(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth); - -/* Returns the size of the target surface for a rotozoomSurface() call */ - -SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, - int *dstheight); - -SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSizeXY -(int width, int height, double angle, double zoomx, double zoomy, - int *dstwidth, int *dstheight); - -/* - - zoomSurface() - - Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. - 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1 - then the destination 32bit surface is anti-aliased. If the surface is not 8bit - or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. - - */ - -SDL_ROTOZOOM_SCOPE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth); - -/* Returns the size of the target surface for a zoomSurface() call */ - -SDL_ROTOZOOM_SCOPE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight); - - -/* - shrinkSurface() - - Shrinks a 32bit or 8bit 'src' surface ti a newly created 'dst' surface. - 'factorx' and 'factory' are the shrinking ratios (i.e. 2=1/2 the size, - 3=1/3 the size, etc.) The destination surface is antialiased by averaging - the source box RGBA or Y information. If the surface is not 8bit - or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. - */ - -SDL_ROTOZOOM_SCOPE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory); - -/* - - Other functions - - */ - -SDL_ROTOZOOM_SCOPE SDL_Surface* rotateSurface90Degrees(SDL_Surface* pSurf, int numClockwiseTurns); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif - -#endif /* _SDL_rotate_h */