src/video/SDL_blit_N.c
author Sylvain Becker
Tue, 27 Oct 2020 21:14:49 +0100
changeset 14207 7225f02f0055
parent 13871 e58323b0cf8e
permissions -rw-r--r--
Android: apply code simplications found with lint / Android Studio
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../SDL_internal.h"
    22 
    23 #if SDL_HAVE_BLIT_N
    24 
    25 #include "SDL_video.h"
    26 #include "SDL_endian.h"
    27 #include "SDL_cpuinfo.h"
    28 #include "SDL_blit.h"
    29 
    30 #include "SDL_assert.h"
    31 
    32 /* General optimized routines that write char by char */
    33 #define HAVE_FAST_WRITE_INT8 1
    34 
    35 /* On some CPU, it's slower than combining and write a word */
    36 #if defined(__MIPS__) 
    37 #  undef  HAVE_FAST_WRITE_INT8
    38 #  define HAVE_FAST_WRITE_INT8 0
    39 #endif
    40 
    41 /* Functions to blit from N-bit surfaces to other surfaces */
    42 
    43 enum blit_features {
    44 	BLIT_FEATURE_NONE = 0,
    45 	BLIT_FEATURE_HAS_MMX = 1,
    46 	BLIT_FEATURE_HAS_ALTIVEC = 2,
    47 	BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH = 4,
    48 	BLIT_FEATURE_HAS_ARM_SIMD = 8
    49 };
    50 
    51 #if SDL_ALTIVEC_BLITTERS
    52 #ifdef HAVE_ALTIVEC_H
    53 #include <altivec.h>
    54 #endif
    55 #ifdef __MACOSX__
    56 #include <sys/sysctl.h>
    57 static size_t
    58 GetL3CacheSize(void)
    59 {
    60     const char key[] = "hw.l3cachesize";
    61     u_int64_t result = 0;
    62     size_t typeSize = sizeof(result);
    63 
    64 
    65     int err = sysctlbyname(key, &result, &typeSize, NULL, 0);
    66     if (0 != err)
    67         return 0;
    68 
    69     return result;
    70 }
    71 #else
    72 static size_t
    73 GetL3CacheSize(void)
    74 {
    75     /* XXX: Just guess G4 */
    76     return 2097152;
    77 }
    78 #endif /* __MACOSX__ */
    79 
    80 #if (defined(__MACOSX__) && (__GNUC__ < 4))
    81 #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
    82         (vector unsigned char) ( a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p )
    83 #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
    84         (vector unsigned short) ( a,b,c,d,e,f,g,h )
    85 #else
    86 #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
    87         (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p }
    88 #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
    89         (vector unsigned short) { a,b,c,d,e,f,g,h }
    90 #endif
    91 
    92 #define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F)
    93 #define VSWIZZLE32(a,b,c,d) (vector unsigned char) \
    94                                ( 0x00+a, 0x00+b, 0x00+c, 0x00+d, \
    95                                  0x04+a, 0x04+b, 0x04+c, 0x04+d, \
    96                                  0x08+a, 0x08+b, 0x08+c, 0x08+d, \
    97                                  0x0C+a, 0x0C+b, 0x0C+c, 0x0C+d )
    98 
    99 #define MAKE8888(dstfmt, r, g, b, a)  \
   100     ( ((r<<dstfmt->Rshift)&dstfmt->Rmask) | \
   101       ((g<<dstfmt->Gshift)&dstfmt->Gmask) | \
   102       ((b<<dstfmt->Bshift)&dstfmt->Bmask) | \
   103       ((a<<dstfmt->Ashift)&dstfmt->Amask) )
   104 
   105 /*
   106  * Data Stream Touch...Altivec cache prefetching.
   107  *
   108  *  Don't use this on a G5...however, the speed boost is very significant
   109  *   on a G4.
   110  */
   111 #define DST_CHAN_SRC 1
   112 #define DST_CHAN_DEST 2
   113 
   114 /* macro to set DST control word value... */
   115 #define DST_CTRL(size, count, stride) \
   116     (((size) << 24) | ((count) << 16) | (stride))
   117 
   118 #define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \
   119     ? vec_lvsl(0, src) \
   120     : vec_add(vec_lvsl(8, src), vec_splat_u8(8)))
   121 
   122 /* Calculate the permute vector used for 32->32 swizzling */
   123 static vector unsigned char
   124 calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt)
   125 {
   126     /*
   127      * We have to assume that the bits that aren't used by other
   128      *  colors is alpha, and it's one complete byte, since some formats
   129      *  leave alpha with a zero mask, but we should still swizzle the bits.
   130      */
   131     /* ARGB */
   132     const static const struct SDL_PixelFormat default_pixel_format = {
   133         0, NULL, 0, 0,
   134         {0, 0},
   135         0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
   136         0, 0, 0, 0,
   137         16, 8, 0, 24,
   138         0, NULL
   139     };
   140     const vector unsigned char plus = VECUINT8_LITERAL(0x00, 0x00, 0x00, 0x00,
   141                                                        0x04, 0x04, 0x04, 0x04,
   142                                                        0x08, 0x08, 0x08, 0x08,
   143                                                        0x0C, 0x0C, 0x0C,
   144                                                        0x0C);
   145     vector unsigned char vswiz;
   146     vector unsigned int srcvec;
   147     Uint32 rmask, gmask, bmask, amask;
   148 
   149     if (!srcfmt) {
   150         srcfmt = &default_pixel_format;
   151     }
   152     if (!dstfmt) {
   153         dstfmt = &default_pixel_format;
   154     }
   155 
   156 #define RESHIFT(X) (3 - ((X) >> 3))
   157     rmask = RESHIFT(srcfmt->Rshift) << (dstfmt->Rshift);
   158     gmask = RESHIFT(srcfmt->Gshift) << (dstfmt->Gshift);
   159     bmask = RESHIFT(srcfmt->Bshift) << (dstfmt->Bshift);
   160 
   161     /* Use zero for alpha if either surface doesn't have alpha */
   162     if (dstfmt->Amask) {
   163         amask =
   164             ((srcfmt->Amask) ? RESHIFT(srcfmt->
   165                                        Ashift) : 0x10) << (dstfmt->Ashift);
   166     } else {
   167         amask =
   168             0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^
   169                           0xFFFFFFFF);
   170     }
   171 #undef RESHIFT
   172 
   173     ((unsigned int *) (char *) &srcvec)[0] = (rmask | gmask | bmask | amask);
   174     vswiz = vec_add(plus, (vector unsigned char) vec_splat(srcvec, 0));
   175     return (vswiz);
   176 }
   177 
   178 #if defined(__powerpc__) && (SDL_BYTEORDER == SDL_LIL_ENDIAN)
   179 /* reorder bytes for PowerPC little endian */
   180 static vector unsigned char reorder_ppc64le_vec(vector unsigned char vpermute)
   181 {
   182     /* The result vector of calc_swizzle32 reorder bytes using vec_perm.
   183        The LE transformation for vec_perm has an implicit assumption
   184        that the permutation is being used to reorder vector elements,
   185        not to reorder bytes within those elements.  
   186        Unfortunatly the result order is not the expected one for powerpc
   187        little endian when the two first vector parameters of vec_perm are
   188        not of type 'vector char'. This is because the numbering from the
   189        left for BE, and numbering from the right for LE, produces a
   190        different interpretation of what the odd and even lanes are.
   191        Refer to fedora bug 1392465
   192      */
   193 
   194     const vector unsigned char ppc64le_reorder = VECUINT8_LITERAL(
   195                                       0x01, 0x00, 0x03, 0x02,
   196                                       0x05, 0x04, 0x07, 0x06,
   197                                       0x09, 0x08, 0x0B, 0x0A,
   198                                       0x0D, 0x0C, 0x0F, 0x0E );
   199 
   200     vector unsigned char vswiz_ppc64le;
   201     vswiz_ppc64le = vec_perm(vpermute, vpermute, ppc64le_reorder);
   202     return(vswiz_ppc64le);
   203 }
   204 #endif
   205 
   206 static void Blit_RGB888_RGB565(SDL_BlitInfo * info);
   207 static void
   208 Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info)
   209 {
   210     int height = info->dst_h;
   211     Uint8 *src = (Uint8 *) info->src;
   212     int srcskip = info->src_skip;
   213     Uint8 *dst = (Uint8 *) info->dst;
   214     int dstskip = info->dst_skip;
   215     SDL_PixelFormat *srcfmt = info->src_fmt;
   216     vector unsigned char valpha = vec_splat_u8(0);
   217     vector unsigned char vpermute = calc_swizzle32(srcfmt, NULL);
   218     vector unsigned char vgmerge = VECUINT8_LITERAL(0x00, 0x02, 0x00, 0x06,
   219                                                     0x00, 0x0a, 0x00, 0x0e,
   220                                                     0x00, 0x12, 0x00, 0x16,
   221                                                     0x00, 0x1a, 0x00, 0x1e);
   222     vector unsigned short v1 = vec_splat_u16(1);
   223     vector unsigned short v3 = vec_splat_u16(3);
   224     vector unsigned short v3f =
   225         VECUINT16_LITERAL(0x003f, 0x003f, 0x003f, 0x003f,
   226                           0x003f, 0x003f, 0x003f, 0x003f);
   227     vector unsigned short vfc =
   228         VECUINT16_LITERAL(0x00fc, 0x00fc, 0x00fc, 0x00fc,
   229                           0x00fc, 0x00fc, 0x00fc, 0x00fc);
   230     vector unsigned short vf800 = (vector unsigned short) vec_splat_u8(-7);
   231     vf800 = vec_sl(vf800, vec_splat_u16(8));
   232 
   233     while (height--) {
   234         vector unsigned char valigner;
   235         vector unsigned char voverflow;
   236         vector unsigned char vsrc;
   237 
   238         int width = info->dst_w;
   239         int extrawidth;
   240 
   241         /* do scalar until we can align... */
   242 #define ONE_PIXEL_BLEND(condition, widthvar) \
   243         while (condition) { \
   244             Uint32 Pixel; \
   245             unsigned sR, sG, sB, sA; \
   246             DISEMBLE_RGBA((Uint8 *)src, 4, srcfmt, Pixel, \
   247                           sR, sG, sB, sA); \
   248             *(Uint16 *)(dst) = (((sR << 8) & 0x0000F800) | \
   249                                 ((sG << 3) & 0x000007E0) | \
   250                                 ((sB >> 3) & 0x0000001F)); \
   251             dst += 2; \
   252             src += 4; \
   253             widthvar--; \
   254         }
   255 
   256         ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
   257 
   258         /* After all that work, here's the vector part! */
   259         extrawidth = (width % 8);       /* trailing unaligned stores */
   260         width -= extrawidth;
   261         vsrc = vec_ld(0, src);
   262         valigner = VEC_ALIGNER(src);
   263 
   264         while (width) {
   265             vector unsigned short vpixel, vrpixel, vgpixel, vbpixel;
   266             vector unsigned int vsrc1, vsrc2;
   267             vector unsigned char vdst;
   268 
   269             voverflow = vec_ld(15, src);
   270             vsrc = vec_perm(vsrc, voverflow, valigner);
   271             vsrc1 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
   272             src += 16;
   273             vsrc = voverflow;
   274             voverflow = vec_ld(15, src);
   275             vsrc = vec_perm(vsrc, voverflow, valigner);
   276             vsrc2 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
   277             /* 1555 */
   278             vpixel = (vector unsigned short) vec_packpx(vsrc1, vsrc2);
   279             vgpixel = (vector unsigned short) vec_perm(vsrc1, vsrc2, vgmerge);
   280             vgpixel = vec_and(vgpixel, vfc);
   281             vgpixel = vec_sl(vgpixel, v3);
   282             vrpixel = vec_sl(vpixel, v1);
   283             vrpixel = vec_and(vrpixel, vf800);
   284             vbpixel = vec_and(vpixel, v3f);
   285             vdst =
   286                 vec_or((vector unsigned char) vrpixel,
   287                        (vector unsigned char) vgpixel);
   288             /* 565 */
   289             vdst = vec_or(vdst, (vector unsigned char) vbpixel);
   290             vec_st(vdst, 0, dst);
   291 
   292             width -= 8;
   293             src += 16;
   294             dst += 16;
   295             vsrc = voverflow;
   296         }
   297 
   298         SDL_assert(width == 0);
   299 
   300         /* do scalar until we can align... */
   301         ONE_PIXEL_BLEND((extrawidth), extrawidth);
   302 #undef ONE_PIXEL_BLEND
   303 
   304         src += srcskip;         /* move to next row, accounting for pitch. */
   305         dst += dstskip;
   306     }
   307 
   308 
   309 }
   310 
   311 static void
   312 Blit_RGB565_32Altivec(SDL_BlitInfo * info)
   313 {
   314     int height = info->dst_h;
   315     Uint8 *src = (Uint8 *) info->src;
   316     int srcskip = info->src_skip;
   317     Uint8 *dst = (Uint8 *) info->dst;
   318     int dstskip = info->dst_skip;
   319     SDL_PixelFormat *srcfmt = info->src_fmt;
   320     SDL_PixelFormat *dstfmt = info->dst_fmt;
   321     unsigned alpha;
   322     vector unsigned char valpha;
   323     vector unsigned char vpermute;
   324     vector unsigned short vf800;
   325     vector unsigned int v8 = vec_splat_u32(8);
   326     vector unsigned int v16 = vec_add(v8, v8);
   327     vector unsigned short v2 = vec_splat_u16(2);
   328     vector unsigned short v3 = vec_splat_u16(3);
   329     /*
   330        0x10 - 0x1f is the alpha
   331        0x00 - 0x0e evens are the red
   332        0x01 - 0x0f odds are zero
   333      */
   334     vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
   335                                                        0x10, 0x02, 0x01, 0x01,
   336                                                        0x10, 0x04, 0x01, 0x01,
   337                                                        0x10, 0x06, 0x01,
   338                                                        0x01);
   339     vector unsigned char vredalpha2 =
   340         (vector unsigned
   341          char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
   342         );
   343     /*
   344        0x00 - 0x0f is ARxx ARxx ARxx ARxx
   345        0x11 - 0x0f odds are blue
   346      */
   347     vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
   348                                                    0x04, 0x05, 0x06, 0x13,
   349                                                    0x08, 0x09, 0x0a, 0x15,
   350                                                    0x0c, 0x0d, 0x0e, 0x17);
   351     vector unsigned char vblue2 =
   352         (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
   353         );
   354     /*
   355        0x00 - 0x0f is ARxB ARxB ARxB ARxB
   356        0x10 - 0x0e evens are green
   357      */
   358     vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
   359                                                     0x04, 0x05, 0x12, 0x07,
   360                                                     0x08, 0x09, 0x14, 0x0b,
   361                                                     0x0c, 0x0d, 0x16, 0x0f);
   362     vector unsigned char vgreen2 =
   363         (vector unsigned
   364          char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
   365         );
   366 
   367     SDL_assert(srcfmt->BytesPerPixel == 2);
   368     SDL_assert(dstfmt->BytesPerPixel == 4);
   369 
   370     vf800 = (vector unsigned short) vec_splat_u8(-7);
   371     vf800 = vec_sl(vf800, vec_splat_u16(8));
   372 
   373     if (dstfmt->Amask && info->a) {
   374         ((unsigned char *) &valpha)[0] = alpha = info->a;
   375         valpha = vec_splat(valpha, 0);
   376     } else {
   377         alpha = 0;
   378         valpha = vec_splat_u8(0);
   379     }
   380 
   381     vpermute = calc_swizzle32(NULL, dstfmt);
   382     while (height--) {
   383         vector unsigned char valigner;
   384         vector unsigned char voverflow;
   385         vector unsigned char vsrc;
   386 
   387         int width = info->dst_w;
   388         int extrawidth;
   389 
   390         /* do scalar until we can align... */
   391 #define ONE_PIXEL_BLEND(condition, widthvar) \
   392         while (condition) { \
   393             unsigned sR, sG, sB; \
   394             unsigned short Pixel = *((unsigned short *)src); \
   395             sR = (Pixel >> 8) & 0xf8; \
   396             sG = (Pixel >> 3) & 0xfc; \
   397             sB = (Pixel << 3) & 0xf8; \
   398             ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
   399             src += 2; \
   400             dst += 4; \
   401             widthvar--; \
   402         }
   403         ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
   404 
   405         /* After all that work, here's the vector part! */
   406         extrawidth = (width % 8);       /* trailing unaligned stores */
   407         width -= extrawidth;
   408         vsrc = vec_ld(0, src);
   409         valigner = VEC_ALIGNER(src);
   410 
   411         while (width) {
   412             vector unsigned short vR, vG, vB;
   413             vector unsigned char vdst1, vdst2;
   414 
   415             voverflow = vec_ld(15, src);
   416             vsrc = vec_perm(vsrc, voverflow, valigner);
   417 
   418             vR = vec_and((vector unsigned short) vsrc, vf800);
   419             vB = vec_sl((vector unsigned short) vsrc, v3);
   420             vG = vec_sl(vB, v2);
   421 
   422             vdst1 =
   423                 (vector unsigned char) vec_perm((vector unsigned char) vR,
   424                                                 valpha, vredalpha1);
   425             vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
   426             vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
   427             vdst1 = vec_perm(vdst1, valpha, vpermute);
   428             vec_st(vdst1, 0, dst);
   429 
   430             vdst2 =
   431                 (vector unsigned char) vec_perm((vector unsigned char) vR,
   432                                                 valpha, vredalpha2);
   433             vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
   434             vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
   435             vdst2 = vec_perm(vdst2, valpha, vpermute);
   436             vec_st(vdst2, 16, dst);
   437 
   438             width -= 8;
   439             dst += 32;
   440             src += 16;
   441             vsrc = voverflow;
   442         }
   443 
   444         SDL_assert(width == 0);
   445 
   446 
   447         /* do scalar until we can align... */
   448         ONE_PIXEL_BLEND((extrawidth), extrawidth);
   449 #undef ONE_PIXEL_BLEND
   450 
   451         src += srcskip;         /* move to next row, accounting for pitch. */
   452         dst += dstskip;
   453     }
   454 
   455 }
   456 
   457 
   458 static void
   459 Blit_RGB555_32Altivec(SDL_BlitInfo * info)
   460 {
   461     int height = info->dst_h;
   462     Uint8 *src = (Uint8 *) info->src;
   463     int srcskip = info->src_skip;
   464     Uint8 *dst = (Uint8 *) info->dst;
   465     int dstskip = info->dst_skip;
   466     SDL_PixelFormat *srcfmt = info->src_fmt;
   467     SDL_PixelFormat *dstfmt = info->dst_fmt;
   468     unsigned alpha;
   469     vector unsigned char valpha;
   470     vector unsigned char vpermute;
   471     vector unsigned short vf800;
   472     vector unsigned int v8 = vec_splat_u32(8);
   473     vector unsigned int v16 = vec_add(v8, v8);
   474     vector unsigned short v1 = vec_splat_u16(1);
   475     vector unsigned short v3 = vec_splat_u16(3);
   476     /*
   477        0x10 - 0x1f is the alpha
   478        0x00 - 0x0e evens are the red
   479        0x01 - 0x0f odds are zero
   480      */
   481     vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
   482                                                        0x10, 0x02, 0x01, 0x01,
   483                                                        0x10, 0x04, 0x01, 0x01,
   484                                                        0x10, 0x06, 0x01,
   485                                                        0x01);
   486     vector unsigned char vredalpha2 =
   487         (vector unsigned
   488          char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
   489         );
   490     /*
   491        0x00 - 0x0f is ARxx ARxx ARxx ARxx
   492        0x11 - 0x0f odds are blue
   493      */
   494     vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
   495                                                    0x04, 0x05, 0x06, 0x13,
   496                                                    0x08, 0x09, 0x0a, 0x15,
   497                                                    0x0c, 0x0d, 0x0e, 0x17);
   498     vector unsigned char vblue2 =
   499         (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
   500         );
   501     /*
   502        0x00 - 0x0f is ARxB ARxB ARxB ARxB
   503        0x10 - 0x0e evens are green
   504      */
   505     vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
   506                                                     0x04, 0x05, 0x12, 0x07,
   507                                                     0x08, 0x09, 0x14, 0x0b,
   508                                                     0x0c, 0x0d, 0x16, 0x0f);
   509     vector unsigned char vgreen2 =
   510         (vector unsigned
   511          char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
   512         );
   513 
   514     SDL_assert(srcfmt->BytesPerPixel == 2);
   515     SDL_assert(dstfmt->BytesPerPixel == 4);
   516 
   517     vf800 = (vector unsigned short) vec_splat_u8(-7);
   518     vf800 = vec_sl(vf800, vec_splat_u16(8));
   519 
   520     if (dstfmt->Amask && info->a) {
   521         ((unsigned char *) &valpha)[0] = alpha = info->a;
   522         valpha = vec_splat(valpha, 0);
   523     } else {
   524         alpha = 0;
   525         valpha = vec_splat_u8(0);
   526     }
   527 
   528     vpermute = calc_swizzle32(NULL, dstfmt);
   529     while (height--) {
   530         vector unsigned char valigner;
   531         vector unsigned char voverflow;
   532         vector unsigned char vsrc;
   533 
   534         int width = info->dst_w;
   535         int extrawidth;
   536 
   537         /* do scalar until we can align... */
   538 #define ONE_PIXEL_BLEND(condition, widthvar) \
   539         while (condition) { \
   540             unsigned sR, sG, sB; \
   541             unsigned short Pixel = *((unsigned short *)src); \
   542             sR = (Pixel >> 7) & 0xf8; \
   543             sG = (Pixel >> 2) & 0xf8; \
   544             sB = (Pixel << 3) & 0xf8; \
   545             ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
   546             src += 2; \
   547             dst += 4; \
   548             widthvar--; \
   549         }
   550         ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
   551 
   552         /* After all that work, here's the vector part! */
   553         extrawidth = (width % 8);       /* trailing unaligned stores */
   554         width -= extrawidth;
   555         vsrc = vec_ld(0, src);
   556         valigner = VEC_ALIGNER(src);
   557 
   558         while (width) {
   559             vector unsigned short vR, vG, vB;
   560             vector unsigned char vdst1, vdst2;
   561 
   562             voverflow = vec_ld(15, src);
   563             vsrc = vec_perm(vsrc, voverflow, valigner);
   564 
   565             vR = vec_and(vec_sl((vector unsigned short) vsrc, v1), vf800);
   566             vB = vec_sl((vector unsigned short) vsrc, v3);
   567             vG = vec_sl(vB, v3);
   568 
   569             vdst1 =
   570                 (vector unsigned char) vec_perm((vector unsigned char) vR,
   571                                                 valpha, vredalpha1);
   572             vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
   573             vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
   574             vdst1 = vec_perm(vdst1, valpha, vpermute);
   575             vec_st(vdst1, 0, dst);
   576 
   577             vdst2 =
   578                 (vector unsigned char) vec_perm((vector unsigned char) vR,
   579                                                 valpha, vredalpha2);
   580             vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
   581             vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
   582             vdst2 = vec_perm(vdst2, valpha, vpermute);
   583             vec_st(vdst2, 16, dst);
   584 
   585             width -= 8;
   586             dst += 32;
   587             src += 16;
   588             vsrc = voverflow;
   589         }
   590 
   591         SDL_assert(width == 0);
   592 
   593 
   594         /* do scalar until we can align... */
   595         ONE_PIXEL_BLEND((extrawidth), extrawidth);
   596 #undef ONE_PIXEL_BLEND
   597 
   598         src += srcskip;         /* move to next row, accounting for pitch. */
   599         dst += dstskip;
   600     }
   601 
   602 }
   603 
   604 static void BlitNtoNKey(SDL_BlitInfo * info);
   605 static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info);
   606 static void
   607 Blit32to32KeyAltivec(SDL_BlitInfo * info)
   608 {
   609     int height = info->dst_h;
   610     Uint32 *srcp = (Uint32 *) info->src;
   611     int srcskip = info->src_skip / 4;
   612     Uint32 *dstp = (Uint32 *) info->dst;
   613     int dstskip = info->dst_skip / 4;
   614     SDL_PixelFormat *srcfmt = info->src_fmt;
   615     int srcbpp = srcfmt->BytesPerPixel;
   616     SDL_PixelFormat *dstfmt = info->dst_fmt;
   617     int dstbpp = dstfmt->BytesPerPixel;
   618     int copy_alpha = (srcfmt->Amask && dstfmt->Amask);
   619     unsigned alpha = dstfmt->Amask ? info->a : 0;
   620     Uint32 rgbmask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
   621     Uint32 ckey = info->colorkey;
   622     vector unsigned int valpha;
   623     vector unsigned char vpermute;
   624     vector unsigned char vzero;
   625     vector unsigned int vckey;
   626     vector unsigned int vrgbmask;
   627     vpermute = calc_swizzle32(srcfmt, dstfmt);
   628     if (info->dst_w < 16) {
   629         if (copy_alpha) {
   630             BlitNtoNKeyCopyAlpha(info);
   631         } else {
   632             BlitNtoNKey(info);
   633         }
   634         return;
   635     }
   636     vzero = vec_splat_u8(0);
   637     if (alpha) {
   638         ((unsigned char *) &valpha)[0] = (unsigned char) alpha;
   639         valpha =
   640             (vector unsigned int) vec_splat((vector unsigned char) valpha, 0);
   641     } else {
   642         valpha = (vector unsigned int) vzero;
   643     }
   644     ckey &= rgbmask;
   645     ((unsigned int *) (char *) &vckey)[0] = ckey;
   646     vckey = vec_splat(vckey, 0);
   647     ((unsigned int *) (char *) &vrgbmask)[0] = rgbmask;
   648     vrgbmask = vec_splat(vrgbmask, 0);
   649 
   650     while (height--) {
   651 #define ONE_PIXEL_BLEND(condition, widthvar) \
   652         if (copy_alpha) { \
   653             while (condition) { \
   654                 Uint32 Pixel; \
   655                 unsigned sR, sG, sB, sA; \
   656                 DISEMBLE_RGBA((Uint8 *)srcp, srcbpp, srcfmt, Pixel, \
   657                           sR, sG, sB, sA); \
   658                 if ( (Pixel & rgbmask) != ckey ) { \
   659                       ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
   660                             sR, sG, sB, sA); \
   661                 } \
   662                 dstp = (Uint32 *) (((Uint8 *) dstp) + dstbpp); \
   663                 srcp = (Uint32 *) (((Uint8 *) srcp) + srcbpp); \
   664                 widthvar--; \
   665             } \
   666         } else { \
   667             while (condition) { \
   668                 Uint32 Pixel; \
   669                 unsigned sR, sG, sB; \
   670                 RETRIEVE_RGB_PIXEL((Uint8 *)srcp, srcbpp, Pixel); \
   671                 if ( Pixel != ckey ) { \
   672                     RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \
   673                     ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
   674                               sR, sG, sB, alpha); \
   675                 } \
   676                 dstp = (Uint32 *) (((Uint8 *)dstp) + dstbpp); \
   677                 srcp = (Uint32 *) (((Uint8 *)srcp) + srcbpp); \
   678                 widthvar--; \
   679             } \
   680         }
   681         int width = info->dst_w;
   682         ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
   683         SDL_assert(width > 0);
   684         if (width > 0) {
   685             int extrawidth = (width % 4);
   686             vector unsigned char valigner = VEC_ALIGNER(srcp);
   687             vector unsigned int vs = vec_ld(0, srcp);
   688             width -= extrawidth;
   689             SDL_assert(width >= 4);
   690             while (width) {
   691                 vector unsigned char vsel;
   692                 vector unsigned int vd;
   693                 vector unsigned int voverflow = vec_ld(15, srcp);
   694                 /* load the source vec */
   695                 vs = vec_perm(vs, voverflow, valigner);
   696                 /* vsel is set for items that match the key */
   697                 vsel = (vector unsigned char) vec_and(vs, vrgbmask);
   698                 vsel = (vector unsigned char) vec_cmpeq(vs, vckey);
   699 #if defined(__powerpc__) && (SDL_BYTEORDER == SDL_LIL_ENDIAN)
   700                 /* reorder bytes for PowerPC little endian */
   701                 vpermute = reorder_ppc64le_vec(vpermute);
   702 #endif
   703                 /* permute the src vec to the dest format */
   704                 vs = vec_perm(vs, valpha, vpermute);
   705                 /* load the destination vec */
   706                 vd = vec_ld(0, dstp);
   707                 /* select the source and dest into vs */
   708                 vd = (vector unsigned int) vec_sel((vector unsigned char) vs,
   709                                                    (vector unsigned char) vd,
   710                                                    vsel);
   711 
   712                 vec_st(vd, 0, dstp);
   713                 srcp += 4;
   714                 width -= 4;
   715                 dstp += 4;
   716                 vs = voverflow;
   717             }
   718             ONE_PIXEL_BLEND((extrawidth), extrawidth);
   719 #undef ONE_PIXEL_BLEND
   720             srcp += srcskip;
   721             dstp += dstskip;
   722         }
   723     }
   724 }
   725 
   726 /* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
   727 /* Use this on a G5 */
   728 static void
   729 ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info)
   730 {
   731     int height = info->dst_h;
   732     Uint32 *src = (Uint32 *) info->src;
   733     int srcskip = info->src_skip / 4;
   734     Uint32 *dst = (Uint32 *) info->dst;
   735     int dstskip = info->dst_skip / 4;
   736     SDL_PixelFormat *srcfmt = info->src_fmt;
   737     SDL_PixelFormat *dstfmt = info->dst_fmt;
   738     vector unsigned int vzero = vec_splat_u32(0);
   739     vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
   740     if (dstfmt->Amask && !srcfmt->Amask) {
   741         if (info->a) {
   742             vector unsigned char valpha;
   743             ((unsigned char *) &valpha)[0] = info->a;
   744             vzero = (vector unsigned int) vec_splat(valpha, 0);
   745         }
   746     }
   747 
   748     SDL_assert(srcfmt->BytesPerPixel == 4);
   749     SDL_assert(dstfmt->BytesPerPixel == 4);
   750 
   751     while (height--) {
   752         vector unsigned char valigner;
   753         vector unsigned int vbits;
   754         vector unsigned int voverflow;
   755         Uint32 bits;
   756         Uint8 r, g, b, a;
   757 
   758         int width = info->dst_w;
   759         int extrawidth;
   760 
   761         /* do scalar until we can align... */
   762         while ((UNALIGNED_PTR(dst)) && (width)) {
   763             bits = *(src++);
   764             RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
   765             if(!srcfmt->Amask)
   766               a = info->a;
   767             *(dst++) = MAKE8888(dstfmt, r, g, b, a);
   768             width--;
   769         }
   770 
   771         /* After all that work, here's the vector part! */
   772         extrawidth = (width % 4);
   773         width -= extrawidth;
   774         valigner = VEC_ALIGNER(src);
   775         vbits = vec_ld(0, src);
   776 
   777         while (width) {
   778             voverflow = vec_ld(15, src);
   779             src += 4;
   780             width -= 4;
   781             vbits = vec_perm(vbits, voverflow, valigner);       /* src is ready. */
   782 #if defined(__powerpc__) && (SDL_BYTEORDER == SDL_LIL_ENDIAN)
   783             /* reorder bytes for PowerPC little endian */
   784             vpermute = reorder_ppc64le_vec(vpermute);
   785 #endif
   786             vbits = vec_perm(vbits, vzero, vpermute);   /* swizzle it. */
   787             vec_st(vbits, 0, dst);      /* store it back out. */
   788             dst += 4;
   789             vbits = voverflow;
   790         }
   791 
   792         SDL_assert(width == 0);
   793 
   794         /* cover pixels at the end of the row that didn't fit in 16 bytes. */
   795         while (extrawidth) {
   796             bits = *(src++);    /* max 7 pixels, don't bother with prefetch. */
   797             RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
   798             if(!srcfmt->Amask)
   799               a = info->a;
   800             *(dst++) = MAKE8888(dstfmt, r, g, b, a);
   801             extrawidth--;
   802         }
   803 
   804         src += srcskip;
   805         dst += dstskip;
   806     }
   807 
   808 }
   809 
   810 /* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
   811 /* Use this on a G4 */
   812 static void
   813 ConvertAltivec32to32_prefetch(SDL_BlitInfo * info)
   814 {
   815     const int scalar_dst_lead = sizeof(Uint32) * 4;
   816     const int vector_dst_lead = sizeof(Uint32) * 16;
   817 
   818     int height = info->dst_h;
   819     Uint32 *src = (Uint32 *) info->src;
   820     int srcskip = info->src_skip / 4;
   821     Uint32 *dst = (Uint32 *) info->dst;
   822     int dstskip = info->dst_skip / 4;
   823     SDL_PixelFormat *srcfmt = info->src_fmt;
   824     SDL_PixelFormat *dstfmt = info->dst_fmt;
   825     vector unsigned int vzero = vec_splat_u32(0);
   826     vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
   827     if (dstfmt->Amask && !srcfmt->Amask) {
   828         if (info->a) {
   829             vector unsigned char valpha;
   830             ((unsigned char *) &valpha)[0] = info->a;
   831             vzero = (vector unsigned int) vec_splat(valpha, 0);
   832         }
   833     }
   834 
   835     SDL_assert(srcfmt->BytesPerPixel == 4);
   836     SDL_assert(dstfmt->BytesPerPixel == 4);
   837 
   838     while (height--) {
   839         vector unsigned char valigner;
   840         vector unsigned int vbits;
   841         vector unsigned int voverflow;
   842         Uint32 bits;
   843         Uint8 r, g, b, a;
   844 
   845         int width = info->dst_w;
   846         int extrawidth;
   847 
   848         /* do scalar until we can align... */
   849         while ((UNALIGNED_PTR(dst)) && (width)) {
   850             vec_dstt(src + scalar_dst_lead, DST_CTRL(2, 32, 1024),
   851                      DST_CHAN_SRC);
   852             vec_dstst(dst + scalar_dst_lead, DST_CTRL(2, 32, 1024),
   853                       DST_CHAN_DEST);
   854             bits = *(src++);
   855             RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
   856             if(!srcfmt->Amask)
   857               a = info->a;
   858             *(dst++) = MAKE8888(dstfmt, r, g, b, a);
   859             width--;
   860         }
   861 
   862         /* After all that work, here's the vector part! */
   863         extrawidth = (width % 4);
   864         width -= extrawidth;
   865         valigner = VEC_ALIGNER(src);
   866         vbits = vec_ld(0, src);
   867 
   868         while (width) {
   869             vec_dstt(src + vector_dst_lead, DST_CTRL(2, 32, 1024),
   870                      DST_CHAN_SRC);
   871             vec_dstst(dst + vector_dst_lead, DST_CTRL(2, 32, 1024),
   872                       DST_CHAN_DEST);
   873             voverflow = vec_ld(15, src);
   874             src += 4;
   875             width -= 4;
   876             vbits = vec_perm(vbits, voverflow, valigner);       /* src is ready. */
   877 #if defined(__powerpc__) && (SDL_BYTEORDER == SDL_LIL_ENDIAN)
   878             /* reorder bytes for PowerPC little endian */
   879             vpermute = reorder_ppc64le_vec(vpermute);
   880 #endif
   881             vbits = vec_perm(vbits, vzero, vpermute);   /* swizzle it. */
   882             vec_st(vbits, 0, dst);      /* store it back out. */
   883             dst += 4;
   884             vbits = voverflow;
   885         }
   886 
   887         SDL_assert(width == 0);
   888 
   889         /* cover pixels at the end of the row that didn't fit in 16 bytes. */
   890         while (extrawidth) {
   891             bits = *(src++);    /* max 7 pixels, don't bother with prefetch. */
   892             RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
   893             if(!srcfmt->Amask)
   894               a = info->a;
   895             *(dst++) = MAKE8888(dstfmt, r, g, b, a);
   896             extrawidth--;
   897         }
   898 
   899         src += srcskip;
   900         dst += dstskip;
   901     }
   902 
   903     vec_dss(DST_CHAN_SRC);
   904     vec_dss(DST_CHAN_DEST);
   905 }
   906 
   907 static enum blit_features
   908 GetBlitFeatures(void)
   909 {
   910     static enum blit_features features = -1;
   911     if (features == (enum blit_features) -1) {
   912         /* Provide an override for testing .. */
   913         char *override = SDL_getenv("SDL_ALTIVEC_BLIT_FEATURES");
   914         if (override) {
   915             unsigned int features_as_uint = 0;
   916             SDL_sscanf(override, "%u", &features_as_uint);
   917             features = (enum blit_features) features_as_uint;
   918         } else {
   919             features = (0
   920                         /* Feature 1 is has-MMX */
   921                         | ((SDL_HasMMX())? BLIT_FEATURE_HAS_MMX : 0)
   922                         /* Feature 2 is has-AltiVec */
   923                         | ((SDL_HasAltiVec())? BLIT_FEATURE_HAS_ALTIVEC : 0)
   924                         /* Feature 4 is dont-use-prefetch */
   925                         /* !!!! FIXME: Check for G5 or later, not the cache size! Always prefetch on a G4. */
   926                         | ((GetL3CacheSize() == 0) ? BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH : 0)
   927                 );
   928         }
   929     }
   930     return features;
   931 }
   932 
   933 #if __MWERKS__
   934 #pragma altivec_model off
   935 #endif
   936 #else
   937 /* Feature 1 is has-MMX */
   938 #define GetBlitFeatures() ((SDL_HasMMX() ? BLIT_FEATURE_HAS_MMX : 0) | (SDL_HasARMSIMD() ? BLIT_FEATURE_HAS_ARM_SIMD : 0))
   939 #endif
   940 
   941 #if SDL_ARM_SIMD_BLITTERS
   942 void Blit_BGR888_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride);
   943 
   944 static void
   945 Blit_BGR888_RGB888ARMSIMD(SDL_BlitInfo * info)
   946 {
   947 	int32_t width = info->dst_w;
   948 	int32_t height = info->dst_h;
   949 	uint32_t *dstp = (uint32_t *)info->dst;
   950 	int32_t dststride = width + (info->dst_skip >> 2);
   951 	uint32_t *srcp = (uint32_t *)info->src;
   952 	int32_t srcstride = width + (info->src_skip >> 2);
   953 
   954 	Blit_BGR888_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
   955 }
   956 
   957 void Blit_RGB444_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint16_t *src, int32_t src_stride);
   958 
   959 static void
   960 Blit_RGB444_RGB888ARMSIMD(SDL_BlitInfo * info)
   961 {
   962 	int32_t width = info->dst_w;
   963 	int32_t height = info->dst_h;
   964 	uint32_t *dstp = (uint32_t *)info->dst;
   965 	int32_t dststride = width + (info->dst_skip >> 2);
   966 	uint16_t *srcp = (uint16_t *)info->src;
   967 	int32_t srcstride = width + (info->src_skip >> 1);
   968 
   969 	Blit_RGB444_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
   970 }
   971 #endif
   972 
   973 /* This is now endian dependent */
   974 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   975 #define HI  1
   976 #define LO  0
   977 #else /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
   978 #define HI  0
   979 #define LO  1
   980 #endif
   981 
   982 /* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */
   983 #define RGB888_RGB332(dst, src) { \
   984     dst = (Uint8)((((src)&0x00E00000)>>16)| \
   985                   (((src)&0x0000E000)>>11)| \
   986                   (((src)&0x000000C0)>>6)); \
   987 }
   988 static void
   989 Blit_RGB888_index8(SDL_BlitInfo * info)
   990 {
   991 #ifndef USE_DUFFS_LOOP
   992     int c;
   993 #endif
   994     int width, height;
   995     Uint32 *src;
   996     const Uint8 *map;
   997     Uint8 *dst;
   998     int srcskip, dstskip;
   999 
  1000     /* Set up some basic variables */
  1001     width = info->dst_w;
  1002     height = info->dst_h;
  1003     src = (Uint32 *) info->src;
  1004     srcskip = info->src_skip / 4;
  1005     dst = info->dst;
  1006     dstskip = info->dst_skip;
  1007     map = info->table;
  1008 
  1009     if (map == NULL) {
  1010         while (height--) {
  1011 #ifdef USE_DUFFS_LOOP
  1012             /* *INDENT-OFF* */
  1013             DUFFS_LOOP(
  1014                 RGB888_RGB332(*dst++, *src);
  1015             , width);
  1016             /* *INDENT-ON* */
  1017 #else
  1018             for (c = width / 4; c; --c) {
  1019                 /* Pack RGB into 8bit pixel */
  1020                 ++src;
  1021                 RGB888_RGB332(*dst++, *src);
  1022                 ++src;
  1023                 RGB888_RGB332(*dst++, *src);
  1024                 ++src;
  1025                 RGB888_RGB332(*dst++, *src);
  1026                 ++src;
  1027             }
  1028             switch (width & 3) {
  1029             case 3:
  1030                 RGB888_RGB332(*dst++, *src);
  1031                 ++src;
  1032             case 2:
  1033                 RGB888_RGB332(*dst++, *src);
  1034                 ++src;
  1035             case 1:
  1036                 RGB888_RGB332(*dst++, *src);
  1037                 ++src;
  1038             }
  1039 #endif /* USE_DUFFS_LOOP */
  1040             src += srcskip;
  1041             dst += dstskip;
  1042         }
  1043     } else {
  1044         int Pixel;
  1045 
  1046         while (height--) {
  1047 #ifdef USE_DUFFS_LOOP
  1048             /* *INDENT-OFF* */
  1049             DUFFS_LOOP(
  1050                 RGB888_RGB332(Pixel, *src);
  1051                 *dst++ = map[Pixel];
  1052                 ++src;
  1053             , width);
  1054             /* *INDENT-ON* */
  1055 #else
  1056             for (c = width / 4; c; --c) {
  1057                 /* Pack RGB into 8bit pixel */
  1058                 RGB888_RGB332(Pixel, *src);
  1059                 *dst++ = map[Pixel];
  1060                 ++src;
  1061                 RGB888_RGB332(Pixel, *src);
  1062                 *dst++ = map[Pixel];
  1063                 ++src;
  1064                 RGB888_RGB332(Pixel, *src);
  1065                 *dst++ = map[Pixel];
  1066                 ++src;
  1067                 RGB888_RGB332(Pixel, *src);
  1068                 *dst++ = map[Pixel];
  1069                 ++src;
  1070             }
  1071             switch (width & 3) {
  1072             case 3:
  1073                 RGB888_RGB332(Pixel, *src);
  1074                 *dst++ = map[Pixel];
  1075                 ++src;
  1076             case 2:
  1077                 RGB888_RGB332(Pixel, *src);
  1078                 *dst++ = map[Pixel];
  1079                 ++src;
  1080             case 1:
  1081                 RGB888_RGB332(Pixel, *src);
  1082                 *dst++ = map[Pixel];
  1083                 ++src;
  1084             }
  1085 #endif /* USE_DUFFS_LOOP */
  1086             src += srcskip;
  1087             dst += dstskip;
  1088         }
  1089     }
  1090 }
  1091 
  1092 /* Special optimized blit for RGB 10-10-10 --> RGB 3-3-2 */
  1093 #define RGB101010_RGB332(dst, src) { \
  1094     dst = (Uint8)((((src)&0x38000000)>>22)| \
  1095                   (((src)&0x000E0000)>>15)| \
  1096                   (((src)&0x00000300)>>8)); \
  1097 }
  1098 static void
  1099 Blit_RGB101010_index8(SDL_BlitInfo * info)
  1100 {
  1101 #ifndef USE_DUFFS_LOOP
  1102     int c;
  1103 #endif
  1104     int width, height;
  1105     Uint32 *src;
  1106     const Uint8 *map;
  1107     Uint8 *dst;
  1108     int srcskip, dstskip;
  1109 
  1110     /* Set up some basic variables */
  1111     width = info->dst_w;
  1112     height = info->dst_h;
  1113     src = (Uint32 *) info->src;
  1114     srcskip = info->src_skip / 4;
  1115     dst = info->dst;
  1116     dstskip = info->dst_skip;
  1117     map = info->table;
  1118 
  1119     if (map == NULL) {
  1120         while (height--) {
  1121 #ifdef USE_DUFFS_LOOP
  1122             /* *INDENT-OFF* */
  1123             DUFFS_LOOP(
  1124                 RGB101010_RGB332(*dst++, *src);
  1125             , width);
  1126             /* *INDENT-ON* */
  1127 #else
  1128             for (c = width / 4; c; --c) {
  1129                 /* Pack RGB into 8bit pixel */
  1130                 ++src;
  1131                 RGB101010_RGB332(*dst++, *src);
  1132                 ++src;
  1133                 RGB101010_RGB332(*dst++, *src);
  1134                 ++src;
  1135                 RGB101010_RGB332(*dst++, *src);
  1136                 ++src;
  1137             }
  1138             switch (width & 3) {
  1139             case 3:
  1140                 RGB101010_RGB332(*dst++, *src);
  1141                 ++src;
  1142             case 2:
  1143                 RGB101010_RGB332(*dst++, *src);
  1144                 ++src;
  1145             case 1:
  1146                 RGB101010_RGB332(*dst++, *src);
  1147                 ++src;
  1148             }
  1149 #endif /* USE_DUFFS_LOOP */
  1150             src += srcskip;
  1151             dst += dstskip;
  1152         }
  1153     } else {
  1154         int Pixel;
  1155 
  1156         while (height--) {
  1157 #ifdef USE_DUFFS_LOOP
  1158             /* *INDENT-OFF* */
  1159             DUFFS_LOOP(
  1160                 RGB101010_RGB332(Pixel, *src);
  1161                 *dst++ = map[Pixel];
  1162                 ++src;
  1163             , width);
  1164             /* *INDENT-ON* */
  1165 #else
  1166             for (c = width / 4; c; --c) {
  1167                 /* Pack RGB into 8bit pixel */
  1168                 RGB101010_RGB332(Pixel, *src);
  1169                 *dst++ = map[Pixel];
  1170                 ++src;
  1171                 RGB101010_RGB332(Pixel, *src);
  1172                 *dst++ = map[Pixel];
  1173                 ++src;
  1174                 RGB101010_RGB332(Pixel, *src);
  1175                 *dst++ = map[Pixel];
  1176                 ++src;
  1177                 RGB101010_RGB332(Pixel, *src);
  1178                 *dst++ = map[Pixel];
  1179                 ++src;
  1180             }
  1181             switch (width & 3) {
  1182             case 3:
  1183                 RGB101010_RGB332(Pixel, *src);
  1184                 *dst++ = map[Pixel];
  1185                 ++src;
  1186             case 2:
  1187                 RGB101010_RGB332(Pixel, *src);
  1188                 *dst++ = map[Pixel];
  1189                 ++src;
  1190             case 1:
  1191                 RGB101010_RGB332(Pixel, *src);
  1192                 *dst++ = map[Pixel];
  1193                 ++src;
  1194             }
  1195 #endif /* USE_DUFFS_LOOP */
  1196             src += srcskip;
  1197             dst += dstskip;
  1198         }
  1199     }
  1200 }
  1201 
  1202 /* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */
  1203 #define RGB888_RGB555(dst, src) { \
  1204     *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>9)| \
  1205                                 (((*src)&0x0000F800)>>6)| \
  1206                                 (((*src)&0x000000F8)>>3)); \
  1207 }
  1208 #ifndef USE_DUFFS_LOOP
  1209 #define RGB888_RGB555_TWO(dst, src) { \
  1210     *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \
  1211                          (((src[HI])&0x0000F800)>>6)| \
  1212                          (((src[HI])&0x000000F8)>>3))<<16)| \
  1213                          (((src[LO])&0x00F80000)>>9)| \
  1214                          (((src[LO])&0x0000F800)>>6)| \
  1215                          (((src[LO])&0x000000F8)>>3); \
  1216 }
  1217 #endif
  1218 static void
  1219 Blit_RGB888_RGB555(SDL_BlitInfo * info)
  1220 {
  1221 #ifndef USE_DUFFS_LOOP
  1222     int c;
  1223 #endif
  1224     int width, height;
  1225     Uint32 *src;
  1226     Uint16 *dst;
  1227     int srcskip, dstskip;
  1228 
  1229     /* Set up some basic variables */
  1230     width = info->dst_w;
  1231     height = info->dst_h;
  1232     src = (Uint32 *) info->src;
  1233     srcskip = info->src_skip / 4;
  1234     dst = (Uint16 *) info->dst;
  1235     dstskip = info->dst_skip / 2;
  1236 
  1237 #ifdef USE_DUFFS_LOOP
  1238     while (height--) {
  1239         /* *INDENT-OFF* */
  1240         DUFFS_LOOP(
  1241             RGB888_RGB555(dst, src);
  1242             ++src;
  1243             ++dst;
  1244         , width);
  1245         /* *INDENT-ON* */
  1246         src += srcskip;
  1247         dst += dstskip;
  1248     }
  1249 #else
  1250     /* Memory align at 4-byte boundary, if necessary */
  1251     if ((long) dst & 0x03) {
  1252         /* Don't do anything if width is 0 */
  1253         if (width == 0) {
  1254             return;
  1255         }
  1256         --width;
  1257 
  1258         while (height--) {
  1259             /* Perform copy alignment */
  1260             RGB888_RGB555(dst, src);
  1261             ++src;
  1262             ++dst;
  1263 
  1264             /* Copy in 4 pixel chunks */
  1265             for (c = width / 4; c; --c) {
  1266                 RGB888_RGB555_TWO(dst, src);
  1267                 src += 2;
  1268                 dst += 2;
  1269                 RGB888_RGB555_TWO(dst, src);
  1270                 src += 2;
  1271                 dst += 2;
  1272             }
  1273             /* Get any leftovers */
  1274             switch (width & 3) {
  1275             case 3:
  1276                 RGB888_RGB555(dst, src);
  1277                 ++src;
  1278                 ++dst;
  1279             case 2:
  1280                 RGB888_RGB555_TWO(dst, src);
  1281                 src += 2;
  1282                 dst += 2;
  1283                 break;
  1284             case 1:
  1285                 RGB888_RGB555(dst, src);
  1286                 ++src;
  1287                 ++dst;
  1288                 break;
  1289             }
  1290             src += srcskip;
  1291             dst += dstskip;
  1292         }
  1293     } else {
  1294         while (height--) {
  1295             /* Copy in 4 pixel chunks */
  1296             for (c = width / 4; c; --c) {
  1297                 RGB888_RGB555_TWO(dst, src);
  1298                 src += 2;
  1299                 dst += 2;
  1300                 RGB888_RGB555_TWO(dst, src);
  1301                 src += 2;
  1302                 dst += 2;
  1303             }
  1304             /* Get any leftovers */
  1305             switch (width & 3) {
  1306             case 3:
  1307                 RGB888_RGB555(dst, src);
  1308                 ++src;
  1309                 ++dst;
  1310             case 2:
  1311                 RGB888_RGB555_TWO(dst, src);
  1312                 src += 2;
  1313                 dst += 2;
  1314                 break;
  1315             case 1:
  1316                 RGB888_RGB555(dst, src);
  1317                 ++src;
  1318                 ++dst;
  1319                 break;
  1320             }
  1321             src += srcskip;
  1322             dst += dstskip;
  1323         }
  1324     }
  1325 #endif /* USE_DUFFS_LOOP */
  1326 }
  1327 
  1328 /* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */
  1329 #define RGB888_RGB565(dst, src) { \
  1330     *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>8)| \
  1331                                 (((*src)&0x0000FC00)>>5)| \
  1332                                 (((*src)&0x000000F8)>>3)); \
  1333 }
  1334 #ifndef USE_DUFFS_LOOP
  1335 #define RGB888_RGB565_TWO(dst, src) { \
  1336     *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \
  1337                          (((src[HI])&0x0000FC00)>>5)| \
  1338                          (((src[HI])&0x000000F8)>>3))<<16)| \
  1339                          (((src[LO])&0x00F80000)>>8)| \
  1340                          (((src[LO])&0x0000FC00)>>5)| \
  1341                          (((src[LO])&0x000000F8)>>3); \
  1342 }
  1343 #endif
  1344 static void
  1345 Blit_RGB888_RGB565(SDL_BlitInfo * info)
  1346 {
  1347 #ifndef USE_DUFFS_LOOP
  1348     int c;
  1349 #endif
  1350     int width, height;
  1351     Uint32 *src;
  1352     Uint16 *dst;
  1353     int srcskip, dstskip;
  1354 
  1355     /* Set up some basic variables */
  1356     width = info->dst_w;
  1357     height = info->dst_h;
  1358     src = (Uint32 *) info->src;
  1359     srcskip = info->src_skip / 4;
  1360     dst = (Uint16 *) info->dst;
  1361     dstskip = info->dst_skip / 2;
  1362 
  1363 #ifdef USE_DUFFS_LOOP
  1364     while (height--) {
  1365         /* *INDENT-OFF* */
  1366         DUFFS_LOOP(
  1367             RGB888_RGB565(dst, src);
  1368             ++src;
  1369             ++dst;
  1370         , width);
  1371         /* *INDENT-ON* */
  1372         src += srcskip;
  1373         dst += dstskip;
  1374     }
  1375 #else
  1376     /* Memory align at 4-byte boundary, if necessary */
  1377     if ((long) dst & 0x03) {
  1378         /* Don't do anything if width is 0 */
  1379         if (width == 0) {
  1380             return;
  1381         }
  1382         --width;
  1383 
  1384         while (height--) {
  1385             /* Perform copy alignment */
  1386             RGB888_RGB565(dst, src);
  1387             ++src;
  1388             ++dst;
  1389 
  1390             /* Copy in 4 pixel chunks */
  1391             for (c = width / 4; c; --c) {
  1392                 RGB888_RGB565_TWO(dst, src);
  1393                 src += 2;
  1394                 dst += 2;
  1395                 RGB888_RGB565_TWO(dst, src);
  1396                 src += 2;
  1397                 dst += 2;
  1398             }
  1399             /* Get any leftovers */
  1400             switch (width & 3) {
  1401             case 3:
  1402                 RGB888_RGB565(dst, src);
  1403                 ++src;
  1404                 ++dst;
  1405             case 2:
  1406                 RGB888_RGB565_TWO(dst, src);
  1407                 src += 2;
  1408                 dst += 2;
  1409                 break;
  1410             case 1:
  1411                 RGB888_RGB565(dst, src);
  1412                 ++src;
  1413                 ++dst;
  1414                 break;
  1415             }
  1416             src += srcskip;
  1417             dst += dstskip;
  1418         }
  1419     } else {
  1420         while (height--) {
  1421             /* Copy in 4 pixel chunks */
  1422             for (c = width / 4; c; --c) {
  1423                 RGB888_RGB565_TWO(dst, src);
  1424                 src += 2;
  1425                 dst += 2;
  1426                 RGB888_RGB565_TWO(dst, src);
  1427                 src += 2;
  1428                 dst += 2;
  1429             }
  1430             /* Get any leftovers */
  1431             switch (width & 3) {
  1432             case 3:
  1433                 RGB888_RGB565(dst, src);
  1434                 ++src;
  1435                 ++dst;
  1436             case 2:
  1437                 RGB888_RGB565_TWO(dst, src);
  1438                 src += 2;
  1439                 dst += 2;
  1440                 break;
  1441             case 1:
  1442                 RGB888_RGB565(dst, src);
  1443                 ++src;
  1444                 ++dst;
  1445                 break;
  1446             }
  1447             src += srcskip;
  1448             dst += dstskip;
  1449         }
  1450     }
  1451 #endif /* USE_DUFFS_LOOP */
  1452 }
  1453 
  1454 
  1455 #if SDL_HAVE_BLIT_N_RGB565
  1456 
  1457 /* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */
  1458 #define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1])
  1459 static void
  1460 Blit_RGB565_32(SDL_BlitInfo * info, const Uint32 * map)
  1461 {
  1462 #ifndef USE_DUFFS_LOOP
  1463     int c;
  1464 #endif
  1465     int width, height;
  1466     Uint8 *src;
  1467     Uint32 *dst;
  1468     int srcskip, dstskip;
  1469 
  1470     /* Set up some basic variables */
  1471     width = info->dst_w;
  1472     height = info->dst_h;
  1473     src = info->src;
  1474     srcskip = info->src_skip;
  1475     dst = (Uint32 *) info->dst;
  1476     dstskip = info->dst_skip / 4;
  1477 
  1478 #ifdef USE_DUFFS_LOOP
  1479     while (height--) {
  1480         /* *INDENT-OFF* */
  1481         DUFFS_LOOP(
  1482         {
  1483             *dst++ = RGB565_32(dst, src, map);
  1484             src += 2;
  1485         },
  1486         width);
  1487         /* *INDENT-ON* */
  1488         src += srcskip;
  1489         dst += dstskip;
  1490     }
  1491 #else
  1492     while (height--) {
  1493         /* Copy in 4 pixel chunks */
  1494         for (c = width / 4; c; --c) {
  1495             *dst++ = RGB565_32(dst, src, map);
  1496             src += 2;
  1497             *dst++ = RGB565_32(dst, src, map);
  1498             src += 2;
  1499             *dst++ = RGB565_32(dst, src, map);
  1500             src += 2;
  1501             *dst++ = RGB565_32(dst, src, map);
  1502             src += 2;
  1503         }
  1504         /* Get any leftovers */
  1505         switch (width & 3) {
  1506         case 3:
  1507             *dst++ = RGB565_32(dst, src, map);
  1508             src += 2;
  1509         case 2:
  1510             *dst++ = RGB565_32(dst, src, map);
  1511             src += 2;
  1512         case 1:
  1513             *dst++ = RGB565_32(dst, src, map);
  1514             src += 2;
  1515             break;
  1516         }
  1517         src += srcskip;
  1518         dst += dstskip;
  1519     }
  1520 #endif /* USE_DUFFS_LOOP */
  1521 }
  1522 
  1523 /* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */
  1524 static const Uint32 RGB565_ARGB8888_LUT[512] = {
  1525     0x00000000, 0xff000000, 0x00000008, 0xff002000,
  1526     0x00000010, 0xff004000, 0x00000018, 0xff006100,
  1527     0x00000020, 0xff008100, 0x00000029, 0xff00a100,
  1528     0x00000031, 0xff00c200, 0x00000039, 0xff00e200,
  1529     0x00000041, 0xff080000, 0x0000004a, 0xff082000,
  1530     0x00000052, 0xff084000, 0x0000005a, 0xff086100,
  1531     0x00000062, 0xff088100, 0x0000006a, 0xff08a100,
  1532     0x00000073, 0xff08c200, 0x0000007b, 0xff08e200,
  1533     0x00000083, 0xff100000, 0x0000008b, 0xff102000,
  1534     0x00000094, 0xff104000, 0x0000009c, 0xff106100,
  1535     0x000000a4, 0xff108100, 0x000000ac, 0xff10a100,
  1536     0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200,
  1537     0x000000c5, 0xff180000, 0x000000cd, 0xff182000,
  1538     0x000000d5, 0xff184000, 0x000000de, 0xff186100,
  1539     0x000000e6, 0xff188100, 0x000000ee, 0xff18a100,
  1540     0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200,
  1541     0x00000400, 0xff200000, 0x00000408, 0xff202000,
  1542     0x00000410, 0xff204000, 0x00000418, 0xff206100,
  1543     0x00000420, 0xff208100, 0x00000429, 0xff20a100,
  1544     0x00000431, 0xff20c200, 0x00000439, 0xff20e200,
  1545     0x00000441, 0xff290000, 0x0000044a, 0xff292000,
  1546     0x00000452, 0xff294000, 0x0000045a, 0xff296100,
  1547     0x00000462, 0xff298100, 0x0000046a, 0xff29a100,
  1548     0x00000473, 0xff29c200, 0x0000047b, 0xff29e200,
  1549     0x00000483, 0xff310000, 0x0000048b, 0xff312000,
  1550     0x00000494, 0xff314000, 0x0000049c, 0xff316100,
  1551     0x000004a4, 0xff318100, 0x000004ac, 0xff31a100,
  1552     0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200,
  1553     0x000004c5, 0xff390000, 0x000004cd, 0xff392000,
  1554     0x000004d5, 0xff394000, 0x000004de, 0xff396100,
  1555     0x000004e6, 0xff398100, 0x000004ee, 0xff39a100,
  1556     0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200,
  1557     0x00000800, 0xff410000, 0x00000808, 0xff412000,
  1558     0x00000810, 0xff414000, 0x00000818, 0xff416100,
  1559     0x00000820, 0xff418100, 0x00000829, 0xff41a100,
  1560     0x00000831, 0xff41c200, 0x00000839, 0xff41e200,
  1561     0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000,
  1562     0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100,
  1563     0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100,
  1564     0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200,
  1565     0x00000883, 0xff520000, 0x0000088b, 0xff522000,
  1566     0x00000894, 0xff524000, 0x0000089c, 0xff526100,
  1567     0x000008a4, 0xff528100, 0x000008ac, 0xff52a100,
  1568     0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200,
  1569     0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000,
  1570     0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100,
  1571     0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100,
  1572     0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200,
  1573     0x00000c00, 0xff620000, 0x00000c08, 0xff622000,
  1574     0x00000c10, 0xff624000, 0x00000c18, 0xff626100,
  1575     0x00000c20, 0xff628100, 0x00000c29, 0xff62a100,
  1576     0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200,
  1577     0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000,
  1578     0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100,
  1579     0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100,
  1580     0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200,
  1581     0x00000c83, 0xff730000, 0x00000c8b, 0xff732000,
  1582     0x00000c94, 0xff734000, 0x00000c9c, 0xff736100,
  1583     0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100,
  1584     0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200,
  1585     0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000,
  1586     0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100,
  1587     0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100,
  1588     0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200,
  1589     0x00001000, 0xff830000, 0x00001008, 0xff832000,
  1590     0x00001010, 0xff834000, 0x00001018, 0xff836100,
  1591     0x00001020, 0xff838100, 0x00001029, 0xff83a100,
  1592     0x00001031, 0xff83c200, 0x00001039, 0xff83e200,
  1593     0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000,
  1594     0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100,
  1595     0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100,
  1596     0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200,
  1597     0x00001083, 0xff940000, 0x0000108b, 0xff942000,
  1598     0x00001094, 0xff944000, 0x0000109c, 0xff946100,
  1599     0x000010a4, 0xff948100, 0x000010ac, 0xff94a100,
  1600     0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200,
  1601     0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000,
  1602     0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100,
  1603     0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100,
  1604     0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200,
  1605     0x00001400, 0xffa40000, 0x00001408, 0xffa42000,
  1606     0x00001410, 0xffa44000, 0x00001418, 0xffa46100,
  1607     0x00001420, 0xffa48100, 0x00001429, 0xffa4a100,
  1608     0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200,
  1609     0x00001441, 0xffac0000, 0x0000144a, 0xffac2000,
  1610     0x00001452, 0xffac4000, 0x0000145a, 0xffac6100,
  1611     0x00001462, 0xffac8100, 0x0000146a, 0xffaca100,
  1612     0x00001473, 0xffacc200, 0x0000147b, 0xfface200,
  1613     0x00001483, 0xffb40000, 0x0000148b, 0xffb42000,
  1614     0x00001494, 0xffb44000, 0x0000149c, 0xffb46100,
  1615     0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100,
  1616     0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200,
  1617     0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000,
  1618     0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100,
  1619     0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100,
  1620     0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200,
  1621     0x00001800, 0xffc50000, 0x00001808, 0xffc52000,
  1622     0x00001810, 0xffc54000, 0x00001818, 0xffc56100,
  1623     0x00001820, 0xffc58100, 0x00001829, 0xffc5a100,
  1624     0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200,
  1625     0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000,
  1626     0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100,
  1627     0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100,
  1628     0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200,
  1629     0x00001883, 0xffd50000, 0x0000188b, 0xffd52000,
  1630     0x00001894, 0xffd54000, 0x0000189c, 0xffd56100,
  1631     0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100,
  1632     0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200,
  1633     0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000,
  1634     0x000018d5, 0xffde4000, 0x000018de, 0xffde6100,
  1635     0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100,
  1636     0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200,
  1637     0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000,
  1638     0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100,
  1639     0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100,
  1640     0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200,
  1641     0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000,
  1642     0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100,
  1643     0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100,
  1644     0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200,
  1645     0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000,
  1646     0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100,
  1647     0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100,
  1648     0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200,
  1649     0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000,
  1650     0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100,
  1651     0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100,
  1652     0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200
  1653 };
  1654 
  1655 static void
  1656 Blit_RGB565_ARGB8888(SDL_BlitInfo * info)
  1657 {
  1658     Blit_RGB565_32(info, RGB565_ARGB8888_LUT);
  1659 }
  1660 
  1661 /* Special optimized blit for RGB 5-6-5 --> ABGR 8-8-8-8 */
  1662 static const Uint32 RGB565_ABGR8888_LUT[512] = {
  1663     0xff000000, 0x00000000, 0xff080000, 0x00002000,
  1664     0xff100000, 0x00004000, 0xff180000, 0x00006100,
  1665     0xff200000, 0x00008100, 0xff290000, 0x0000a100,
  1666     0xff310000, 0x0000c200, 0xff390000, 0x0000e200,
  1667     0xff410000, 0x00000008, 0xff4a0000, 0x00002008,
  1668     0xff520000, 0x00004008, 0xff5a0000, 0x00006108,
  1669     0xff620000, 0x00008108, 0xff6a0000, 0x0000a108,
  1670     0xff730000, 0x0000c208, 0xff7b0000, 0x0000e208,
  1671     0xff830000, 0x00000010, 0xff8b0000, 0x00002010,
  1672     0xff940000, 0x00004010, 0xff9c0000, 0x00006110,
  1673     0xffa40000, 0x00008110, 0xffac0000, 0x0000a110,
  1674     0xffb40000, 0x0000c210, 0xffbd0000, 0x0000e210,
  1675     0xffc50000, 0x00000018, 0xffcd0000, 0x00002018,
  1676     0xffd50000, 0x00004018, 0xffde0000, 0x00006118,
  1677     0xffe60000, 0x00008118, 0xffee0000, 0x0000a118,
  1678     0xfff60000, 0x0000c218, 0xffff0000, 0x0000e218,
  1679     0xff000400, 0x00000020, 0xff080400, 0x00002020,
  1680     0xff100400, 0x00004020, 0xff180400, 0x00006120,
  1681     0xff200400, 0x00008120, 0xff290400, 0x0000a120,
  1682     0xff310400, 0x0000c220, 0xff390400, 0x0000e220,
  1683     0xff410400, 0x00000029, 0xff4a0400, 0x00002029,
  1684     0xff520400, 0x00004029, 0xff5a0400, 0x00006129,
  1685     0xff620400, 0x00008129, 0xff6a0400, 0x0000a129,
  1686     0xff730400, 0x0000c229, 0xff7b0400, 0x0000e229,
  1687     0xff830400, 0x00000031, 0xff8b0400, 0x00002031,
  1688     0xff940400, 0x00004031, 0xff9c0400, 0x00006131,
  1689     0xffa40400, 0x00008131, 0xffac0400, 0x0000a131,
  1690     0xffb40400, 0x0000c231, 0xffbd0400, 0x0000e231,
  1691     0xffc50400, 0x00000039, 0xffcd0400, 0x00002039,
  1692     0xffd50400, 0x00004039, 0xffde0400, 0x00006139,
  1693     0xffe60400, 0x00008139, 0xffee0400, 0x0000a139,
  1694     0xfff60400, 0x0000c239, 0xffff0400, 0x0000e239,
  1695     0xff000800, 0x00000041, 0xff080800, 0x00002041,
  1696     0xff100800, 0x00004041, 0xff180800, 0x00006141,
  1697     0xff200800, 0x00008141, 0xff290800, 0x0000a141,
  1698     0xff310800, 0x0000c241, 0xff390800, 0x0000e241,
  1699     0xff410800, 0x0000004a, 0xff4a0800, 0x0000204a,
  1700     0xff520800, 0x0000404a, 0xff5a0800, 0x0000614a,
  1701     0xff620800, 0x0000814a, 0xff6a0800, 0x0000a14a,
  1702     0xff730800, 0x0000c24a, 0xff7b0800, 0x0000e24a,
  1703     0xff830800, 0x00000052, 0xff8b0800, 0x00002052,
  1704     0xff940800, 0x00004052, 0xff9c0800, 0x00006152,
  1705     0xffa40800, 0x00008152, 0xffac0800, 0x0000a152,
  1706     0xffb40800, 0x0000c252, 0xffbd0800, 0x0000e252,
  1707     0xffc50800, 0x0000005a, 0xffcd0800, 0x0000205a,
  1708     0xffd50800, 0x0000405a, 0xffde0800, 0x0000615a,
  1709     0xffe60800, 0x0000815a, 0xffee0800, 0x0000a15a,
  1710     0xfff60800, 0x0000c25a, 0xffff0800, 0x0000e25a,
  1711     0xff000c00, 0x00000062, 0xff080c00, 0x00002062,
  1712     0xff100c00, 0x00004062, 0xff180c00, 0x00006162,
  1713     0xff200c00, 0x00008162, 0xff290c00, 0x0000a162,
  1714     0xff310c00, 0x0000c262, 0xff390c00, 0x0000e262,
  1715     0xff410c00, 0x0000006a, 0xff4a0c00, 0x0000206a,
  1716     0xff520c00, 0x0000406a, 0xff5a0c00, 0x0000616a,
  1717     0xff620c00, 0x0000816a, 0xff6a0c00, 0x0000a16a,
  1718     0xff730c00, 0x0000c26a, 0xff7b0c00, 0x0000e26a,
  1719     0xff830c00, 0x00000073, 0xff8b0c00, 0x00002073,
  1720     0xff940c00, 0x00004073, 0xff9c0c00, 0x00006173,
  1721     0xffa40c00, 0x00008173, 0xffac0c00, 0x0000a173,
  1722     0xffb40c00, 0x0000c273, 0xffbd0c00, 0x0000e273,
  1723     0xffc50c00, 0x0000007b, 0xffcd0c00, 0x0000207b,
  1724     0xffd50c00, 0x0000407b, 0xffde0c00, 0x0000617b,
  1725     0xffe60c00, 0x0000817b, 0xffee0c00, 0x0000a17b,
  1726     0xfff60c00, 0x0000c27b, 0xffff0c00, 0x0000e27b,
  1727     0xff001000, 0x00000083, 0xff081000, 0x00002083,
  1728     0xff101000, 0x00004083, 0xff181000, 0x00006183,
  1729     0xff201000, 0x00008183, 0xff291000, 0x0000a183,
  1730     0xff311000, 0x0000c283, 0xff391000, 0x0000e283,
  1731     0xff411000, 0x0000008b, 0xff4a1000, 0x0000208b,
  1732     0xff521000, 0x0000408b, 0xff5a1000, 0x0000618b,
  1733     0xff621000, 0x0000818b, 0xff6a1000, 0x0000a18b,
  1734     0xff731000, 0x0000c28b, 0xff7b1000, 0x0000e28b,
  1735     0xff831000, 0x00000094, 0xff8b1000, 0x00002094,
  1736     0xff941000, 0x00004094, 0xff9c1000, 0x00006194,
  1737     0xffa41000, 0x00008194, 0xffac1000, 0x0000a194,
  1738     0xffb41000, 0x0000c294, 0xffbd1000, 0x0000e294,
  1739     0xffc51000, 0x0000009c, 0xffcd1000, 0x0000209c,
  1740     0xffd51000, 0x0000409c, 0xffde1000, 0x0000619c,
  1741     0xffe61000, 0x0000819c, 0xffee1000, 0x0000a19c,
  1742     0xfff61000, 0x0000c29c, 0xffff1000, 0x0000e29c,
  1743     0xff001400, 0x000000a4, 0xff081400, 0x000020a4,
  1744     0xff101400, 0x000040a4, 0xff181400, 0x000061a4,
  1745     0xff201400, 0x000081a4, 0xff291400, 0x0000a1a4,
  1746     0xff311400, 0x0000c2a4, 0xff391400, 0x0000e2a4,
  1747     0xff411400, 0x000000ac, 0xff4a1400, 0x000020ac,
  1748     0xff521400, 0x000040ac, 0xff5a1400, 0x000061ac,
  1749     0xff621400, 0x000081ac, 0xff6a1400, 0x0000a1ac,
  1750     0xff731400, 0x0000c2ac, 0xff7b1400, 0x0000e2ac,
  1751     0xff831400, 0x000000b4, 0xff8b1400, 0x000020b4,
  1752     0xff941400, 0x000040b4, 0xff9c1400, 0x000061b4,
  1753     0xffa41400, 0x000081b4, 0xffac1400, 0x0000a1b4,
  1754     0xffb41400, 0x0000c2b4, 0xffbd1400, 0x0000e2b4,
  1755     0xffc51400, 0x000000bd, 0xffcd1400, 0x000020bd,
  1756     0xffd51400, 0x000040bd, 0xffde1400, 0x000061bd,
  1757     0xffe61400, 0x000081bd, 0xffee1400, 0x0000a1bd,
  1758     0xfff61400, 0x0000c2bd, 0xffff1400, 0x0000e2bd,
  1759     0xff001800, 0x000000c5, 0xff081800, 0x000020c5,
  1760     0xff101800, 0x000040c5, 0xff181800, 0x000061c5,
  1761     0xff201800, 0x000081c5, 0xff291800, 0x0000a1c5,
  1762     0xff311800, 0x0000c2c5, 0xff391800, 0x0000e2c5,
  1763     0xff411800, 0x000000cd, 0xff4a1800, 0x000020cd,
  1764     0xff521800, 0x000040cd, 0xff5a1800, 0x000061cd,
  1765     0xff621800, 0x000081cd, 0xff6a1800, 0x0000a1cd,
  1766     0xff731800, 0x0000c2cd, 0xff7b1800, 0x0000e2cd,
  1767     0xff831800, 0x000000d5, 0xff8b1800, 0x000020d5,
  1768     0xff941800, 0x000040d5, 0xff9c1800, 0x000061d5,
  1769     0xffa41800, 0x000081d5, 0xffac1800, 0x0000a1d5,
  1770     0xffb41800, 0x0000c2d5, 0xffbd1800, 0x0000e2d5,
  1771     0xffc51800, 0x000000de, 0xffcd1800, 0x000020de,
  1772     0xffd51800, 0x000040de, 0xffde1800, 0x000061de,
  1773     0xffe61800, 0x000081de, 0xffee1800, 0x0000a1de,
  1774     0xfff61800, 0x0000c2de, 0xffff1800, 0x0000e2de,
  1775     0xff001c00, 0x000000e6, 0xff081c00, 0x000020e6,
  1776     0xff101c00, 0x000040e6, 0xff181c00, 0x000061e6,
  1777     0xff201c00, 0x000081e6, 0xff291c00, 0x0000a1e6,
  1778     0xff311c00, 0x0000c2e6, 0xff391c00, 0x0000e2e6,
  1779     0xff411c00, 0x000000ee, 0xff4a1c00, 0x000020ee,
  1780     0xff521c00, 0x000040ee, 0xff5a1c00, 0x000061ee,
  1781     0xff621c00, 0x000081ee, 0xff6a1c00, 0x0000a1ee,
  1782     0xff731c00, 0x0000c2ee, 0xff7b1c00, 0x0000e2ee,
  1783     0xff831c00, 0x000000f6, 0xff8b1c00, 0x000020f6,
  1784     0xff941c00, 0x000040f6, 0xff9c1c00, 0x000061f6,
  1785     0xffa41c00, 0x000081f6, 0xffac1c00, 0x0000a1f6,
  1786     0xffb41c00, 0x0000c2f6, 0xffbd1c00, 0x0000e2f6,
  1787     0xffc51c00, 0x000000ff, 0xffcd1c00, 0x000020ff,
  1788     0xffd51c00, 0x000040ff, 0xffde1c00, 0x000061ff,
  1789     0xffe61c00, 0x000081ff, 0xffee1c00, 0x0000a1ff,
  1790     0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff
  1791 };
  1792 
  1793 static void
  1794 Blit_RGB565_ABGR8888(SDL_BlitInfo * info)
  1795 {
  1796     Blit_RGB565_32(info, RGB565_ABGR8888_LUT);
  1797 }
  1798 
  1799 /* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
  1800 static const Uint32 RGB565_RGBA8888_LUT[512] = {
  1801     0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
  1802     0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
  1803     0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
  1804     0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
  1805     0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
  1806     0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
  1807     0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
  1808     0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
  1809     0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
  1810     0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
  1811     0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
  1812     0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
  1813     0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
  1814     0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
  1815     0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
  1816     0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
  1817     0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
  1818     0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
  1819     0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
  1820     0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
  1821     0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
  1822     0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
  1823     0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
  1824     0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
  1825     0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
  1826     0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
  1827     0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
  1828     0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
  1829     0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
  1830     0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
  1831     0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
  1832     0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
  1833     0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
  1834     0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
  1835     0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
  1836     0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
  1837     0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
  1838     0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
  1839     0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
  1840     0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
  1841     0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
  1842     0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
  1843     0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
  1844     0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
  1845     0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
  1846     0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
  1847     0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
  1848     0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
  1849     0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
  1850     0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
  1851     0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
  1852     0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
  1853     0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
  1854     0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
  1855     0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
  1856     0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
  1857     0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
  1858     0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
  1859     0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
  1860     0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
  1861     0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
  1862     0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
  1863     0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
  1864     0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
  1865     0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
  1866     0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
  1867     0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
  1868     0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
  1869     0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
  1870     0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
  1871     0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
  1872     0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
  1873     0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
  1874     0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
  1875     0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
  1876     0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
  1877     0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
  1878     0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
  1879     0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
  1880     0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
  1881     0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
  1882     0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
  1883     0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
  1884     0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
  1885     0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
  1886     0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
  1887     0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
  1888     0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
  1889     0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
  1890     0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
  1891     0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
  1892     0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
  1893     0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
  1894     0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
  1895     0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
  1896     0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
  1897     0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
  1898     0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
  1899     0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
  1900     0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
  1901     0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
  1902     0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
  1903     0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
  1904     0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
  1905     0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
  1906     0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
  1907     0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
  1908     0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
  1909     0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
  1910     0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
  1911     0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
  1912     0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
  1913     0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
  1914     0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
  1915     0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
  1916     0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
  1917     0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
  1918     0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
  1919     0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
  1920     0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
  1921     0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
  1922     0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
  1923     0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
  1924     0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
  1925     0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
  1926     0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
  1927     0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
  1928     0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
  1929 };
  1930 
  1931 static void
  1932 Blit_RGB565_RGBA8888(SDL_BlitInfo * info)
  1933 {
  1934     Blit_RGB565_32(info, RGB565_RGBA8888_LUT);
  1935 }
  1936 
  1937 /* Special optimized blit for RGB 5-6-5 --> BGRA 8-8-8-8 */
  1938 static const Uint32 RGB565_BGRA8888_LUT[512] = {
  1939     0x00000000, 0x000000ff, 0x08000000, 0x002000ff,
  1940     0x10000000, 0x004000ff, 0x18000000, 0x006100ff,
  1941     0x20000000, 0x008100ff, 0x29000000, 0x00a100ff,
  1942     0x31000000, 0x00c200ff, 0x39000000, 0x00e200ff,
  1943     0x41000000, 0x000008ff, 0x4a000000, 0x002008ff,
  1944     0x52000000, 0x004008ff, 0x5a000000, 0x006108ff,
  1945     0x62000000, 0x008108ff, 0x6a000000, 0x00a108ff,
  1946     0x73000000, 0x00c208ff, 0x7b000000, 0x00e208ff,
  1947     0x83000000, 0x000010ff, 0x8b000000, 0x002010ff,
  1948     0x94000000, 0x004010ff, 0x9c000000, 0x006110ff,
  1949     0xa4000000, 0x008110ff, 0xac000000, 0x00a110ff,
  1950     0xb4000000, 0x00c210ff, 0xbd000000, 0x00e210ff,
  1951     0xc5000000, 0x000018ff, 0xcd000000, 0x002018ff,
  1952     0xd5000000, 0x004018ff, 0xde000000, 0x006118ff,
  1953     0xe6000000, 0x008118ff, 0xee000000, 0x00a118ff,
  1954     0xf6000000, 0x00c218ff, 0xff000000, 0x00e218ff,
  1955     0x00040000, 0x000020ff, 0x08040000, 0x002020ff,
  1956     0x10040000, 0x004020ff, 0x18040000, 0x006120ff,
  1957     0x20040000, 0x008120ff, 0x29040000, 0x00a120ff,
  1958     0x31040000, 0x00c220ff, 0x39040000, 0x00e220ff,
  1959     0x41040000, 0x000029ff, 0x4a040000, 0x002029ff,
  1960     0x52040000, 0x004029ff, 0x5a040000, 0x006129ff,
  1961     0x62040000, 0x008129ff, 0x6a040000, 0x00a129ff,
  1962     0x73040000, 0x00c229ff, 0x7b040000, 0x00e229ff,
  1963     0x83040000, 0x000031ff, 0x8b040000, 0x002031ff,
  1964     0x94040000, 0x004031ff, 0x9c040000, 0x006131ff,
  1965     0xa4040000, 0x008131ff, 0xac040000, 0x00a131ff,
  1966     0xb4040000, 0x00c231ff, 0xbd040000, 0x00e231ff,
  1967     0xc5040000, 0x000039ff, 0xcd040000, 0x002039ff,
  1968     0xd5040000, 0x004039ff, 0xde040000, 0x006139ff,
  1969     0xe6040000, 0x008139ff, 0xee040000, 0x00a139ff,
  1970     0xf6040000, 0x00c239ff, 0xff040000, 0x00e239ff,
  1971     0x00080000, 0x000041ff, 0x08080000, 0x002041ff,
  1972     0x10080000, 0x004041ff, 0x18080000, 0x006141ff,
  1973     0x20080000, 0x008141ff, 0x29080000, 0x00a141ff,
  1974     0x31080000, 0x00c241ff, 0x39080000, 0x00e241ff,
  1975     0x41080000, 0x00004aff, 0x4a080000, 0x00204aff,
  1976     0x52080000, 0x00404aff, 0x5a080000, 0x00614aff,
  1977     0x62080000, 0x00814aff, 0x6a080000, 0x00a14aff,
  1978     0x73080000, 0x00c24aff, 0x7b080000, 0x00e24aff,
  1979     0x83080000, 0x000052ff, 0x8b080000, 0x002052ff,
  1980     0x94080000, 0x004052ff, 0x9c080000, 0x006152ff,
  1981     0xa4080000, 0x008152ff, 0xac080000, 0x00a152ff,
  1982     0xb4080000, 0x00c252ff, 0xbd080000, 0x00e252ff,
  1983     0xc5080000, 0x00005aff, 0xcd080000, 0x00205aff,
  1984     0xd5080000, 0x00405aff, 0xde080000, 0x00615aff,
  1985     0xe6080000, 0x00815aff, 0xee080000, 0x00a15aff,
  1986     0xf6080000, 0x00c25aff, 0xff080000, 0x00e25aff,
  1987     0x000c0000, 0x000062ff, 0x080c0000, 0x002062ff,
  1988     0x100c0000, 0x004062ff, 0x180c0000, 0x006162ff,
  1989     0x200c0000, 0x008162ff, 0x290c0000, 0x00a162ff,
  1990     0x310c0000, 0x00c262ff, 0x390c0000, 0x00e262ff,
  1991     0x410c0000, 0x00006aff, 0x4a0c0000, 0x00206aff,
  1992     0x520c0000, 0x00406aff, 0x5a0c0000, 0x00616aff,
  1993     0x620c0000, 0x00816aff, 0x6a0c0000, 0x00a16aff,
  1994     0x730c0000, 0x00c26aff, 0x7b0c0000, 0x00e26aff,
  1995     0x830c0000, 0x000073ff, 0x8b0c0000, 0x002073ff,
  1996     0x940c0000, 0x004073ff, 0x9c0c0000, 0x006173ff,
  1997     0xa40c0000, 0x008173ff, 0xac0c0000, 0x00a173ff,
  1998     0xb40c0000, 0x00c273ff, 0xbd0c0000, 0x00e273ff,
  1999     0xc50c0000, 0x00007bff, 0xcd0c0000, 0x00207bff,
  2000     0xd50c0000, 0x00407bff, 0xde0c0000, 0x00617bff,
  2001     0xe60c0000, 0x00817bff, 0xee0c0000, 0x00a17bff,
  2002     0xf60c0000, 0x00c27bff, 0xff0c0000, 0x00e27bff,
  2003     0x00100000, 0x000083ff, 0x08100000, 0x002083ff,
  2004     0x10100000, 0x004083ff, 0x18100000, 0x006183ff,
  2005     0x20100000, 0x008183ff, 0x29100000, 0x00a183ff,
  2006     0x31100000, 0x00c283ff, 0x39100000, 0x00e283ff,
  2007     0x41100000, 0x00008bff, 0x4a100000, 0x00208bff,
  2008     0x52100000, 0x00408bff, 0x5a100000, 0x00618bff,
  2009     0x62100000, 0x00818bff, 0x6a100000, 0x00a18bff,
  2010     0x73100000, 0x00c28bff, 0x7b100000, 0x00e28bff,
  2011     0x83100000, 0x000094ff, 0x8b100000, 0x002094ff,
  2012     0x94100000, 0x004094ff, 0x9c100000, 0x006194ff,
  2013     0xa4100000, 0x008194ff, 0xac100000, 0x00a194ff,
  2014     0xb4100000, 0x00c294ff, 0xbd100000, 0x00e294ff,
  2015     0xc5100000, 0x00009cff, 0xcd100000, 0x00209cff,
  2016     0xd5100000, 0x00409cff, 0xde100000, 0x00619cff,
  2017     0xe6100000, 0x00819cff, 0xee100000, 0x00a19cff,
  2018     0xf6100000, 0x00c29cff, 0xff100000, 0x00e29cff,
  2019     0x00140000, 0x0000a4ff, 0x08140000, 0x0020a4ff,
  2020     0x10140000, 0x0040a4ff, 0x18140000, 0x0061a4ff,
  2021     0x20140000, 0x0081a4ff, 0x29140000, 0x00a1a4ff,
  2022     0x31140000, 0x00c2a4ff, 0x39140000, 0x00e2a4ff,
  2023     0x41140000, 0x0000acff, 0x4a140000, 0x0020acff,
  2024     0x52140000, 0x0040acff, 0x5a140000, 0x0061acff,
  2025     0x62140000, 0x0081acff, 0x6a140000, 0x00a1acff,
  2026     0x73140000, 0x00c2acff, 0x7b140000, 0x00e2acff,
  2027     0x83140000, 0x0000b4ff, 0x8b140000, 0x0020b4ff,
  2028     0x94140000, 0x0040b4ff, 0x9c140000, 0x0061b4ff,
  2029     0xa4140000, 0x0081b4ff, 0xac140000, 0x00a1b4ff,
  2030     0xb4140000, 0x00c2b4ff, 0xbd140000, 0x00e2b4ff,
  2031     0xc5140000, 0x0000bdff, 0xcd140000, 0x0020bdff,
  2032     0xd5140000, 0x0040bdff, 0xde140000, 0x0061bdff,
  2033     0xe6140000, 0x0081bdff, 0xee140000, 0x00a1bdff,
  2034     0xf6140000, 0x00c2bdff, 0xff140000, 0x00e2bdff,
  2035     0x00180000, 0x0000c5ff, 0x08180000, 0x0020c5ff,
  2036     0x10180000, 0x0040c5ff, 0x18180000, 0x0061c5ff,
  2037     0x20180000, 0x0081c5ff, 0x29180000, 0x00a1c5ff,
  2038     0x31180000, 0x00c2c5ff, 0x39180000, 0x00e2c5ff,
  2039     0x41180000, 0x0000cdff, 0x4a180000, 0x0020cdff,
  2040     0x52180000, 0x0040cdff, 0x5a180000, 0x0061cdff,
  2041     0x62180000, 0x0081cdff, 0x6a180000, 0x00a1cdff,
  2042     0x73180000, 0x00c2cdff, 0x7b180000, 0x00e2cdff,
  2043     0x83180000, 0x0000d5ff, 0x8b180000, 0x0020d5ff,
  2044     0x94180000, 0x0040d5ff, 0x9c180000, 0x0061d5ff,
  2045     0xa4180000, 0x0081d5ff, 0xac180000, 0x00a1d5ff,
  2046     0xb4180000, 0x00c2d5ff, 0xbd180000, 0x00e2d5ff,
  2047     0xc5180000, 0x0000deff, 0xcd180000, 0x0020deff,
  2048     0xd5180000, 0x0040deff, 0xde180000, 0x0061deff,
  2049     0xe6180000, 0x0081deff, 0xee180000, 0x00a1deff,
  2050     0xf6180000, 0x00c2deff, 0xff180000, 0x00e2deff,
  2051     0x001c0000, 0x0000e6ff, 0x081c0000, 0x0020e6ff,
  2052     0x101c0000, 0x0040e6ff, 0x181c0000, 0x0061e6ff,
  2053     0x201c0000, 0x0081e6ff, 0x291c0000, 0x00a1e6ff,
  2054     0x311c0000, 0x00c2e6ff, 0x391c0000, 0x00e2e6ff,
  2055     0x411c0000, 0x0000eeff, 0x4a1c0000, 0x0020eeff,
  2056     0x521c0000, 0x0040eeff, 0x5a1c0000, 0x0061eeff,
  2057     0x621c0000, 0x0081eeff, 0x6a1c0000, 0x00a1eeff,
  2058     0x731c0000, 0x00c2eeff, 0x7b1c0000, 0x00e2eeff,
  2059     0x831c0000, 0x0000f6ff, 0x8b1c0000, 0x0020f6ff,
  2060     0x941c0000, 0x0040f6ff, 0x9c1c0000, 0x0061f6ff,
  2061     0xa41c0000, 0x0081f6ff, 0xac1c0000, 0x00a1f6ff,
  2062     0xb41c0000, 0x00c2f6ff, 0xbd1c0000, 0x00e2f6ff,
  2063     0xc51c0000, 0x0000ffff, 0xcd1c0000, 0x0020ffff,
  2064     0xd51c0000, 0x0040ffff, 0xde1c0000, 0x0061ffff,
  2065     0xe61c0000, 0x0081ffff, 0xee1c0000, 0x00a1ffff,
  2066     0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff
  2067 };
  2068 
  2069 static void
  2070 Blit_RGB565_BGRA8888(SDL_BlitInfo * info)
  2071 {
  2072     Blit_RGB565_32(info, RGB565_BGRA8888_LUT);
  2073 }
  2074 
  2075 #endif /* SDL_HAVE_BLIT_N_RGB565 */
  2076 
  2077 static void
  2078 BlitNto1(SDL_BlitInfo * info)
  2079 {
  2080 #ifndef USE_DUFFS_LOOP
  2081     int c;
  2082 #endif
  2083     int width, height;
  2084     Uint8 *src;
  2085     const Uint8 *map;
  2086     Uint8 *dst;
  2087     int srcskip, dstskip;
  2088     int srcbpp;
  2089     Uint32 Pixel;
  2090     int sR, sG, sB;
  2091     SDL_PixelFormat *srcfmt;
  2092 
  2093     /* Set up some basic variables */
  2094     width = info->dst_w;
  2095     height = info->dst_h;
  2096     src = info->src;
  2097     srcskip = info->src_skip;
  2098     dst = info->dst;
  2099     dstskip = info->dst_skip;
  2100     map = info->table;
  2101     srcfmt = info->src_fmt;
  2102     srcbpp = srcfmt->BytesPerPixel;
  2103 
  2104     if (map == NULL) {
  2105         while (height--) {
  2106 #ifdef USE_DUFFS_LOOP
  2107             /* *INDENT-OFF* */
  2108             DUFFS_LOOP(
  2109                 DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
  2110                                 sR, sG, sB);
  2111                 if ( 1 ) {
  2112                     /* Pack RGB into 8bit pixel */
  2113                     *dst = ((sR>>5)<<(3+2))|
  2114                             ((sG>>5)<<(2)) |
  2115                             ((sB>>6)<<(0)) ;
  2116                 }
  2117                 dst++;
  2118                 src += srcbpp;
  2119             , width);
  2120             /* *INDENT-ON* */
  2121 #else
  2122             for (c = width; c; --c) {
  2123                 DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
  2124                 if (1) {
  2125                     /* Pack RGB into 8bit pixel */
  2126                     *dst = ((sR >> 5) << (3 + 2)) |
  2127                         ((sG >> 5) << (2)) | ((sB >> 6) << (0));
  2128                 }
  2129                 dst++;
  2130                 src += srcbpp;
  2131             }
  2132 #endif
  2133             src += srcskip;
  2134             dst += dstskip;
  2135         }
  2136     } else {
  2137         while (height--) {
  2138 #ifdef USE_DUFFS_LOOP
  2139             /* *INDENT-OFF* */
  2140             DUFFS_LOOP(
  2141                 DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
  2142                                 sR, sG, sB);
  2143                 if ( 1 ) {
  2144                     /* Pack RGB into 8bit pixel */
  2145                     *dst = map[((sR>>5)<<(3+2))|
  2146                            ((sG>>5)<<(2))  |
  2147                            ((sB>>6)<<(0))  ];
  2148                 }
  2149                 dst++;
  2150                 src += srcbpp;
  2151             , width);
  2152             /* *INDENT-ON* */
  2153 #else
  2154             for (c = width; c; --c) {
  2155                 DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
  2156                 if (1) {
  2157                     /* Pack RGB into 8bit pixel */
  2158                     *dst = map[((sR >> 5) << (3 + 2)) |
  2159                                ((sG >> 5) << (2)) | ((sB >> 6) << (0))];
  2160                 }
  2161                 dst++;
  2162                 src += srcbpp;
  2163             }
  2164 #endif /* USE_DUFFS_LOOP */
  2165             src += srcskip;
  2166             dst += dstskip;
  2167         }
  2168     }
  2169 }
  2170 
  2171 /* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */
  2172 static void
  2173 Blit4to4MaskAlpha(SDL_BlitInfo * info)
  2174 {
  2175     int width = info->dst_w;
  2176     int height = info->dst_h;
  2177     Uint32 *src = (Uint32 *) info->src;
  2178     int srcskip = info->src_skip;
  2179     Uint32 *dst = (Uint32 *) info->dst;
  2180     int dstskip = info->dst_skip;
  2181     SDL_PixelFormat *srcfmt = info->src_fmt;
  2182     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2183 
  2184     if (dstfmt->Amask) {
  2185         /* RGB->RGBA, SET_ALPHA */
  2186         Uint32 mask = ((Uint32)info->a >> dstfmt->Aloss) << dstfmt->Ashift;
  2187 
  2188         while (height--) {
  2189             /* *INDENT-OFF* */
  2190             DUFFS_LOOP(
  2191             {
  2192                 *dst = *src | mask;
  2193                 ++dst;
  2194                 ++src;
  2195             },
  2196             width);
  2197             /* *INDENT-ON* */
  2198             src = (Uint32 *) ((Uint8 *) src + srcskip);
  2199             dst = (Uint32 *) ((Uint8 *) dst + dstskip);
  2200         }
  2201     } else {
  2202         /* RGBA->RGB, NO_ALPHA */
  2203         Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
  2204 
  2205         while (height--) {
  2206             /* *INDENT-OFF* */
  2207             DUFFS_LOOP(
  2208             {
  2209                 *dst = *src & mask;
  2210                 ++dst;
  2211                 ++src;
  2212             },
  2213             width);
  2214             /* *INDENT-ON* */
  2215             src = (Uint32 *) ((Uint8 *) src + srcskip);
  2216             dst = (Uint32 *) ((Uint8 *) dst + dstskip);
  2217         }
  2218     }
  2219 }
  2220 
  2221 /* blits 32 bit RGBA<->RGBA with both surfaces having the same R,G,B,A fields */
  2222 static void
  2223 Blit4to4CopyAlpha(SDL_BlitInfo * info)
  2224 {
  2225     int width = info->dst_w;
  2226     int height = info->dst_h;
  2227     Uint32 *src = (Uint32 *) info->src;
  2228     int srcskip = info->src_skip;
  2229     Uint32 *dst = (Uint32 *) info->dst;
  2230     int dstskip = info->dst_skip;
  2231 
  2232     /* RGBA->RGBA, COPY_ALPHA */
  2233     while (height--) {
  2234         /* *INDENT-OFF* */
  2235         DUFFS_LOOP(
  2236         {
  2237             *dst = *src;
  2238             ++dst;
  2239             ++src;
  2240         },
  2241         width);
  2242         /* *INDENT-ON* */
  2243         src = (Uint32 *) ((Uint8 *) src + srcskip);
  2244         dst = (Uint32 *) ((Uint8 *) dst + dstskip);
  2245     }
  2246 }
  2247 
  2248 /* permutation for mapping srcfmt to dstfmt, overloading or not the alpha channel */
  2249 static void
  2250 get_permutation(SDL_PixelFormat *srcfmt, SDL_PixelFormat *dstfmt,
  2251         int *_p0 , int *_p1, int *_p2, int *_p3, int *_alpha_channel)
  2252 {
  2253     int alpha_channel = 0, p0, p1, p2, p3;
  2254 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  2255     int Pixel = 0x04030201; /* identity permutation */
  2256 #else
  2257     int Pixel = 0x01020304; /* identity permutation */
  2258     int srcbpp = srcfmt->BytesPerPixel;
  2259     int dstbpp = dstfmt->BytesPerPixel;
  2260 #endif
  2261 
  2262     if (srcfmt->Amask) {
  2263         RGBA_FROM_PIXEL(Pixel, srcfmt, p0, p1, p2, p3);
  2264     } else {
  2265         RGB_FROM_PIXEL(Pixel, srcfmt, p0, p1, p2);
  2266         p3 = 0;
  2267     }
  2268 
  2269     if (dstfmt->Amask) {
  2270         if (srcfmt->Amask) {
  2271             PIXEL_FROM_RGBA(Pixel, dstfmt, p0, p1, p2, p3);
  2272         } else {
  2273             PIXEL_FROM_RGBA(Pixel, dstfmt, p0, p1, p2, 0);
  2274         }
  2275     } else {
  2276         PIXEL_FROM_RGB(Pixel, dstfmt, p0, p1, p2);
  2277     }
  2278 
  2279 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  2280     p0 = Pixel & 0xFF;
  2281     p1 = (Pixel >> 8) & 0xFF;
  2282     p2 = (Pixel >> 16) & 0xFF;
  2283     p3 = (Pixel >> 24) & 0xFF;
  2284 #else
  2285     p3 = Pixel & 0xFF;
  2286     p2 = (Pixel >> 8) & 0xFF;
  2287     p1 = (Pixel >> 16) & 0xFF;
  2288     p0 = (Pixel >> 24) & 0xFF;
  2289 #endif
  2290 
  2291     if (p0 == 0) {
  2292         p0 = 1;
  2293         alpha_channel = 0;
  2294     } else if (p1 == 0) {
  2295         p1 = 1;
  2296         alpha_channel = 1;
  2297     } else if (p2 == 0) {
  2298         p2 = 1;
  2299         alpha_channel = 2;
  2300     } else if (p3 == 0) {
  2301         p3 = 1;
  2302         alpha_channel = 3;
  2303     }
  2304 
  2305 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  2306 #else
  2307     if (srcbpp == 3 && dstbpp == 4) {
  2308         if (p0 != 1) p0--;
  2309         if (p1 != 1) p1--;
  2310         if (p2 != 1) p2--;
  2311         if (p3 != 1) p3--;
  2312     } else if (srcbpp == 4 && dstbpp == 3) {
  2313         p0 = p1;
  2314         p1 = p2;
  2315         p2 = p3;
  2316     }
  2317 #endif
  2318     *_p0 = p0 - 1;
  2319     *_p1 = p1 - 1;
  2320     *_p2 = p2 - 1;
  2321     *_p3 = p3 - 1;
  2322 
  2323     if (_alpha_channel) {
  2324         *_alpha_channel = alpha_channel;
  2325     }
  2326 }
  2327 
  2328 
  2329 static void
  2330 BlitNtoN(SDL_BlitInfo * info)
  2331 {
  2332     int width = info->dst_w;
  2333     int height = info->dst_h;
  2334     Uint8 *src = info->src;
  2335     int srcskip = info->src_skip;
  2336     Uint8 *dst = info->dst;
  2337     int dstskip = info->dst_skip;
  2338     SDL_PixelFormat *srcfmt = info->src_fmt;
  2339     int srcbpp = srcfmt->BytesPerPixel;
  2340     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2341     int dstbpp = dstfmt->BytesPerPixel;
  2342     unsigned alpha = dstfmt->Amask ? info->a : 0;
  2343 
  2344 #if HAVE_FAST_WRITE_INT8
  2345     /* Blit with permutation: 4->4 */
  2346     if (srcbpp == 4 && dstbpp == 4 &&
  2347         srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 &&
  2348         dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
  2349 
  2350         /* Find the appropriate permutation */
  2351         int alpha_channel, p0, p1, p2, p3;
  2352         get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel);
  2353 
  2354         while (height--) {
  2355             /* *INDENT-OFF* */
  2356             DUFFS_LOOP(
  2357             {
  2358                 dst[0] = src[p0];
  2359                 dst[1] = src[p1];
  2360                 dst[2] = src[p2];
  2361                 dst[3] = src[p3];
  2362                 dst[alpha_channel] = alpha;
  2363                 src += 4;
  2364                 dst += 4;
  2365             }, width);
  2366             /* *INDENT-ON* */
  2367             src += srcskip;
  2368             dst += dstskip;
  2369         }
  2370         return;
  2371     }
  2372 #endif
  2373 
  2374     /* Blit with permutation: 4->3 */
  2375     if (srcbpp == 4 && dstbpp == 3 &&
  2376         srcfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
  2377 
  2378         /* Find the appropriate permutation */
  2379         int p0, p1, p2, p3;
  2380         get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL);
  2381 
  2382         while (height--) {
  2383             /* *INDENT-OFF* */
  2384             DUFFS_LOOP(
  2385             {
  2386                 dst[0] = src[p0];
  2387                 dst[1] = src[p1];
  2388                 dst[2] = src[p2];
  2389                 src += 4;
  2390                 dst += 3;
  2391             }, width);
  2392             /* *INDENT-ON* */
  2393             src += srcskip;
  2394             dst += dstskip;
  2395         }
  2396         return;
  2397     }
  2398 
  2399 #if HAVE_FAST_WRITE_INT8
  2400     /* Blit with permutation: 3->4 */
  2401     if (srcbpp == 3 && dstbpp == 4 &&
  2402         dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
  2403 
  2404         /* Find the appropriate permutation */
  2405         int alpha_channel, p0, p1, p2, p3;
  2406         get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel);
  2407 
  2408         while (height--) {
  2409             /* *INDENT-OFF* */
  2410             DUFFS_LOOP(
  2411             {
  2412                 dst[0] = src[p0];
  2413                 dst[1] = src[p1];
  2414                 dst[2] = src[p2];
  2415                 dst[3] = src[p3];
  2416                 dst[alpha_channel] = alpha;
  2417                 src += 3;
  2418                 dst += 4;
  2419             }, width);
  2420             /* *INDENT-ON* */
  2421             src += srcskip;
  2422             dst += dstskip;
  2423         }
  2424         return;
  2425     }
  2426 #endif
  2427 
  2428     while (height--) {
  2429         /* *INDENT-OFF* */
  2430         DUFFS_LOOP(
  2431         {
  2432             Uint32 Pixel;
  2433             unsigned sR;
  2434             unsigned sG;
  2435             unsigned sB;
  2436             DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
  2437             ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
  2438             dst += dstbpp;
  2439             src += srcbpp;
  2440         },
  2441         width);
  2442         /* *INDENT-ON* */
  2443         src += srcskip;
  2444         dst += dstskip;
  2445     }
  2446 }
  2447 
  2448 static void
  2449 BlitNtoNCopyAlpha(SDL_BlitInfo * info)
  2450 {
  2451     int width = info->dst_w;
  2452     int height = info->dst_h;
  2453     Uint8 *src = info->src;
  2454     int srcskip = info->src_skip;
  2455     Uint8 *dst = info->dst;
  2456     int dstskip = info->dst_skip;
  2457     SDL_PixelFormat *srcfmt = info->src_fmt;
  2458     int srcbpp = srcfmt->BytesPerPixel;
  2459     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2460     int dstbpp = dstfmt->BytesPerPixel;
  2461     int c;
  2462 
  2463 #if HAVE_FAST_WRITE_INT8
  2464     /* Blit with permutation: 4->4 */
  2465     if (srcbpp == 4 && dstbpp == 4 &&
  2466         srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 &&
  2467         dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
  2468 
  2469         /* Find the appropriate permutation */
  2470         int p0, p1, p2, p3;
  2471         get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL);
  2472 
  2473         while (height--) {
  2474             /* *INDENT-OFF* */
  2475             DUFFS_LOOP(
  2476             {
  2477                 dst[0] = src[p0];
  2478                 dst[1] = src[p1];
  2479                 dst[2] = src[p2];
  2480                 dst[3] = src[p3];
  2481                 src += 4;
  2482                 dst += 4;
  2483             }, width);
  2484             /* *INDENT-ON* */
  2485             src += srcskip;
  2486             dst += dstskip;
  2487         }
  2488         return;
  2489     }
  2490 #endif
  2491 
  2492     while (height--) {
  2493         for (c = width; c; --c) {
  2494             Uint32 Pixel;
  2495             unsigned sR, sG, sB, sA;
  2496             DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
  2497             ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
  2498             dst += dstbpp;
  2499             src += srcbpp;
  2500         }
  2501         src += srcskip;
  2502         dst += dstskip;
  2503     }
  2504 }
  2505 
  2506 static void
  2507 BlitNto1Key(SDL_BlitInfo * info)
  2508 {
  2509     int width = info->dst_w;
  2510     int height = info->dst_h;
  2511     Uint8 *src = info->src;
  2512     int srcskip = info->src_skip;
  2513     Uint8 *dst = info->dst;
  2514     int dstskip = info->dst_skip;
  2515     SDL_PixelFormat *srcfmt = info->src_fmt;
  2516     const Uint8 *palmap = info->table;
  2517     Uint32 ckey = info->colorkey;
  2518     Uint32 rgbmask = ~srcfmt->Amask;
  2519     int srcbpp;
  2520     Uint32 Pixel;
  2521     unsigned sR, sG, sB;
  2522 
  2523     /* Set up some basic variables */
  2524     srcbpp = srcfmt->BytesPerPixel;
  2525     ckey &= rgbmask;
  2526 
  2527     if (palmap == NULL) {
  2528         while (height--) {
  2529             /* *INDENT-OFF* */
  2530             DUFFS_LOOP(
  2531             {
  2532                 DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
  2533                                 sR, sG, sB);
  2534                 if ( (Pixel & rgbmask) != ckey ) {
  2535                     /* Pack RGB into 8bit pixel */
  2536                     *dst = (Uint8)(((sR>>5)<<(3+2))|
  2537                                    ((sG>>5)<<(2)) |
  2538                                    ((sB>>6)<<(0)));
  2539                 }
  2540                 dst++;
  2541                 src += srcbpp;
  2542             },
  2543             width);
  2544             /* *INDENT-ON* */
  2545             src += srcskip;
  2546             dst += dstskip;
  2547         }
  2548     } else {
  2549         while (height--) {
  2550             /* *INDENT-OFF* */
  2551             DUFFS_LOOP(
  2552             {
  2553                 DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
  2554                                 sR, sG, sB);
  2555                 if ( (Pixel & rgbmask) != ckey ) {
  2556                     /* Pack RGB into 8bit pixel */
  2557                     *dst = (Uint8)palmap[((sR>>5)<<(3+2))|
  2558                                          ((sG>>5)<<(2))  |
  2559                                          ((sB>>6)<<(0))  ];
  2560                 }
  2561                 dst++;
  2562                 src += srcbpp;
  2563             },
  2564             width);
  2565             /* *INDENT-ON* */
  2566             src += srcskip;
  2567             dst += dstskip;
  2568         }
  2569     }
  2570 }
  2571 
  2572 static void
  2573 Blit2to2Key(SDL_BlitInfo * info)
  2574 {
  2575     int width = info->dst_w;
  2576     int height = info->dst_h;
  2577     Uint16 *srcp = (Uint16 *) info->src;
  2578     int srcskip = info->src_skip;
  2579     Uint16 *dstp = (Uint16 *) info->dst;
  2580     int dstskip = info->dst_skip;
  2581     Uint32 ckey = info->colorkey;
  2582     Uint32 rgbmask = ~info->src_fmt->Amask;
  2583 
  2584     /* Set up some basic variables */
  2585     srcskip /= 2;
  2586     dstskip /= 2;
  2587     ckey &= rgbmask;
  2588 
  2589     while (height--) {
  2590         /* *INDENT-OFF* */
  2591         DUFFS_LOOP(
  2592         {
  2593             if ( (*srcp & rgbmask) != ckey ) {
  2594                 *dstp = *srcp;
  2595             }
  2596             dstp++;
  2597             srcp++;
  2598         },
  2599         width);
  2600         /* *INDENT-ON* */
  2601         srcp += srcskip;
  2602         dstp += dstskip;
  2603     }
  2604 }
  2605 
  2606 static void
  2607 BlitNtoNKey(SDL_BlitInfo * info)
  2608 {
  2609     int width = info->dst_w;
  2610     int height = info->dst_h;
  2611     Uint8 *src = info->src;
  2612     int srcskip = info->src_skip;
  2613     Uint8 *dst = info->dst;
  2614     int dstskip = info->dst_skip;
  2615     Uint32 ckey = info->colorkey;
  2616     SDL_PixelFormat *srcfmt = info->src_fmt;
  2617     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2618     int srcbpp = srcfmt->BytesPerPixel;
  2619     int dstbpp = dstfmt->BytesPerPixel;
  2620     unsigned alpha = dstfmt->Amask ? info->a : 0;
  2621     Uint32 rgbmask = ~srcfmt->Amask;
  2622     int sfmt = srcfmt->format;
  2623     int dfmt = dstfmt->format;
  2624 
  2625     /* Set up some basic variables */
  2626     ckey &= rgbmask;
  2627 
  2628     /* BPP 4, same rgb */
  2629     if (srcbpp == 4 && dstbpp == 4 && srcfmt->Rmask == dstfmt->Rmask && srcfmt->Gmask == dstfmt->Gmask && srcfmt->Bmask == dstfmt->Bmask) {
  2630         Uint32 *src32 = (Uint32*)src;
  2631         Uint32 *dst32 = (Uint32*)dst;
  2632 
  2633         if (dstfmt->Amask) {
  2634             /* RGB->RGBA, SET_ALPHA */
  2635             Uint32 mask = ((Uint32)info->a) << dstfmt->Ashift;
  2636             while (height--) {
  2637                 /* *INDENT-OFF* */
  2638                 DUFFS_LOOP(
  2639                 {
  2640                     if ((*src32 & rgbmask) != ckey) {
  2641                         *dst32 = *src32 | mask;
  2642                     }
  2643                     ++dst32;
  2644                     ++src32;
  2645                 }, width);
  2646                 /* *INDENT-ON* */
  2647                 src32 = (Uint32 *) ((Uint8 *) src32 + srcskip);
  2648                 dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip);
  2649             }
  2650             return;
  2651         } else {
  2652             /* RGBA->RGB, NO_ALPHA */
  2653             Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
  2654             while (height--) {
  2655                 /* *INDENT-OFF* */
  2656                 DUFFS_LOOP(
  2657                 {
  2658                     if ((*src32 & rgbmask) != ckey) {
  2659                         *dst32 = *src32 & mask;
  2660                     }
  2661                     ++dst32;
  2662                     ++src32;
  2663                 }, width);
  2664                 /* *INDENT-ON* */
  2665                 src32 = (Uint32 *) ((Uint8 *) src32 + srcskip);
  2666                 dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip);
  2667             }
  2668             return;
  2669         }
  2670     }
  2671 
  2672 #if HAVE_FAST_WRITE_INT8
  2673     /* Blit with permutation: 4->4 */
  2674     if (srcbpp == 4 && dstbpp == 4 &&
  2675         srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 &&
  2676         dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
  2677 
  2678         /* Find the appropriate permutation */
  2679         int alpha_channel, p0, p1, p2, p3;
  2680         get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel);
  2681 
  2682         while (height--) {
  2683             /* *INDENT-OFF* */
  2684             DUFFS_LOOP(
  2685             {
  2686                 Uint32 *src32 = (Uint32*)src;
  2687 
  2688                 if ((*src32 & rgbmask) != ckey) {
  2689                     dst[0] = src[p0];
  2690                     dst[1] = src[p1];
  2691                     dst[2] = src[p2];
  2692                     dst[3] = src[p3];
  2693                     dst[alpha_channel] = alpha;
  2694                 }
  2695                 src += 4;
  2696                 dst += 4;
  2697             }, width);
  2698             /* *INDENT-ON* */
  2699             src += srcskip;
  2700             dst += dstskip;
  2701         }
  2702         return;
  2703     }
  2704 #endif
  2705 
  2706     /* BPP 3, same rgb triplet */
  2707     if ((sfmt == SDL_PIXELFORMAT_RGB24 && dfmt == SDL_PIXELFORMAT_RGB24) ||
  2708         (sfmt == SDL_PIXELFORMAT_BGR24 && dfmt == SDL_PIXELFORMAT_BGR24)) {
  2709 
  2710 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  2711         Uint8 k0 = ckey & 0xFF;
  2712         Uint8 k1 = (ckey >> 8)  & 0xFF;
  2713         Uint8 k2 = (ckey >> 16) & 0xFF;
  2714 #else
  2715         Uint8 k0 = (ckey >> 16) & 0xFF;
  2716         Uint8 k1 = (ckey >> 8) & 0xFF;
  2717         Uint8 k2 = ckey & 0xFF;
  2718 #endif
  2719 
  2720         while (height--) {
  2721             /* *INDENT-OFF* */
  2722             DUFFS_LOOP(
  2723             {
  2724                 Uint8 s0 = src[0];
  2725                 Uint8 s1 = src[1];
  2726                 Uint8 s2 = src[2];
  2727 
  2728                 if (k0 != s0 || k1 != s1 || k2 != s2) {
  2729                     dst[0] = s0;
  2730                     dst[1] = s1;
  2731                     dst[2] = s2;
  2732                 }
  2733                 src += 3;
  2734                 dst += 3;
  2735             },
  2736             width);
  2737             /* *INDENT-ON* */
  2738             src += srcskip;
  2739             dst += dstskip;
  2740         }
  2741         return;
  2742     }
  2743 
  2744     /* BPP 3, inversed rgb triplet */
  2745     if ((sfmt == SDL_PIXELFORMAT_RGB24 && dfmt == SDL_PIXELFORMAT_BGR24) ||
  2746         (sfmt == SDL_PIXELFORMAT_BGR24 && dfmt == SDL_PIXELFORMAT_RGB24)) {
  2747 
  2748 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  2749         Uint8 k0 = ckey & 0xFF;
  2750         Uint8 k1 = (ckey >> 8)  & 0xFF;
  2751         Uint8 k2 = (ckey >> 16) & 0xFF;
  2752 #else
  2753         Uint8 k0 = (ckey >> 16) & 0xFF;
  2754         Uint8 k1 = (ckey >> 8) & 0xFF;
  2755         Uint8 k2 = ckey & 0xFF;
  2756 #endif
  2757 
  2758         while (height--) {
  2759             /* *INDENT-OFF* */
  2760             DUFFS_LOOP(
  2761             {
  2762                 Uint8 s0 = src[0];
  2763                 Uint8 s1 = src[1];
  2764                 Uint8 s2 = src[2];
  2765                 if (k0 != s0 || k1 != s1 || k2 != s2) {
  2766                     /* Inversed RGB */
  2767                     dst[0] = s2;
  2768                     dst[1] = s1;
  2769                     dst[2] = s0;
  2770                 }
  2771                 src += 3;
  2772                 dst += 3;
  2773             },
  2774             width);
  2775             /* *INDENT-ON* */
  2776             src += srcskip;
  2777             dst += dstskip;
  2778         }
  2779         return;
  2780     }
  2781 
  2782     /* Blit with permutation: 4->3 */
  2783     if (srcbpp == 4 && dstbpp == 3 &&
  2784         srcfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
  2785 
  2786         /* Find the appropriate permutation */
  2787         int p0, p1, p2, p3;
  2788         get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL);
  2789 
  2790         while (height--) {
  2791             /* *INDENT-OFF* */
  2792             DUFFS_LOOP(
  2793             {
  2794                 Uint32 *src32 = (Uint32*)src;
  2795                 if ((*src32 & rgbmask) != ckey) {
  2796                     dst[0] = src[p0];
  2797                     dst[1] = src[p1];
  2798                     dst[2] = src[p2];
  2799                 }
  2800                 src += 4;
  2801                 dst += 3;
  2802             }, width);
  2803             /* *INDENT-ON* */
  2804             src += srcskip;
  2805             dst += dstskip;
  2806         }
  2807         return;
  2808     }
  2809 
  2810 #if HAVE_FAST_WRITE_INT8
  2811     /* Blit with permutation: 3->4 */
  2812     if (srcbpp == 3 && dstbpp == 4 &&
  2813         dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
  2814 
  2815 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  2816         Uint8 k0 = ckey & 0xFF;
  2817         Uint8 k1 = (ckey >> 8)  & 0xFF;
  2818         Uint8 k2 = (ckey >> 16) & 0xFF;
  2819 #else
  2820         Uint8 k0 = (ckey >> 16) & 0xFF;
  2821         Uint8 k1 = (ckey >> 8) & 0xFF;
  2822         Uint8 k2 = ckey  & 0xFF;
  2823 #endif
  2824 
  2825         /* Find the appropriate permutation */
  2826         int alpha_channel, p0, p1, p2, p3;
  2827         get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel);
  2828 
  2829         while (height--) {
  2830             /* *INDENT-OFF* */
  2831             DUFFS_LOOP(
  2832             {
  2833                 Uint8 s0 = src[0];
  2834                 Uint8 s1 = src[1];
  2835                 Uint8 s2 = src[2];
  2836 
  2837                 if (k0 != s0 || k1 != s1 || k2 != s2) {
  2838                     dst[0] = src[p0];
  2839                     dst[1] = src[p1];
  2840                     dst[2] = src[p2];
  2841                     dst[3] = src[p3];
  2842                     dst[alpha_channel] = alpha;
  2843                 }
  2844                 src += 3;
  2845                 dst += 4;
  2846             }, width);
  2847             /* *INDENT-ON* */
  2848             src += srcskip;
  2849             dst += dstskip;
  2850         }
  2851         return;
  2852     }
  2853 #endif
  2854 
  2855     while (height--) {
  2856         /* *INDENT-OFF* */
  2857         DUFFS_LOOP(
  2858         {
  2859             Uint32 Pixel;
  2860             unsigned sR;
  2861             unsigned sG;
  2862             unsigned sB;
  2863             RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel);
  2864             if ( (Pixel & rgbmask) != ckey ) {
  2865                 RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB);
  2866                 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
  2867             }
  2868             dst += dstbpp;
  2869             src += srcbpp;
  2870         },
  2871         width);
  2872         /* *INDENT-ON* */
  2873         src += srcskip;
  2874         dst += dstskip;
  2875     }
  2876 }
  2877 
  2878 static void
  2879 BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info)
  2880 {
  2881     int width = info->dst_w;
  2882     int height = info->dst_h;
  2883     Uint8 *src = info->src;
  2884     int srcskip = info->src_skip;
  2885     Uint8 *dst = info->dst;
  2886     int dstskip = info->dst_skip;
  2887     Uint32 ckey = info->colorkey;
  2888     SDL_PixelFormat *srcfmt = info->src_fmt;
  2889     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2890     Uint32 rgbmask = ~srcfmt->Amask;
  2891 
  2892     Uint8 srcbpp;
  2893     Uint8 dstbpp;
  2894     Uint32 Pixel;
  2895     unsigned sR, sG, sB, sA;
  2896 
  2897     /* Set up some basic variables */
  2898     srcbpp = srcfmt->BytesPerPixel;
  2899     dstbpp = dstfmt->BytesPerPixel;
  2900     ckey &= rgbmask;
  2901 
  2902     /* Fastpath: same source/destination format, with Amask, bpp 32, loop is vectorized. ~10x faster */
  2903     if (srcfmt->format == dstfmt->format) {
  2904 
  2905         if (srcfmt->format == SDL_PIXELFORMAT_ARGB8888 ||
  2906             srcfmt->format == SDL_PIXELFORMAT_ABGR8888 ||
  2907             srcfmt->format == SDL_PIXELFORMAT_BGRA8888 ||
  2908             srcfmt->format == SDL_PIXELFORMAT_RGBA8888) {
  2909 
  2910             Uint32 *src32 = (Uint32*)src;
  2911             Uint32 *dst32 = (Uint32*)dst;
  2912             while (height--) {
  2913                 /* *INDENT-OFF* */
  2914                 DUFFS_LOOP(
  2915                 {
  2916                     if ((*src32 & rgbmask) != ckey) {
  2917                         *dst32 = *src32;
  2918                     }
  2919                     ++src32;
  2920                     ++dst32;
  2921                 },
  2922                 width);
  2923                 /* *INDENT-ON* */
  2924                 src32 = (Uint32 *)((Uint8 *)src32 + srcskip);
  2925                 dst32 = (Uint32 *)((Uint8 *)dst32 + dstskip);
  2926             }
  2927         }
  2928         return;
  2929     }
  2930 
  2931 #if HAVE_FAST_WRITE_INT8
  2932     /* Blit with permutation: 4->4 */
  2933     if (srcbpp == 4 && dstbpp == 4 &&
  2934         srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 &&
  2935         dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
  2936 
  2937         /* Find the appropriate permutation */
  2938         int p0, p1, p2, p3;
  2939         get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL);
  2940 
  2941         while (height--) {
  2942             /* *INDENT-OFF* */
  2943             DUFFS_LOOP(
  2944             {
  2945                 Uint32 *src32 = (Uint32*)src;
  2946                 if ((*src32 & rgbmask) != ckey) {
  2947                     dst[0] = src[p0];
  2948                     dst[1] = src[p1];
  2949                     dst[2] = src[p2];
  2950                     dst[3] = src[p3];
  2951                 }
  2952                 src += 4;
  2953                 dst += 4;
  2954             }, width);
  2955             /* *INDENT-ON* */
  2956             src += srcskip;
  2957             dst += dstskip;
  2958         }
  2959         return;
  2960     }
  2961 #endif
  2962 
  2963     while (height--) {
  2964         /* *INDENT-OFF* */
  2965         DUFFS_LOOP(
  2966         {
  2967             DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
  2968             if ( (Pixel & rgbmask) != ckey ) {
  2969                   ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
  2970             }
  2971             dst += dstbpp;
  2972             src += srcbpp;
  2973         },
  2974         width);
  2975         /* *INDENT-ON* */
  2976         src += srcskip;
  2977         dst += dstskip;
  2978     }
  2979 }
  2980 
  2981 /* Special optimized blit for ARGB 2-10-10-10 --> RGBA */
  2982 static void
  2983 Blit2101010toN(SDL_BlitInfo * info)
  2984 {
  2985     int width = info->dst_w;
  2986     int height = info->dst_h;
  2987     Uint8 *src = info->src;
  2988     int srcskip = info->src_skip;
  2989     Uint8 *dst = info->dst;
  2990     int dstskip = info->dst_skip;
  2991     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2992     int dstbpp = dstfmt->BytesPerPixel;
  2993     Uint32 Pixel;
  2994     unsigned sR, sG, sB, sA;
  2995 
  2996     while (height--) {
  2997         /* *INDENT-OFF* */
  2998         DUFFS_LOOP(
  2999         {
  3000             Pixel = *(Uint32 *)src;
  3001             RGBA_FROM_ARGB2101010(Pixel, sR, sG, sB, sA);
  3002             ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
  3003             dst += dstbpp;
  3004             src += 4;
  3005         },
  3006         width);
  3007         /* *INDENT-ON* */
  3008         src += srcskip;
  3009         dst += dstskip;
  3010     }
  3011 }
  3012 
  3013 /* Special optimized blit for RGBA --> ARGB 2-10-10-10 */
  3014 static void
  3015 BlitNto2101010(SDL_BlitInfo * info)
  3016 {
  3017     int width = info->dst_w;
  3018     int height = info->dst_h;
  3019     Uint8 *src = info->src;
  3020     int srcskip = info->src_skip;
  3021     Uint8 *dst = info->dst;
  3022     int dstskip = info->dst_skip;
  3023     SDL_PixelFormat *srcfmt = info->src_fmt;
  3024     int srcbpp = srcfmt->BytesPerPixel;
  3025     Uint32 Pixel;
  3026     unsigned sR, sG, sB, sA;
  3027 
  3028     while (height--) {
  3029         /* *INDENT-OFF* */
  3030         DUFFS_LOOP(
  3031         {
  3032             DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
  3033             ARGB2101010_FROM_RGBA(Pixel, sR, sG, sB, sA);
  3034             *(Uint32 *)dst = Pixel;
  3035             dst += 4;
  3036             src += srcbpp;
  3037         },
  3038         width);
  3039         /* *INDENT-ON* */
  3040         src += srcskip;
  3041         dst += dstskip;
  3042     }
  3043 }
  3044 
  3045 /* Blit_3or4_to_3or4__same_rgb: 3 or 4 bpp, same RGB triplet */
  3046 static void
  3047 Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info)
  3048 {
  3049     int width = info->dst_w;
  3050     int height = info->dst_h;
  3051     Uint8 *src = info->src;
  3052     int srcskip = info->src_skip;
  3053     Uint8 *dst = info->dst;
  3054     int dstskip = info->dst_skip;
  3055     SDL_PixelFormat *srcfmt = info->src_fmt;
  3056     int srcbpp = srcfmt->BytesPerPixel;
  3057     SDL_PixelFormat *dstfmt = info->dst_fmt;
  3058     int dstbpp = dstfmt->BytesPerPixel;
  3059 
  3060     if (dstfmt->Amask) {
  3061         /* SET_ALPHA */
  3062         Uint32 mask = ((Uint32)info->a) << dstfmt->Ashift;
  3063 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  3064         int i0 = 0, i1 = 1, i2 = 2;
  3065 #else
  3066         int i0 = srcbpp - 1 - 0;
  3067         int i1 = srcbpp - 1 - 1;
  3068         int i2 = srcbpp - 1 - 2;
  3069 #endif
  3070         while (height--) {
  3071             /* *INDENT-OFF* */
  3072             DUFFS_LOOP(
  3073             {
  3074                 Uint32 *dst32 = (Uint32*)dst;
  3075                 Uint8 s0 = src[i0];
  3076                 Uint8 s1 = src[i1];
  3077                 Uint8 s2 = src[i2];
  3078                 *dst32 = (s0) | (s1 << 8) | (s2 << 16) | mask;
  3079                 dst += 4;
  3080                 src += srcbpp;
  3081             }, width);
  3082             /* *INDENT-ON* */
  3083             src += srcskip;
  3084             dst += dstskip;
  3085         }
  3086     } else {
  3087         /* NO_ALPHA */
  3088 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  3089         int i0 = 0, i1 = 1, i2 = 2;
  3090         int j0 = 0, j1 = 1, j2 = 2;
  3091 #else
  3092         int i0 = srcbpp - 1 - 0;
  3093         int i1 = srcbpp - 1 - 1;
  3094         int i2 = srcbpp - 1 - 2;
  3095         int j0 = dstbpp - 1 - 0;
  3096         int j1 = dstbpp - 1 - 1;
  3097         int j2 = dstbpp - 1 - 2;
  3098 #endif
  3099         while (height--) {
  3100             /* *INDENT-OFF* */
  3101             DUFFS_LOOP(
  3102             {
  3103                 Uint8 s0 = src[i0];
  3104                 Uint8 s1 = src[i1];
  3105                 Uint8 s2 = src[i2];
  3106                 dst[j0] = s0;
  3107                 dst[j1] = s1;
  3108                 dst[j2] = s2;
  3109                 dst += dstbpp;
  3110                 src += srcbpp;
  3111             }, width);
  3112             /* *INDENT-ON* */
  3113             src += srcskip;
  3114             dst += dstskip;
  3115         }
  3116     }
  3117 }
  3118 
  3119 /* Blit_3or4_to_3or4__inversed_rgb: 3 or 4 bpp, inversed RGB triplet */
  3120 static void
  3121 Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info)
  3122 {
  3123     int width = info->dst_w;
  3124     int height = info->dst_h;
  3125     Uint8 *src = info->src;
  3126     int srcskip = info->src_skip;
  3127     Uint8 *dst = info->dst;
  3128     int dstskip = info->dst_skip;
  3129     SDL_PixelFormat *srcfmt = info->src_fmt;
  3130     int srcbpp = srcfmt->BytesPerPixel;
  3131     SDL_PixelFormat *dstfmt = info->dst_fmt;
  3132     int dstbpp = dstfmt->BytesPerPixel;
  3133 
  3134     if (dstfmt->Amask) {
  3135         if (srcfmt->Amask) {
  3136             /* COPY_ALPHA */
  3137             /* Only to switch ABGR8888 <-> ARGB8888 */
  3138             while (height--) {
  3139 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  3140                 int i0 = 0, i1 = 1, i2 = 2, i3 = 3;
  3141 #else
  3142                 int i0 = 3, i1 = 2, i2 = 1, i3 = 0;
  3143 #endif
  3144                 /* *INDENT-OFF* */
  3145                 DUFFS_LOOP(
  3146                 {
  3147                     Uint32 *dst32 = (Uint32*)dst;
  3148                     Uint8 s0 = src[i0];
  3149                     Uint8 s1 = src[i1];
  3150                     Uint8 s2 = src[i2];
  3151                     Uint32 alphashift = ((Uint32)src[i3]) << dstfmt->Ashift;
  3152                     /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
  3153                     *dst32 = (s0 << 16) | (s1 << 8) | (s2) | alphashift;
  3154                     dst += 4;
  3155                     src += 4;
  3156                 }, width);
  3157                 /* *INDENT-ON* */
  3158                 src += srcskip;
  3159                 dst += dstskip;
  3160             }
  3161         } else {
  3162             /* SET_ALPHA */
  3163             Uint32 mask = ((Uint32)info->a) << dstfmt->Ashift;
  3164 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  3165             int i0 = 0, i1 = 1, i2 = 2;
  3166 #else
  3167             int i0 = srcbpp - 1 - 0;
  3168             int i1 = srcbpp - 1 - 1;
  3169             int i2 = srcbpp - 1 - 2;
  3170 #endif
  3171             while (height--) {
  3172                 /* *INDENT-OFF* */
  3173                 DUFFS_LOOP(
  3174                 {
  3175                     Uint32 *dst32 = (Uint32*)dst;
  3176                     Uint8 s0 = src[i0];
  3177                     Uint8 s1 = src[i1];
  3178                     Uint8 s2 = src[i2];
  3179                     /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
  3180                     *dst32 = (s0 << 16) | (s1 << 8) | (s2) | mask;
  3181                     dst += 4;
  3182                     src += srcbpp;
  3183                 }, width);
  3184                 /* *INDENT-ON* */
  3185                 src += srcskip;
  3186                 dst += dstskip;
  3187             }
  3188         }
  3189     } else {
  3190         /* NO_ALPHA */
  3191 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  3192         int i0 = 0, i1 = 1, i2 = 2;
  3193         int j0 = 2, j1 = 1, j2 = 0;
  3194 #else
  3195         int i0 = srcbpp - 1 - 0;
  3196         int i1 = srcbpp - 1 - 1;
  3197         int i2 = srcbpp - 1 - 2;
  3198         int j0 = dstbpp - 1 - 2;
  3199         int j1 = dstbpp - 1 - 1;
  3200         int j2 = dstbpp - 1 - 0;
  3201 #endif
  3202         while (height--) {
  3203             /* *INDENT-OFF* */
  3204             DUFFS_LOOP(
  3205             {
  3206                 Uint8 s0 = src[i0];
  3207                 Uint8 s1 = src[i1];
  3208                 Uint8 s2 = src[i2];
  3209                 /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
  3210                 dst[j0] = s0;
  3211                 dst[j1] = s1;
  3212                 dst[j2] = s2;
  3213                 dst += dstbpp;
  3214                 src += srcbpp;
  3215             }, width);
  3216             /* *INDENT-ON* */
  3217             src += srcskip;
  3218             dst += dstskip;
  3219         }
  3220     }
  3221 }
  3222 
  3223 /* Normal N to N optimized blitters */
  3224 #define NO_ALPHA   1
  3225 #define SET_ALPHA  2
  3226 #define COPY_ALPHA 4
  3227 struct blit_table
  3228 {
  3229     Uint32 srcR, srcG, srcB;
  3230     int dstbpp;
  3231     Uint32 dstR, dstG, dstB;
  3232     enum blit_features blit_features;
  3233     SDL_BlitFunc blitfunc;
  3234     Uint32 alpha;  /* bitwise NO_ALPHA, SET_ALPHA, COPY_ALPHA */
  3235 };
  3236 static const struct blit_table normal_blit_1[] = {
  3237     /* Default for 8-bit RGB source, never optimized */
  3238     {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
  3239 };
  3240 
  3241 static const struct blit_table normal_blit_2[] = {
  3242 #if SDL_ALTIVEC_BLITTERS
  3243     /* has-altivec */
  3244     {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
  3245      BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
  3246     {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
  3247      BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
  3248 #endif
  3249 #if SDL_ARM_SIMD_BLITTERS
  3250     {0x00000F00, 0x000000F0, 0x0000000F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
  3251      BLIT_FEATURE_HAS_ARM_SIMD, Blit_RGB444_RGB888ARMSIMD, NO_ALPHA | COPY_ALPHA},
  3252 #endif
  3253 #if SDL_HAVE_BLIT_N_RGB565
  3254     {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
  3255      0, Blit_RGB565_ARGB8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
  3256     {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
  3257      0, Blit_RGB565_ABGR8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
  3258     {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, 0x0000FF00,
  3259      0, Blit_RGB565_RGBA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
  3260     {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000,
  3261      0, Blit_RGB565_BGRA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
  3262 #endif
  3263 
  3264     /* Default for 16-bit RGB source, used if no other blitter matches */
  3265     {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
  3266 };
  3267 
  3268 static const struct blit_table normal_blit_3[] = {
  3269     /* 3->4 with same rgb triplet */
  3270     {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
  3271      0, Blit_3or4_to_3or4__same_rgb,
  3272 #if HAVE_FAST_WRITE_INT8
  3273         NO_ALPHA |
  3274 #endif
  3275         SET_ALPHA},
  3276     {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
  3277      0, Blit_3or4_to_3or4__same_rgb,
  3278 #if HAVE_FAST_WRITE_INT8
  3279         NO_ALPHA |
  3280 #endif
  3281         SET_ALPHA},
  3282     /* 3->4 with inversed rgb triplet */
  3283     {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
  3284      0, Blit_3or4_to_3or4__inversed_rgb,
  3285 #if HAVE_FAST_WRITE_INT8
  3286         NO_ALPHA |
  3287 #endif
  3288         SET_ALPHA},
  3289     {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
  3290      0, Blit_3or4_to_3or4__inversed_rgb,
  3291 #if HAVE_FAST_WRITE_INT8
  3292         NO_ALPHA |
  3293 #endif
  3294         SET_ALPHA},
  3295     /* 3->3 to switch RGB 24 <-> BGR 24 */
  3296     {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x00FF0000, 0x0000FF00, 0x000000FF,
  3297      0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA },
  3298     {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
  3299      0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA },
  3300     /* Default for 24-bit RGB source, never optimized */
  3301     {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
  3302 };
  3303 
  3304 static const struct blit_table normal_blit_4[] = {
  3305 #if SDL_ALTIVEC_BLITTERS
  3306     /* has-altivec | dont-use-prefetch */
  3307     {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
  3308      BLIT_FEATURE_HAS_ALTIVEC | BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH, ConvertAltivec32to32_noprefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
  3309     /* has-altivec */
  3310     {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
  3311      BLIT_FEATURE_HAS_ALTIVEC, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
  3312     /* has-altivec */
  3313     {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F,
  3314      BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB888_RGB565Altivec, NO_ALPHA},
  3315 #endif
  3316 #if SDL_ARM_SIMD_BLITTERS
  3317     {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
  3318      BLIT_FEATURE_HAS_ARM_SIMD, Blit_BGR888_RGB888ARMSIMD, NO_ALPHA | COPY_ALPHA },
  3319 #endif
  3320     /* 4->3 with same rgb triplet */
  3321     {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
  3322      0, Blit_3or4_to_3or4__same_rgb, NO_ALPHA | SET_ALPHA},
  3323     {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x00FF0000, 0x0000FF00, 0x000000FF,
  3324      0, Blit_3or4_to_3or4__same_rgb, NO_ALPHA | SET_ALPHA},
  3325     /* 4->3 with inversed rgb triplet */
  3326     {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x00FF0000, 0x0000FF00, 0x000000FF,
  3327      0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA},
  3328     {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
  3329      0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA},
  3330     /* 4->4 with inversed rgb triplet, and COPY_ALPHA to switch ABGR8888 <-> ARGB8888 */
  3331     {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
  3332      0, Blit_3or4_to_3or4__inversed_rgb,
  3333 #if HAVE_FAST_WRITE_INT8
  3334         NO_ALPHA |
  3335 #endif
  3336         SET_ALPHA | COPY_ALPHA},
  3337     {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
  3338      0, Blit_3or4_to_3or4__inversed_rgb,
  3339 #if HAVE_FAST_WRITE_INT8
  3340         NO_ALPHA |
  3341 #endif
  3342         SET_ALPHA | COPY_ALPHA},
  3343     /* RGB 888 and RGB 565 */
  3344     {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F,
  3345      0, Blit_RGB888_RGB565, NO_ALPHA},
  3346     {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F,
  3347      0, Blit_RGB888_RGB555, NO_ALPHA},
  3348     /* Default for 32-bit RGB source, used if no other blitter matches */
  3349     {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
  3350 };
  3351 
  3352 static const struct blit_table *const normal_blit[] = {
  3353     normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4
  3354 };
  3355 
  3356 /* Mask matches table, or table entry is zero */
  3357 #define MASKOK(x, y) (((x) == (y)) || ((y) == 0x00000000))
  3358 
  3359 SDL_BlitFunc
  3360 SDL_CalculateBlitN(SDL_Surface * surface)
  3361 {
  3362     SDL_PixelFormat *srcfmt;
  3363     SDL_PixelFormat *dstfmt;
  3364     const struct blit_table *table;
  3365     int which;
  3366     SDL_BlitFunc blitfun;
  3367 
  3368     /* Set up data for choosing the blit */
  3369     srcfmt = surface->format;
  3370     dstfmt = surface->map->dst->format;
  3371 
  3372     /* We don't support destinations less than 8-bits */
  3373     if (dstfmt->BitsPerPixel < 8) {
  3374         return (NULL);
  3375     }
  3376 
  3377     switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
  3378     case 0:
  3379         blitfun = NULL;
  3380         if (dstfmt->BitsPerPixel == 8) {
  3381             if ((srcfmt->BytesPerPixel == 4) &&
  3382                 (srcfmt->Rmask == 0x00FF0000) &&
  3383                 (srcfmt->Gmask == 0x0000FF00) &&
  3384                 (srcfmt->Bmask == 0x000000FF)) {
  3385                 blitfun = Blit_RGB888_index8;
  3386             } else if ((srcfmt->BytesPerPixel == 4) &&
  3387                 (srcfmt->Rmask == 0x3FF00000) &&
  3388                 (srcfmt->Gmask == 0x000FFC00) &&
  3389                 (srcfmt->Bmask == 0x000003FF)) {
  3390                 blitfun = Blit_RGB101010_index8;
  3391             } else {
  3392                 blitfun = BlitNto1;
  3393             }
  3394         } else {
  3395             /* Now the meat, choose the blitter we want */
  3396             Uint32 a_need = NO_ALPHA;
  3397             if (dstfmt->Amask)
  3398                 a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA;
  3399             table = normal_blit[srcfmt->BytesPerPixel - 1];
  3400             for (which = 0; table[which].dstbpp; ++which) {
  3401                 if (MASKOK(srcfmt->Rmask, table[which].srcR) &&
  3402                     MASKOK(srcfmt->Gmask, table[which].srcG) &&
  3403                     MASKOK(srcfmt->Bmask, table[which].srcB) &&
  3404                     MASKOK(dstfmt->Rmask, table[which].dstR) &&
  3405                     MASKOK(dstfmt->Gmask, table[which].dstG) &&
  3406                     MASKOK(dstfmt->Bmask, table[which].dstB) &&
  3407                     dstfmt->BytesPerPixel == table[which].dstbpp &&
  3408                     (a_need & table[which].alpha) == a_need &&
  3409                     ((table[which].blit_features & GetBlitFeatures()) ==
  3410                      table[which].blit_features))
  3411                     break;
  3412             }
  3413             blitfun = table[which].blitfunc;
  3414 
  3415             if (blitfun == BlitNtoN) {  /* default C fallback catch-all. Slow! */
  3416                 if (srcfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
  3417                     blitfun = Blit2101010toN;
  3418                 } else if (dstfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
  3419                     blitfun = BlitNto2101010;
  3420                 } else if (srcfmt->BytesPerPixel == 4 &&
  3421                             dstfmt->BytesPerPixel == 4 &&
  3422                             srcfmt->Rmask == dstfmt->Rmask &&
  3423                             srcfmt->Gmask == dstfmt->Gmask &&
  3424                             srcfmt->Bmask == dstfmt->Bmask) {
  3425                     if (a_need == COPY_ALPHA) {
  3426                         if (srcfmt->Amask == dstfmt->Amask) {
  3427                             /* Fastpath C fallback: 32bit RGBA<->RGBA blit with matching RGBA */
  3428                             blitfun = Blit4to4CopyAlpha;
  3429                         } else {
  3430                             blitfun = BlitNtoNCopyAlpha;
  3431                         }
  3432                     } else {
  3433                         /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */
  3434                         blitfun = Blit4to4MaskAlpha;
  3435                     }
  3436                 } else if (a_need == COPY_ALPHA) {
  3437                     blitfun = BlitNtoNCopyAlpha;
  3438                 }
  3439             }
  3440         }
  3441         return (blitfun);
  3442 
  3443     case SDL_COPY_COLORKEY:
  3444         /* colorkey blit: Here we don't have too many options, mostly
  3445            because RLE is the preferred fast way to deal with this.
  3446            If a particular case turns out to be useful we'll add it. */
  3447 
  3448         if (srcfmt->BytesPerPixel == 2 && surface->map->identity)
  3449             return Blit2to2Key;
  3450         else if (dstfmt->BytesPerPixel == 1)
  3451             return BlitNto1Key;
  3452         else {
  3453 #if SDL_ALTIVEC_BLITTERS
  3454             if ((srcfmt->BytesPerPixel == 4) && (dstfmt->BytesPerPixel == 4)
  3455                 && SDL_HasAltiVec()) {
  3456                 return Blit32to32KeyAltivec;
  3457             } else
  3458 #endif
  3459             if (srcfmt->Amask && dstfmt->Amask) {
  3460                 return BlitNtoNKeyCopyAlpha;
  3461             } else {
  3462                 return BlitNtoNKey;
  3463             }
  3464         }
  3465     }
  3466 
  3467     return NULL;
  3468 }
  3469 
  3470 #endif /* SDL_HAVE_BLIT_N */
  3471 
  3472 /* vi: set ts=4 sw=4 expandtab: */