src/video/SDL_blit_0.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 16 May 2005 05:34:58 +0000
changeset 1057 e9d23bb80140
parent 769 b8d311d90021
child 1058 e6c91fd1911e
permissions -rw-r--r--
Date: Mon, 02 May 2005 04:23:16 -0500
From: Jonathan Atkins
Subject: Re: [PATCH] *CRITICAL* 8bit direct RGB palette not being created

I think that SDL_AllocFormat should create the palette for all 8bit
surfaces. And when the RGBAmasks match the normal 3:3:2:0 we need to
apply the old behavior. If the mask doesn't match that, then we need
to make the right palette assuming the masks are valid (I don't think
we validate any masks for high color surfaces...so we wouldn't here)
Then there's always a palette available for the 8bit surfaces.
This restores the normal behavior and allows for masks to create
palettes automatically for odd masks even, which would be a neato
thing to have in there, as SDL never did this before.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 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->format->BitsPerPixel > 1 ) {
   456 		/* We don't support sub 8-bit packed pixel modes */
   457 		return NULL;
   458 	}
   459 	if ( surface->map->dst->format->BitsPerPixel < 8 ) {
   460 		which = 0;
   461 	} else {
   462 		which = surface->map->dst->format->BytesPerPixel;
   463 	}
   464 	switch(blit_index) {
   465 	case 0:			/* copy */
   466 	    return bitmap_blit[which];
   467 
   468 	case 1:			/* colorkey */
   469 	    return colorkey_blit[which];
   470 
   471 	case 2:			/* alpha */
   472 	    return which >= 2 ? BlitBtoNAlpha : NULL;
   473 
   474 	case 4:			/* alpha + colorkey */
   475 	    return which >= 2 ? BlitBtoNAlphaKey : NULL;
   476 	}
   477 	return NULL;
   478 }
   479