src/video/SDL_blit_0.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 01 Feb 2006 06:32:25 +0000
changeset 1312 c9b51268668f
parent 1058 e6c91fd1911e
child 1330 450721ad5436
permissions -rw-r--r--
Updated copyright information and removed rcs id lines (problematic in branch merges)
I batch edited these files, so please let me know if I've accidentally removed anybody's
credit here.
     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 
    23 #include <stdio.h>
    24 #include <string.h>
    25 
    26 #include "SDL_types.h"
    27 #include "SDL_video.h"
    28 #include "SDL_blit.h"
    29 
    30 /* Functions to blit from bitmaps to other surfaces */
    31 
    32 static void BlitBto1(SDL_BlitInfo *info)
    33 {
    34 	int c;
    35 	int width, height;
    36 	Uint8 *src, *map, *dst;
    37 	int srcskip, dstskip;
    38 
    39 	/* Set up some basic variables */
    40 	width = info->d_width;
    41 	height = info->d_height;
    42 	src = info->s_pixels;
    43 	srcskip = info->s_skip;
    44 	dst = info->d_pixels;
    45 	dstskip = info->d_skip;
    46 	map = info->table;
    47 	srcskip += width-(width+7)/8;
    48 
    49 	if ( map ) {
    50 		while ( height-- ) {
    51 		        Uint8 byte = 0, bit;
    52 	    		for ( c=0; c<width; ++c ) {
    53 				if ( (c&7) == 0 ) {
    54 					byte = *src++;
    55 				}
    56 				bit = (byte&0x80)>>7;
    57 				if ( 1 ) {
    58 				  *dst = map[bit];
    59 				}
    60 				dst++;
    61 				byte <<= 1;
    62 			}
    63 			src += srcskip;
    64 			dst += dstskip;
    65 		}
    66 	} else {
    67 		while ( height-- ) {
    68 		        Uint8 byte = 0, bit;
    69 	    		for ( c=0; c<width; ++c ) {
    70 				if ( (c&7) == 0 ) {
    71 					byte = *src++;
    72 				}
    73 				bit = (byte&0x80)>>7;
    74 				if ( 1 ) {
    75 				  *dst = bit;
    76 				}
    77 				dst++;
    78 				byte <<= 1;
    79 			}
    80 			src += srcskip;
    81 			dst += dstskip;
    82 		}
    83 	}
    84 }
    85 static void 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->d_width;
    95 	height = info->d_height;
    96 	src = info->s_pixels;
    97 	srcskip = info->s_skip;
    98 	dst = (Uint16 *)info->d_pixels;
    99 	dstskip = info->d_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 static void BlitBto3(SDL_BlitInfo *info)
   121 {
   122 	int c, o;
   123 	int width, height;
   124 	Uint8 *src, *map, *dst;
   125 	int srcskip, dstskip;
   126 
   127 	/* Set up some basic variables */
   128 	width = info->d_width;
   129 	height = info->d_height;
   130 	src = info->s_pixels;
   131 	srcskip = info->s_skip;
   132 	dst = info->d_pixels;
   133 	dstskip = info->d_skip;
   134 	map = info->table;
   135 	srcskip += width-(width+7)/8;
   136 
   137 	while ( height-- ) {
   138 	        Uint8 byte = 0, bit;
   139 	    	for ( c=0; c<width; ++c ) {
   140 			if ( (c&7) == 0 ) {
   141 				byte = *src++;
   142 			}
   143 			bit = (byte&0x80)>>7;
   144 			if ( 1 ) {
   145 				o = bit * 4;
   146 				dst[0] = map[o++];
   147 				dst[1] = map[o++];
   148 				dst[2] = map[o++];
   149 			}
   150 			byte <<= 1;
   151 			dst += 3;
   152 		}
   153 		src += srcskip;
   154 		dst += dstskip;
   155 	}
   156 }
   157 static void BlitBto4(SDL_BlitInfo *info)
   158 {
   159 	int width, height;
   160 	Uint8 *src;
   161 	Uint32 *map, *dst;
   162 	int srcskip, dstskip;
   163 	int c;
   164 
   165 	/* Set up some basic variables */
   166 	width = info->d_width;
   167 	height = info->d_height;
   168 	src = info->s_pixels;
   169 	srcskip = info->s_skip;
   170 	dst = (Uint32 *)info->d_pixels;
   171 	dstskip = info->d_skip/4;
   172 	map = (Uint32 *)info->table;
   173 	srcskip += width-(width+7)/8;
   174 
   175 	while ( height-- ) {
   176 	        Uint8 byte = 0, bit;
   177 	    	for ( c=0; c<width; ++c ) {
   178 			if ( (c&7) == 0 ) {
   179 				byte = *src++;
   180 			}
   181 			bit = (byte&0x80)>>7;
   182 			if ( 1 ) {
   183 				*dst = map[bit];
   184 			}
   185 			byte <<= 1;
   186 			dst++;
   187 		}
   188 		src += srcskip;
   189 		dst += dstskip;
   190 	}
   191 }
   192 
   193 static void BlitBto1Key(SDL_BlitInfo *info)
   194 {
   195         int width = info->d_width;
   196 	int height = info->d_height;
   197 	Uint8 *src = info->s_pixels;
   198 	Uint8 *dst = info->d_pixels;
   199 	int srcskip = info->s_skip;
   200 	int dstskip = info->d_skip;
   201 	Uint32 ckey = info->src->colorkey;
   202 	Uint8 *palmap = info->table;
   203 	int c;
   204 
   205 	/* Set up some basic variables */
   206 	srcskip += width-(width+7)/8;
   207 
   208 	if ( palmap ) {
   209 		while ( height-- ) {
   210 		        Uint8  byte = 0, bit;
   211 	    		for ( c=0; c<width; ++c ) {
   212 				if ( (c&7) == 0 ) {
   213 					byte = *src++;
   214 				}
   215 				bit = (byte&0x80)>>7;
   216 				if ( bit != ckey ) {
   217 				  *dst = palmap[bit];
   218 				}
   219 				dst++;
   220 				byte <<= 1;
   221 			}
   222 			src += srcskip;
   223 			dst += dstskip;
   224 		}
   225 	} else {
   226 		while ( height-- ) {
   227 		        Uint8  byte = 0, bit;
   228 	    		for ( c=0; c<width; ++c ) {
   229 				if ( (c&7) == 0 ) {
   230 					byte = *src++;
   231 				}
   232 				bit = (byte&0x80)>>7;
   233 				if ( bit != ckey ) {
   234 				  *dst = bit;
   235 				}
   236 				dst++;
   237 				byte <<= 1;
   238 			}
   239 			src += srcskip;
   240 			dst += dstskip;
   241 		}
   242 	}
   243 }
   244 
   245 static void BlitBto2Key(SDL_BlitInfo *info)
   246 {
   247         int width = info->d_width;
   248 	int height = info->d_height;
   249 	Uint8 *src = info->s_pixels;
   250 	Uint16 *dstp = (Uint16 *)info->d_pixels;
   251 	int srcskip = info->s_skip;
   252 	int dstskip = info->d_skip;
   253 	Uint32 ckey = info->src->colorkey;
   254 	Uint8 *palmap = info->table;
   255 	int c;
   256 
   257 	/* Set up some basic variables */
   258 	srcskip += width-(width+7)/8;
   259 	dstskip /= 2;
   260 
   261 	while ( height-- ) {
   262 	        Uint8 byte = 0, bit;
   263 	    	for ( c=0; c<width; ++c ) {
   264 			if ( (c&7) == 0 ) {
   265 				byte = *src++;
   266 			}
   267 			bit = (byte&0x80)>>7;
   268 			if ( bit != ckey ) {
   269 				*dstp=((Uint16 *)palmap)[bit];
   270 			}
   271 			byte <<= 1;
   272 			dstp++;
   273 		}
   274 		src += srcskip;
   275 		dstp += dstskip;
   276 	}
   277 }
   278 
   279 static void BlitBto3Key(SDL_BlitInfo *info)
   280 {
   281         int width = info->d_width;
   282 	int height = info->d_height;
   283 	Uint8 *src = info->s_pixels;
   284 	Uint8 *dst = info->d_pixels;
   285 	int srcskip = info->s_skip;
   286 	int dstskip = info->d_skip;
   287 	Uint32 ckey = info->src->colorkey;
   288 	Uint8 *palmap = info->table;
   289 	int c;
   290 
   291 	/* Set up some basic variables */
   292 	srcskip += width-(width+7)/8;
   293 
   294 	while ( height-- ) {
   295 	        Uint8  byte = 0, bit;
   296 	    	for ( c=0; c<width; ++c ) {
   297 			if ( (c&7) == 0 ) {
   298 				byte = *src++;
   299 			}
   300 			bit = (byte&0x80)>>7;
   301 			if ( bit != ckey ) {
   302 				memcpy(dst, &palmap[bit*4], 3);
   303 			}
   304 			byte <<= 1;
   305 			dst += 3;
   306 		}
   307 		src += srcskip;
   308 		dst += dstskip;
   309 	}
   310 }
   311 
   312 static void BlitBto4Key(SDL_BlitInfo *info)
   313 {
   314         int width = info->d_width;
   315 	int height = info->d_height;
   316 	Uint8 *src = info->s_pixels;
   317 	Uint32 *dstp = (Uint32 *)info->d_pixels;
   318 	int srcskip = info->s_skip;
   319 	int dstskip = info->d_skip;
   320 	Uint32 ckey = info->src->colorkey;
   321 	Uint8 *palmap = info->table;
   322 	int c;
   323 
   324 	/* Set up some basic variables */
   325 	srcskip += width-(width+7)/8;
   326 	dstskip /= 4;
   327 
   328 	while ( height-- ) {
   329 	        Uint8 byte = 0, bit;
   330 	    	for ( c=0; c<width; ++c ) {
   331 			if ( (c&7) == 0 ) {
   332 				byte = *src++;
   333 			}
   334 			bit = (byte&0x80)>>7;
   335 			if ( bit != ckey ) {
   336 				*dstp=((Uint32 *)palmap)[bit];
   337 			}
   338 			byte <<= 1;
   339 			dstp++;
   340 		}
   341 		src += srcskip;
   342 		dstp += dstskip;
   343 	}
   344 }
   345 
   346 static void BlitBtoNAlpha(SDL_BlitInfo *info)
   347 {
   348         int width = info->d_width;
   349 	int height = info->d_height;
   350 	Uint8 *src = info->s_pixels;
   351 	Uint8 *dst = info->d_pixels;
   352 	int srcskip = info->s_skip;
   353 	int dstskip = info->d_skip;
   354 	const SDL_Color *srcpal	= info->src->palette->colors;
   355 	SDL_PixelFormat *dstfmt = info->dst;
   356 	int  dstbpp;
   357 	int c;
   358 	const int A = info->src->alpha;
   359 
   360 	/* Set up some basic variables */
   361 	dstbpp = dstfmt->BytesPerPixel;
   362 	srcskip += width-(width+7)/8;
   363 
   364 	while ( height-- ) {
   365 	        Uint8 byte = 0, bit;
   366 	    	for ( c=0; c<width; ++c ) {
   367 			if ( (c&7) == 0 ) {
   368 				byte = *src++;
   369 			}
   370 			bit = (byte&0x80)>>7;
   371 			if ( 1 ) {
   372 			        Uint32 pixel;
   373 			        unsigned sR, sG, sB;
   374 				unsigned dR, dG, dB;
   375 				sR = srcpal[bit].r;
   376 				sG = srcpal[bit].g;
   377 				sB = srcpal[bit].b;
   378 				DISEMBLE_RGB(dst, dstbpp, dstfmt,
   379 							pixel, dR, dG, dB);
   380 				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
   381 			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
   382 			}
   383 			byte <<= 1;
   384 			dst += dstbpp;
   385 		}
   386 		src += srcskip;
   387 		dst += dstskip;
   388 	}
   389 }
   390 
   391 static void BlitBtoNAlphaKey(SDL_BlitInfo *info)
   392 {
   393         int width = info->d_width;
   394 	int height = info->d_height;
   395 	Uint8 *src = info->s_pixels;
   396 	Uint8 *dst = info->d_pixels;
   397 	int srcskip = info->s_skip;
   398 	int dstskip = info->d_skip;
   399 	SDL_PixelFormat *srcfmt = info->src;
   400 	SDL_PixelFormat *dstfmt = info->dst;
   401 	const SDL_Color *srcpal	= srcfmt->palette->colors;
   402 	int dstbpp;
   403 	int c;
   404 	const int A = srcfmt->alpha;
   405 	Uint32 ckey = srcfmt->colorkey;
   406 
   407 	/* Set up some basic variables */
   408 	dstbpp = dstfmt->BytesPerPixel;
   409 	srcskip += width-(width+7)/8;
   410 
   411 	while ( height-- ) {
   412 	        Uint8  byte = 0, bit;
   413 	    	for ( c=0; c<width; ++c ) {
   414 			if ( (c&7) == 0 ) {
   415 				byte = *src++;
   416 			}
   417 			bit = (byte&0x80)>>7;
   418 			if ( bit != ckey ) {
   419 			        int sR, sG, sB;
   420 				int dR, dG, dB;
   421 				Uint32 pixel;
   422 				sR = srcpal[bit].r;
   423 				sG = srcpal[bit].g;
   424 				sB = srcpal[bit].b;
   425 				DISEMBLE_RGB(dst, dstbpp, dstfmt,
   426 							pixel, dR, dG, dB);
   427 				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
   428 			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
   429 			}
   430 			byte <<= 1;
   431 			dst += dstbpp;
   432 		}
   433 		src += srcskip;
   434 		dst += dstskip;
   435 	}
   436 }
   437 
   438 static SDL_loblit bitmap_blit[] = {
   439 	NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
   440 };
   441 
   442 static SDL_loblit colorkey_blit[] = {
   443     NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
   444 };
   445 
   446 SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int blit_index)
   447 {
   448 	int which;
   449 
   450 	if ( surface->format->BitsPerPixel != 1 ) {
   451 		/* We don't support sub 8-bit packed pixel modes */
   452 		return NULL;
   453 	}
   454 	if ( surface->map->dst->format->BitsPerPixel < 8 ) {
   455 		which = 0;
   456 	} else {
   457 		which = surface->map->dst->format->BytesPerPixel;
   458 	}
   459 	switch(blit_index) {
   460 	case 0:			/* copy */
   461 	    return bitmap_blit[which];
   462 
   463 	case 1:			/* colorkey */
   464 	    return colorkey_blit[which];
   465 
   466 	case 2:			/* alpha */
   467 	    return which >= 2 ? BlitBtoNAlpha : NULL;
   468 
   469 	case 4:			/* alpha + colorkey */
   470 	    return which >= 2 ? BlitBtoNAlphaKey : NULL;
   471 	}
   472 	return NULL;
   473 }
   474