src/video/SDL_blit_0.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 14 Dec 2001 12:38:15 +0000
changeset 252 e8157fcb3114
parent 91 e85e03f195b4
child 297 f6ffac90895c
permissions -rw-r--r--
Updated the source with the correct e-mail address
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 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     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 #include <stdio.h>
    29 #include <string.h>
    30 
    31 #include "SDL_types.h"
    32 #include "SDL_video.h"
    33 #include "SDL_blit.h"
    34 
    35 /* Functions to blit from bitmaps to other surfaces */
    36 
    37 static void BlitBto1(SDL_BlitInfo *info)
    38 {
    39 	int c;
    40 	int width, height;
    41 	Uint8 *src, *map, *dst;
    42 	int srcskip, dstskip;
    43 
    44 	/* Set up some basic variables */
    45 	width = info->d_width;
    46 	height = info->d_height;
    47 	src = info->s_pixels;
    48 	srcskip = info->s_skip;
    49 	dst = info->d_pixels;
    50 	dstskip = info->d_skip;
    51 	map = info->table;
    52 	srcskip += width-(width+7)/8;
    53 
    54 	if ( map ) {
    55 		while ( height-- ) {
    56 		        Uint8 byte = 0, bit;
    57 	    		for ( c=0; c<width; ++c ) {
    58 				if ( (c&7) == 0 ) {
    59 					byte = *src++;
    60 				}
    61 				bit = (byte&0x80)>>7;
    62 				if ( 1 ) {
    63 				  *dst = map[bit];
    64 				}
    65 				dst++;
    66 				byte <<= 1;
    67 			}
    68 			src += srcskip;
    69 			dst += dstskip;
    70 		}
    71 	} else {
    72 		while ( height-- ) {
    73 		        Uint8 byte = 0, bit;
    74 	    		for ( c=0; c<width; ++c ) {
    75 				if ( (c&7) == 0 ) {
    76 					byte = *src++;
    77 				}
    78 				bit = (byte&0x80)>>7;
    79 				if ( 1 ) {
    80 				  *dst = bit;
    81 				}
    82 				dst++;
    83 				byte <<= 1;
    84 			}
    85 			src += srcskip;
    86 			dst += dstskip;
    87 		}
    88 	}
    89 }
    90 static void BlitBto2(SDL_BlitInfo *info)
    91 {
    92 	int c;
    93 	int width, height;
    94 	Uint8 *src;
    95 	Uint16 *map, *dst;
    96 	int srcskip, dstskip;
    97 
    98 	/* Set up some basic variables */
    99 	width = info->d_width;
   100 	height = info->d_height;
   101 	src = info->s_pixels;
   102 	srcskip = info->s_skip;
   103 	dst = (Uint16 *)info->d_pixels;
   104 	dstskip = info->d_skip/2;
   105 	map = (Uint16 *)info->table;
   106 	srcskip += width-(width+7)/8;
   107 
   108 	while ( height-- ) {
   109 	        Uint8 byte = 0, bit;
   110 	    	for ( c=0; c<width; ++c ) {
   111 			if ( (c&7) == 0 ) {
   112 				byte = *src++;
   113 			}
   114 			bit = (byte&0x80)>>7;
   115 			if ( 1 ) {
   116 				*dst = map[bit];
   117 			}
   118 			byte <<= 1;
   119 			dst++;
   120 		}
   121 		src += srcskip;
   122 		dst += dstskip;
   123 	}
   124 }
   125 static void BlitBto3(SDL_BlitInfo *info)
   126 {
   127 	int c, o;
   128 	int width, height;
   129 	Uint8 *src, *map, *dst;
   130 	int srcskip, dstskip;
   131 
   132 	/* Set up some basic variables */
   133 	width = info->d_width;
   134 	height = info->d_height;
   135 	src = info->s_pixels;
   136 	srcskip = info->s_skip;
   137 	dst = info->d_pixels;
   138 	dstskip = info->d_skip;
   139 	map = info->table;
   140 	srcskip += width-(width+7)/8;
   141 
   142 	while ( height-- ) {
   143 	        Uint8 byte = 0, bit;
   144 	    	for ( c=0; c<width; ++c ) {
   145 			if ( (c&7) == 0 ) {
   146 				byte = *src++;
   147 			}
   148 			bit = (byte&0x80)>>7;
   149 			if ( 1 ) {
   150 				o = bit * 4;
   151 				dst[0] = map[o++];
   152 				dst[1] = map[o++];
   153 				dst[2] = map[o++];
   154 			}
   155 			byte <<= 1;
   156 			dst += 3;
   157 		}
   158 		src += srcskip;
   159 		dst += dstskip;
   160 	}
   161 }
   162 static void BlitBto4(SDL_BlitInfo *info)
   163 {
   164 	int width, height;
   165 	Uint8 *src;
   166 	Uint32 *map, *dst;
   167 	int srcskip, dstskip;
   168 	int c;
   169 
   170 	/* Set up some basic variables */
   171 	width = info->d_width;
   172 	height = info->d_height;
   173 	src = info->s_pixels;
   174 	srcskip = info->s_skip;
   175 	dst = (Uint32 *)info->d_pixels;
   176 	dstskip = info->d_skip/4;
   177 	map = (Uint32 *)info->table;
   178 	srcskip += width-(width+7)/8;
   179 
   180 	while ( height-- ) {
   181 	        Uint8 byte = 0, bit;
   182 	    	for ( c=0; c<width; ++c ) {
   183 			if ( (c&7) == 0 ) {
   184 				byte = *src++;
   185 			}
   186 			bit = (byte&0x80)>>7;
   187 			if ( 1 ) {
   188 				*dst = map[bit];
   189 			}
   190 			byte <<= 1;
   191 			dst++;
   192 		}
   193 		src += srcskip;
   194 		dst += dstskip;
   195 	}
   196 }
   197 
   198 static void BlitBto1Key(SDL_BlitInfo *info)
   199 {
   200         int width = info->d_width;
   201 	int height = info->d_height;
   202 	Uint8 *src = info->s_pixels;
   203 	Uint8 *dst = info->d_pixels;
   204 	int srcskip = info->s_skip;
   205 	int dstskip = info->d_skip;
   206 	Uint32 ckey = info->src->colorkey;
   207 	Uint8 *palmap = info->table;
   208 	int c;
   209 
   210 	/* Set up some basic variables */
   211 	srcskip += width-(width+7)/8;
   212 
   213 	if ( palmap ) {
   214 		while ( height-- ) {
   215 		        Uint8  byte = 0, bit;
   216 	    		for ( c=0; c<width; ++c ) {
   217 				if ( (c&7) == 0 ) {
   218 					byte = *src++;
   219 				}
   220 				bit = (byte&0x80)>>7;
   221 				if ( bit != ckey ) {
   222 				  *dst = palmap[bit];
   223 				}
   224 				dst++;
   225 				byte <<= 1;
   226 			}
   227 			src += srcskip;
   228 			dst += dstskip;
   229 		}
   230 	} else {
   231 		while ( height-- ) {
   232 		        Uint8  byte = 0, bit;
   233 	    		for ( c=0; c<width; ++c ) {
   234 				if ( (c&7) == 0 ) {
   235 					byte = *src++;
   236 				}
   237 				bit = (byte&0x80)>>7;
   238 				if ( bit != ckey ) {
   239 				  *dst = bit;
   240 				}
   241 				dst++;
   242 				byte <<= 1;
   243 			}
   244 			src += srcskip;
   245 			dst += dstskip;
   246 		}
   247 	}
   248 }
   249 
   250 static void BlitBto2Key(SDL_BlitInfo *info)
   251 {
   252         int width = info->d_width;
   253 	int height = info->d_height;
   254 	Uint8 *src = info->s_pixels;
   255 	Uint16 *dstp = (Uint16 *)info->d_pixels;
   256 	int srcskip = info->s_skip;
   257 	int dstskip = info->d_skip;
   258 	Uint32 ckey = info->src->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 BlitBto3Key(SDL_BlitInfo *info)
   285 {
   286         int width = info->d_width;
   287 	int height = info->d_height;
   288 	Uint8 *src = info->s_pixels;
   289 	Uint8 *dst = info->d_pixels;
   290 	int srcskip = info->s_skip;
   291 	int dstskip = info->d_skip;
   292 	Uint32 ckey = info->src->colorkey;
   293 	Uint8 *palmap = info->table;
   294 	int c;
   295 
   296 	/* Set up some basic variables */
   297 	srcskip += width-(width+7)/8;
   298 
   299 	while ( height-- ) {
   300 	        Uint8  byte = 0, bit;
   301 	    	for ( c=0; c<width; ++c ) {
   302 			if ( (c&7) == 0 ) {
   303 				byte = *src++;
   304 			}
   305 			bit = (byte&0x80)>>7;
   306 			if ( bit != ckey ) {
   307 				memcpy(dst, &palmap[bit*4], 3);
   308 			}
   309 			byte <<= 1;
   310 			dst += 3;
   311 		}
   312 		src += srcskip;
   313 		dst += dstskip;
   314 	}
   315 }
   316 
   317 static void BlitBto4Key(SDL_BlitInfo *info)
   318 {
   319         int width = info->d_width;
   320 	int height = info->d_height;
   321 	Uint8 *src = info->s_pixels;
   322 	Uint32 *dstp = (Uint32 *)info->d_pixels;
   323 	int srcskip = info->s_skip;
   324 	int dstskip = info->d_skip;
   325 	Uint32 ckey = info->src->colorkey;
   326 	Uint8 *palmap = info->table;
   327 	int c;
   328 
   329 	/* Set up some basic variables */
   330 	srcskip += width-(width+7)/8;
   331 	dstskip /= 4;
   332 
   333 	while ( height-- ) {
   334 	        Uint8 byte = 0, bit;
   335 	    	for ( c=0; c<width; ++c ) {
   336 			if ( (c&7) == 0 ) {
   337 				byte = *src++;
   338 			}
   339 			bit = (byte&0x80)>>7;
   340 			if ( bit != ckey ) {
   341 				*dstp=((Uint32 *)palmap)[bit];
   342 			}
   343 			byte <<= 1;
   344 			dstp++;
   345 		}
   346 		src += srcskip;
   347 		dstp += dstskip;
   348 	}
   349 }
   350 
   351 static void BlitBtoNAlpha(SDL_BlitInfo *info)
   352 {
   353         int width = info->d_width;
   354 	int height = info->d_height;
   355 	Uint8 *src = info->s_pixels;
   356 	Uint8 *dst = info->d_pixels;
   357 	int srcskip = info->s_skip;
   358 	int dstskip = info->d_skip;
   359 	const SDL_Color *srcpal	= info->src->palette->colors;
   360 	SDL_PixelFormat *dstfmt = info->dst;
   361 	int  dstbpp;
   362 	int c;
   363 	const int A = info->src->alpha;
   364 
   365 	/* Set up some basic variables */
   366 	dstbpp = dstfmt->BytesPerPixel;
   367 	srcskip += width-(width+7)/8;
   368 
   369 	while ( height-- ) {
   370 	        Uint8 byte = 0, bit;
   371 	    	for ( c=0; c<width; ++c ) {
   372 			if ( (c&7) == 0 ) {
   373 				byte = *src++;
   374 			}
   375 			bit = (byte&0x80)>>7;
   376 			if ( 1 ) {
   377 			        Uint32 pixel;
   378 			        unsigned sR, sG, sB;
   379 				unsigned dR, dG, dB;
   380 				sR = srcpal[bit].r;
   381 				sG = srcpal[bit].g;
   382 				sB = srcpal[bit].b;
   383 				DISEMBLE_RGB(dst, dstbpp, dstfmt,
   384 							pixel, dR, dG, dB);
   385 				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
   386 			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
   387 			}
   388 			byte <<= 1;
   389 			dst += dstbpp;
   390 		}
   391 		src += srcskip;
   392 		dst += dstskip;
   393 	}
   394 }
   395 
   396 static void BlitBtoNAlphaKey(SDL_BlitInfo *info)
   397 {
   398         int width = info->d_width;
   399 	int height = info->d_height;
   400 	Uint8 *src = info->s_pixels;
   401 	Uint8 *dst = info->d_pixels;
   402 	int srcskip = info->s_skip;
   403 	int dstskip = info->d_skip;
   404 	SDL_PixelFormat *srcfmt = info->src;
   405 	SDL_PixelFormat *dstfmt = info->dst;
   406 	const SDL_Color *srcpal	= srcfmt->palette->colors;
   407 	int dstbpp;
   408 	int c;
   409 	const int A = srcfmt->alpha;
   410 	Uint32 ckey = srcfmt->colorkey;
   411 
   412 	/* Set up some basic variables */
   413 	dstbpp = dstfmt->BytesPerPixel;
   414 	srcskip += width-(width+7)/8;
   415 
   416 	while ( height-- ) {
   417 	        Uint8  byte = 0, bit;
   418 	    	for ( c=0; c<width; ++c ) {
   419 			if ( (c&7) == 0 ) {
   420 				byte = *src++;
   421 			}
   422 			bit = (byte&0x80)>>7;
   423 			if ( bit != ckey ) {
   424 			        int sR, sG, sB;
   425 				int dR, dG, dB;
   426 				Uint32 pixel;
   427 				sR = srcpal[bit].r;
   428 				sG = srcpal[bit].g;
   429 				sB = srcpal[bit].b;
   430 				DISEMBLE_RGB(dst, dstbpp, dstfmt,
   431 							pixel, dR, dG, dB);
   432 				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
   433 			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
   434 			}
   435 			byte <<= 1;
   436 			dst += dstbpp;
   437 		}
   438 		src += srcskip;
   439 		dst += dstskip;
   440 	}
   441 }
   442 
   443 static SDL_loblit bitmap_blit[] = {
   444 	NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
   445 };
   446 
   447 static SDL_loblit colorkey_blit[] = {
   448     NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
   449 };
   450 
   451 SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int blit_index)
   452 {
   453 	int which;
   454 
   455 	if ( surface->map->dst->format->BitsPerPixel < 8 ) {
   456 		which = 0;
   457 	} else {
   458 		which = surface->map->dst->format->BytesPerPixel;
   459 	}
   460 	switch(blit_index) {
   461 	case 0:			/* copy */
   462 	    return bitmap_blit[which];
   463 
   464 	case 1:			/* colorkey */
   465 	    return colorkey_blit[which];
   466 
   467 	case 2:			/* alpha */
   468 	    return which >= 2 ? BlitBtoNAlpha : NULL;
   469 
   470 	case 4:			/* alpha + colorkey */
   471 	    return which >= 2 ? BlitBtoNAlphaKey : NULL;
   472 	}
   473 	return NULL;
   474 }
   475