Commit da56cefa8bcaf4a33b33f4299921098278250867

Sam Lantinga 2018-10-30T07:00:03

Fixed bug 4188 - Software renderer SDL_RenderCopyEx blits corrupt image under certain cases Sylvain Re-opening this issue. It fixes the test-case, but it introduces a regression with another bug (bug #4313). So here's a new patch that activate cropping of the source surface to solve the issue. It also reverts the wrong changeset. It prevents unneeded colorkey error message.

diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c
index 0c14cac..709dfe8 100644
--- a/src/render/software/SDL_render_sw.c
+++ b/src/render/software/SDL_render_sw.c
@@ -657,6 +657,11 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
         blitRequired = SDL_TRUE;
     }
 
+    /* srcrect is not selecting the whole src surface, so cropping is needed */
+    if (!(srcrect->w == src->w && srcrect->h == src->h && srcrect->x == 0 && srcrect->y == 0)) {
+        blitRequired = SDL_TRUE;
+    }
+
     /* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */
     if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) {
         applyModulation = SDL_TRUE;
diff --git a/src/render/software/SDL_rotate.c b/src/render/software/SDL_rotate.c
index 43811ef..09e099c 100644
--- a/src/render/software/SDL_rotate.c
+++ b/src/render/software/SDL_rotate.c
@@ -83,7 +83,9 @@ static Uint32
 _colorkey(SDL_Surface *src)
 {
     Uint32 key = 0;
-    SDL_GetColorKey(src, &key);
+    if (SDL_HasColorKey(src)) {
+        SDL_GetColorKey(src, &key);
+    }
     return key;
 }
 
@@ -150,17 +152,17 @@ SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle,
 /* Computes source pointer X/Y increments for a rotation that's a multiple of 90 degrees. */
 static void
 computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int flipy,
-                          int *sincx, int *sincy, int *signx, int *signy, SDL_Surface *dst)
+                          int *sincx, int *sincy, int *signx, int *signy)
 {
     int pitch = flipy ? -src->pitch : src->pitch;
     if (flipx) {
         bpp = -bpp;
     }
     switch (angle) { /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
-    case 0: *sincx = bpp; *sincy = pitch - dst->w * *sincx; *signx = *signy = 1; break;
-    case 1: *sincx = -pitch; *sincy = bpp - *sincx * dst->h; *signx = 1; *signy = -1; break;
-    case 2: *sincx = -bpp; *sincy = -dst->w * *sincx - pitch; *signx = *signy = -1; break;
-    case 3: default: *sincx = pitch; *sincy = -*sincx * dst->h - bpp; *signx = -1; *signy = 1; break;
+    case 0: *sincx = bpp; *sincy = pitch - src->w * *sincx; *signx = *signy = 1; break;
+    case 1: *sincx = -pitch; *sincy = bpp - *sincx * src->h; *signx = 1; *signy = -1; break;
+    case 2: *sincx = -bpp; *sincy = -src->w * *sincx - pitch; *signx = *signy = -1; break;
+    case 3: default: *sincx = pitch; *sincy = -*sincx * src->h - bpp; *signx = -1; *signy = 1; break;
     }
     if (flipx) {
         *signx = -*signx;
@@ -175,9 +177,10 @@ computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int 
     int dy, dincy = dst->pitch - dst->w*sizeof(pixelType), sincx, sincy, signx, signy;                      \
     Uint8 *sp = (Uint8*)src->pixels, *dp = (Uint8*)dst->pixels, *de;                                        \
                                                                                                             \
-    computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy, dst); \
-    if (signx < 0) sp += (dst->w-1)*sizeof(pixelType);                                                      \
-    if (signy < 0) sp += (dst->h-1)*src->pitch;                                                             \
+    computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy); \
+    if (signx < 0) sp += (src->w-1)*sizeof(pixelType);                                                      \
+    if (signy < 0) sp += (src->h-1)*src->pitch;                                                             \
+                                                                                                            \
     for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) {                                             \
         if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */               \
             SDL_memcpy(dp, sp, dst->w*sizeof(pixelType));                                                   \
@@ -423,8 +426,10 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, 
     if (src == NULL)
         return NULL;
 
-    if (SDL_GetColorKey(src, &colorkey) == 0) {
-        colorKeyAvailable = SDL_TRUE;
+    if (SDL_HasColorKey(src)) {
+        if (SDL_GetColorKey(src, &colorkey) == 0) {
+            colorKeyAvailable = SDL_TRUE;
+        }
     }
 
     /* This function requires a 32-bit surface or 8-bit surface with a colorkey */