2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 Sam Lantinga
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.
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.
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
22 #include "SDL_config.h"
24 #include "SDL_video.h"
26 #include "SDL_sysvideo.h"
27 #include "SDL_endian.h"
29 /* Functions to blit from 8-bit surfaces to other surfaces */
31 static void Blit1to1(SDL_BlitInfo *info)
33 #ifndef USE_DUFFS_LOOP
37 Uint8 *src, *map, *dst;
40 /* Set up some basic variables */
41 width = info->d_width;
42 height = info->d_height;
44 srcskip = info->s_skip;
46 dstskip = info->d_skip;
59 for ( c=width; c; --c ) {
69 /* This is now endian dependent */
70 #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
73 #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
77 static void Blit1to2(SDL_BlitInfo *info)
79 #ifndef USE_DUFFS_LOOP
87 /* Set up some basic variables */
88 width = info->d_width;
89 height = info->d_height;
91 srcskip = info->s_skip;
93 dstskip = info->d_skip;
94 map = (Uint16 *)info->table;
100 *(Uint16 *)dst = map[*src++];
108 /* Memory align at 4-byte boundary, if necessary */
109 if ( (long)dst & 0x03 ) {
110 /* Don't do anything if width is 0 */
117 /* Perform copy alignment */
118 *(Uint16 *)dst = map[*src++];
121 /* Copy in 4 pixel chunks */
122 for ( c=width/4; c; --c ) {
124 (map[src[HI]]<<16)|(map[src[LO]]);
128 (map[src[HI]]<<16)|(map[src[LO]]);
132 /* Get any leftovers */
135 *(Uint16 *)dst = map[*src++];
139 (map[src[HI]]<<16)|(map[src[LO]]);
144 *(Uint16 *)dst = map[*src++];
153 /* Copy in 4 pixel chunks */
154 for ( c=width/4; c; --c ) {
156 (map[src[HI]]<<16)|(map[src[LO]]);
160 (map[src[HI]]<<16)|(map[src[LO]]);
164 /* Get any leftovers */
167 *(Uint16 *)dst = map[*src++];
171 (map[src[HI]]<<16)|(map[src[LO]]);
176 *(Uint16 *)dst = map[*src++];
184 #endif /* USE_DUFFS_LOOP */
186 static void Blit1to3(SDL_BlitInfo *info)
188 #ifndef USE_DUFFS_LOOP
193 Uint8 *src, *map, *dst;
194 int srcskip, dstskip;
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;
206 #ifdef USE_DUFFS_LOOP
218 for ( c=width; c; --c ) {
226 #endif /* USE_DUFFS_LOOP */
231 static void Blit1to4(SDL_BlitInfo *info)
233 #ifndef USE_DUFFS_LOOP
239 int srcskip, dstskip;
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;
251 #ifdef USE_DUFFS_LOOP
253 *dst++ = map[*src++];
256 for ( c=width/4; c; --c ) {
257 *dst++ = map[*src++];
258 *dst++ = map[*src++];
259 *dst++ = map[*src++];
260 *dst++ = map[*src++];
262 switch ( width & 3 ) {
264 *dst++ = map[*src++];
266 *dst++ = map[*src++];
268 *dst++ = map[*src++];
270 #endif /* USE_DUFFS_LOOP */
276 static void Blit1to1Key(SDL_BlitInfo *info)
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;
291 if ( *src != ckey ) {
305 if ( *src != ckey ) {
318 static void Blit1to2Key(SDL_BlitInfo *info)
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;
329 /* Set up some basic variables */
335 if ( *src != ckey ) {
347 static void Blit1to3Key(SDL_BlitInfo *info)
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;
362 if ( *src != ckey ) {
364 dst[0] = palmap[o++];
365 dst[1] = palmap[o++];
366 dst[2] = palmap[o++];
377 static void Blit1to4Key(SDL_BlitInfo *info)
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;
388 /* Set up some basic variables */
394 if ( *src != ckey ) {
395 *dstp = palmap[*src];
406 static void Blit1toNAlpha(SDL_BlitInfo *info)
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;
417 const int A = info->src->alpha;
419 /* Set up some basic variables */
420 dstbpp = dstfmt->BytesPerPixel;
431 DISEMBLE_RGB(dst, dstbpp, dstfmt,
433 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
434 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
444 static void Blit1toNAlphaKey(SDL_BlitInfo *info)
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;
457 const int A = srcfmt->alpha;
459 /* Set up some basic variables */
460 dstbpp = dstfmt->BytesPerPixel;
467 if ( *src != ckey ) {
472 DISEMBLE_RGB(dst, dstbpp, dstfmt,
474 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
475 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
486 static SDL_loblit one_blit[] = {
487 NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
490 static SDL_loblit one_blitkey[] = {
491 NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
494 SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index)
497 SDL_PixelFormat *dstfmt;
499 dstfmt = surface->map->dst->format;
500 if ( dstfmt->BitsPerPixel < 8 ) {
503 which = dstfmt->BytesPerPixel;
507 return one_blit[which];
509 case 1: /* colorkey */
510 return one_blitkey[which];
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;
518 case 3: /* alpha + colorkey */
519 return which >= 2 ? Blit1toNAlphaKey : NULL;