src/video/SDL_blit_N.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 28 May 2006 13:04:16 +0000
branchSDL-1.3
changeset 1662 782fd950bd46
parent 1659 14717b52abc0
child 1668 4da1ee79c9af
permissions -rw-r--r--
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.

WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.

The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce

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