2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
21 #include "../SDL_internal.h"
23 #include "SDL_video.h"
25 #include "SDL_sysvideo.h"
26 #include "SDL_endian.h"
28 /* Functions to blit from 8-bit surfaces to other surfaces */
31 Blit1to1(SDL_BlitInfo * info)
33 #ifndef USE_DUFFS_LOOP
37 Uint8 *src, *map, *dst;
40 /* Set up some basic variables */
44 srcskip = info->src_skip;
46 dstskip = info->dst_skip;
61 for (c = width; c; --c) {
72 /* This is now endian dependent */
73 #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
76 #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
81 Blit1to2(SDL_BlitInfo * info)
83 #ifndef USE_DUFFS_LOOP
91 /* Set up some basic variables */
95 srcskip = info->src_skip;
97 dstskip = info->dst_skip;
98 map = (Uint16 *) info->table;
100 #ifdef USE_DUFFS_LOOP
105 *(Uint16 *)dst = map[*src++];
114 /* Memory align at 4-byte boundary, if necessary */
115 if ((long) dst & 0x03) {
116 /* Don't do anything if width is 0 */
123 /* Perform copy alignment */
124 *(Uint16 *) dst = map[*src++];
127 /* Copy in 4 pixel chunks */
128 for (c = width / 4; c; --c) {
129 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
132 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
136 /* Get any leftovers */
139 *(Uint16 *) dst = map[*src++];
142 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
147 *(Uint16 *) dst = map[*src++];
156 /* Copy in 4 pixel chunks */
157 for (c = width / 4; c; --c) {
158 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
161 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
165 /* Get any leftovers */
168 *(Uint16 *) dst = map[*src++];
171 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
176 *(Uint16 *) dst = map[*src++];
184 #endif /* USE_DUFFS_LOOP */
188 Blit1to3(SDL_BlitInfo * info)
190 #ifndef USE_DUFFS_LOOP
195 Uint8 *src, *map, *dst;
196 int srcskip, dstskip;
198 /* Set up some basic variables */
200 height = info->dst_h;
202 srcskip = info->src_skip;
204 dstskip = info->dst_skip;
208 #ifdef USE_DUFFS_LOOP
222 for (c = width; c; --c) {
230 #endif /* USE_DUFFS_LOOP */
237 Blit1to4(SDL_BlitInfo * info)
239 #ifndef USE_DUFFS_LOOP
245 int srcskip, dstskip;
247 /* Set up some basic variables */
249 height = info->dst_h;
251 srcskip = info->src_skip;
252 dst = (Uint32 *) info->dst;
253 dstskip = info->dst_skip / 4;
254 map = (Uint32 *) info->table;
257 #ifdef USE_DUFFS_LOOP
260 *dst++ = map[*src++];
264 for (c = width / 4; c; --c) {
265 *dst++ = map[*src++];
266 *dst++ = map[*src++];
267 *dst++ = map[*src++];
268 *dst++ = map[*src++];
272 *dst++ = map[*src++];
274 *dst++ = map[*src++];
276 *dst++ = map[*src++];
278 #endif /* USE_DUFFS_LOOP */
285 Blit1to1Key(SDL_BlitInfo * info)
287 int width = info->dst_w;
288 int height = info->dst_h;
289 Uint8 *src = info->src;
290 int srcskip = info->src_skip;
291 Uint8 *dst = info->dst;
292 int dstskip = info->dst_skip;
293 Uint8 *palmap = info->table;
294 Uint32 ckey = info->colorkey;
301 if ( *src != ckey ) {
317 if ( *src != ckey ) {
332 Blit1to2Key(SDL_BlitInfo * info)
334 int width = info->dst_w;
335 int height = info->dst_h;
336 Uint8 *src = info->src;
337 int srcskip = info->src_skip;
338 Uint16 *dstp = (Uint16 *) info->dst;
339 int dstskip = info->dst_skip;
340 Uint16 *palmap = (Uint16 *) info->table;
341 Uint32 ckey = info->colorkey;
343 /* Set up some basic variables */
350 if ( *src != ckey ) {
364 Blit1to3Key(SDL_BlitInfo * info)
366 int width = info->dst_w;
367 int height = info->dst_h;
368 Uint8 *src = info->src;
369 int srcskip = info->src_skip;
370 Uint8 *dst = info->dst;
371 int dstskip = info->dst_skip;
372 Uint8 *palmap = info->table;
373 Uint32 ckey = info->colorkey;
380 if ( *src != ckey ) {
382 dst[0] = palmap[o++];
383 dst[1] = palmap[o++];
384 dst[2] = palmap[o++];
397 Blit1to4Key(SDL_BlitInfo * info)
399 int width = info->dst_w;
400 int height = info->dst_h;
401 Uint8 *src = info->src;
402 int srcskip = info->src_skip;
403 Uint32 *dstp = (Uint32 *) info->dst;
404 int dstskip = info->dst_skip;
405 Uint32 *palmap = (Uint32 *) info->table;
406 Uint32 ckey = info->colorkey;
408 /* Set up some basic variables */
415 if ( *src != ckey ) {
416 *dstp = palmap[*src];
429 Blit1toNAlpha(SDL_BlitInfo * info)
431 int width = info->dst_w;
432 int height = info->dst_h;
433 Uint8 *src = info->src;
434 int srcskip = info->src_skip;
435 Uint8 *dst = info->dst;
436 int dstskip = info->dst_skip;
437 SDL_PixelFormat *dstfmt = info->dst_fmt;
438 const SDL_Color *srcpal = info->src_fmt->palette->colors;
442 unsigned dR, dG, dB, dA;
443 const unsigned A = info->a;
445 /* Set up some basic variables */
446 dstbpp = dstfmt->BytesPerPixel;
455 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
456 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
457 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
469 Blit1toNAlphaKey(SDL_BlitInfo * info)
471 int width = info->dst_w;
472 int height = info->dst_h;
473 Uint8 *src = info->src;
474 int srcskip = info->src_skip;
475 Uint8 *dst = info->dst;
476 int dstskip = info->dst_skip;
477 SDL_PixelFormat *dstfmt = info->dst_fmt;
478 const SDL_Color *srcpal = info->src_fmt->palette->colors;
479 Uint32 ckey = info->colorkey;
483 unsigned dR, dG, dB, dA;
484 const unsigned A = info->a;
486 /* Set up some basic variables */
487 dstbpp = dstfmt->BytesPerPixel;
493 if ( *src != ckey ) {
497 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
498 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
499 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
511 static const SDL_BlitFunc one_blit[] = {
512 (SDL_BlitFunc) NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
515 static const SDL_BlitFunc one_blitkey[] = {
516 (SDL_BlitFunc) NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
520 SDL_CalculateBlit1(SDL_Surface * surface)
523 SDL_PixelFormat *dstfmt;
525 dstfmt = surface->map->dst->format;
526 if (dstfmt->BitsPerPixel < 8) {
529 which = dstfmt->BytesPerPixel;
531 switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
533 return one_blit[which];
535 case SDL_COPY_COLORKEY:
536 return one_blitkey[which];
538 case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
539 /* Supporting 8bpp->8bpp alpha is doable but requires lots of
540 tables which consume space and takes time to precompute,
541 so is better left to the user */
542 return which >= 2 ? Blit1toNAlpha : (SDL_BlitFunc) NULL;
544 case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
545 return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc) NULL;
547 return (SDL_BlitFunc) NULL;
550 /* vi: set ts=4 sw=4 expandtab: */