2 Simple DirectMedia Layer
3 Copyright (C) 1997-2020 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"
25 #include "SDL_video.h"
27 #include "SDL_sysvideo.h"
28 #include "SDL_endian.h"
30 /* Functions to blit from 8-bit surfaces to other surfaces */
33 Blit1to1(SDL_BlitInfo * info)
35 #ifndef USE_DUFFS_LOOP
39 Uint8 *src, *map, *dst;
42 /* Set up some basic variables */
46 srcskip = info->src_skip;
48 dstskip = info->dst_skip;
63 for (c = width; c; --c) {
74 /* This is now endian dependent */
75 #ifndef USE_DUFFS_LOOP
76 # if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
79 # else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
85 Blit1to2(SDL_BlitInfo * info)
87 #ifndef USE_DUFFS_LOOP
95 /* Set up some basic variables */
99 srcskip = info->src_skip;
101 dstskip = info->dst_skip;
102 map = (Uint16 *) info->table;
104 #ifdef USE_DUFFS_LOOP
109 *(Uint16 *)dst = map[*src++];
118 /* Memory align at 4-byte boundary, if necessary */
119 if ((long) dst & 0x03) {
120 /* Don't do anything if width is 0 */
127 /* Perform copy alignment */
128 *(Uint16 *) dst = map[*src++];
131 /* Copy in 4 pixel chunks */
132 for (c = width / 4; c; --c) {
133 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
136 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
140 /* Get any leftovers */
143 *(Uint16 *) dst = map[*src++];
146 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
151 *(Uint16 *) dst = map[*src++];
160 /* Copy in 4 pixel chunks */
161 for (c = width / 4; c; --c) {
162 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
165 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
169 /* Get any leftovers */
172 *(Uint16 *) dst = map[*src++];
175 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
180 *(Uint16 *) dst = map[*src++];
188 #endif /* USE_DUFFS_LOOP */
192 Blit1to3(SDL_BlitInfo * info)
194 #ifndef USE_DUFFS_LOOP
199 Uint8 *src, *map, *dst;
200 int srcskip, dstskip;
202 /* Set up some basic variables */
204 height = info->dst_h;
206 srcskip = info->src_skip;
208 dstskip = info->dst_skip;
212 #ifdef USE_DUFFS_LOOP
226 for (c = width; c; --c) {
234 #endif /* USE_DUFFS_LOOP */
241 Blit1to4(SDL_BlitInfo * info)
243 #ifndef USE_DUFFS_LOOP
249 int srcskip, dstskip;
251 /* Set up some basic variables */
253 height = info->dst_h;
255 srcskip = info->src_skip;
256 dst = (Uint32 *) info->dst;
257 dstskip = info->dst_skip / 4;
258 map = (Uint32 *) info->table;
261 #ifdef USE_DUFFS_LOOP
264 *dst++ = map[*src++];
268 for (c = width / 4; c; --c) {
269 *dst++ = map[*src++];
270 *dst++ = map[*src++];
271 *dst++ = map[*src++];
272 *dst++ = map[*src++];
276 *dst++ = map[*src++];
278 *dst++ = map[*src++];
280 *dst++ = map[*src++];
282 #endif /* USE_DUFFS_LOOP */
289 Blit1to1Key(SDL_BlitInfo * info)
291 int width = info->dst_w;
292 int height = info->dst_h;
293 Uint8 *src = info->src;
294 int srcskip = info->src_skip;
295 Uint8 *dst = info->dst;
296 int dstskip = info->dst_skip;
297 Uint8 *palmap = info->table;
298 Uint32 ckey = info->colorkey;
305 if ( *src != ckey ) {
321 if ( *src != ckey ) {
336 Blit1to2Key(SDL_BlitInfo * info)
338 int width = info->dst_w;
339 int height = info->dst_h;
340 Uint8 *src = info->src;
341 int srcskip = info->src_skip;
342 Uint16 *dstp = (Uint16 *) info->dst;
343 int dstskip = info->dst_skip;
344 Uint16 *palmap = (Uint16 *) info->table;
345 Uint32 ckey = info->colorkey;
347 /* Set up some basic variables */
354 if ( *src != ckey ) {
368 Blit1to3Key(SDL_BlitInfo * info)
370 int width = info->dst_w;
371 int height = info->dst_h;
372 Uint8 *src = info->src;
373 int srcskip = info->src_skip;
374 Uint8 *dst = info->dst;
375 int dstskip = info->dst_skip;
376 Uint8 *palmap = info->table;
377 Uint32 ckey = info->colorkey;
384 if ( *src != ckey ) {
386 dst[0] = palmap[o++];
387 dst[1] = palmap[o++];
388 dst[2] = palmap[o++];
401 Blit1to4Key(SDL_BlitInfo * info)
403 int width = info->dst_w;
404 int height = info->dst_h;
405 Uint8 *src = info->src;
406 int srcskip = info->src_skip;
407 Uint32 *dstp = (Uint32 *) info->dst;
408 int dstskip = info->dst_skip;
409 Uint32 *palmap = (Uint32 *) info->table;
410 Uint32 ckey = info->colorkey;
412 /* Set up some basic variables */
419 if ( *src != ckey ) {
420 *dstp = palmap[*src];
433 Blit1toNAlpha(SDL_BlitInfo * info)
435 int width = info->dst_w;
436 int height = info->dst_h;
437 Uint8 *src = info->src;
438 int srcskip = info->src_skip;
439 Uint8 *dst = info->dst;
440 int dstskip = info->dst_skip;
441 SDL_PixelFormat *dstfmt = info->dst_fmt;
442 const SDL_Color *srcpal = info->src_fmt->palette->colors;
446 unsigned dR, dG, dB, dA;
447 const unsigned A = info->a;
449 /* Set up some basic variables */
450 dstbpp = dstfmt->BytesPerPixel;
459 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
460 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
461 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
473 Blit1toNAlphaKey(SDL_BlitInfo * info)
475 int width = info->dst_w;
476 int height = info->dst_h;
477 Uint8 *src = info->src;
478 int srcskip = info->src_skip;
479 Uint8 *dst = info->dst;
480 int dstskip = info->dst_skip;
481 SDL_PixelFormat *dstfmt = info->dst_fmt;
482 const SDL_Color *srcpal = info->src_fmt->palette->colors;
483 Uint32 ckey = info->colorkey;
487 unsigned dR, dG, dB, dA;
488 const unsigned A = info->a;
490 /* Set up some basic variables */
491 dstbpp = dstfmt->BytesPerPixel;
497 if ( *src != ckey ) {
501 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
502 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
503 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
515 static const SDL_BlitFunc one_blit[] = {
516 (SDL_BlitFunc) NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
519 static const SDL_BlitFunc one_blitkey[] = {
520 (SDL_BlitFunc) NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
524 SDL_CalculateBlit1(SDL_Surface * surface)
527 SDL_PixelFormat *dstfmt;
529 dstfmt = surface->map->dst->format;
530 if (dstfmt->BitsPerPixel < 8) {
533 which = dstfmt->BytesPerPixel;
535 switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
537 return one_blit[which];
539 case SDL_COPY_COLORKEY:
540 return one_blitkey[which];
542 case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
543 /* Supporting 8bpp->8bpp alpha is doable but requires lots of
544 tables which consume space and takes time to precompute,
545 so is better left to the user */
546 return which >= 2 ? Blit1toNAlpha : (SDL_BlitFunc) NULL;
548 case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
549 return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc) NULL;
551 return (SDL_BlitFunc) NULL;
554 #endif /* SDL_HAVE_BLIT_1 */
556 /* vi: set ts=4 sw=4 expandtab: */