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