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