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