Atlas - SDL_blit_1.c

Home / ext / SDL2 / src / video Lines: 1 | Size: 12751 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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 31Blit1to1(SDL_BlitInfo * info) 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 82static void 83Blit1to2(SDL_BlitInfo * info) 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 189static void 190Blit1to3(SDL_BlitInfo * info) 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 238static void 239Blit1to4(SDL_BlitInfo * info) 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 286static void 287Blit1to1Key(SDL_BlitInfo * info) 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 333static void 334Blit1to2Key(SDL_BlitInfo * info) 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 365static void 366Blit1to3Key(SDL_BlitInfo * info) 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 398static void 399Blit1to4Key(SDL_BlitInfo * info) 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 430static void 431Blit1toNAlpha(SDL_BlitInfo * info) 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 470static void 471Blit1toNAlphaKey(SDL_BlitInfo * info) 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 513static const SDL_BlitFunc one_blit[] = { 514 (SDL_BlitFunc) NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4 515}; 516 517static const SDL_BlitFunc one_blitkey[] = { 518 (SDL_BlitFunc) NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key 519}; 520 521SDL_BlitFunc 522SDL_CalculateBlit1(SDL_Surface * surface) 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 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; 545 546 case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: 547 return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc) NULL; 548 } 549 return (SDL_BlitFunc) NULL; 550} 551 552/* vi: set ts=4 sw=4 expandtab: */ 553
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.