symbian-qemu-0.9.1-12/libsdl-trunk/src/video/SDL_blit_1.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 #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 Blit1to1(SDL_BlitInfo *info)
       
    32 {
       
    33 #ifndef USE_DUFFS_LOOP
       
    34 	int c;
       
    35 #endif
       
    36 	int width, height;
       
    37 	Uint8 *src, *map, *dst;
       
    38 	int srcskip, dstskip;
       
    39 
       
    40 	/* Set up some basic variables */
       
    41 	width = info->d_width;
       
    42 	height = info->d_height;
       
    43 	src = info->s_pixels;
       
    44 	srcskip = info->s_skip;
       
    45 	dst = info->d_pixels;
       
    46 	dstskip = info->d_skip;
       
    47 	map = info->table;
       
    48 
       
    49 	while ( height-- ) {
       
    50 #ifdef USE_DUFFS_LOOP
       
    51 		DUFFS_LOOP(
       
    52 			{
       
    53 			  *dst = map[*src];
       
    54 			}
       
    55 			dst++;
       
    56 			src++;
       
    57 		, width);
       
    58 #else
       
    59 		for ( c=width; c; --c ) {
       
    60 		        *dst = map[*src];
       
    61 			dst++;
       
    62 			src++;
       
    63 		}
       
    64 #endif
       
    65 		src += srcskip;
       
    66 		dst += dstskip;
       
    67 	}
       
    68 }
       
    69 /* This is now endian dependent */
       
    70 #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
       
    71 #define HI	1
       
    72 #define LO	0
       
    73 #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
       
    74 #define HI	0
       
    75 #define LO	1
       
    76 #endif
       
    77 static void Blit1to2(SDL_BlitInfo *info)
       
    78 {
       
    79 #ifndef USE_DUFFS_LOOP
       
    80 	int c;
       
    81 #endif
       
    82 	int width, height;
       
    83 	Uint8 *src, *dst;
       
    84 	Uint16 *map;
       
    85 	int srcskip, dstskip;
       
    86 
       
    87 	/* Set up some basic variables */
       
    88 	width = info->d_width;
       
    89 	height = info->d_height;
       
    90 	src = info->s_pixels;
       
    91 	srcskip = info->s_skip;
       
    92 	dst = info->d_pixels;
       
    93 	dstskip = info->d_skip;
       
    94 	map = (Uint16 *)info->table;
       
    95 
       
    96 #ifdef USE_DUFFS_LOOP
       
    97 	while ( height-- ) {
       
    98 		DUFFS_LOOP(
       
    99 		{
       
   100 			*(Uint16 *)dst = map[*src++];
       
   101 			dst += 2;
       
   102 		},
       
   103 		width);
       
   104 		src += srcskip;
       
   105 		dst += dstskip;
       
   106 	}
       
   107 #else
       
   108 	/* Memory align at 4-byte boundary, if necessary */
       
   109 	if ( (long)dst & 0x03 ) {
       
   110 		/* Don't do anything if width is 0 */
       
   111 		if ( width == 0 ) {
       
   112 			return;
       
   113 		}
       
   114 		--width;
       
   115 
       
   116 		while ( height-- ) {
       
   117 			/* Perform copy alignment */
       
   118 			*(Uint16 *)dst = map[*src++];
       
   119 			dst += 2;
       
   120 
       
   121 			/* Copy in 4 pixel chunks */
       
   122 			for ( c=width/4; c; --c ) {
       
   123 				*(Uint32 *)dst =
       
   124 					(map[src[HI]]<<16)|(map[src[LO]]);
       
   125 				src += 2;
       
   126 				dst += 4;
       
   127 				*(Uint32 *)dst =
       
   128 					(map[src[HI]]<<16)|(map[src[LO]]);
       
   129 				src += 2;
       
   130 				dst += 4;
       
   131 			}
       
   132 			/* Get any leftovers */
       
   133 			switch (width & 3) {
       
   134 				case 3:
       
   135 					*(Uint16 *)dst = map[*src++];
       
   136 					dst += 2;
       
   137 				case 2:
       
   138 					*(Uint32 *)dst =
       
   139 					  (map[src[HI]]<<16)|(map[src[LO]]);
       
   140 					src += 2;
       
   141 					dst += 4;
       
   142 					break;
       
   143 				case 1:
       
   144 					*(Uint16 *)dst = map[*src++];
       
   145 					dst += 2;
       
   146 					break;
       
   147 			}
       
   148 			src += srcskip;
       
   149 			dst += dstskip;
       
   150 		}
       
   151 	} else { 
       
   152 		while ( height-- ) {
       
   153 			/* Copy in 4 pixel chunks */
       
   154 			for ( c=width/4; c; --c ) {
       
   155 				*(Uint32 *)dst =
       
   156 					(map[src[HI]]<<16)|(map[src[LO]]);
       
   157 				src += 2;
       
   158 				dst += 4;
       
   159 				*(Uint32 *)dst =
       
   160 					(map[src[HI]]<<16)|(map[src[LO]]);
       
   161 				src += 2;
       
   162 				dst += 4;
       
   163 			}
       
   164 			/* Get any leftovers */
       
   165 			switch (width & 3) {
       
   166 				case 3:
       
   167 					*(Uint16 *)dst = map[*src++];
       
   168 					dst += 2;
       
   169 				case 2:
       
   170 					*(Uint32 *)dst =
       
   171 					  (map[src[HI]]<<16)|(map[src[LO]]);
       
   172 					src += 2;
       
   173 					dst += 4;
       
   174 					break;
       
   175 				case 1:
       
   176 					*(Uint16 *)dst = map[*src++];
       
   177 					dst += 2;
       
   178 					break;
       
   179 			}
       
   180 			src += srcskip;
       
   181 			dst += dstskip;
       
   182 		}
       
   183 	}
       
   184 #endif /* USE_DUFFS_LOOP */
       
   185 }
       
   186 static void Blit1to3(SDL_BlitInfo *info)
       
   187 {
       
   188 #ifndef USE_DUFFS_LOOP
       
   189 	int c;
       
   190 #endif
       
   191 	int o;
       
   192 	int width, height;
       
   193 	Uint8 *src, *map, *dst;
       
   194 	int srcskip, dstskip;
       
   195 
       
   196 	/* Set up some basic variables */
       
   197 	width = info->d_width;
       
   198 	height = info->d_height;
       
   199 	src = info->s_pixels;
       
   200 	srcskip = info->s_skip;
       
   201 	dst = info->d_pixels;
       
   202 	dstskip = info->d_skip;
       
   203 	map = info->table;
       
   204 
       
   205 	while ( height-- ) {
       
   206 #ifdef USE_DUFFS_LOOP
       
   207 		DUFFS_LOOP(
       
   208 			{
       
   209 				o = *src * 4;
       
   210 				dst[0] = map[o++];
       
   211 				dst[1] = map[o++];
       
   212 				dst[2] = map[o++];
       
   213 			}
       
   214 			src++;
       
   215 			dst += 3;
       
   216 		, width);
       
   217 #else
       
   218 		for ( c=width; c; --c ) {
       
   219 			o = *src * 4;
       
   220 			dst[0] = map[o++];
       
   221 			dst[1] = map[o++];
       
   222 			dst[2] = map[o++];
       
   223 			src++;
       
   224 			dst += 3;
       
   225 		}
       
   226 #endif /* USE_DUFFS_LOOP */
       
   227 		src += srcskip;
       
   228 		dst += dstskip;
       
   229 	}
       
   230 }
       
   231 static void Blit1to4(SDL_BlitInfo *info)
       
   232 {
       
   233 #ifndef USE_DUFFS_LOOP
       
   234 	int c;
       
   235 #endif
       
   236 	int width, height;
       
   237 	Uint8 *src;
       
   238 	Uint32 *map, *dst;
       
   239 	int srcskip, dstskip;
       
   240 
       
   241 	/* Set up some basic variables */
       
   242 	width = info->d_width;
       
   243 	height = info->d_height;
       
   244 	src = info->s_pixels;
       
   245 	srcskip = info->s_skip;
       
   246 	dst = (Uint32 *)info->d_pixels;
       
   247 	dstskip = info->d_skip/4;
       
   248 	map = (Uint32 *)info->table;
       
   249 
       
   250 	while ( height-- ) {
       
   251 #ifdef USE_DUFFS_LOOP
       
   252 		DUFFS_LOOP(
       
   253 			*dst++ = map[*src++];
       
   254 		, width);
       
   255 #else
       
   256 		for ( c=width/4; c; --c ) {
       
   257 			*dst++ = map[*src++];
       
   258 			*dst++ = map[*src++];
       
   259 			*dst++ = map[*src++];
       
   260 			*dst++ = map[*src++];
       
   261 		}
       
   262 		switch ( width & 3 ) {
       
   263 			case 3:
       
   264 				*dst++ = map[*src++];
       
   265 			case 2:
       
   266 				*dst++ = map[*src++];
       
   267 			case 1:
       
   268 				*dst++ = map[*src++];
       
   269 		}
       
   270 #endif /* USE_DUFFS_LOOP */
       
   271 		src += srcskip;
       
   272 		dst += dstskip;
       
   273 	}
       
   274 }
       
   275 
       
   276 static void Blit1to1Key(SDL_BlitInfo *info)
       
   277 {
       
   278 	int width = info->d_width;
       
   279 	int height = info->d_height;
       
   280 	Uint8 *src = info->s_pixels;
       
   281 	int srcskip = info->s_skip;
       
   282 	Uint8 *dst = info->d_pixels;
       
   283 	int dstskip = info->d_skip;
       
   284 	Uint8 *palmap = info->table;
       
   285 	Uint32 ckey = info->src->colorkey;
       
   286         
       
   287 	if ( palmap ) {
       
   288 		while ( height-- ) {
       
   289 			DUFFS_LOOP(
       
   290 			{
       
   291 				if ( *src != ckey ) {
       
   292 				  *dst = palmap[*src];
       
   293 				}
       
   294 				dst++;
       
   295 				src++;
       
   296 			},
       
   297 			width);
       
   298 			src += srcskip;
       
   299 			dst += dstskip;
       
   300 		}
       
   301 	} else {
       
   302 		while ( height-- ) {
       
   303 			DUFFS_LOOP(
       
   304 			{
       
   305 				if ( *src != ckey ) {
       
   306 				  *dst = *src;
       
   307 				}
       
   308 				dst++;
       
   309 				src++;
       
   310 			},
       
   311 			width);
       
   312 			src += srcskip;
       
   313 			dst += dstskip;
       
   314 		}
       
   315 	}
       
   316 }
       
   317 
       
   318 static void Blit1to2Key(SDL_BlitInfo *info)
       
   319 {
       
   320 	int width = info->d_width;
       
   321 	int height = info->d_height;
       
   322 	Uint8 *src = info->s_pixels;
       
   323 	int srcskip = info->s_skip;
       
   324 	Uint16 *dstp = (Uint16 *)info->d_pixels;
       
   325 	int dstskip = info->d_skip;
       
   326 	Uint16 *palmap = (Uint16 *)info->table;
       
   327 	Uint32 ckey = info->src->colorkey;
       
   328 
       
   329 	/* Set up some basic variables */
       
   330 	dstskip /= 2;
       
   331 
       
   332 	while ( height-- ) {
       
   333 		DUFFS_LOOP(
       
   334 		{
       
   335 			if ( *src != ckey ) {
       
   336 				*dstp=palmap[*src];
       
   337 			}
       
   338 			src++;
       
   339 			dstp++;
       
   340 		},
       
   341 		width);
       
   342 		src += srcskip;
       
   343 		dstp += dstskip;
       
   344 	}
       
   345 }
       
   346 
       
   347 static void Blit1to3Key(SDL_BlitInfo *info)
       
   348 {
       
   349 	int width = info->d_width;
       
   350 	int height = info->d_height;
       
   351 	Uint8 *src = info->s_pixels;
       
   352 	int srcskip = info->s_skip;
       
   353 	Uint8 *dst = info->d_pixels;
       
   354 	int dstskip = info->d_skip;
       
   355 	Uint8 *palmap = info->table;
       
   356 	Uint32 ckey = info->src->colorkey;
       
   357 	int o;
       
   358 
       
   359 	while ( height-- ) {
       
   360 		DUFFS_LOOP(
       
   361 		{
       
   362 			if ( *src != ckey ) {
       
   363 				o = *src * 4;
       
   364 				dst[0] = palmap[o++];
       
   365 				dst[1] = palmap[o++];
       
   366 				dst[2] = palmap[o++];
       
   367 			}
       
   368 			src++;
       
   369 			dst += 3;
       
   370 		},
       
   371 		width);
       
   372 		src += srcskip;
       
   373 		dst += dstskip;
       
   374 	}
       
   375 }
       
   376 
       
   377 static void Blit1to4Key(SDL_BlitInfo *info)
       
   378 {
       
   379 	int width = info->d_width;
       
   380 	int height = info->d_height;
       
   381 	Uint8 *src = info->s_pixels;
       
   382 	int srcskip = info->s_skip;
       
   383 	Uint32 *dstp = (Uint32 *)info->d_pixels;
       
   384 	int dstskip = info->d_skip;
       
   385 	Uint32 *palmap = (Uint32 *)info->table;
       
   386 	Uint32 ckey = info->src->colorkey;
       
   387 
       
   388 	/* Set up some basic variables */
       
   389 	dstskip /= 4;
       
   390 
       
   391 	while ( height-- ) {
       
   392 		DUFFS_LOOP(
       
   393 		{
       
   394 			if ( *src != ckey ) {
       
   395 				*dstp = palmap[*src];
       
   396 			}
       
   397 			src++;
       
   398 			dstp++;
       
   399 		},
       
   400 		width);
       
   401 		src += srcskip;
       
   402 		dstp += dstskip;
       
   403 	}
       
   404 }
       
   405 
       
   406 static void Blit1toNAlpha(SDL_BlitInfo *info)
       
   407 {
       
   408 	int width = info->d_width;
       
   409 	int height = info->d_height;
       
   410 	Uint8 *src = info->s_pixels;
       
   411 	int srcskip = info->s_skip;
       
   412 	Uint8 *dst = info->d_pixels;
       
   413 	int dstskip = info->d_skip;
       
   414 	SDL_PixelFormat *dstfmt = info->dst;
       
   415 	const SDL_Color *srcpal	= info->src->palette->colors;
       
   416 	int dstbpp;
       
   417 	const int A = info->src->alpha;
       
   418 
       
   419 	/* Set up some basic variables */
       
   420 	dstbpp = dstfmt->BytesPerPixel;
       
   421 
       
   422 	while ( height-- ) {
       
   423 	        int sR, sG, sB;
       
   424 		int dR, dG, dB;
       
   425 	    	DUFFS_LOOP4(
       
   426 			{
       
   427 			        Uint32 pixel;
       
   428 				sR = srcpal[*src].r;
       
   429 				sG = srcpal[*src].g;
       
   430 				sB = srcpal[*src].b;
       
   431 				DISEMBLE_RGB(dst, dstbpp, dstfmt,
       
   432 					     pixel, dR, dG, dB);
       
   433 				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
       
   434 			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
       
   435 				src++;
       
   436 				dst += dstbpp;
       
   437 			},
       
   438 			width);
       
   439 		src += srcskip;
       
   440 		dst += dstskip;
       
   441 	}
       
   442 }
       
   443 
       
   444 static void Blit1toNAlphaKey(SDL_BlitInfo *info)
       
   445 {
       
   446 	int width = info->d_width;
       
   447 	int height = info->d_height;
       
   448 	Uint8 *src = info->s_pixels;
       
   449 	int srcskip = info->s_skip;
       
   450 	Uint8 *dst = info->d_pixels;
       
   451 	int dstskip = info->d_skip;
       
   452 	SDL_PixelFormat *srcfmt = info->src;
       
   453 	SDL_PixelFormat *dstfmt = info->dst;
       
   454 	const SDL_Color *srcpal	= info->src->palette->colors;
       
   455 	Uint32 ckey = srcfmt->colorkey;
       
   456 	int dstbpp;
       
   457 	const int A = srcfmt->alpha;
       
   458 
       
   459 	/* Set up some basic variables */
       
   460 	dstbpp = dstfmt->BytesPerPixel;
       
   461 
       
   462 	while ( height-- ) {
       
   463 	        int sR, sG, sB;
       
   464 		int dR, dG, dB;
       
   465 		DUFFS_LOOP(
       
   466 		{
       
   467 			if ( *src != ckey ) {
       
   468 			        Uint32 pixel;
       
   469 				sR = srcpal[*src].r;
       
   470 				sG = srcpal[*src].g;
       
   471 				sB = srcpal[*src].b;
       
   472 				DISEMBLE_RGB(dst, dstbpp, dstfmt,
       
   473 							pixel, dR, dG, dB);
       
   474 				ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
       
   475 			  	ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
       
   476 			}
       
   477 			src++;
       
   478 			dst += dstbpp;
       
   479 		},
       
   480 		width);
       
   481 		src += srcskip;
       
   482 		dst += dstskip;
       
   483 	}
       
   484 }
       
   485 
       
   486 static SDL_loblit one_blit[] = {
       
   487 	NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
       
   488 };
       
   489 
       
   490 static SDL_loblit one_blitkey[] = {
       
   491         NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
       
   492 };
       
   493 
       
   494 SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index)
       
   495 {
       
   496 	int which;
       
   497 	SDL_PixelFormat *dstfmt;
       
   498 
       
   499 	dstfmt = surface->map->dst->format;
       
   500 	if ( dstfmt->BitsPerPixel < 8 ) {
       
   501 		which = 0;
       
   502 	} else {
       
   503 		which = dstfmt->BytesPerPixel;
       
   504 	}
       
   505 	switch(blit_index) {
       
   506 	case 0:			/* copy */
       
   507 	    return one_blit[which];
       
   508 
       
   509 	case 1:			/* colorkey */
       
   510 	    return one_blitkey[which];
       
   511 
       
   512 	case 2:			/* alpha */
       
   513 	    /* Supporting 8bpp->8bpp alpha is doable but requires lots of
       
   514 	       tables which consume space and takes time to precompute,
       
   515 	       so is better left to the user */
       
   516 	    return which >= 2 ? Blit1toNAlpha : NULL;
       
   517 
       
   518 	case 3:			/* alpha + colorkey */
       
   519 	    return which >= 2 ? Blit1toNAlphaKey : NULL;
       
   520 
       
   521 	}
       
   522 	return NULL;
       
   523 }