SDL_blit_0.c (12396B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 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 26/* Functions to blit from bitmaps to other surfaces */ 27 28static void 29BlitBto1(SDL_BlitInfo * info) 30{ 31 int c; 32 int width, height; 33 Uint8 *src, *map, *dst; 34 int srcskip, dstskip; 35 36 /* Set up some basic variables */ 37 width = info->dst_w; 38 height = info->dst_h; 39 src = info->src; 40 srcskip = info->src_skip; 41 dst = info->dst; 42 dstskip = info->dst_skip; 43 map = info->table; 44 srcskip += width - (width + 7) / 8; 45 46 if (map) { 47 while (height--) { 48 Uint8 byte = 0, bit; 49 for (c = 0; c < width; ++c) { 50 if ((c & 7) == 0) { 51 byte = *src++; 52 } 53 bit = (byte & 0x80) >> 7; 54 if (1) { 55 *dst = map[bit]; 56 } 57 dst++; 58 byte <<= 1; 59 } 60 src += srcskip; 61 dst += dstskip; 62 } 63 } else { 64 while (height--) { 65 Uint8 byte = 0, bit; 66 for (c = 0; c < width; ++c) { 67 if ((c & 7) == 0) { 68 byte = *src++; 69 } 70 bit = (byte & 0x80) >> 7; 71 if (1) { 72 *dst = bit; 73 } 74 dst++; 75 byte <<= 1; 76 } 77 src += srcskip; 78 dst += dstskip; 79 } 80 } 81} 82 83static void 84BlitBto2(SDL_BlitInfo * info) 85{ 86 int c; 87 int width, height; 88 Uint8 *src; 89 Uint16 *map, *dst; 90 int srcskip, dstskip; 91 92 /* Set up some basic variables */ 93 width = info->dst_w; 94 height = info->dst_h; 95 src = info->src; 96 srcskip = info->src_skip; 97 dst = (Uint16 *) info->dst; 98 dstskip = info->dst_skip / 2; 99 map = (Uint16 *) info->table; 100 srcskip += width - (width + 7) / 8; 101 102 while (height--) { 103 Uint8 byte = 0, bit; 104 for (c = 0; c < width; ++c) { 105 if ((c & 7) == 0) { 106 byte = *src++; 107 } 108 bit = (byte & 0x80) >> 7; 109 if (1) { 110 *dst = map[bit]; 111 } 112 byte <<= 1; 113 dst++; 114 } 115 src += srcskip; 116 dst += dstskip; 117 } 118} 119 120static void 121BlitBto3(SDL_BlitInfo * info) 122{ 123 int c, o; 124 int width, height; 125 Uint8 *src, *map, *dst; 126 int srcskip, dstskip; 127 128 /* Set up some basic variables */ 129 width = info->dst_w; 130 height = info->dst_h; 131 src = info->src; 132 srcskip = info->src_skip; 133 dst = info->dst; 134 dstskip = info->dst_skip; 135 map = info->table; 136 srcskip += width - (width + 7) / 8; 137 138 while (height--) { 139 Uint8 byte = 0, bit; 140 for (c = 0; c < width; ++c) { 141 if ((c & 7) == 0) { 142 byte = *src++; 143 } 144 bit = (byte & 0x80) >> 7; 145 if (1) { 146 o = bit * 4; 147 dst[0] = map[o++]; 148 dst[1] = map[o++]; 149 dst[2] = map[o++]; 150 } 151 byte <<= 1; 152 dst += 3; 153 } 154 src += srcskip; 155 dst += dstskip; 156 } 157} 158 159static void 160BlitBto4(SDL_BlitInfo * info) 161{ 162 int width, height; 163 Uint8 *src; 164 Uint32 *map, *dst; 165 int srcskip, dstskip; 166 int c; 167 168 /* Set up some basic variables */ 169 width = info->dst_w; 170 height = info->dst_h; 171 src = info->src; 172 srcskip = info->src_skip; 173 dst = (Uint32 *) info->dst; 174 dstskip = info->dst_skip / 4; 175 map = (Uint32 *) info->table; 176 srcskip += width - (width + 7) / 8; 177 178 while (height--) { 179 Uint8 byte = 0, bit; 180 for (c = 0; c < width; ++c) { 181 if ((c & 7) == 0) { 182 byte = *src++; 183 } 184 bit = (byte & 0x80) >> 7; 185 if (1) { 186 *dst = map[bit]; 187 } 188 byte <<= 1; 189 dst++; 190 } 191 src += srcskip; 192 dst += dstskip; 193 } 194} 195 196static void 197BlitBto1Key(SDL_BlitInfo * info) 198{ 199 int width = info->dst_w; 200 int height = info->dst_h; 201 Uint8 *src = info->src; 202 Uint8 *dst = info->dst; 203 int srcskip = info->src_skip; 204 int dstskip = info->dst_skip; 205 Uint32 ckey = info->colorkey; 206 Uint8 *palmap = info->table; 207 int c; 208 209 /* Set up some basic variables */ 210 srcskip += width - (width + 7) / 8; 211 212 if (palmap) { 213 while (height--) { 214 Uint8 byte = 0, bit; 215 for (c = 0; c < width; ++c) { 216 if ((c & 7) == 0) { 217 byte = *src++; 218 } 219 bit = (byte & 0x80) >> 7; 220 if (bit != ckey) { 221 *dst = palmap[bit]; 222 } 223 dst++; 224 byte <<= 1; 225 } 226 src += srcskip; 227 dst += dstskip; 228 } 229 } else { 230 while (height--) { 231 Uint8 byte = 0, bit; 232 for (c = 0; c < width; ++c) { 233 if ((c & 7) == 0) { 234 byte = *src++; 235 } 236 bit = (byte & 0x80) >> 7; 237 if (bit != ckey) { 238 *dst = bit; 239 } 240 dst++; 241 byte <<= 1; 242 } 243 src += srcskip; 244 dst += dstskip; 245 } 246 } 247} 248 249static void 250BlitBto2Key(SDL_BlitInfo * info) 251{ 252 int width = info->dst_w; 253 int height = info->dst_h; 254 Uint8 *src = info->src; 255 Uint16 *dstp = (Uint16 *) info->dst; 256 int srcskip = info->src_skip; 257 int dstskip = info->dst_skip; 258 Uint32 ckey = info->colorkey; 259 Uint8 *palmap = info->table; 260 int c; 261 262 /* Set up some basic variables */ 263 srcskip += width - (width + 7) / 8; 264 dstskip /= 2; 265 266 while (height--) { 267 Uint8 byte = 0, bit; 268 for (c = 0; c < width; ++c) { 269 if ((c & 7) == 0) { 270 byte = *src++; 271 } 272 bit = (byte & 0x80) >> 7; 273 if (bit != ckey) { 274 *dstp = ((Uint16 *) palmap)[bit]; 275 } 276 byte <<= 1; 277 dstp++; 278 } 279 src += srcskip; 280 dstp += dstskip; 281 } 282} 283 284static void 285BlitBto3Key(SDL_BlitInfo * info) 286{ 287 int width = info->dst_w; 288 int height = info->dst_h; 289 Uint8 *src = info->src; 290 Uint8 *dst = info->dst; 291 int srcskip = info->src_skip; 292 int dstskip = info->dst_skip; 293 Uint32 ckey = info->colorkey; 294 Uint8 *palmap = info->table; 295 int c; 296 297 /* Set up some basic variables */ 298 srcskip += width - (width + 7) / 8; 299 300 while (height--) { 301 Uint8 byte = 0, bit; 302 for (c = 0; c < width; ++c) { 303 if ((c & 7) == 0) { 304 byte = *src++; 305 } 306 bit = (byte & 0x80) >> 7; 307 if (bit != ckey) { 308 SDL_memcpy(dst, &palmap[bit * 4], 3); 309 } 310 byte <<= 1; 311 dst += 3; 312 } 313 src += srcskip; 314 dst += dstskip; 315 } 316} 317 318static void 319BlitBto4Key(SDL_BlitInfo * info) 320{ 321 int width = info->dst_w; 322 int height = info->dst_h; 323 Uint8 *src = info->src; 324 Uint32 *dstp = (Uint32 *) info->dst; 325 int srcskip = info->src_skip; 326 int dstskip = info->dst_skip; 327 Uint32 ckey = info->colorkey; 328 Uint8 *palmap = info->table; 329 int c; 330 331 /* Set up some basic variables */ 332 srcskip += width - (width + 7) / 8; 333 dstskip /= 4; 334 335 while (height--) { 336 Uint8 byte = 0, bit; 337 for (c = 0; c < width; ++c) { 338 if ((c & 7) == 0) { 339 byte = *src++; 340 } 341 bit = (byte & 0x80) >> 7; 342 if (bit != ckey) { 343 *dstp = ((Uint32 *) palmap)[bit]; 344 } 345 byte <<= 1; 346 dstp++; 347 } 348 src += srcskip; 349 dstp += dstskip; 350 } 351} 352 353static void 354BlitBtoNAlpha(SDL_BlitInfo * info) 355{ 356 int width = info->dst_w; 357 int height = info->dst_h; 358 Uint8 *src = info->src; 359 Uint8 *dst = info->dst; 360 int srcskip = info->src_skip; 361 int dstskip = info->dst_skip; 362 const SDL_Color *srcpal = info->src_fmt->palette->colors; 363 SDL_PixelFormat *dstfmt = info->dst_fmt; 364 int dstbpp; 365 int c; 366 Uint32 pixel; 367 unsigned sR, sG, sB; 368 unsigned dR, dG, dB, dA; 369 const unsigned A = info->a; 370 371 /* Set up some basic variables */ 372 dstbpp = dstfmt->BytesPerPixel; 373 srcskip += width - (width + 7) / 8; 374 375 while (height--) { 376 Uint8 byte = 0, bit; 377 for (c = 0; c < width; ++c) { 378 if ((c & 7) == 0) { 379 byte = *src++; 380 } 381 bit = (byte & 0x80) >> 7; 382 if (1) { 383 sR = srcpal[bit].r; 384 sG = srcpal[bit].g; 385 sB = srcpal[bit].b; 386 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); 387 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); 388 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); 389 } 390 byte <<= 1; 391 dst += dstbpp; 392 } 393 src += srcskip; 394 dst += dstskip; 395 } 396} 397 398static void 399BlitBtoNAlphaKey(SDL_BlitInfo * info) 400{ 401 int width = info->dst_w; 402 int height = info->dst_h; 403 Uint8 *src = info->src; 404 Uint8 *dst = info->dst; 405 int srcskip = info->src_skip; 406 int dstskip = info->dst_skip; 407 SDL_PixelFormat *srcfmt = info->src_fmt; 408 SDL_PixelFormat *dstfmt = info->dst_fmt; 409 const SDL_Color *srcpal = srcfmt->palette->colors; 410 int dstbpp; 411 int c; 412 Uint32 pixel; 413 unsigned sR, sG, sB; 414 unsigned dR, dG, dB, dA; 415 const unsigned A = info->a; 416 Uint32 ckey = info->colorkey; 417 418 /* Set up some basic variables */ 419 dstbpp = dstfmt->BytesPerPixel; 420 srcskip += width - (width + 7) / 8; 421 422 while (height--) { 423 Uint8 byte = 0, bit; 424 for (c = 0; c < width; ++c) { 425 if ((c & 7) == 0) { 426 byte = *src++; 427 } 428 bit = (byte & 0x80) >> 7; 429 if (bit != ckey) { 430 sR = srcpal[bit].r; 431 sG = srcpal[bit].g; 432 sB = srcpal[bit].b; 433 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); 434 ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); 435 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); 436 } 437 byte <<= 1; 438 dst += dstbpp; 439 } 440 src += srcskip; 441 dst += dstskip; 442 } 443} 444 445static const SDL_BlitFunc bitmap_blit[] = { 446 (SDL_BlitFunc) NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4 447}; 448 449static const SDL_BlitFunc colorkey_blit[] = { 450 (SDL_BlitFunc) NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key 451}; 452 453SDL_BlitFunc 454SDL_CalculateBlit0(SDL_Surface * surface) 455{ 456 int which; 457 458 if (surface->format->BitsPerPixel != 1) { 459 /* We don't support sub 8-bit packed pixel modes */ 460 return (SDL_BlitFunc) NULL; 461 } 462 if (surface->map->dst->format->BitsPerPixel < 8) { 463 which = 0; 464 } else { 465 which = surface->map->dst->format->BytesPerPixel; 466 } 467 switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) { 468 case 0: 469 return bitmap_blit[which]; 470 471 case SDL_COPY_COLORKEY: 472 return colorkey_blit[which]; 473 474 case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: 475 return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc) NULL; 476 477 case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: 478 return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc) NULL; 479 } 480 return (SDL_BlitFunc) NULL; 481} 482 483/* vi: set ts=4 sw=4 expandtab: */