Atlas - SDL_blit_1.c
Home / ext / SDL / src / video Lines: 1 | Size: 14829 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 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#ifdef SDL_HAVE_BLIT_1 24 25#include "SDL_surface_c.h" 26#include "SDL_sysvideo.h" 27 28// Functions to blit from 8-bit surfaces to other surfaces 29 30static void Blit1to1(SDL_BlitInfo *info) 31{ 32#ifndef USE_DUFFS_LOOP 33 int c; 34#endif 35 int width, height; 36 Uint8 *src, *map, *dst; 37 int srcskip, dstskip; 38 39 // Set up some basic variables 40 width = info->dst_w; 41 height = info->dst_h; 42 src = info->src; 43 srcskip = info->src_skip; 44 dst = info->dst; 45 dstskip = info->dst_skip; 46 map = info->table; 47 48 while (height--) { 49#ifdef USE_DUFFS_LOOP 50 /* *INDENT-OFF* */ // clang-format off 51 DUFFS_LOOP_TRIVIAL( 52 { 53 *dst = map[*src]; 54 } 55 dst++; 56 src++; 57 , width); 58 /* *INDENT-ON* */ // clang-format on 59#else 60 for (c = width; c; --c) { 61 *dst = map[*src]; 62 dst++; 63 src++; 64 } 65#endif 66 src += srcskip; 67 dst += dstskip; 68 } 69} 70 71// This is now endian dependent 72#ifndef USE_DUFFS_LOOP 73#if (SDL_BYTEORDER == SDL_LIL_ENDIAN) 74#define HI 1 75#define LO 0 76#else // ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) 77#define HI 0 78#define LO 1 79#endif 80#endif 81static void Blit1to2(SDL_BlitInfo *info) 82{ 83#ifndef USE_DUFFS_LOOP 84 int c; 85#endif 86 int width, height; 87 Uint8 *src, *dst; 88 Uint16 *map; 89 int srcskip, dstskip; 90 91 // Set up some basic variables 92 width = info->dst_w; 93 height = info->dst_h; 94 src = info->src; 95 srcskip = info->src_skip; 96 dst = info->dst; 97 dstskip = info->dst_skip; 98 map = (Uint16 *)info->table; 99 100#ifdef USE_DUFFS_LOOP 101 while (height--) { 102 /* *INDENT-OFF* */ // clang-format off 103 DUFFS_LOOP_TRIVIAL( 104 { 105 *(Uint16 *)dst = map[*src++]; 106 dst += 2; 107 }, 108 width); 109 /* *INDENT-ON* */ // clang-format on 110 src += srcskip; 111 dst += dstskip; 112 } 113#else 114 // Memory align at 4-byte boundary, if necessary 115 if ((long)dst & 0x03) { 116 // Don't do anything if width is 0 117 if (width == 0) { 118 return; 119 } 120 --width; 121 122 while (height--) { 123 // Perform copy alignment 124 *(Uint16 *)dst = map[*src++]; 125 dst += 2; 126 127 // Copy in 4 pixel chunks 128 for (c = width / 4; c; --c) { 129 *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); 130 src += 2; 131 dst += 4; 132 *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); 133 src += 2; 134 dst += 4; 135 } 136 // Get any leftovers 137 switch (width & 3) { 138 case 3: 139 *(Uint16 *)dst = map[*src++]; 140 dst += 2; 141 SDL_FALLTHROUGH; 142 case 2: 143 *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); 144 src += 2; 145 dst += 4; 146 break; 147 case 1: 148 *(Uint16 *)dst = map[*src++]; 149 dst += 2; 150 break; 151 } 152 src += srcskip; 153 dst += dstskip; 154 } 155 } else { 156 while (height--) { 157 // Copy in 4 pixel chunks 158 for (c = width / 4; c; --c) { 159 *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); 160 src += 2; 161 dst += 4; 162 *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); 163 src += 2; 164 dst += 4; 165 } 166 // Get any leftovers 167 switch (width & 3) { 168 case 3: 169 *(Uint16 *)dst = map[*src++]; 170 dst += 2; 171 SDL_FALLTHROUGH; 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 Blit1to3(SDL_BlitInfo *info) 190{ 191#ifndef USE_DUFFS_LOOP 192 int c; 193#endif 194 int o; 195 int width, height; 196 Uint8 *src, *map, *dst; 197 int srcskip, dstskip; 198 199 // Set up some basic variables 200 width = info->dst_w; 201 height = info->dst_h; 202 src = info->src; 203 srcskip = info->src_skip; 204 dst = info->dst; 205 dstskip = info->dst_skip; 206 map = info->table; 207 208 while (height--) { 209#ifdef USE_DUFFS_LOOP 210 /* *INDENT-OFF* */ // clang-format off 211 DUFFS_LOOP( 212 { 213 o = *src * 4; 214 dst[0] = map[o++]; 215 dst[1] = map[o++]; 216 dst[2] = map[o++]; 217 } 218 src++; 219 dst += 3; 220 , width); 221 /* *INDENT-ON* */ // clang-format on 222#else 223 for (c = width; c; --c) { 224 o = *src * 4; 225 dst[0] = map[o++]; 226 dst[1] = map[o++]; 227 dst[2] = map[o++]; 228 src++; 229 dst += 3; 230 } 231#endif // USE_DUFFS_LOOP 232 src += srcskip; 233 dst += dstskip; 234 } 235} 236 237static void Blit1to4(SDL_BlitInfo *info) 238{ 239#ifndef USE_DUFFS_LOOP 240 int c; 241#endif 242 int width, height; 243 Uint8 *src; 244 Uint32 *map, *dst; 245 int srcskip, dstskip; 246 247 // Set up some basic variables 248 width = info->dst_w; 249 height = info->dst_h; 250 src = info->src; 251 srcskip = info->src_skip; 252 dst = (Uint32 *)info->dst; 253 dstskip = info->dst_skip / 4; 254 map = (Uint32 *)info->table; 255 256 while (height--) { 257#ifdef USE_DUFFS_LOOP 258 /* *INDENT-OFF* */ // clang-format off 259 DUFFS_LOOP_TRIVIAL( 260 *dst++ = map[*src++]; 261 , width); 262 /* *INDENT-ON* */ // clang-format on 263#else 264 for (c = width / 4; c; --c) { 265 *dst++ = map[*src++]; 266 *dst++ = map[*src++]; 267 *dst++ = map[*src++]; 268 *dst++ = map[*src++]; 269 } 270 switch (width & 3) { 271 case 3: 272 *dst++ = map[*src++]; 273 SDL_FALLTHROUGH; 274 case 2: 275 *dst++ = map[*src++]; 276 SDL_FALLTHROUGH; 277 case 1: 278 *dst++ = map[*src++]; 279 } 280#endif // USE_DUFFS_LOOP 281 src += srcskip; 282 dst += dstskip; 283 } 284} 285 286static void Blit1to1Key(SDL_BlitInfo *info) 287{ 288 int width = info->dst_w; 289 int height = info->dst_h; 290 Uint8 *src = info->src; 291 int srcskip = info->src_skip; 292 Uint8 *dst = info->dst; 293 int dstskip = info->dst_skip; 294 Uint8 *palmap = info->table; 295 Uint32 ckey = info->colorkey; 296 297 if (palmap) { 298 while (height--) { 299 /* *INDENT-OFF* */ // clang-format off 300 DUFFS_LOOP_TRIVIAL( 301 { 302 if ( *src != ckey ) { 303 *dst = palmap[*src]; 304 } 305 dst++; 306 src++; 307 }, 308 width); 309 /* *INDENT-ON* */ // clang-format on 310 src += srcskip; 311 dst += dstskip; 312 } 313 } else { 314 while (height--) { 315 /* *INDENT-OFF* */ // clang-format off 316 DUFFS_LOOP_TRIVIAL( 317 { 318 if ( *src != ckey ) { 319 *dst = *src; 320 } 321 dst++; 322 src++; 323 }, 324 width); 325 /* *INDENT-ON* */ // clang-format on 326 src += srcskip; 327 dst += dstskip; 328 } 329 } 330} 331 332static void Blit1to2Key(SDL_BlitInfo *info) 333{ 334 int width = info->dst_w; 335 int height = info->dst_h; 336 Uint8 *src = info->src; 337 int srcskip = info->src_skip; 338 Uint16 *dstp = (Uint16 *)info->dst; 339 int dstskip = info->dst_skip; 340 Uint16 *palmap = (Uint16 *)info->table; 341 Uint32 ckey = info->colorkey; 342 343 // Set up some basic variables 344 dstskip /= 2; 345 346 while (height--) { 347 /* *INDENT-OFF* */ // clang-format off 348 DUFFS_LOOP_TRIVIAL( 349 { 350 if ( *src != ckey ) { 351 *dstp=palmap[*src]; 352 } 353 src++; 354 dstp++; 355 }, 356 width); 357 /* *INDENT-ON* */ // clang-format on 358 src += srcskip; 359 dstp += dstskip; 360 } 361} 362 363static void Blit1to3Key(SDL_BlitInfo *info) 364{ 365 int width = info->dst_w; 366 int height = info->dst_h; 367 Uint8 *src = info->src; 368 int srcskip = info->src_skip; 369 Uint8 *dst = info->dst; 370 int dstskip = info->dst_skip; 371 Uint8 *palmap = info->table; 372 Uint32 ckey = info->colorkey; 373 int o; 374 375 while (height--) { 376 /* *INDENT-OFF* */ // clang-format off 377 DUFFS_LOOP( 378 { 379 if ( *src != ckey ) { 380 o = *src * 4; 381 dst[0] = palmap[o++]; 382 dst[1] = palmap[o++]; 383 dst[2] = palmap[o++]; 384 } 385 src++; 386 dst += 3; 387 }, 388 width); 389 /* *INDENT-ON* */ // clang-format on 390 src += srcskip; 391 dst += dstskip; 392 } 393} 394 395static void Blit1to4Key(SDL_BlitInfo *info) 396{ 397 int width = info->dst_w; 398 int height = info->dst_h; 399 Uint8 *src = info->src; 400 int srcskip = info->src_skip; 401 Uint32 *dstp = (Uint32 *)info->dst; 402 int dstskip = info->dst_skip; 403 Uint32 *palmap = (Uint32 *)info->table; 404 Uint32 ckey = info->colorkey; 405 406 // Set up some basic variables 407 dstskip /= 4; 408 409 while (height--) { 410 /* *INDENT-OFF* */ // clang-format off 411 DUFFS_LOOP_TRIVIAL( 412 { 413 if ( *src != ckey ) { 414 *dstp = palmap[*src]; 415 } 416 src++; 417 dstp++; 418 }, 419 width); 420 /* *INDENT-ON* */ // clang-format on 421 src += srcskip; 422 dstp += dstskip; 423 } 424} 425 426static void Blit1toNAlpha(SDL_BlitInfo *info) 427{ 428 int width = info->dst_w; 429 int height = info->dst_h; 430 Uint8 *src = info->src; 431 int srcskip = info->src_skip; 432 Uint8 *dst = info->dst; 433 int dstskip = info->dst_skip; 434 const SDL_PixelFormatDetails *dstfmt = info->dst_fmt; 435 const SDL_Color *srcpal = info->src_pal->colors; 436 int dstbpp; 437 Uint32 pixelvalue; 438 unsigned sR, sG, sB, sA; 439 unsigned dR, dG, dB, dA; 440 const unsigned A = info->a; 441 442 // Set up some basic variables 443 dstbpp = dstfmt->bytes_per_pixel; 444 445 while (height--) { 446 /* *INDENT-OFF* */ // clang-format off 447 DUFFS_LOOP( 448 { 449 sR = srcpal[*src].r; 450 sG = srcpal[*src].g; 451 sB = srcpal[*src].b; 452 sA = (srcpal[*src].a * A) / 255; 453 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixelvalue, dR, dG, dB, dA); 454 ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA); 455 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); 456 src++; 457 dst += dstbpp; 458 }, 459 width); 460 /* *INDENT-ON* */ // clang-format on 461 src += srcskip; 462 dst += dstskip; 463 } 464} 465 466static void Blit1toNAlphaKey(SDL_BlitInfo *info) 467{ 468 int width = info->dst_w; 469 int height = info->dst_h; 470 Uint8 *src = info->src; 471 int srcskip = info->src_skip; 472 Uint8 *dst = info->dst; 473 int dstskip = info->dst_skip; 474 const SDL_PixelFormatDetails *dstfmt = info->dst_fmt; 475 const SDL_Color *srcpal = info->src_pal->colors; 476 Uint32 ckey = info->colorkey; 477 int dstbpp; 478 Uint32 pixelvalue; 479 unsigned sR, sG, sB, sA; 480 unsigned dR, dG, dB, dA; 481 const unsigned A = info->a; 482 483 // Set up some basic variables 484 dstbpp = dstfmt->bytes_per_pixel; 485 486 while (height--) { 487 /* *INDENT-OFF* */ // clang-format off 488 DUFFS_LOOP( 489 { 490 if ( *src != ckey ) { 491 sR = srcpal[*src].r; 492 sG = srcpal[*src].g; 493 sB = srcpal[*src].b; 494 sA = (srcpal[*src].a * A) / 255; 495 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixelvalue, dR, dG, dB, dA); 496 ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA); 497 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); 498 } 499 src++; 500 dst += dstbpp; 501 }, 502 width); 503 /* *INDENT-ON* */ // clang-format on 504 src += srcskip; 505 dst += dstskip; 506 } 507} 508 509static const SDL_BlitFunc one_blit[] = { 510 (SDL_BlitFunc)NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4 511}; 512 513static const SDL_BlitFunc one_blitkey[] = { 514 (SDL_BlitFunc)NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key 515}; 516 517SDL_BlitFunc SDL_CalculateBlit1(SDL_Surface *surface) 518{ 519 int which; 520 521 if (SDL_BITSPERPIXEL(surface->map.info.dst_fmt->format) < 8) { 522 which = 0; 523 } else { 524 which = SDL_BYTESPERPIXEL(surface->map.info.dst_fmt->format); 525 } 526 527 switch (surface->map.info.flags & ~SDL_COPY_RLE_MASK) { 528 case 0: 529 if (which < SDL_arraysize(one_blit)) { 530 return one_blit[which]; 531 } 532 break; 533 534 case SDL_COPY_COLORKEY: 535 if (which < SDL_arraysize(one_blitkey)) { 536 return one_blitkey[which]; 537 } 538 break; 539 540 case SDL_COPY_COLORKEY | SDL_COPY_BLEND: // this is not super-robust but handles a specific case we found sdl12-compat. 541 if (surface->map.info.a == 255) { 542 if (which < SDL_arraysize(one_blitkey)) { 543 return one_blitkey[which]; 544 } 545 } else { 546 return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc)NULL; 547 } 548 break; 549 550 case SDL_COPY_BLEND: 551 case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: 552 /* Supporting 8bpp->8bpp alpha is doable but requires lots of 553 tables which consume space and takes time to precompute, 554 so is better left to the user */ 555 return which >= 2 ? Blit1toNAlpha : (SDL_BlitFunc)NULL; 556 557 case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: 558 return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc)NULL; 559 } 560 return (SDL_BlitFunc)NULL; 561} 562 563#endif // SDL_HAVE_BLIT_1 564[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.