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