SDL_blit_1.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#include "SDL_video.h"
#include "SDL_blit.h"
#include "SDL_sysvideo.h"
#include "SDL_endian.h"
/* Functions to blit from 8-bit surfaces to other surfaces */
static void
Blit1to1(SDL_BlitInfo * info)
{
#ifndef USE_DUFFS_LOOP
int c;
#endif
int width, height;
Uint8 *src, *map, *dst;
int srcskip, dstskip;
/* Set up some basic variables */
width = info->dst_w;
height = info->dst_h;
src = info->src;
srcskip = info->src_skip;
dst = info->dst;
dstskip = info->dst_skip;
map = info->table;
while (height--) {
#ifdef USE_DUFFS_LOOP
/* *INDENT-OFF* */
DUFFS_LOOP(
{
*dst = map[*src];
}
dst++;
src++;
, width);
/* *INDENT-ON* */
#else
for (c = width; c; --c) {
*dst = map[*src];
dst++;
src++;
}
#endif
src += srcskip;
dst += dstskip;
}
}
/* This is now endian dependent */
#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
#define HI 1
#define LO 0
#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
#define HI 0
#define LO 1
#endif
static void
Blit1to2(SDL_BlitInfo * info)
{
#ifndef USE_DUFFS_LOOP
int c;
#endif
int width, height;
Uint8 *src, *dst;
Uint16 *map;
int srcskip, dstskip;
/* Set up some basic variables */
width = info->dst_w;
height = info->dst_h;
src = info->src;
srcskip = info->src_skip;
dst = info->dst;
dstskip = info->dst_skip;
map = (Uint16 *) info->table;
#ifdef USE_DUFFS_LOOP
while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP(
{
*(Uint16 *)dst = map[*src++];
dst += 2;
},
width);
/* *INDENT-ON* */
src += srcskip;
dst += dstskip;
}
#else
/* Memory align at 4-byte boundary, if necessary */
if ((long) dst & 0x03) {
/* Don't do anything if width is 0 */
if (width == 0) {
return;
}
--width;
while (height--) {
/* Perform copy alignment */
*(Uint16 *) dst = map[*src++];
dst += 2;
/* Copy in 4 pixel chunks */
for (c = width / 4; c; --c) {
*(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
src += 2;
dst += 4;
*(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
src += 2;
dst += 4;
}
/* Get any leftovers */
switch (width & 3) {
case 3:
*(Uint16 *) dst = map[*src++];
dst += 2;
case 2:
*(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
src += 2;
dst += 4;
break;
case 1:
*(Uint16 *) dst = map[*src++];
dst += 2;
break;
}
src += srcskip;
dst += dstskip;
}
} else {
while (height--) {
/* Copy in 4 pixel chunks */
for (c = width / 4; c; --c) {
*(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
src += 2;
dst += 4;
*(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
src += 2;
dst += 4;
}
/* Get any leftovers */
switch (width & 3) {
case 3:
*(Uint16 *) dst = map[*src++];
dst += 2;
case 2:
*(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
src += 2;
dst += 4;
break;
case 1:
*(Uint16 *) dst = map[*src++];
dst += 2;
break;
}
src += srcskip;
dst += dstskip;
}
}
#endif /* USE_DUFFS_LOOP */
}
static void
Blit1to3(SDL_BlitInfo * info)
{
#ifndef USE_DUFFS_LOOP
int c;
#endif
int o;
int width, height;
Uint8 *src, *map, *dst;
int srcskip, dstskip;
/* Set up some basic variables */
width = info->dst_w;
height = info->dst_h;
src = info->src;
srcskip = info->src_skip;
dst = info->dst;
dstskip = info->dst_skip;
map = info->table;
while (height--) {
#ifdef USE_DUFFS_LOOP
/* *INDENT-OFF* */
DUFFS_LOOP(
{
o = *src * 4;
dst[0] = map[o++];
dst[1] = map[o++];
dst[2] = map[o++];
}
src++;
dst += 3;
, width);
/* *INDENT-ON* */
#else
for (c = width; c; --c) {
o = *src * 4;
dst[0] = map[o++];
dst[1] = map[o++];
dst[2] = map[o++];
src++;
dst += 3;
}
#endif /* USE_DUFFS_LOOP */
src += srcskip;
dst += dstskip;
}
}
static void
Blit1to4(SDL_BlitInfo * info)
{
#ifndef USE_DUFFS_LOOP
int c;
#endif
int width, height;
Uint8 *src;
Uint32 *map, *dst;
int srcskip, dstskip;
/* Set up some basic variables */
width = info->dst_w;
height = info->dst_h;
src = info->src;
srcskip = info->src_skip;
dst = (Uint32 *) info->dst;
dstskip = info->dst_skip / 4;
map = (Uint32 *) info->table;
while (height--) {
#ifdef USE_DUFFS_LOOP
/* *INDENT-OFF* */
DUFFS_LOOP(
*dst++ = map[*src++];
, width);
/* *INDENT-ON* */
#else
for (c = width / 4; c; --c) {
*dst++ = map[*src++];
*dst++ = map[*src++];
*dst++ = map[*src++];
*dst++ = map[*src++];
}
switch (width & 3) {
case 3:
*dst++ = map[*src++];
case 2:
*dst++ = map[*src++];
case 1:
*dst++ = map[*src++];
}
#endif /* USE_DUFFS_LOOP */
src += srcskip;
dst += dstskip;
}
}
static void
Blit1to1Key(SDL_BlitInfo * info)
{
int width = info->dst_w;
int height = info->dst_h;
Uint8 *src = info->src;
int srcskip = info->src_skip;
Uint8 *dst = info->dst;
int dstskip = info->dst_skip;
Uint8 *palmap = info->table;
Uint32 ckey = info->colorkey;
if (palmap) {
while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP(
{
if ( *src != ckey ) {
*dst = palmap[*src];
}
dst++;
src++;
},
width);
/* *INDENT-ON* */
src += srcskip;
dst += dstskip;
}
} else {
while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP(
{
if ( *src != ckey ) {
*dst = *src;
}
dst++;
src++;
},
width);
/* *INDENT-ON* */
src += srcskip;
dst += dstskip;
}
}
}
static void
Blit1to2Key(SDL_BlitInfo * info)
{
int width = info->dst_w;
int height = info->dst_h;
Uint8 *src = info->src;
int srcskip = info->src_skip;
Uint16 *dstp = (Uint16 *) info->dst;
int dstskip = info->dst_skip;
Uint16 *palmap = (Uint16 *) info->table;
Uint32 ckey = info->colorkey;
/* Set up some basic variables */
dstskip /= 2;
while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP(
{
if ( *src != ckey ) {
*dstp=palmap[*src];
}
src++;
dstp++;
},
width);
/* *INDENT-ON* */
src += srcskip;
dstp += dstskip;
}
}
static void
Blit1to3Key(SDL_BlitInfo * info)
{
int width = info->dst_w;
int height = info->dst_h;
Uint8 *src = info->src;
int srcskip = info->src_skip;
Uint8 *dst = info->dst;
int dstskip = info->dst_skip;
Uint8 *palmap = info->table;
Uint32 ckey = info->colorkey;
int o;
while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP(
{
if ( *src != ckey ) {
o = *src * 4;
dst[0] = palmap[o++];
dst[1] = palmap[o++];
dst[2] = palmap[o++];
}
src++;
dst += 3;
},
width);
/* *INDENT-ON* */
src += srcskip;
dst += dstskip;
}
}
static void
Blit1to4Key(SDL_BlitInfo * info)
{
int width = info->dst_w;
int height = info->dst_h;
Uint8 *src = info->src;
int srcskip = info->src_skip;
Uint32 *dstp = (Uint32 *) info->dst;
int dstskip = info->dst_skip;
Uint32 *palmap = (Uint32 *) info->table;
Uint32 ckey = info->colorkey;
/* Set up some basic variables */
dstskip /= 4;
while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP(
{
if ( *src != ckey ) {
*dstp = palmap[*src];
}
src++;
dstp++;
},
width);
/* *INDENT-ON* */
src += srcskip;
dstp += dstskip;
}
}
static void
Blit1toNAlpha(SDL_BlitInfo * info)
{
int width = info->dst_w;
int height = info->dst_h;
Uint8 *src = info->src;
int srcskip = info->src_skip;
Uint8 *dst = info->dst;
int dstskip = info->dst_skip;
SDL_PixelFormat *dstfmt = info->dst_fmt;
const SDL_Color *srcpal = info->src_fmt->palette->colors;
int dstbpp;
Uint32 pixel;
unsigned sR, sG, sB;
unsigned dR, dG, dB, dA;
const unsigned A = info->a;
/* Set up some basic variables */
dstbpp = dstfmt->BytesPerPixel;
while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP4(
{
sR = srcpal[*src].r;
sG = srcpal[*src].g;
sB = srcpal[*src].b;
DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
src++;
dst += dstbpp;
},
width);
/* *INDENT-ON* */
src += srcskip;
dst += dstskip;
}
}
static void
Blit1toNAlphaKey(SDL_BlitInfo * info)
{
int width = info->dst_w;
int height = info->dst_h;
Uint8 *src = info->src;
int srcskip = info->src_skip;
Uint8 *dst = info->dst;
int dstskip = info->dst_skip;
SDL_PixelFormat *dstfmt = info->dst_fmt;
const SDL_Color *srcpal = info->src_fmt->palette->colors;
Uint32 ckey = info->colorkey;
int dstbpp;
Uint32 pixel;
unsigned sR, sG, sB;
unsigned dR, dG, dB, dA;
const unsigned A = info->a;
/* Set up some basic variables */
dstbpp = dstfmt->BytesPerPixel;
while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP(
{
if ( *src != ckey ) {
sR = srcpal[*src].r;
sG = srcpal[*src].g;
sB = srcpal[*src].b;
DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
}
src++;
dst += dstbpp;
},
width);
/* *INDENT-ON* */
src += srcskip;
dst += dstskip;
}
}
static const SDL_BlitFunc one_blit[] = {
(SDL_BlitFunc) NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
};
static const SDL_BlitFunc one_blitkey[] = {
(SDL_BlitFunc) NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
};
SDL_BlitFunc
SDL_CalculateBlit1(SDL_Surface * surface)
{
int which;
SDL_PixelFormat *dstfmt;
dstfmt = surface->map->dst->format;
if (dstfmt->BitsPerPixel < 8) {
which = 0;
} else {
which = dstfmt->BytesPerPixel;
}
switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
case 0:
return one_blit[which];
case SDL_COPY_COLORKEY:
return one_blitkey[which];
case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
/* Supporting 8bpp->8bpp alpha is doable but requires lots of
tables which consume space and takes time to precompute,
so is better left to the user */
return which >= 2 ? Blit1toNAlpha : (SDL_BlitFunc) NULL;
case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc) NULL;
}
return (SDL_BlitFunc) NULL;
}
/* vi: set ts=4 sw=4 expandtab: */
SDL_BlitInfo::table
Uint8 * table
Definition: SDL_blit.h:67
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
SDL_Color
Definition: SDL_pixels.h:279
SDL_COPY_COLORKEY
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:39
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
SDL_BlitInfo::src_skip
int src_skip
Definition: SDL_blit.h:60
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
SDL_Color::g
Uint8 g
Definition: SDL_pixels.h:282
ALPHA_BLEND_RGBA
#define ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA)
Definition: SDL_blit.h:453
SDL_PixelFormat::BytesPerPixel
Uint8 BytesPerPixel
Definition: SDL_pixels.h:304
SDL_BlitInfo::flags
int flags
Definition: SDL_blit.h:68
Blit1to3Key
static void Blit1to3Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:364
SDL_BlitInfo::src_fmt
SDL_PixelFormat * src_fmt
Definition: SDL_blit.h:65
ASSEMBLE_RGBA
#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)
Definition: SDL_blit.h:401
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
one_blitkey
static const SDL_BlitFunc one_blitkey[]
Definition: SDL_blit_1.c:515
SDL_COPY_RLE_MASK
#define SDL_COPY_RLE_MASK
Definition: SDL_blit.h:44
SDL_Color::b
Uint8 b
Definition: SDL_pixels.h:283
SDL_CalculateBlit1
SDL_BlitFunc SDL_CalculateBlit1(SDL_Surface *surface)
Definition: SDL_blit_1.c:520
SDL_BlitInfo::dst_skip
int dst_skip
Definition: SDL_blit.h:64
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
SDL_BlitInfo::dst_h
int dst_h
Definition: SDL_blit.h:62
SDL_BlitInfo::colorkey
Uint32 colorkey
Definition: SDL_blit.h:69
SDL_BlitInfo::dst
Uint8 * dst
Definition: SDL_blit.h:61
SDL_Surface::map
struct SDL_BlitMap * map
Definition: SDL_surface.h:88
SDL_video.h
DISEMBLE_RGBA
#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a)
Definition: SDL_blit.h:352
SDL_Color::r
Uint8 r
Definition: SDL_pixels.h:281
SDL_BlitInfo
Definition: SDL_blit.h:55
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
SDL_PixelFormat::BitsPerPixel
Uint8 BitsPerPixel
Definition: SDL_pixels.h:303
one_blit
static const SDL_BlitFunc one_blit[]
Definition: SDL_blit_1.c:511
Blit1to2Key
static void Blit1to2Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:332
LO
#define LO
Definition: SDL_blit_1.c:75
DUFFS_LOOP4
#define DUFFS_LOOP4(pixel_copy_increment, width)
Definition: SDL_blit.h:487
Blit1toNAlphaKey
static void Blit1toNAlphaKey(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:469
DUFFS_LOOP
#define DUFFS_LOOP(pixel_copy_increment, width)
Definition: SDL_blit.h:499
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
Blit1to2
static void Blit1to2(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:81
SDL_BlitInfo::src
Uint8 * src
Definition: SDL_blit.h:57
SDL_sysvideo.h
SDL_BlitInfo::dst_fmt
SDL_PixelFormat * dst_fmt
Definition: SDL_blit.h:66
SDL_endian.h
Blit1to4Key
static void Blit1to4Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:397
SDL_BlitMap::dst
SDL_Surface * dst
Definition: SDL_blit.h:87
NULL
#define NULL
Definition: begin_code.h:143
SDL_Palette::colors
SDL_Color * colors
Definition: SDL_pixels.h:291
SDL_Surface::format
SDL_PixelFormat * format
Definition: SDL_surface.h:72
SDL_blit.h
SDL_COPY_MODULATE_ALPHA
#define SDL_COPY_MODULATE_ALPHA
Definition: SDL_blit.h:35
Blit1to3
static void Blit1to3(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:188
SDL_PixelFormat
Definition: SDL_pixels.h:299
Blit1toNAlpha
static void Blit1toNAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:429
SDL_BlitFunc
void(* SDL_BlitFunc)(SDL_BlitInfo *info)
Definition: SDL_blit.h:73
Blit1to1Key
static void Blit1to1Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:285
Uint16
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:147
SDL_PixelFormat::palette
SDL_Palette * palette
Definition: SDL_pixels.h:302
SDL_BlitInfo::dst_w
int dst_w
Definition: SDL_blit.h:62
map
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint GLint GLint j2 GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLfloat *params GLenum GLint GLenum GLenum GLvoid *pixels GLenum GLint GLenum GLint *params GLenum GLenum GLint *params GLenum GLsizei const GLvoid *pointer GLenum GLenum const GLint *params GLenum GLfloat GLfloat GLint GLint const GLfloat *points GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat *points GLint GLfloat GLfloat GLint GLfloat GLfloat v2 GLenum GLenum const GLint *params GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum map
Definition: SDL_glfuncs.h:289
USE_DUFFS_LOOP
#define USE_DUFFS_LOOP
Definition: SDL_blit.h:466
src
GLenum src
Definition: SDL_opengl_glext.h:1737
SDL_COPY_BLEND
#define SDL_COPY_BLEND
Definition: SDL_blit.h:36
SDL_BlitMap::info
SDL_BlitInfo info
Definition: SDL_blit.h:91
HI
#define HI
Definition: SDL_blit_1.c:74
Blit1to4
static void Blit1to4(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:237
SDL_BlitInfo::a
Uint8 a
Definition: SDL_blit.h:70
Blit1to1
static void Blit1to1(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:31