2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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 #ifndef USE_DUFFS_LOOP
74 # if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
77 # else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
83 Blit1to2(SDL_BlitInfo * info)
85 #ifndef USE_DUFFS_LOOP
93 /* Set up some basic variables */
97 srcskip = info->src_skip;
99 dstskip = info->dst_skip;
100 map = (Uint16 *) info->table;
102 #ifdef USE_DUFFS_LOOP
107 *(Uint16 *)dst = map[*src++];
116 /* Memory align at 4-byte boundary, if necessary */
117 if ((long) dst & 0x03) {
118 /* Don't do anything if width is 0 */
125 /* Perform copy alignment */
126 *(Uint16 *) dst = map[*src++];
129 /* Copy in 4 pixel chunks */
130 for (c = width / 4; c; --c) {
131 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
134 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
138 /* Get any leftovers */
141 *(Uint16 *) dst = map[*src++];
144 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
149 *(Uint16 *) dst = map[*src++];
158 /* Copy in 4 pixel chunks */
159 for (c = width / 4; c; --c) {
160 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
163 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
167 /* Get any leftovers */
170 *(Uint16 *) dst = map[*src++];
173 *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
178 *(Uint16 *) dst = map[*src++];
186 #endif /* USE_DUFFS_LOOP */
190 Blit1to3(SDL_BlitInfo * info)
192 #ifndef USE_DUFFS_LOOP
197 Uint8 *src, *map, *dst;
198 int srcskip, dstskip;
200 /* Set up some basic variables */
202 height = info->dst_h;
204 srcskip = info->src_skip;
206 dstskip = info->dst_skip;
210 #ifdef USE_DUFFS_LOOP
224 for (c = width; c; --c) {
232 #endif /* USE_DUFFS_LOOP */
239 Blit1to4(SDL_BlitInfo * info)
241 #ifndef USE_DUFFS_LOOP
247 int srcskip, dstskip;
249 /* Set up some basic variables */
251 height = info->dst_h;
253 srcskip = info->src_skip;
254 dst = (Uint32 *) info->dst;
255 dstskip = info->dst_skip / 4;
256 map = (Uint32 *) info->table;
259 #ifdef USE_DUFFS_LOOP
262 *dst++ = map[*src++];
266 for (c = width / 4; c; --c) {
267 *dst++ = map[*src++];
268 *dst++ = map[*src++];
269 *dst++ = map[*src++];
270 *dst++ = map[*src++];
274 *dst++ = map[*src++];
276 *dst++ = map[*src++];
278 *dst++ = map[*src++];
280 #endif /* USE_DUFFS_LOOP */
287 Blit1to1Key(SDL_BlitInfo * info)
289 int width = info->dst_w;
290 int height = info->dst_h;
291 Uint8 *src = info->src;
292 int srcskip = info->src_skip;
293 Uint8 *dst = info->dst;
294 int dstskip = info->dst_skip;
295 Uint8 *palmap = info->table;
296 Uint32 ckey = info->colorkey;
303 if ( *src != ckey ) {
319 if ( *src != ckey ) {
334 Blit1to2Key(SDL_BlitInfo * info)
336 int width = info->dst_w;
337 int height = info->dst_h;
338 Uint8 *src = info->src;
339 int srcskip = info->src_skip;
340 Uint16 *dstp = (Uint16 *) info->dst;
341 int dstskip = info->dst_skip;
342 Uint16 *palmap = (Uint16 *) info->table;
343 Uint32 ckey = info->colorkey;
345 /* Set up some basic variables */
352 if ( *src != ckey ) {
366 Blit1to3Key(SDL_BlitInfo * info)
368 int width = info->dst_w;
369 int height = info->dst_h;
370 Uint8 *src = info->src;
371 int srcskip = info->src_skip;
372 Uint8 *dst = info->dst;
373 int dstskip = info->dst_skip;
374 Uint8 *palmap = info->table;
375 Uint32 ckey = info->colorkey;
382 if ( *src != ckey ) {
384 dst[0] = palmap[o++];
385 dst[1] = palmap[o++];
386 dst[2] = palmap[o++];
399 Blit1to4Key(SDL_BlitInfo * info)
401 int width = info->dst_w;
402 int height = info->dst_h;
403 Uint8 *src = info->src;
404 int srcskip = info->src_skip;
405 Uint32 *dstp = (Uint32 *) info->dst;
406 int dstskip = info->dst_skip;
407 Uint32 *palmap = (Uint32 *) info->table;
408 Uint32 ckey = info->colorkey;
410 /* Set up some basic variables */
417 if ( *src != ckey ) {
418 *dstp = palmap[*src];
431 Blit1toNAlpha(SDL_BlitInfo * info)
433 int width = info->dst_w;
434 int height = info->dst_h;
435 Uint8 *src = info->src;
436 int srcskip = info->src_skip;
437 Uint8 *dst = info->dst;
438 int dstskip = info->dst_skip;
439 SDL_PixelFormat *dstfmt = info->dst_fmt;
440 const SDL_Color *srcpal = info->src_fmt->palette->colors;
444 unsigned dR, dG, dB, dA;
445 const unsigned A = info->a;
447 /* Set up some basic variables */
448 dstbpp = dstfmt->BytesPerPixel;
457 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
458 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
459 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
471 Blit1toNAlphaKey(SDL_BlitInfo * info)
473 int width = info->dst_w;
474 int height = info->dst_h;
475 Uint8 *src = info->src;
476 int srcskip = info->src_skip;
477 Uint8 *dst = info->dst;
478 int dstskip = info->dst_skip;
479 SDL_PixelFormat *dstfmt = info->dst_fmt;
480 const SDL_Color *srcpal = info->src_fmt->palette->colors;
481 Uint32 ckey = info->colorkey;
485 unsigned dR, dG, dB, dA;
486 const unsigned A = info->a;
488 /* Set up some basic variables */
489 dstbpp = dstfmt->BytesPerPixel;
495 if ( *src != ckey ) {
499 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
500 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
501 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
513 static const SDL_BlitFunc one_blit[] = {
514 (SDL_BlitFunc) NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
517 static const SDL_BlitFunc one_blitkey[] = {
518 (SDL_BlitFunc) NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
522 SDL_CalculateBlit1(SDL_Surface * surface)
525 SDL_PixelFormat *dstfmt;
527 dstfmt = surface->map->dst->format;
528 if (dstfmt->BitsPerPixel < 8) {
531 which = dstfmt->BytesPerPixel;
533 switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
535 return one_blit[which];
537 case SDL_COPY_COLORKEY:
538 return one_blitkey[which];
540 case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
541 /* Supporting 8bpp->8bpp alpha is doable but requires lots of
542 tables which consume space and takes time to precompute,
543 so is better left to the user */
544 return which >= 2 ? Blit1toNAlpha : (SDL_BlitFunc) NULL;
546 case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
547 return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc) NULL;
549 return (SDL_BlitFunc) NULL;
552 /* vi: set ts=4 sw=4 expandtab: */