SDL  2.0
SDL_blit_1.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4 
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.
8 
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:
12 
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.
20 */
21 #include "../SDL_internal.h"
22 
23 #if SDL_HAVE_BLIT_1
24 
25 #include "SDL_video.h"
26 #include "SDL_blit.h"
27 #include "SDL_sysvideo.h"
28 #include "SDL_endian.h"
29 
30 /* Functions to blit from 8-bit surfaces to other surfaces */
31 
32 static void
34 {
35 #ifndef USE_DUFFS_LOOP
36  int c;
37 #endif
38  int width, height;
39  Uint8 *src, *map, *dst;
40  int srcskip, dstskip;
41 
42  /* Set up some basic variables */
43  width = info->dst_w;
44  height = info->dst_h;
45  src = info->src;
46  srcskip = info->src_skip;
47  dst = info->dst;
48  dstskip = info->dst_skip;
49  map = info->table;
50 
51  while (height--) {
52 #ifdef USE_DUFFS_LOOP
53  /* *INDENT-OFF* */
54  DUFFS_LOOP(
55  {
56  *dst = map[*src];
57  }
58  dst++;
59  src++;
60  , width);
61  /* *INDENT-ON* */
62 #else
63  for (c = width; c; --c) {
64  *dst = map[*src];
65  dst++;
66  src++;
67  }
68 #endif
69  src += srcskip;
70  dst += dstskip;
71  }
72 }
73 
74 /* This is now endian dependent */
75 #ifndef USE_DUFFS_LOOP
76 # if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
77 # define HI 1
78 # define LO 0
79 # else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
80 # define HI 0
81 # define LO 1
82 # endif
83 #endif
84 static void
86 {
87 #ifndef USE_DUFFS_LOOP
88  int c;
89 #endif
90  int width, height;
91  Uint8 *src, *dst;
92  Uint16 *map;
93  int srcskip, dstskip;
94 
95  /* Set up some basic variables */
96  width = info->dst_w;
97  height = info->dst_h;
98  src = info->src;
99  srcskip = info->src_skip;
100  dst = info->dst;
101  dstskip = info->dst_skip;
102  map = (Uint16 *) info->table;
103 
104 #ifdef USE_DUFFS_LOOP
105  while (height--) {
106  /* *INDENT-OFF* */
107  DUFFS_LOOP(
108  {
109  *(Uint16 *)dst = map[*src++];
110  dst += 2;
111  },
112  width);
113  /* *INDENT-ON* */
114  src += srcskip;
115  dst += dstskip;
116  }
117 #else
118  /* Memory align at 4-byte boundary, if necessary */
119  if ((long) dst & 0x03) {
120  /* Don't do anything if width is 0 */
121  if (width == 0) {
122  return;
123  }
124  --width;
125 
126  while (height--) {
127  /* Perform copy alignment */
128  *(Uint16 *) dst = map[*src++];
129  dst += 2;
130 
131  /* Copy in 4 pixel chunks */
132  for (c = width / 4; c; --c) {
133  *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
134  src += 2;
135  dst += 4;
136  *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
137  src += 2;
138  dst += 4;
139  }
140  /* Get any leftovers */
141  switch (width & 3) {
142  case 3:
143  *(Uint16 *) dst = map[*src++];
144  dst += 2;
145  case 2:
146  *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
147  src += 2;
148  dst += 4;
149  break;
150  case 1:
151  *(Uint16 *) dst = map[*src++];
152  dst += 2;
153  break;
154  }
155  src += srcskip;
156  dst += dstskip;
157  }
158  } else {
159  while (height--) {
160  /* Copy in 4 pixel chunks */
161  for (c = width / 4; c; --c) {
162  *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
163  src += 2;
164  dst += 4;
165  *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
166  src += 2;
167  dst += 4;
168  }
169  /* Get any leftovers */
170  switch (width & 3) {
171  case 3:
172  *(Uint16 *) dst = map[*src++];
173  dst += 2;
174  case 2:
175  *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
176  src += 2;
177  dst += 4;
178  break;
179  case 1:
180  *(Uint16 *) dst = map[*src++];
181  dst += 2;
182  break;
183  }
184  src += srcskip;
185  dst += dstskip;
186  }
187  }
188 #endif /* USE_DUFFS_LOOP */
189 }
190 
191 static void
193 {
194 #ifndef USE_DUFFS_LOOP
195  int c;
196 #endif
197  int o;
198  int width, height;
199  Uint8 *src, *map, *dst;
200  int srcskip, dstskip;
201 
202  /* Set up some basic variables */
203  width = info->dst_w;
204  height = info->dst_h;
205  src = info->src;
206  srcskip = info->src_skip;
207  dst = info->dst;
208  dstskip = info->dst_skip;
209  map = info->table;
210 
211  while (height--) {
212 #ifdef USE_DUFFS_LOOP
213  /* *INDENT-OFF* */
214  DUFFS_LOOP(
215  {
216  o = *src * 4;
217  dst[0] = map[o++];
218  dst[1] = map[o++];
219  dst[2] = map[o++];
220  }
221  src++;
222  dst += 3;
223  , width);
224  /* *INDENT-ON* */
225 #else
226  for (c = width; c; --c) {
227  o = *src * 4;
228  dst[0] = map[o++];
229  dst[1] = map[o++];
230  dst[2] = map[o++];
231  src++;
232  dst += 3;
233  }
234 #endif /* USE_DUFFS_LOOP */
235  src += srcskip;
236  dst += dstskip;
237  }
238 }
239 
240 static void
242 {
243 #ifndef USE_DUFFS_LOOP
244  int c;
245 #endif
246  int width, height;
247  Uint8 *src;
248  Uint32 *map, *dst;
249  int srcskip, dstskip;
250 
251  /* Set up some basic variables */
252  width = info->dst_w;
253  height = info->dst_h;
254  src = info->src;
255  srcskip = info->src_skip;
256  dst = (Uint32 *) info->dst;
257  dstskip = info->dst_skip / 4;
258  map = (Uint32 *) info->table;
259 
260  while (height--) {
261 #ifdef USE_DUFFS_LOOP
262  /* *INDENT-OFF* */
263  DUFFS_LOOP(
264  *dst++ = map[*src++];
265  , width);
266  /* *INDENT-ON* */
267 #else
268  for (c = width / 4; c; --c) {
269  *dst++ = map[*src++];
270  *dst++ = map[*src++];
271  *dst++ = map[*src++];
272  *dst++ = map[*src++];
273  }
274  switch (width & 3) {
275  case 3:
276  *dst++ = map[*src++];
277  case 2:
278  *dst++ = map[*src++];
279  case 1:
280  *dst++ = map[*src++];
281  }
282 #endif /* USE_DUFFS_LOOP */
283  src += srcskip;
284  dst += dstskip;
285  }
286 }
287 
288 static void
290 {
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;
299 
300  if (palmap) {
301  while (height--) {
302  /* *INDENT-OFF* */
303  DUFFS_LOOP(
304  {
305  if ( *src != ckey ) {
306  *dst = palmap[*src];
307  }
308  dst++;
309  src++;
310  },
311  width);
312  /* *INDENT-ON* */
313  src += srcskip;
314  dst += dstskip;
315  }
316  } else {
317  while (height--) {
318  /* *INDENT-OFF* */
319  DUFFS_LOOP(
320  {
321  if ( *src != ckey ) {
322  *dst = *src;
323  }
324  dst++;
325  src++;
326  },
327  width);
328  /* *INDENT-ON* */
329  src += srcskip;
330  dst += dstskip;
331  }
332  }
333 }
334 
335 static void
337 {
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;
346 
347  /* Set up some basic variables */
348  dstskip /= 2;
349 
350  while (height--) {
351  /* *INDENT-OFF* */
352  DUFFS_LOOP(
353  {
354  if ( *src != ckey ) {
355  *dstp=palmap[*src];
356  }
357  src++;
358  dstp++;
359  },
360  width);
361  /* *INDENT-ON* */
362  src += srcskip;
363  dstp += dstskip;
364  }
365 }
366 
367 static void
369 {
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;
378  int o;
379 
380  while (height--) {
381  /* *INDENT-OFF* */
382  DUFFS_LOOP(
383  {
384  if ( *src != ckey ) {
385  o = *src * 4;
386  dst[0] = palmap[o++];
387  dst[1] = palmap[o++];
388  dst[2] = palmap[o++];
389  }
390  src++;
391  dst += 3;
392  },
393  width);
394  /* *INDENT-ON* */
395  src += srcskip;
396  dst += dstskip;
397  }
398 }
399 
400 static void
402 {
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;
411 
412  /* Set up some basic variables */
413  dstskip /= 4;
414 
415  while (height--) {
416  /* *INDENT-OFF* */
417  DUFFS_LOOP(
418  {
419  if ( *src != ckey ) {
420  *dstp = palmap[*src];
421  }
422  src++;
423  dstp++;
424  },
425  width);
426  /* *INDENT-ON* */
427  src += srcskip;
428  dstp += dstskip;
429  }
430 }
431 
432 static void
434 {
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;
443  int dstbpp;
444  Uint32 pixel;
445  unsigned sR, sG, sB;
446  unsigned dR, dG, dB, dA;
447  const unsigned A = info->a;
448 
449  /* Set up some basic variables */
450  dstbpp = dstfmt->BytesPerPixel;
451 
452  while (height--) {
453  /* *INDENT-OFF* */
454  DUFFS_LOOP4(
455  {
456  sR = srcpal[*src].r;
457  sG = srcpal[*src].g;
458  sB = srcpal[*src].b;
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);
462  src++;
463  dst += dstbpp;
464  },
465  width);
466  /* *INDENT-ON* */
467  src += srcskip;
468  dst += dstskip;
469  }
470 }
471 
472 static void
474 {
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;
484  int dstbpp;
485  Uint32 pixel;
486  unsigned sR, sG, sB;
487  unsigned dR, dG, dB, dA;
488  const unsigned A = info->a;
489 
490  /* Set up some basic variables */
491  dstbpp = dstfmt->BytesPerPixel;
492 
493  while (height--) {
494  /* *INDENT-OFF* */
495  DUFFS_LOOP(
496  {
497  if ( *src != ckey ) {
498  sR = srcpal[*src].r;
499  sG = srcpal[*src].g;
500  sB = srcpal[*src].b;
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);
504  }
505  src++;
506  dst += dstbpp;
507  },
508  width);
509  /* *INDENT-ON* */
510  src += srcskip;
511  dst += dstskip;
512  }
513 }
514 
515 static const SDL_BlitFunc one_blit[] = {
517 };
518 
519 static const SDL_BlitFunc one_blitkey[] = {
521 };
522 
525 {
526  int which;
527  SDL_PixelFormat *dstfmt;
528 
529  dstfmt = surface->map->dst->format;
530  if (dstfmt->BitsPerPixel < 8) {
531  which = 0;
532  } else {
533  which = dstfmt->BytesPerPixel;
534  }
535  switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
536  case 0:
537  return one_blit[which];
538 
539  case SDL_COPY_COLORKEY:
540  return one_blitkey[which];
541 
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;
547 
549  return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc) NULL;
550  }
551  return (SDL_BlitFunc) NULL;
552 }
553 
554 #endif /* SDL_HAVE_BLIT_1 */
555 
556 /* vi: set ts=4 sw=4 expandtab: */
SDL_BlitInfo::src
Uint8 * src
Definition: SDL_blit.h:58
SDL_BlitInfo::src_skip
int src_skip
Definition: SDL_blit.h:61
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11096
ASSEMBLE_RGBA
#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)
Definition: SDL_blit.h:403
SDL_PixelFormat::BitsPerPixel
Uint8 BitsPerPixel
Definition: SDL_pixels.h:322
SDL_PixelFormat::BytesPerPixel
Uint8 BytesPerPixel
Definition: SDL_pixels.h:323
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_Color::b
Uint8 b
Definition: SDL_pixels.h:302
DUFFS_LOOP4
#define DUFFS_LOOP4(pixel_copy_increment, width)
Definition: SDL_blit.h:489
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
USE_DUFFS_LOOP
#define USE_DUFFS_LOOP
Definition: SDL_blit.h:468
NULL
#define NULL
Definition: begin_code.h:167
surface
EGLSurface surface
Definition: eglext.h:248
SDL_PixelFormat::format
Uint32 format
Definition: SDL_pixels.h:320
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
Blit1to4Key
static void Blit1to4Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:401
SDL_BlitInfo::dst_w
int dst_w
Definition: SDL_blit.h:63
SDL_BlitInfo
Definition: SDL_blit.h:57
SDL_Color::r
Uint8 r
Definition: SDL_pixels.h:300
SDL_BlitInfo::dst_h
int dst_h
Definition: SDL_blit.h:63
SDL_COPY_COLORKEY
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:40
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_endian.h
Blit1to4
static void Blit1to4(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:241
Blit1to1
static void Blit1to1(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:33
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:291
SDL_COPY_RLE_MASK
#define SDL_COPY_RLE_MASK
Definition: SDL_blit.h:45
DISEMBLE_RGBA
#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a)
Definition: SDL_blit.h:354
one_blitkey
static const SDL_BlitFunc one_blitkey[]
Definition: SDL_blit_1.c:519
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1740
SDL_BlitInfo::dst
Uint8 * dst
Definition: SDL_blit.h:62
DUFFS_LOOP
#define DUFFS_LOOP(pixel_copy_increment, width)
Definition: SDL_blit.h:501
SDL_CalculateBlit1
SDL_BlitFunc SDL_CalculateBlit1(SDL_Surface *surface)
Definition: SDL_blit_1.c:524
Blit1to2Key
static void Blit1to2Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:336
SDL_Palette::colors
SDL_Color * colors
Definition: SDL_pixels.h:310
SDL_BlitInfo::src_fmt
SDL_PixelFormat * src_fmt
Definition: SDL_blit.h:66
SDL_Color::g
Uint8 g
Definition: SDL_pixels.h:301
Blit1toNAlphaKey
static void Blit1toNAlphaKey(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:473
Blit1to3Key
static void Blit1to3Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:368
Blit1to2
static void Blit1to2(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:85
SDL_blit.h
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
Blit1toNAlpha
static void Blit1toNAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:433
SDL_COPY_BLEND
#define SDL_COPY_BLEND
Definition: SDL_blit.h:36
SDL_BlitInfo::dst_skip
int dst_skip
Definition: SDL_blit.h:65
SDL_BlitInfo::table
Uint8 * table
Definition: SDL_blit.h:68
SDL_PixelFormat::palette
SDL_Palette * palette
Definition: SDL_pixels.h:321
HI
#define HI
Definition: SDL_blit_N.c:975
ALPHA_BLEND_RGBA
#define ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA)
Definition: SDL_blit.h:455
SDL_PixelFormat
Definition: SDL_pixels.h:319
SDL_BlitInfo::a
Uint8 a
Definition: SDL_blit.h:71
one_blit
static const SDL_BlitFunc one_blit[]
Definition: SDL_blit_1.c:515
SDL_COPY_MODULATE_ALPHA
#define SDL_COPY_MODULATE_ALPHA
Definition: SDL_blit.h:35
SDL_BlitInfo::dst_fmt
SDL_PixelFormat * dst_fmt
Definition: SDL_blit.h:67
src
GLenum src
Definition: SDL_opengl_glext.h:1740
SDL_BlitInfo::colorkey
Uint32 colorkey
Definition: SDL_blit.h:70
SDL_Color
Definition: SDL_pixels.h:299
Blit1to3
static void Blit1to3(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:192
SDL_video.h
SDL_sysvideo.h
Blit1to1Key
static void Blit1to1Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:289
LO
#define LO
Definition: SDL_blit_N.c:976
SDL_BlitFunc
void(* SDL_BlitFunc)(SDL_BlitInfo *info)
Definition: SDL_blit.h:74