src/video/SDL_blit_1.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 17 Feb 2011 02:18:41 -0800
changeset 5332 ae8b6fb1feaf
parent 5262 b530ef003506
child 5535 96594ac5fd1a
permissions -rw-r--r--
Fixed warnings about unused variables and so forth.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2011 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_video.h"
    25 #include "SDL_blit.h"
    26 #include "SDL_sysvideo.h"
    27 #include "SDL_endian.h"
    28 
    29 /* Functions to blit from 8-bit surfaces to other surfaces */
    30 
    31 static void
    32 Blit1to1(SDL_BlitInfo * info)
    33 {
    34 #ifndef USE_DUFFS_LOOP
    35     int c;
    36 #endif
    37     int width, height;
    38     Uint8 *src, *map, *dst;
    39     int srcskip, dstskip;
    40 
    41     /* Set up some basic variables */
    42     width = info->dst_w;
    43     height = info->dst_h;
    44     src = info->src;
    45     srcskip = info->src_skip;
    46     dst = info->dst;
    47     dstskip = info->dst_skip;
    48     map = info->table;
    49 
    50     while (height--) {
    51 #ifdef USE_DUFFS_LOOP
    52         /* *INDENT-OFF* */
    53 		DUFFS_LOOP(
    54 			{
    55 			  *dst = map[*src];
    56 			}
    57 			dst++;
    58 			src++;
    59 		, width);
    60         /* *INDENT-ON* */
    61 #else
    62         for (c = width; c; --c) {
    63             *dst = map[*src];
    64             dst++;
    65             src++;
    66         }
    67 #endif
    68         src += srcskip;
    69         dst += dstskip;
    70     }
    71 }
    72 
    73 /* This is now endian dependent */
    74 #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
    75 #define HI	1
    76 #define LO	0
    77 #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
    78 #define HI	0
    79 #define LO	1
    80 #endif
    81 static void
    82 Blit1to2(SDL_BlitInfo * info)
    83 {
    84 #ifndef USE_DUFFS_LOOP
    85     int c;
    86 #endif
    87     int width, height;
    88     Uint8 *src, *dst;
    89     Uint16 *map;
    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 = info->dst;
    98     dstskip = info->dst_skip;
    99     map = (Uint16 *) info->table;
   100 
   101 #ifdef USE_DUFFS_LOOP
   102     while (height--) {
   103 		/* *INDENT-OFF* */
   104 		DUFFS_LOOP(
   105 		{
   106 			*(Uint16 *)dst = map[*src++];
   107 			dst += 2;
   108 		},
   109 		width);
   110 		/* *INDENT-ON* */
   111         src += srcskip;
   112         dst += dstskip;
   113     }
   114 #else
   115     /* Memory align at 4-byte boundary, if necessary */
   116     if ((long) dst & 0x03) {
   117         /* Don't do anything if width is 0 */
   118         if (width == 0) {
   119             return;
   120         }
   121         --width;
   122 
   123         while (height--) {
   124             /* Perform copy alignment */
   125             *(Uint16 *) dst = map[*src++];
   126             dst += 2;
   127 
   128             /* Copy in 4 pixel chunks */
   129             for (c = width / 4; c; --c) {
   130                 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
   131                 src += 2;
   132                 dst += 4;
   133                 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
   134                 src += 2;
   135                 dst += 4;
   136             }
   137             /* Get any leftovers */
   138             switch (width & 3) {
   139             case 3:
   140                 *(Uint16 *) dst = map[*src++];
   141                 dst += 2;
   142             case 2:
   143                 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
   144                 src += 2;
   145                 dst += 4;
   146                 break;
   147             case 1:
   148                 *(Uint16 *) dst = map[*src++];
   149                 dst += 2;
   150                 break;
   151             }
   152             src += srcskip;
   153             dst += dstskip;
   154         }
   155     } else {
   156         while (height--) {
   157             /* Copy in 4 pixel chunks */
   158             for (c = width / 4; c; --c) {
   159                 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
   160                 src += 2;
   161                 dst += 4;
   162                 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
   163                 src += 2;
   164                 dst += 4;
   165             }
   166             /* Get any leftovers */
   167             switch (width & 3) {
   168             case 3:
   169                 *(Uint16 *) dst = map[*src++];
   170                 dst += 2;
   171             case 2:
   172                 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
   173                 src += 2;
   174                 dst += 4;
   175                 break;
   176             case 1:
   177                 *(Uint16 *) dst = map[*src++];
   178                 dst += 2;
   179                 break;
   180             }
   181             src += srcskip;
   182             dst += dstskip;
   183         }
   184     }
   185 #endif /* USE_DUFFS_LOOP */
   186 }
   187 
   188 static void
   189 Blit1to3(SDL_BlitInfo * info)
   190 {
   191 #ifndef USE_DUFFS_LOOP
   192     int c;
   193 #endif
   194     int o;
   195     int width, height;
   196     Uint8 *src, *map, *dst;
   197     int srcskip, dstskip;
   198 
   199     /* Set up some basic variables */
   200     width = info->dst_w;
   201     height = info->dst_h;
   202     src = info->src;
   203     srcskip = info->src_skip;
   204     dst = info->dst;
   205     dstskip = info->dst_skip;
   206     map = info->table;
   207 
   208     while (height--) {
   209 #ifdef USE_DUFFS_LOOP
   210 		/* *INDENT-OFF* */
   211 		DUFFS_LOOP(
   212 			{
   213 				o = *src * 4;
   214 				dst[0] = map[o++];
   215 				dst[1] = map[o++];
   216 				dst[2] = map[o++];
   217 			}
   218 			src++;
   219 			dst += 3;
   220 		, width);
   221 		/* *INDENT-ON* */
   222 #else
   223         for (c = width; c; --c) {
   224             o = *src * 4;
   225             dst[0] = map[o++];
   226             dst[1] = map[o++];
   227             dst[2] = map[o++];
   228             src++;
   229             dst += 3;
   230         }
   231 #endif /* USE_DUFFS_LOOP */
   232         src += srcskip;
   233         dst += dstskip;
   234     }
   235 }
   236 
   237 static void
   238 Blit1to4(SDL_BlitInfo * info)
   239 {
   240 #ifndef USE_DUFFS_LOOP
   241     int c;
   242 #endif
   243     int width, height;
   244     Uint8 *src;
   245     Uint32 *map, *dst;
   246     int srcskip, dstskip;
   247 
   248     /* Set up some basic variables */
   249     width = info->dst_w;
   250     height = info->dst_h;
   251     src = info->src;
   252     srcskip = info->src_skip;
   253     dst = (Uint32 *) info->dst;
   254     dstskip = info->dst_skip / 4;
   255     map = (Uint32 *) info->table;
   256 
   257     while (height--) {
   258 #ifdef USE_DUFFS_LOOP
   259 		/* *INDENT-OFF* */
   260 		DUFFS_LOOP(
   261 			*dst++ = map[*src++];
   262 		, width);
   263 		/* *INDENT-ON* */
   264 #else
   265         for (c = width / 4; c; --c) {
   266             *dst++ = map[*src++];
   267             *dst++ = map[*src++];
   268             *dst++ = map[*src++];
   269             *dst++ = map[*src++];
   270         }
   271         switch (width & 3) {
   272         case 3:
   273             *dst++ = map[*src++];
   274         case 2:
   275             *dst++ = map[*src++];
   276         case 1:
   277             *dst++ = map[*src++];
   278         }
   279 #endif /* USE_DUFFS_LOOP */
   280         src += srcskip;
   281         dst += dstskip;
   282     }
   283 }
   284 
   285 static void
   286 Blit1to1Key(SDL_BlitInfo * info)
   287 {
   288     int width = info->dst_w;
   289     int height = info->dst_h;
   290     Uint8 *src = info->src;
   291     int srcskip = info->src_skip;
   292     Uint8 *dst = info->dst;
   293     int dstskip = info->dst_skip;
   294     Uint8 *palmap = info->table;
   295     Uint32 ckey = info->colorkey;
   296 
   297     if (palmap) {
   298         while (height--) {
   299 			/* *INDENT-OFF* */
   300 			DUFFS_LOOP(
   301 			{
   302 				if ( *src != ckey ) {
   303 				  *dst = palmap[*src];
   304 				}
   305 				dst++;
   306 				src++;
   307 			},
   308 			width);
   309 			/* *INDENT-ON* */
   310             src += srcskip;
   311             dst += dstskip;
   312         }
   313     } else {
   314         while (height--) {
   315 			/* *INDENT-OFF* */
   316 			DUFFS_LOOP(
   317 			{
   318 				if ( *src != ckey ) {
   319 				  *dst = *src;
   320 				}
   321 				dst++;
   322 				src++;
   323 			},
   324 			width);
   325 			/* *INDENT-ON* */
   326             src += srcskip;
   327             dst += dstskip;
   328         }
   329     }
   330 }
   331 
   332 static void
   333 Blit1to2Key(SDL_BlitInfo * info)
   334 {
   335     int width = info->dst_w;
   336     int height = info->dst_h;
   337     Uint8 *src = info->src;
   338     int srcskip = info->src_skip;
   339     Uint16 *dstp = (Uint16 *) info->dst;
   340     int dstskip = info->dst_skip;
   341     Uint16 *palmap = (Uint16 *) info->table;
   342     Uint32 ckey = info->colorkey;
   343 
   344     /* Set up some basic variables */
   345     dstskip /= 2;
   346 
   347     while (height--) {
   348 		/* *INDENT-OFF* */
   349 		DUFFS_LOOP(
   350 		{
   351 			if ( *src != ckey ) {
   352 				*dstp=palmap[*src];
   353 			}
   354 			src++;
   355 			dstp++;
   356 		},
   357 		width);
   358 		/* *INDENT-ON* */
   359         src += srcskip;
   360         dstp += dstskip;
   361     }
   362 }
   363 
   364 static void
   365 Blit1to3Key(SDL_BlitInfo * info)
   366 {
   367     int width = info->dst_w;
   368     int height = info->dst_h;
   369     Uint8 *src = info->src;
   370     int srcskip = info->src_skip;
   371     Uint8 *dst = info->dst;
   372     int dstskip = info->dst_skip;
   373     Uint8 *palmap = info->table;
   374     Uint32 ckey = info->colorkey;
   375     int o;
   376 
   377     while (height--) {
   378 		/* *INDENT-OFF* */
   379 		DUFFS_LOOP(
   380 		{
   381 			if ( *src != ckey ) {
   382 				o = *src * 4;
   383 				dst[0] = palmap[o++];
   384 				dst[1] = palmap[o++];
   385 				dst[2] = palmap[o++];
   386 			}
   387 			src++;
   388 			dst += 3;
   389 		},
   390 		width);
   391 		/* *INDENT-ON* */
   392         src += srcskip;
   393         dst += dstskip;
   394     }
   395 }
   396 
   397 static void
   398 Blit1to4Key(SDL_BlitInfo * info)
   399 {
   400     int width = info->dst_w;
   401     int height = info->dst_h;
   402     Uint8 *src = info->src;
   403     int srcskip = info->src_skip;
   404     Uint32 *dstp = (Uint32 *) info->dst;
   405     int dstskip = info->dst_skip;
   406     Uint32 *palmap = (Uint32 *) info->table;
   407     Uint32 ckey = info->colorkey;
   408 
   409     /* Set up some basic variables */
   410     dstskip /= 4;
   411 
   412     while (height--) {
   413 		/* *INDENT-OFF* */
   414 		DUFFS_LOOP(
   415 		{
   416 			if ( *src != ckey ) {
   417 				*dstp = palmap[*src];
   418 			}
   419 			src++;
   420 			dstp++;
   421 		},
   422 		width);
   423 		/* *INDENT-ON* */
   424         src += srcskip;
   425         dstp += dstskip;
   426     }
   427 }
   428 
   429 static void
   430 Blit1toNAlpha(SDL_BlitInfo * info)
   431 {
   432     int width = info->dst_w;
   433     int height = info->dst_h;
   434     Uint8 *src = info->src;
   435     int srcskip = info->src_skip;
   436     Uint8 *dst = info->dst;
   437     int dstskip = info->dst_skip;
   438     SDL_PixelFormat *dstfmt = info->dst_fmt;
   439     const SDL_Color *srcpal = info->src_fmt->palette->colors;
   440     int dstbpp;
   441     const int A = info->a;
   442 
   443     /* Set up some basic variables */
   444     dstbpp = dstfmt->BytesPerPixel;
   445 
   446     while (height--) {
   447         int sR, sG, sB;
   448         int dR, dG, dB;
   449 	    	/* *INDENT-OFF* */
   450 	    	DUFFS_LOOP4(
   451 			{
   452 			        Uint32 pixel;
   453 				sR = srcpal[*src].r;
   454 				sG = srcpal[*src].g;
   455 				sB = srcpal[*src].b;
   456 				DISEMBLE_RGB(dst, dstbpp, dstfmt,
   457 					     pixel, dR, dG, dB);
   458 				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
   459 			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
   460 				src++;
   461 				dst += dstbpp;
   462 			},
   463 			width);
   464 	    	/* *INDENT-ON* */
   465         src += srcskip;
   466         dst += dstskip;
   467     }
   468 }
   469 
   470 static void
   471 Blit1toNAlphaKey(SDL_BlitInfo * info)
   472 {
   473     int width = info->dst_w;
   474     int height = info->dst_h;
   475     Uint8 *src = info->src;
   476     int srcskip = info->src_skip;
   477     Uint8 *dst = info->dst;
   478     int dstskip = info->dst_skip;
   479     SDL_PixelFormat *dstfmt = info->dst_fmt;
   480     const SDL_Color *srcpal = info->src_fmt->palette->colors;
   481     Uint32 ckey = info->colorkey;
   482     int dstbpp;
   483     const int A = info->a;
   484 
   485     /* Set up some basic variables */
   486     dstbpp = dstfmt->BytesPerPixel;
   487 
   488     while (height--) {
   489         int sR, sG, sB;
   490         int dR, dG, dB;
   491 		/* *INDENT-OFF* */
   492 		DUFFS_LOOP(
   493 		{
   494 			if ( *src != ckey ) {
   495 			        Uint32 pixel;
   496 				sR = srcpal[*src].r;
   497 				sG = srcpal[*src].g;
   498 				sB = srcpal[*src].b;
   499 				DISEMBLE_RGB(dst, dstbpp, dstfmt,
   500 							pixel, dR, dG, dB);
   501 				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
   502 			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
   503 			}
   504 			src++;
   505 			dst += dstbpp;
   506 		},
   507 		width);
   508 		/* *INDENT-ON* */
   509         src += srcskip;
   510         dst += dstskip;
   511     }
   512 }
   513 
   514 static const SDL_BlitFunc one_blit[] = {
   515     NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
   516 };
   517 
   518 static const SDL_BlitFunc one_blitkey[] = {
   519     NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
   520 };
   521 
   522 SDL_BlitFunc
   523 SDL_CalculateBlit1(SDL_Surface * surface)
   524 {
   525     int which;
   526     SDL_PixelFormat *dstfmt;
   527 
   528     dstfmt = surface->map->dst->format;
   529     if (dstfmt->BitsPerPixel < 8) {
   530         which = 0;
   531     } else {
   532         which = dstfmt->BytesPerPixel;
   533     }
   534     switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
   535     case 0:
   536         return one_blit[which];
   537 
   538     case SDL_COPY_COLORKEY:
   539         return one_blitkey[which];
   540 
   541     case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
   542         /* Supporting 8bpp->8bpp alpha is doable but requires lots of
   543            tables which consume space and takes time to precompute,
   544            so is better left to the user */
   545         return which >= 2 ? Blit1toNAlpha : NULL;
   546 
   547     case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
   548         return which >= 2 ? Blit1toNAlphaKey : NULL;
   549     }
   550     return NULL;
   551 }
   552 
   553 /* vi: set ts=4 sw=4 expandtab: */