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