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