SDL 2.0
SDL_blit_1.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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
30static 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* */
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
82static 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* */
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
189static 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* */
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
238static 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* */
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
286static 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* */
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* */
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
333static 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* */
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
365static 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* */
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
398static 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* */
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
430static 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* */
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
470static 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* */
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
513static const SDL_BlitFunc one_blit[] = {
515};
516
517static 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
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: */
#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)
Definition: SDL_blit.h:402
#define ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA)
Definition: SDL_blit.h:454
#define SDL_COPY_RLE_MASK
Definition: SDL_blit.h:44
#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a)
Definition: SDL_blit.h:353
#define USE_DUFFS_LOOP
Definition: SDL_blit.h:467
#define DUFFS_LOOP(pixel_copy_increment, width)
Definition: SDL_blit.h:500
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:39
#define SDL_COPY_MODULATE_ALPHA
Definition: SDL_blit.h:35
void(* SDL_BlitFunc)(SDL_BlitInfo *info)
Definition: SDL_blit.h:73
#define SDL_COPY_BLEND
Definition: SDL_blit.h:36
#define DUFFS_LOOP4(pixel_copy_increment, width)
Definition: SDL_blit.h:488
static void Blit1to2Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:334
static void Blit1to3(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:190
static void Blit1to4Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:399
static void Blit1to3Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:366
static const SDL_BlitFunc one_blitkey[]
Definition: SDL_blit_1.c:517
static void Blit1to1Key(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:287
static void Blit1to1(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:31
SDL_BlitFunc SDL_CalculateBlit1(SDL_Surface *surface)
Definition: SDL_blit_1.c:522
static const SDL_BlitFunc one_blit[]
Definition: SDL_blit_1.c:513
static void Blit1toNAlphaKey(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:471
static void Blit1to4(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:239
static void Blit1toNAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:431
static void Blit1to2(SDL_BlitInfo *info)
Definition: SDL_blit_1.c:83
#define HI
Definition: SDL_blit_N.c:892
#define LO
Definition: SDL_blit_N.c:893
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
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
GLenum src
const GLubyte * c
GLenum GLenum dst
uint32_t Uint32
Definition: SDL_stdinc.h:203
uint16_t Uint16
Definition: SDL_stdinc.h:191
uint8_t Uint8
Definition: SDL_stdinc.h:179
#define NULL
Definition: begin_code.h:167
EGLSurface surface
Definition: eglext.h:248
SDL_PixelFormat * src_fmt
Definition: SDL_blit.h:65
Uint8 * table
Definition: SDL_blit.h:67
int dst_skip
Definition: SDL_blit.h:64
SDL_PixelFormat * dst_fmt
Definition: SDL_blit.h:66
int src_skip
Definition: SDL_blit.h:60
Uint8 a
Definition: SDL_blit.h:70
Uint8 * src
Definition: SDL_blit.h:57
Uint32 colorkey
Definition: SDL_blit.h:69
Uint8 * dst
Definition: SDL_blit.h:61
Uint8 r
Definition: SDL_pixels.h:297
Uint8 b
Definition: SDL_pixels.h:299
Uint8 g
Definition: SDL_pixels.h:298
SDL_Color * colors
Definition: SDL_pixels.h:307
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
Uint8 BitsPerPixel
Definition: SDL_pixels.h:319
SDL_Palette * palette
Definition: SDL_pixels.h:318
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71