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