src/video/SDL_blit_0.c
author Ozkan Sezer <sezeroz@gmail.com>
Fri, 23 Aug 2019 03:01:10 +0300
changeset 13033 70bf772a32d7
parent 12503 806492103856
permissions -rw-r--r--
fix permissions
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../SDL_internal.h"
    22 
    23 #include "SDL_video.h"
    24 #include "SDL_blit.h"
    25 
    26 /* Functions to blit from bitmaps to other surfaces */
    27 
    28 static void
    29 BlitBto1(SDL_BlitInfo * info)
    30 {
    31     int c;
    32     int width, height;
    33     Uint8 *src, *map, *dst;
    34     int srcskip, dstskip;
    35 
    36     /* Set up some basic variables */
    37     width = info->dst_w;
    38     height = info->dst_h;
    39     src = info->src;
    40     srcskip = info->src_skip;
    41     dst = info->dst;
    42     dstskip = info->dst_skip;
    43     map = info->table;
    44     srcskip += width - (width + 7) / 8;
    45 
    46     if (map) {
    47         while (height--) {
    48             Uint8 byte = 0, bit;
    49             for (c = 0; c < width; ++c) {
    50                 if ((c & 7) == 0) {
    51                     byte = *src++;
    52                 }
    53                 bit = (byte & 0x80) >> 7;
    54                 if (1) {
    55                     *dst = map[bit];
    56                 }
    57                 dst++;
    58                 byte <<= 1;
    59             }
    60             src += srcskip;
    61             dst += dstskip;
    62         }
    63     } else {
    64         while (height--) {
    65             Uint8 byte = 0, bit;
    66             for (c = 0; c < width; ++c) {
    67                 if ((c & 7) == 0) {
    68                     byte = *src++;
    69                 }
    70                 bit = (byte & 0x80) >> 7;
    71                 if (1) {
    72                     *dst = bit;
    73                 }
    74                 dst++;
    75                 byte <<= 1;
    76             }
    77             src += srcskip;
    78             dst += dstskip;
    79         }
    80     }
    81 }
    82 
    83 static void
    84 BlitBto2(SDL_BlitInfo * info)
    85 {
    86     int c;
    87     int width, height;
    88     Uint8 *src;
    89     Uint16 *map, *dst;
    90     int srcskip, dstskip;
    91 
    92     /* Set up some basic variables */
    93     width = info->dst_w;
    94     height = info->dst_h;
    95     src = info->src;
    96     srcskip = info->src_skip;
    97     dst = (Uint16 *) info->dst;
    98     dstskip = info->dst_skip / 2;
    99     map = (Uint16 *) info->table;
   100     srcskip += width - (width + 7) / 8;
   101 
   102     while (height--) {
   103         Uint8 byte = 0, bit;
   104         for (c = 0; c < width; ++c) {
   105             if ((c & 7) == 0) {
   106                 byte = *src++;
   107             }
   108             bit = (byte & 0x80) >> 7;
   109             if (1) {
   110                 *dst = map[bit];
   111             }
   112             byte <<= 1;
   113             dst++;
   114         }
   115         src += srcskip;
   116         dst += dstskip;
   117     }
   118 }
   119 
   120 static void
   121 BlitBto3(SDL_BlitInfo * info)
   122 {
   123     int c, o;
   124     int width, height;
   125     Uint8 *src, *map, *dst;
   126     int srcskip, dstskip;
   127 
   128     /* Set up some basic variables */
   129     width = info->dst_w;
   130     height = info->dst_h;
   131     src = info->src;
   132     srcskip = info->src_skip;
   133     dst = info->dst;
   134     dstskip = info->dst_skip;
   135     map = info->table;
   136     srcskip += width - (width + 7) / 8;
   137 
   138     while (height--) {
   139         Uint8 byte = 0, bit;
   140         for (c = 0; c < width; ++c) {
   141             if ((c & 7) == 0) {
   142                 byte = *src++;
   143             }
   144             bit = (byte & 0x80) >> 7;
   145             if (1) {
   146                 o = bit * 4;
   147                 dst[0] = map[o++];
   148                 dst[1] = map[o++];
   149                 dst[2] = map[o++];
   150             }
   151             byte <<= 1;
   152             dst += 3;
   153         }
   154         src += srcskip;
   155         dst += dstskip;
   156     }
   157 }
   158 
   159 static void
   160 BlitBto4(SDL_BlitInfo * info)
   161 {
   162     int width, height;
   163     Uint8 *src;
   164     Uint32 *map, *dst;
   165     int srcskip, dstskip;
   166     int c;
   167 
   168     /* Set up some basic variables */
   169     width = info->dst_w;
   170     height = info->dst_h;
   171     src = info->src;
   172     srcskip = info->src_skip;
   173     dst = (Uint32 *) info->dst;
   174     dstskip = info->dst_skip / 4;
   175     map = (Uint32 *) info->table;
   176     srcskip += width - (width + 7) / 8;
   177 
   178     while (height--) {
   179         Uint8 byte = 0, bit;
   180         for (c = 0; c < width; ++c) {
   181             if ((c & 7) == 0) {
   182                 byte = *src++;
   183             }
   184             bit = (byte & 0x80) >> 7;
   185             if (1) {
   186                 *dst = map[bit];
   187             }
   188             byte <<= 1;
   189             dst++;
   190         }
   191         src += srcskip;
   192         dst += dstskip;
   193     }
   194 }
   195 
   196 static void
   197 BlitBto1Key(SDL_BlitInfo * info)
   198 {
   199     int width = info->dst_w;
   200     int height = info->dst_h;
   201     Uint8 *src = info->src;
   202     Uint8 *dst = info->dst;
   203     int srcskip = info->src_skip;
   204     int dstskip = info->dst_skip;
   205     Uint32 ckey = info->colorkey;
   206     Uint8 *palmap = info->table;
   207     int c;
   208 
   209     /* Set up some basic variables */
   210     srcskip += width - (width + 7) / 8;
   211 
   212     if (palmap) {
   213         while (height--) {
   214             Uint8 byte = 0, bit;
   215             for (c = 0; c < width; ++c) {
   216                 if ((c & 7) == 0) {
   217                     byte = *src++;
   218                 }
   219                 bit = (byte & 0x80) >> 7;
   220                 if (bit != ckey) {
   221                     *dst = palmap[bit];
   222                 }
   223                 dst++;
   224                 byte <<= 1;
   225             }
   226             src += srcskip;
   227             dst += dstskip;
   228         }
   229     } else {
   230         while (height--) {
   231             Uint8 byte = 0, bit;
   232             for (c = 0; c < width; ++c) {
   233                 if ((c & 7) == 0) {
   234                     byte = *src++;
   235                 }
   236                 bit = (byte & 0x80) >> 7;
   237                 if (bit != ckey) {
   238                     *dst = bit;
   239                 }
   240                 dst++;
   241                 byte <<= 1;
   242             }
   243             src += srcskip;
   244             dst += dstskip;
   245         }
   246     }
   247 }
   248 
   249 static void
   250 BlitBto2Key(SDL_BlitInfo * info)
   251 {
   252     int width = info->dst_w;
   253     int height = info->dst_h;
   254     Uint8 *src = info->src;
   255     Uint16 *dstp = (Uint16 *) info->dst;
   256     int srcskip = info->src_skip;
   257     int dstskip = info->dst_skip;
   258     Uint32 ckey = info->colorkey;
   259     Uint8 *palmap = info->table;
   260     int c;
   261 
   262     /* Set up some basic variables */
   263     srcskip += width - (width + 7) / 8;
   264     dstskip /= 2;
   265 
   266     while (height--) {
   267         Uint8 byte = 0, bit;
   268         for (c = 0; c < width; ++c) {
   269             if ((c & 7) == 0) {
   270                 byte = *src++;
   271             }
   272             bit = (byte & 0x80) >> 7;
   273             if (bit != ckey) {
   274                 *dstp = ((Uint16 *) palmap)[bit];
   275             }
   276             byte <<= 1;
   277             dstp++;
   278         }
   279         src += srcskip;
   280         dstp += dstskip;
   281     }
   282 }
   283 
   284 static void
   285 BlitBto3Key(SDL_BlitInfo * info)
   286 {
   287     int width = info->dst_w;
   288     int height = info->dst_h;
   289     Uint8 *src = info->src;
   290     Uint8 *dst = info->dst;
   291     int srcskip = info->src_skip;
   292     int dstskip = info->dst_skip;
   293     Uint32 ckey = info->colorkey;
   294     Uint8 *palmap = info->table;
   295     int c;
   296 
   297     /* Set up some basic variables */
   298     srcskip += width - (width + 7) / 8;
   299 
   300     while (height--) {
   301         Uint8 byte = 0, bit;
   302         for (c = 0; c < width; ++c) {
   303             if ((c & 7) == 0) {
   304                 byte = *src++;
   305             }
   306             bit = (byte & 0x80) >> 7;
   307             if (bit != ckey) {
   308                 SDL_memcpy(dst, &palmap[bit * 4], 3);
   309             }
   310             byte <<= 1;
   311             dst += 3;
   312         }
   313         src += srcskip;
   314         dst += dstskip;
   315     }
   316 }
   317 
   318 static void
   319 BlitBto4Key(SDL_BlitInfo * info)
   320 {
   321     int width = info->dst_w;
   322     int height = info->dst_h;
   323     Uint8 *src = info->src;
   324     Uint32 *dstp = (Uint32 *) info->dst;
   325     int srcskip = info->src_skip;
   326     int dstskip = info->dst_skip;
   327     Uint32 ckey = info->colorkey;
   328     Uint8 *palmap = info->table;
   329     int c;
   330 
   331     /* Set up some basic variables */
   332     srcskip += width - (width + 7) / 8;
   333     dstskip /= 4;
   334 
   335     while (height--) {
   336         Uint8 byte = 0, bit;
   337         for (c = 0; c < width; ++c) {
   338             if ((c & 7) == 0) {
   339                 byte = *src++;
   340             }
   341             bit = (byte & 0x80) >> 7;
   342             if (bit != ckey) {
   343                 *dstp = ((Uint32 *) palmap)[bit];
   344             }
   345             byte <<= 1;
   346             dstp++;
   347         }
   348         src += srcskip;
   349         dstp += dstskip;
   350     }
   351 }
   352 
   353 static void
   354 BlitBtoNAlpha(SDL_BlitInfo * info)
   355 {
   356     int width = info->dst_w;
   357     int height = info->dst_h;
   358     Uint8 *src = info->src;
   359     Uint8 *dst = info->dst;
   360     int srcskip = info->src_skip;
   361     int dstskip = info->dst_skip;
   362     const SDL_Color *srcpal = info->src_fmt->palette->colors;
   363     SDL_PixelFormat *dstfmt = info->dst_fmt;
   364     int dstbpp;
   365     int c;
   366     Uint32 pixel;
   367     unsigned sR, sG, sB;
   368     unsigned dR, dG, dB, dA;
   369     const unsigned A = info->a;
   370 
   371     /* Set up some basic variables */
   372     dstbpp = dstfmt->BytesPerPixel;
   373     srcskip += width - (width + 7) / 8;
   374 
   375     while (height--) {
   376         Uint8 byte = 0, bit;
   377         for (c = 0; c < width; ++c) {
   378             if ((c & 7) == 0) {
   379                 byte = *src++;
   380             }
   381             bit = (byte & 0x80) >> 7;
   382             if (1) {
   383                 sR = srcpal[bit].r;
   384                 sG = srcpal[bit].g;
   385                 sB = srcpal[bit].b;
   386                 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
   387                 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
   388                 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
   389             }
   390             byte <<= 1;
   391             dst += dstbpp;
   392         }
   393         src += srcskip;
   394         dst += dstskip;
   395     }
   396 }
   397 
   398 static void
   399 BlitBtoNAlphaKey(SDL_BlitInfo * info)
   400 {
   401     int width = info->dst_w;
   402     int height = info->dst_h;
   403     Uint8 *src = info->src;
   404     Uint8 *dst = info->dst;
   405     int srcskip = info->src_skip;
   406     int dstskip = info->dst_skip;
   407     SDL_PixelFormat *srcfmt = info->src_fmt;
   408     SDL_PixelFormat *dstfmt = info->dst_fmt;
   409     const SDL_Color *srcpal = srcfmt->palette->colors;
   410     int dstbpp;
   411     int c;
   412     Uint32 pixel;
   413     unsigned sR, sG, sB;
   414     unsigned dR, dG, dB, dA;
   415     const unsigned A = info->a;
   416     Uint32 ckey = info->colorkey;
   417 
   418     /* Set up some basic variables */
   419     dstbpp = dstfmt->BytesPerPixel;
   420     srcskip += width - (width + 7) / 8;
   421 
   422     while (height--) {
   423         Uint8 byte = 0, bit;
   424         for (c = 0; c < width; ++c) {
   425             if ((c & 7) == 0) {
   426                 byte = *src++;
   427             }
   428             bit = (byte & 0x80) >> 7;
   429             if (bit != ckey) {
   430                 sR = srcpal[bit].r;
   431                 sG = srcpal[bit].g;
   432                 sB = srcpal[bit].b;
   433                 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
   434                 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
   435                 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
   436             }
   437             byte <<= 1;
   438             dst += dstbpp;
   439         }
   440         src += srcskip;
   441         dst += dstskip;
   442     }
   443 }
   444 
   445 static const SDL_BlitFunc bitmap_blit[] = {
   446     (SDL_BlitFunc) NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
   447 };
   448 
   449 static const SDL_BlitFunc colorkey_blit[] = {
   450     (SDL_BlitFunc) NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
   451 };
   452 
   453 SDL_BlitFunc
   454 SDL_CalculateBlit0(SDL_Surface * surface)
   455 {
   456     int which;
   457 
   458     if (surface->format->BitsPerPixel != 1) {
   459         /* We don't support sub 8-bit packed pixel modes */
   460         return (SDL_BlitFunc) NULL;
   461     }
   462     if (surface->map->dst->format->BitsPerPixel < 8) {
   463         which = 0;
   464     } else {
   465         which = surface->map->dst->format->BytesPerPixel;
   466     }
   467     switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
   468     case 0:
   469         return bitmap_blit[which];
   470 
   471     case SDL_COPY_COLORKEY:
   472         return colorkey_blit[which];
   473 
   474     case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
   475         return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc) NULL;
   476 
   477     case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
   478         return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc) NULL;
   479     }
   480     return (SDL_BlitFunc) NULL;
   481 }
   482 
   483 /* vi: set ts=4 sw=4 expandtab: */