src/render/software/SDL_rotate.c
changeset 7678 286c42d7c5ed
parent 7677 871d43c6968a
child 7828 1451063c8ecd
equal deleted inserted replaced
7677:871d43c6968a 7678:286c42d7c5ed
    40 #include "SDL.h"
    40 #include "SDL.h"
    41 #include "SDL_rotate.h"
    41 #include "SDL_rotate.h"
    42 
    42 
    43 /* ---- Internally used structures */
    43 /* ---- Internally used structures */
    44 
    44 
    45 /*!
    45 /* !
    46 \brief A 32 bit RGBA pixel.
    46 \brief A 32 bit RGBA pixel.
    47 */
    47 */
    48 typedef struct tColorRGBA {
    48 typedef struct tColorRGBA {
    49     Uint8 r;
    49     Uint8 r;
    50     Uint8 g;
    50     Uint8 g;
    51     Uint8 b;
    51     Uint8 b;
    52     Uint8 a;
    52     Uint8 a;
    53 } tColorRGBA;
    53 } tColorRGBA;
    54 
    54 
    55 /*!
    55 /* !
    56 \brief A 8bit Y/palette pixel.
    56 \brief A 8bit Y/palette pixel.
    57 */
    57 */
    58 typedef struct tColorY {
    58 typedef struct tColorY {
    59     Uint8 y;
    59     Uint8 y;
    60 } tColorY;
    60 } tColorY;
    61 
    61 
    62 /*!
    62 /* !
    63 \brief Returns maximum of two numbers a and b.
    63 \brief Returns maximum of two numbers a and b.
    64 */
    64 */
    65 #define MAX(a,b)    (((a) > (b)) ? (a) : (b))
    65 #define MAX(a,b)    (((a) > (b)) ? (a) : (b))
    66 
    66 
    67 /*!
    67 /* !
    68 \brief Number of guard rows added to destination surfaces.
    68 \brief Number of guard rows added to destination surfaces.
    69 
    69 
    70 This is a simple but effective workaround for observed issues.
    70 This is a simple but effective workaround for observed issues.
    71 These rows allocate extra memory and are then hidden from the surface.
    71 These rows allocate extra memory and are then hidden from the surface.
    72 Rows are added to the end of destination surfaces when they are allocated.
    72 Rows are added to the end of destination surfaces when they are allocated.
    74 just the right src image dimensions and scale/rotation and can lead
    74 just the right src image dimensions and scale/rotation and can lead
    75 to a situation where the program can segfault.
    75 to a situation where the program can segfault.
    76 */
    76 */
    77 #define GUARD_ROWS (2)
    77 #define GUARD_ROWS (2)
    78 
    78 
    79 /*!
    79 /* !
    80 \brief Lower limit of absolute zoom factor or rotation degrees.
    80 \brief Lower limit of absolute zoom factor or rotation degrees.
    81 */
    81 */
    82 #define VALUE_LIMIT 0.001
    82 #define VALUE_LIMIT 0.001
    83 
    83 
    84 /*!
    84 /* !
    85 \brief Returns colorkey info for a surface
    85 \brief Returns colorkey info for a surface
    86 */
    86 */
    87 Uint32 _colorkey(SDL_Surface *src)
    87 Uint32 _colorkey(SDL_Surface *src)
    88 {
    88 {
    89     Uint32 key = 0;
    89     Uint32 key = 0;
    90     SDL_GetColorKey(src, &key);
    90     SDL_GetColorKey(src, &key);
    91     return key;
    91     return key;
    92 }
    92 }
    93 
    93 
    94 
    94 
    95 /*!
    95 /* !
    96 \brief Internal target surface sizing function for rotations with trig result return.
    96 \brief Internal target surface sizing function for rotations with trig result return.
    97 
    97 
    98 \param width The source surface width.
    98 \param width The source surface width.
    99 \param height The source surface height.
    99 \param height The source surface height.
   100 \param angle The angle to rotate in degrees.
   100 \param angle The angle to rotate in degrees.
   132     *dstwidth = 2 * dstwidthhalf;
   132     *dstwidth = 2 * dstwidthhalf;
   133     *dstheight = 2 * dstheighthalf;
   133     *dstheight = 2 * dstheighthalf;
   134 }
   134 }
   135 
   135 
   136 
   136 
   137 /*!
   137 /* !
   138 \brief Internal 32 bit rotozoomer with optional anti-aliasing.
   138 \brief Internal 32 bit rotozoomer with optional anti-aliasing.
   139 
   139 
   140 Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
   140 Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
   141 parameters by scanning the destination surface and applying optionally anti-aliasing
   141 parameters by scanning the destination surface and applying optionally anti-aliasing
   142 by bilinear interpolation.
   142 by bilinear interpolation.
   250             pc = (tColorRGBA *) ((Uint8 *) pc + gap);
   250             pc = (tColorRGBA *) ((Uint8 *) pc + gap);
   251         }
   251         }
   252     }
   252     }
   253 }
   253 }
   254 
   254 
   255 /*!
   255 /* !
   256 
   256 
   257 \brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing.
   257 \brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing.
   258 
   258 
   259 Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
   259 Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
   260 parameters by scanning the destination surface.
   260 parameters by scanning the destination surface.
   315 }
   315 }
   316 
   316 
   317 
   317 
   318 
   318 
   319 
   319 
   320 /*!
   320 /* !
   321 \brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing.
   321 \brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing.
   322 
   322 
   323 Rotates a 32bit or 8bit 'src' surface to newly created 'dst' surface.
   323 Rotates a 32bit or 8bit 'src' surface to newly created 'dst' surface.
   324 'angle' is the rotation in degrees, 'centerx' and 'centery' the rotation center. If 'smooth' is set
   324 'angle' is the rotation in degrees, 'centerx' and 'centery' the rotation center. If 'smooth' is set
   325 then the destination 32bit surface is anti-aliased. If the surface is not 8bit
   325 then the destination 32bit surface is anti-aliased. If the surface is not 8bit
   355     * Sanity check
   355     * Sanity check
   356     */
   356     */
   357     if (src == NULL)
   357     if (src == NULL)
   358         return (NULL);
   358         return (NULL);
   359 
   359 
   360     if (src->flags & SDL_TRUE/*SDL_SRCCOLORKEY */)
   360     if (src->flags & SDL_TRUE/* SDL_SRCCOLORKEY */)
   361     {
   361     {
   362         colorkey = _colorkey(src);
   362         colorkey = _colorkey(src);
   363         SDL_GetRGB(colorkey, src->format, &r, &g, &b);
   363         SDL_GetRGB(colorkey, src->format, &r, &g, &b);
   364         colorKeyAvailable = 1;
   364         colorKeyAvailable = 1;
   365     }
   365     }
   389             SDL_SetColorKey(src, 0, 0);
   389             SDL_SetColorKey(src, 0, 0);
   390 
   390 
   391         SDL_BlitSurface(src, NULL, rz_src, NULL);
   391         SDL_BlitSurface(src, NULL, rz_src, NULL);
   392 
   392 
   393         if(colorKeyAvailable)
   393         if(colorKeyAvailable)
   394             SDL_SetColorKey(src, SDL_TRUE /*SDL_SRCCOLORKEY */, colorkey);
   394             SDL_SetColorKey(src, SDL_TRUE /* SDL_SRCCOLORKEY */, colorkey);
   395         src_converted = 1;
   395         src_converted = 1;
   396         is32bit = 1;
   396         is32bit = 1;
   397     }
   397     }
   398 
   398 
   399 
   399 
   400     /* Determine target size */
   400     /* Determine target size */
   401     /*_rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, &dstwidth, &dstheight, &cangle, &sangle); */
   401     /* _rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, &dstwidth, &dstheight, &cangle, &sangle); */
   402 
   402 
   403     /*
   403     /*
   404     * Calculate target factors from sin/cos and zoom
   404     * Calculate target factors from sin/cos and zoom
   405     */
   405     */
   406     sangleinv = sangle*65536.0;
   406     sangleinv = sangle*65536.0;
   457             flipx, flipy,
   457             flipx, flipy,
   458             smooth);
   458             smooth);
   459         /*
   459         /*
   460         * Turn on source-alpha support
   460         * Turn on source-alpha support
   461         */
   461         */
   462         /*SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); */
   462         /* SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); */
   463         SDL_SetColorKey(rz_dst, /*SDL_SRCCOLORKEY */ SDL_TRUE | SDL_RLEACCEL, _colorkey(rz_src));
   463         SDL_SetColorKey(rz_dst, /* SDL_SRCCOLORKEY */ SDL_TRUE | SDL_RLEACCEL, _colorkey(rz_src));
   464     } else {
   464     } else {
   465         /*
   465         /*
   466         * Copy palette and colorkey info
   466         * Copy palette and colorkey info
   467         */
   467         */
   468         for (i = 0; i < rz_src->format->palette->ncolors; i++) {
   468         for (i = 0; i < rz_src->format->palette->ncolors; i++) {
   473         * Call the 8bit transformation routine to do the rotation
   473         * Call the 8bit transformation routine to do the rotation
   474         */
   474         */
   475         transformSurfaceY(rz_src, rz_dst, centerx, centery,
   475         transformSurfaceY(rz_src, rz_dst, centerx, centery,
   476             (int) (sangleinv), (int) (cangleinv),
   476             (int) (sangleinv), (int) (cangleinv),
   477             flipx, flipy);
   477             flipx, flipy);
   478         SDL_SetColorKey(rz_dst, /*SDL_SRCCOLORKEY */ SDL_TRUE | SDL_RLEACCEL, _colorkey(rz_src));
   478         SDL_SetColorKey(rz_dst, /* SDL_SRCCOLORKEY */ SDL_TRUE | SDL_RLEACCEL, _colorkey(rz_src));
   479     }
   479     }
   480     /*
   480     /*
   481     * Unlock source surface
   481     * Unlock source surface
   482     */
   482     */
   483     if (SDL_MUSTLOCK(rz_src)) {
   483     if (SDL_MUSTLOCK(rz_src)) {