Fix bug 4053: Blit issues on Big Endian CPU
authorSylvain Becker
Mon, 18 Feb 2019 22:06:53 +0100
changeset 12613c8f998f83225
parent 12612 07c39cbbeacf
child 12614 8c5251cbf63c
Fix bug 4053: Blit issues on Big Endian CPU
src/video/SDL_blit_N.c
     1.1 --- a/src/video/SDL_blit_N.c	Mon Feb 18 07:50:33 2019 -0800
     1.2 +++ b/src/video/SDL_blit_N.c	Mon Feb 18 22:06:53 2019 +0100
     1.3 @@ -2155,7 +2155,13 @@
     1.4          int *_p0 , int *_p1, int *_p2, int *_p3, int *_alpha_channel)
     1.5  {
     1.6      int alpha_channel = 0, p0, p1, p2, p3;
     1.7 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
     1.8      int Pixel = 0x04030201; /* identity permutation */
     1.9 +#else
    1.10 +    int Pixel = 0x01020304; /* identity permutation */
    1.11 +    int srcbpp = srcfmt->BytesPerPixel;
    1.12 +    int dstbpp = dstfmt->BytesPerPixel;
    1.13 +#endif
    1.14  
    1.15      if (srcfmt->Amask) {
    1.16          RGBA_FROM_PIXEL(Pixel, srcfmt, p0, p1, p2, p3);
    1.17 @@ -2174,10 +2180,17 @@
    1.18          PIXEL_FROM_RGB(Pixel, dstfmt, p0, p1, p2);
    1.19      }
    1.20  
    1.21 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
    1.22      p0 = Pixel & 0xFF;
    1.23      p1 = (Pixel >> 8) & 0xFF;
    1.24      p2 = (Pixel >> 16) & 0xFF;
    1.25      p3 = (Pixel >> 24) & 0xFF;
    1.26 +#else
    1.27 +    p3 = Pixel & 0xFF;
    1.28 +    p2 = (Pixel >> 8) & 0xFF;
    1.29 +    p1 = (Pixel >> 16) & 0xFF;
    1.30 +    p0 = (Pixel >> 24) & 0xFF;
    1.31 +#endif
    1.32  
    1.33      if (p0 == 0) {
    1.34          p0 = 1;
    1.35 @@ -2193,6 +2206,19 @@
    1.36          alpha_channel = 3;
    1.37      }
    1.38  
    1.39 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
    1.40 +#else
    1.41 +    if (srcbpp == 3 && dstbpp == 4) {
    1.42 +        if (p0 != 1) p0--;
    1.43 +        if (p1 != 1) p1--;
    1.44 +        if (p2 != 1) p2--;
    1.45 +        if (p3 != 1) p3--;
    1.46 +    } else if (srcbpp == 4 && dstbpp == 3) {
    1.47 +        p0 = p1;
    1.48 +        p1 = p2;
    1.49 +        p2 = p3;
    1.50 +    }
    1.51 +#endif
    1.52      *_p0 = p0 - 1;
    1.53      *_p1 = p1 - 1;
    1.54      *_p2 = p2 - 1;
    1.55 @@ -2597,9 +2623,15 @@
    1.56      if ((sfmt == SDL_PIXELFORMAT_RGB24 && dfmt == SDL_PIXELFORMAT_RGB24) ||
    1.57          (sfmt == SDL_PIXELFORMAT_BGR24 && dfmt == SDL_PIXELFORMAT_BGR24)) {
    1.58  
    1.59 -        Uint8 k0 = ckey & 0x000000FF;
    1.60 -        Uint8 k1 = (ckey & 0x0000FF00) >> 8;
    1.61 -        Uint8 k2 = (ckey & 0x00FF0000) >> 16;
    1.62 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
    1.63 +        Uint8 k0 = ckey & 0xFF;
    1.64 +        Uint8 k1 = (ckey >> 8)  & 0xFF;
    1.65 +        Uint8 k2 = (ckey >> 16) & 0xFF;
    1.66 +#else
    1.67 +        Uint8 k0 = (ckey >> 16) & 0xFF;
    1.68 +        Uint8 k1 = (ckey >> 8) & 0xFF;
    1.69 +        Uint8 k2 = ckey & 0xFF;
    1.70 +#endif
    1.71  
    1.72          while (height--) {
    1.73              /* *INDENT-OFF* */
    1.74 @@ -2629,9 +2661,15 @@
    1.75      if ((sfmt == SDL_PIXELFORMAT_RGB24 && dfmt == SDL_PIXELFORMAT_BGR24) ||
    1.76          (sfmt == SDL_PIXELFORMAT_BGR24 && dfmt == SDL_PIXELFORMAT_RGB24)) {
    1.77  
    1.78 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
    1.79          Uint8 k0 = ckey & 0xFF;
    1.80          Uint8 k1 = (ckey >> 8)  & 0xFF;
    1.81          Uint8 k2 = (ckey >> 16) & 0xFF;
    1.82 +#else
    1.83 +        Uint8 k0 = (ckey >> 16) & 0xFF;
    1.84 +        Uint8 k1 = (ckey >> 8) & 0xFF;
    1.85 +        Uint8 k2 = ckey & 0xFF;
    1.86 +#endif
    1.87  
    1.88          while (height--) {
    1.89              /* *INDENT-OFF* */
    1.90 @@ -2693,9 +2731,15 @@
    1.91  
    1.92          Uint32 *dst32 = (Uint32*)dst;
    1.93  
    1.94 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
    1.95          Uint8 k0 = ckey & 0xFF;
    1.96          Uint8 k1 = (ckey >> 8)  & 0xFF;
    1.97          Uint8 k2 = (ckey >> 16) & 0xFF;
    1.98 +#else
    1.99 +        Uint8 k0 = (ckey >> 16) & 0xFF;
   1.100 +        Uint8 k1 = (ckey >> 8) & 0xFF;
   1.101 +        Uint8 k2 = ckey  & 0xFF;
   1.102 +#endif
   1.103  
   1.104          /* Find the appropriate permutation */
   1.105          int alpha_channel, p0, p1, p2, p3;
   1.106 @@ -2939,6 +2983,13 @@
   1.107          /* SET_ALPHA */
   1.108          Uint32 mask = info->a << dstfmt->Ashift;
   1.109          int last_line = 0;
   1.110 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.111 +#else
   1.112 +        int i0 = srcbpp - 1 - 0;
   1.113 +        int i1 = srcbpp - 1 - 1;
   1.114 +        int i2 = srcbpp - 1 - 2;
   1.115 +#endif
   1.116 +
   1.117          if (srcbpp == 3 && height) {
   1.118              height -= 1;
   1.119              last_line = 1;
   1.120 @@ -2949,8 +3000,15 @@
   1.121              DUFFS_LOOP(
   1.122              {
   1.123                  Uint32  *dst32 = (Uint32*)dst;
   1.124 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.125                  Uint32  *src32 = (Uint32*)src;
   1.126                  *dst32 = *src32 | mask;
   1.127 +#else
   1.128 +                Uint8 s0 = src[i0];
   1.129 +                Uint8 s1 = src[i1];
   1.130 +                Uint8 s2 = src[i2];
   1.131 +                *dst32 = (s0) | (s1 << 8) | (s2 << 16) | mask;
   1.132 +#endif
   1.133                  dst += 4;
   1.134                  src += srcbpp;
   1.135              }, width);
   1.136 @@ -2962,9 +3020,15 @@
   1.137          if (last_line) {
   1.138              while (width--) {
   1.139                  Uint32  *dst32 = (Uint32*)dst;
   1.140 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.141                  Uint8 s0 = src[0];
   1.142                  Uint8 s1 = src[1];
   1.143                  Uint8 s2 = src[2];
   1.144 +#else
   1.145 +                Uint8 s0 = src[i0];
   1.146 +                Uint8 s1 = src[i1];
   1.147 +                Uint8 s2 = src[i2];
   1.148 +#endif
   1.149                  *dst32 = (s0) | (s1 << 8) | (s2 << 16) | mask;
   1.150                  dst += 4;
   1.151                  src += srcbpp;
   1.152 @@ -2972,8 +3036,28 @@
   1.153          }
   1.154      } else {
   1.155          /* NO_ALPHA */
   1.156 +        int last_line = 0;
   1.157 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.158          int mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
   1.159 -        int last_line = 0;
   1.160 +#else
   1.161 +        int i0 = srcbpp - 1 - 0;
   1.162 +        int i1 = srcbpp - 1 - 1;
   1.163 +        int i2 = srcbpp - 1 - 2;
   1.164 +        int j0 = dstbpp - 1 - 0;
   1.165 +        int j1 = dstbpp - 1 - 1;
   1.166 +        int j2 = dstbpp - 1 - 2;
   1.167 +        int shift0, shift1, shift2;
   1.168 +        if (dstbpp == 4) {
   1.169 +            shift2 = 16;
   1.170 +            shift1 = 8;
   1.171 +            shift0 = 0;
   1.172 +        } else { /* dstbpp 3 */
   1.173 +            shift2 = 24;
   1.174 +            shift1 = 16;
   1.175 +            shift0 = 8;
   1.176 +        }
   1.177 +#endif
   1.178 +
   1.179          if ((dstbpp == 3 || srcbpp == 3) && height) {
   1.180              height -= 1;
   1.181              last_line = 1;
   1.182 @@ -2984,8 +3068,15 @@
   1.183              DUFFS_LOOP(
   1.184              {
   1.185                  Uint32  *dst32 = (Uint32*)dst;
   1.186 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.187                  Uint32  *src32 = (Uint32*)src;
   1.188                  *dst32 = *src32 & mask;
   1.189 +#else
   1.190 +                Uint8 s0 = src[i0];
   1.191 +                Uint8 s1 = src[i1];
   1.192 +                Uint8 s2 = src[i2];
   1.193 +                *dst32 = (s0 << shift0) | (s1 << shift1) | (s2 << shift2);
   1.194 +#endif
   1.195                  dst += dstbpp;
   1.196                  src += srcbpp;
   1.197              }, width);
   1.198 @@ -2996,12 +3087,21 @@
   1.199  
   1.200          if (last_line) {
   1.201              while (width--) {
   1.202 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.203                  Uint8 s0 = src[0];
   1.204                  Uint8 s1 = src[1];
   1.205                  Uint8 s2 = src[2];
   1.206                  dst[0] = s0;
   1.207                  dst[1] = s1;
   1.208                  dst[2] = s2;
   1.209 +#else
   1.210 +                Uint8 s0 = src[i0];
   1.211 +                Uint8 s1 = src[i1];
   1.212 +                Uint8 s2 = src[i2];
   1.213 +                dst[j0] = s0;
   1.214 +                dst[j1] = s1;
   1.215 +                dst[j2] = s2;
   1.216 +#endif
   1.217                  dst += dstbpp;
   1.218                  src += srcbpp;
   1.219              }
   1.220 @@ -3034,10 +3134,17 @@
   1.221                  DUFFS_LOOP(
   1.222                  {
   1.223                      Uint32 *dst32 = (Uint32*)dst;
   1.224 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.225                      Uint8 s0 = src[0];
   1.226                      Uint8 s1 = src[1];
   1.227                      Uint8 s2 = src[2];
   1.228                      Uint32 alphashift = src[3] << dstfmt->Ashift;
   1.229 +#else
   1.230 +                    Uint8 s0 = src[3];
   1.231 +                    Uint8 s1 = src[2];
   1.232 +                    Uint8 s2 = src[1];
   1.233 +                    Uint32 alphashift = src[0] << dstfmt->Ashift;
   1.234 +#endif
   1.235                      /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
   1.236                      *dst32 = (s0 << 16) | (s1 << 8) | (s2) | alphashift;
   1.237                      dst += dstbpp;
   1.238 @@ -3050,14 +3157,27 @@
   1.239          } else {
   1.240              /* SET_ALPHA */
   1.241              Uint32 mask = info->a << dstfmt->Ashift;
   1.242 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.243 +#else
   1.244 +            int i0 = srcbpp - 1 - 0;
   1.245 +            int i1 = srcbpp - 1 - 1;
   1.246 +            int i2 = srcbpp - 1 - 2;
   1.247 +#endif
   1.248 +
   1.249              while (height--) {
   1.250                  /* *INDENT-OFF* */
   1.251                  DUFFS_LOOP(
   1.252                  {
   1.253                      Uint32 *dst32 = (Uint32*)dst;
   1.254 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.255                      Uint8 s0 = src[0];
   1.256                      Uint8 s1 = src[1];
   1.257                      Uint8 s2 = src[2];
   1.258 +#else
   1.259 +                    Uint8 s0 = src[i0];
   1.260 +                    Uint8 s1 = src[i1];
   1.261 +                    Uint8 s2 = src[i2];
   1.262 +#endif
   1.263                      /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
   1.264                      *dst32 = (s0 << 16) | (s1 << 8) | (s2) | mask;
   1.265                      dst += dstbpp;
   1.266 @@ -3071,6 +3191,23 @@
   1.267      } else {
   1.268          /* NO_ALPHA */
   1.269          int last_line = 0;
   1.270 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.271 +#else
   1.272 +        int i0 = srcbpp - 1 - 0;
   1.273 +        int i1 = srcbpp - 1 - 1;
   1.274 +        int i2 = srcbpp - 1 - 2;
   1.275 +        int shift0, shift1, shift2;
   1.276 +        if (dstbpp == 4) {
   1.277 +            shift0 = 16;
   1.278 +            shift1 = 8;
   1.279 +            shift2 = 0;
   1.280 +        } else { /* dstbpp 3 */
   1.281 +            shift0 = 24;
   1.282 +            shift1 = 16;
   1.283 +            shift2 = 8;
   1.284 +        }
   1.285 +#endif
   1.286 +
   1.287          if (dstbpp == 3 && height) {
   1.288              height -= 1;
   1.289              last_line = 1;
   1.290 @@ -3081,11 +3218,18 @@
   1.291              DUFFS_LOOP(
   1.292              {
   1.293                  Uint32 *dst32 = (Uint32*)dst;
   1.294 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.295                  Uint8 s0 = src[0];
   1.296                  Uint8 s1 = src[1];
   1.297                  Uint8 s2 = src[2];
   1.298                  /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
   1.299                  *dst32 = (s0 << 16) | (s1 << 8) | (s2);
   1.300 +#else
   1.301 +                Uint8 s0 = src[i0];
   1.302 +                Uint8 s1 = src[i1];
   1.303 +                Uint8 s2 = src[i2];
   1.304 +                *dst32 = (s0 << shift0) | (s1 << shift1) | (s2 << shift2);
   1.305 +#endif
   1.306                  dst += dstbpp;
   1.307                  src += srcbpp;
   1.308              }, width);
   1.309 @@ -3096,6 +3240,7 @@
   1.310  
   1.311          if (last_line) {
   1.312              while (width--) {
   1.313 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.314                  Uint8 s0 = src[0];
   1.315                  Uint8 s1 = src[1];
   1.316                  Uint8 s2 = src[2];
   1.317 @@ -3103,6 +3248,15 @@
   1.318                  dst[0] = s2;
   1.319                  dst[1] = s1;
   1.320                  dst[2] = s0;
   1.321 +#else
   1.322 +                Uint8 s0 = src[i0];
   1.323 +                Uint8 s1 = src[i1];
   1.324 +                Uint8 s2 = src[i2];
   1.325 +                /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
   1.326 +                dst[0] = s0;
   1.327 +                dst[1] = s1;
   1.328 +                dst[2] = s2;
   1.329 +#endif
   1.330                  dst += dstbpp;
   1.331                  src += srcbpp;
   1.332              }
   1.333 @@ -3151,7 +3305,6 @@
   1.334  };
   1.335  
   1.336  static const struct blit_table normal_blit_3[] = {
   1.337 -#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.338      /* 3->4 with same rgb triplet */
   1.339      {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
   1.340       0, Blit_3or4_to_3or4__same_rgb, NO_ALPHA | SET_ALPHA},
   1.341 @@ -3167,7 +3320,6 @@
   1.342       0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA },
   1.343      {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
   1.344       0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA },
   1.345 -#endif
   1.346      /* Default for 24-bit RGB source, never optimized */
   1.347      {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
   1.348  };
   1.349 @@ -3184,7 +3336,6 @@
   1.350      {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F,
   1.351       2, Blit_RGB888_RGB565Altivec, NO_ALPHA},
   1.352  #endif
   1.353 -#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.354      /* 4->3 with same rgb triplet */
   1.355      {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
   1.356       0, Blit_3or4_to_3or4__same_rgb, NO_ALPHA | SET_ALPHA},
   1.357 @@ -3195,7 +3346,6 @@
   1.358       0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA},
   1.359      {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
   1.360       0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA},
   1.361 -#endif
   1.362      /* 4->4 with inversed rgb triplet, and COPY_ALPHA to switch ABGR8888 <-> ARGB8888 */
   1.363      {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
   1.364       0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA | COPY_ALPHA},