src/video/SDL_blit_0.c
author Darren Alton <dalton@stevens.edu>
Wed, 27 Aug 2008 04:23:38 +0000
branchgsoc2008_nds
changeset 2698 e1da92da346c
parent 2267 c785543d1843
child 2853 6258fa7cd300
permissions -rw-r--r--
Clean up.
     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_blit.h"
    26 
    27 /* Functions to blit from bitmaps to other surfaces */
    28 
    29 static void
    30 BlitBto1(SDL_BlitInfo * info)
    31 {
    32     int c;
    33     int width, height;
    34     Uint8 *src, *map, *dst;
    35     int srcskip, dstskip;
    36 
    37     /* Set up some basic variables */
    38     width = info->dst_w;
    39     height = info->dst_h;
    40     src = info->src;
    41     srcskip = info->src_skip;
    42     dst = info->dst;
    43     dstskip = info->dst_skip;
    44     map = info->table;
    45     srcskip += width - (width + 7) / 8;
    46 
    47     if (map) {
    48         while (height--) {
    49             Uint8 byte = 0, bit;
    50             for (c = 0; c < width; ++c) {
    51                 if ((c & 7) == 0) {
    52                     byte = *src++;
    53                 }
    54                 bit = (byte & 0x80) >> 7;
    55                 if (1) {
    56                     *dst = map[bit];
    57                 }
    58                 dst++;
    59                 byte <<= 1;
    60             }
    61             src += srcskip;
    62             dst += dstskip;
    63         }
    64     } else {
    65         while (height--) {
    66             Uint8 byte = 0, bit;
    67             for (c = 0; c < width; ++c) {
    68                 if ((c & 7) == 0) {
    69                     byte = *src++;
    70                 }
    71                 bit = (byte & 0x80) >> 7;
    72                 if (1) {
    73                     *dst = bit;
    74                 }
    75                 dst++;
    76                 byte <<= 1;
    77             }
    78             src += srcskip;
    79             dst += dstskip;
    80         }
    81     }
    82 }
    83 
    84 static void
    85 BlitBto2(SDL_BlitInfo * info)
    86 {
    87     int c;
    88     int width, height;
    89     Uint8 *src;
    90     Uint16 *map, *dst;
    91     int srcskip, dstskip;
    92 
    93     /* Set up some basic variables */
    94     width = info->dst_w;
    95     height = info->dst_h;
    96     src = info->src;
    97     srcskip = info->src_skip;
    98     dst = (Uint16 *) info->dst;
    99     dstskip = info->dst_skip / 2;
   100     map = (Uint16 *) info->table;
   101     srcskip += width - (width + 7) / 8;
   102 
   103     while (height--) {
   104         Uint8 byte = 0, bit;
   105         for (c = 0; c < width; ++c) {
   106             if ((c & 7) == 0) {
   107                 byte = *src++;
   108             }
   109             bit = (byte & 0x80) >> 7;
   110             if (1) {
   111                 *dst = map[bit];
   112             }
   113             byte <<= 1;
   114             dst++;
   115         }
   116         src += srcskip;
   117         dst += dstskip;
   118     }
   119 }
   120 
   121 static void
   122 BlitBto3(SDL_BlitInfo * info)
   123 {
   124     int c, o;
   125     int width, height;
   126     Uint8 *src, *map, *dst;
   127     int srcskip, dstskip;
   128 
   129     /* Set up some basic variables */
   130     width = info->dst_w;
   131     height = info->dst_h;
   132     src = info->src;
   133     srcskip = info->src_skip;
   134     dst = info->dst;
   135     dstskip = info->dst_skip;
   136     map = info->table;
   137     srcskip += width - (width + 7) / 8;
   138 
   139     while (height--) {
   140         Uint8 byte = 0, bit;
   141         for (c = 0; c < width; ++c) {
   142             if ((c & 7) == 0) {
   143                 byte = *src++;
   144             }
   145             bit = (byte & 0x80) >> 7;
   146             if (1) {
   147                 o = bit * 4;
   148                 dst[0] = map[o++];
   149                 dst[1] = map[o++];
   150                 dst[2] = map[o++];
   151             }
   152             byte <<= 1;
   153             dst += 3;
   154         }
   155         src += srcskip;
   156         dst += dstskip;
   157     }
   158 }
   159 
   160 static void
   161 BlitBto4(SDL_BlitInfo * info)
   162 {
   163     int width, height;
   164     Uint8 *src;
   165     Uint32 *map, *dst;
   166     int srcskip, dstskip;
   167     int c;
   168 
   169     /* Set up some basic variables */
   170     width = info->dst_w;
   171     height = info->dst_h;
   172     src = info->src;
   173     srcskip = info->src_skip;
   174     dst = (Uint32 *) info->dst;
   175     dstskip = info->dst_skip / 4;
   176     map = (Uint32 *) info->table;
   177     srcskip += width - (width + 7) / 8;
   178 
   179     while (height--) {
   180         Uint8 byte = 0, bit;
   181         for (c = 0; c < width; ++c) {
   182             if ((c & 7) == 0) {
   183                 byte = *src++;
   184             }
   185             bit = (byte & 0x80) >> 7;
   186             if (1) {
   187                 *dst = map[bit];
   188             }
   189             byte <<= 1;
   190             dst++;
   191         }
   192         src += srcskip;
   193         dst += dstskip;
   194     }
   195 }
   196 
   197 static void
   198 BlitBto1Key(SDL_BlitInfo * info)
   199 {
   200     int width = info->dst_w;
   201     int height = info->dst_h;
   202     Uint8 *src = info->src;
   203     Uint8 *dst = info->dst;
   204     int srcskip = info->src_skip;
   205     int dstskip = info->dst_skip;
   206     Uint32 ckey = info->colorkey;
   207     Uint8 *palmap = info->table;
   208     int c;
   209 
   210     /* Set up some basic variables */
   211     srcskip += width - (width + 7) / 8;
   212 
   213     if (palmap) {
   214         while (height--) {
   215             Uint8 byte = 0, bit;
   216             for (c = 0; c < width; ++c) {
   217                 if ((c & 7) == 0) {
   218                     byte = *src++;
   219                 }
   220                 bit = (byte & 0x80) >> 7;
   221                 if (bit != ckey) {
   222                     *dst = palmap[bit];
   223                 }
   224                 dst++;
   225                 byte <<= 1;
   226             }
   227             src += srcskip;
   228             dst += dstskip;
   229         }
   230     } else {
   231         while (height--) {
   232             Uint8 byte = 0, bit;
   233             for (c = 0; c < width; ++c) {
   234                 if ((c & 7) == 0) {
   235                     byte = *src++;
   236                 }
   237                 bit = (byte & 0x80) >> 7;
   238                 if (bit != ckey) {
   239                     *dst = bit;
   240                 }
   241                 dst++;
   242                 byte <<= 1;
   243             }
   244             src += srcskip;
   245             dst += dstskip;
   246         }
   247     }
   248 }
   249 
   250 static void
   251 BlitBto2Key(SDL_BlitInfo * info)
   252 {
   253     int width = info->dst_w;
   254     int height = info->dst_h;
   255     Uint8 *src = info->src;
   256     Uint16 *dstp = (Uint16 *) info->dst;
   257     int srcskip = info->src_skip;
   258     int dstskip = info->dst_skip;
   259     Uint32 ckey = info->colorkey;
   260     Uint8 *palmap = info->table;
   261     int c;
   262 
   263     /* Set up some basic variables */
   264     srcskip += width - (width + 7) / 8;
   265     dstskip /= 2;
   266 
   267     while (height--) {
   268         Uint8 byte = 0, bit;
   269         for (c = 0; c < width; ++c) {
   270             if ((c & 7) == 0) {
   271                 byte = *src++;
   272             }
   273             bit = (byte & 0x80) >> 7;
   274             if (bit != ckey) {
   275                 *dstp = ((Uint16 *) palmap)[bit];
   276             }
   277             byte <<= 1;
   278             dstp++;
   279         }
   280         src += srcskip;
   281         dstp += dstskip;
   282     }
   283 }
   284 
   285 static void
   286 BlitBto3Key(SDL_BlitInfo * info)
   287 {
   288     int width = info->dst_w;
   289     int height = info->dst_h;
   290     Uint8 *src = info->src;
   291     Uint8 *dst = info->dst;
   292     int srcskip = info->src_skip;
   293     int dstskip = info->dst_skip;
   294     Uint32 ckey = info->colorkey;
   295     Uint8 *palmap = info->table;
   296     int c;
   297 
   298     /* Set up some basic variables */
   299     srcskip += width - (width + 7) / 8;
   300 
   301     while (height--) {
   302         Uint8 byte = 0, bit;
   303         for (c = 0; c < width; ++c) {
   304             if ((c & 7) == 0) {
   305                 byte = *src++;
   306             }
   307             bit = (byte & 0x80) >> 7;
   308             if (bit != ckey) {
   309                 SDL_memcpy(dst, &palmap[bit * 4], 3);
   310             }
   311             byte <<= 1;
   312             dst += 3;
   313         }
   314         src += srcskip;
   315         dst += dstskip;
   316     }
   317 }
   318 
   319 static void
   320 BlitBto4Key(SDL_BlitInfo * info)
   321 {
   322     int width = info->dst_w;
   323     int height = info->dst_h;
   324     Uint8 *src = info->src;
   325     Uint32 *dstp = (Uint32 *) info->dst;
   326     int srcskip = info->src_skip;
   327     int dstskip = info->dst_skip;
   328     Uint32 ckey = info->colorkey;
   329     Uint8 *palmap = info->table;
   330     int c;
   331 
   332     /* Set up some basic variables */
   333     srcskip += width - (width + 7) / 8;
   334     dstskip /= 4;
   335 
   336     while (height--) {
   337         Uint8 byte = 0, bit;
   338         for (c = 0; c < width; ++c) {
   339             if ((c & 7) == 0) {
   340                 byte = *src++;
   341             }
   342             bit = (byte & 0x80) >> 7;
   343             if (bit != ckey) {
   344                 *dstp = ((Uint32 *) palmap)[bit];
   345             }
   346             byte <<= 1;
   347             dstp++;
   348         }
   349         src += srcskip;
   350         dstp += dstskip;
   351     }
   352 }
   353 
   354 static void
   355 BlitBtoNAlpha(SDL_BlitInfo * info)
   356 {
   357     int width = info->dst_w;
   358     int height = info->dst_h;
   359     Uint8 *src = info->src;
   360     Uint8 *dst = info->dst;
   361     int srcskip = info->src_skip;
   362     int dstskip = info->dst_skip;
   363     const SDL_Color *srcpal = info->src_fmt->palette->colors;
   364     SDL_PixelFormat *dstfmt = info->dst_fmt;
   365     int dstbpp;
   366     int c;
   367     const int A = info->a;
   368 
   369     /* Set up some basic variables */
   370     dstbpp = dstfmt->BytesPerPixel;
   371     srcskip += width - (width + 7) / 8;
   372 
   373     while (height--) {
   374         Uint8 byte = 0, bit;
   375         for (c = 0; c < width; ++c) {
   376             if ((c & 7) == 0) {
   377                 byte = *src++;
   378             }
   379             bit = (byte & 0x80) >> 7;
   380             if (1) {
   381                 Uint32 pixel;
   382                 unsigned sR, sG, sB;
   383                 unsigned dR, dG, dB;
   384                 sR = srcpal[bit].r;
   385                 sG = srcpal[bit].g;
   386                 sB = srcpal[bit].b;
   387                 DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB);
   388                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
   389                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
   390             }
   391             byte <<= 1;
   392             dst += dstbpp;
   393         }
   394         src += srcskip;
   395         dst += dstskip;
   396     }
   397 }
   398 
   399 static void
   400 BlitBtoNAlphaKey(SDL_BlitInfo * info)
   401 {
   402     int width = info->dst_w;
   403     int height = info->dst_h;
   404     Uint8 *src = info->src;
   405     Uint8 *dst = info->dst;
   406     int srcskip = info->src_skip;
   407     int dstskip = info->dst_skip;
   408     SDL_PixelFormat *srcfmt = info->src_fmt;
   409     SDL_PixelFormat *dstfmt = info->dst_fmt;
   410     const SDL_Color *srcpal = srcfmt->palette->colors;
   411     int dstbpp;
   412     int c;
   413     const int A = info->a;
   414     Uint32 ckey = info->colorkey;
   415 
   416     /* Set up some basic variables */
   417     dstbpp = dstfmt->BytesPerPixel;
   418     srcskip += width - (width + 7) / 8;
   419 
   420     while (height--) {
   421         Uint8 byte = 0, bit;
   422         for (c = 0; c < width; ++c) {
   423             if ((c & 7) == 0) {
   424                 byte = *src++;
   425             }
   426             bit = (byte & 0x80) >> 7;
   427             if (bit != ckey) {
   428                 int sR, sG, sB;
   429                 int dR, dG, dB;
   430                 Uint32 pixel;
   431                 sR = srcpal[bit].r;
   432                 sG = srcpal[bit].g;
   433                 sB = srcpal[bit].b;
   434                 DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB);
   435                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
   436                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
   437             }
   438             byte <<= 1;
   439             dst += dstbpp;
   440         }
   441         src += srcskip;
   442         dst += dstskip;
   443     }
   444 }
   445 
   446 static SDL_BlitFunc bitmap_blit[] = {
   447     NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
   448 };
   449 
   450 static SDL_BlitFunc colorkey_blit[] = {
   451     NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
   452 };
   453 
   454 SDL_BlitFunc
   455 SDL_CalculateBlit0(SDL_Surface * surface)
   456 {
   457     int which;
   458 
   459     if (surface->format->BitsPerPixel != 1) {
   460         /* We don't support sub 8-bit packed pixel modes */
   461         return NULL;
   462     }
   463     if (surface->map->dst->format->BitsPerPixel < 8) {
   464         which = 0;
   465     } else {
   466         which = surface->map->dst->format->BytesPerPixel;
   467     }
   468     switch (surface->map->info.flags) {
   469     case 0:
   470         return bitmap_blit[which];
   471 
   472     case SDL_COPY_COLORKEY:
   473         return colorkey_blit[which];
   474 
   475     case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
   476         return which >= 2 ? BlitBtoNAlpha : NULL;
   477 
   478     case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
   479         return which >= 2 ? BlitBtoNAlphaKey : NULL;
   480     }
   481     return NULL;
   482 }
   483 
   484 /* vi: set ts=4 sw=4 expandtab: */