1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2025 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 | #ifdef SDL_HAVE_BLIT_0 |
24 | |
25 | #include "SDL_surface_c.h" |
26 | |
27 | // Functions to blit from bitmaps to other surfaces |
28 | |
29 | SDL_FORCE_INLINE void BlitBto1(SDL_BlitInfo *info, const Uint32 srcbpp) |
30 | { |
31 | const Uint32 mask = (1 << srcbpp) - 1; |
32 | const Uint32 align = (8 / srcbpp) - 1; |
33 | |
34 | int c; |
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 | if (srcbpp == 4) |
49 | srcskip += width - (width + 1) / 2; |
50 | else if (srcbpp == 2) |
51 | srcskip += width - (width + 3) / 4; |
52 | else if (srcbpp == 1) |
53 | srcskip += width - (width + 7) / 8; |
54 | |
55 | if (map) { |
56 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
57 | while (height--) { |
58 | Uint8 byte = 0, bit; |
59 | for (c = 0; c < width; ++c) { |
60 | if (!(c & align)) { |
61 | byte = *src++; |
62 | } |
63 | bit = (byte & mask); |
64 | if (1) { |
65 | *dst = map[bit]; |
66 | } |
67 | dst++; |
68 | byte >>= srcbpp; |
69 | } |
70 | src += srcskip; |
71 | dst += dstskip; |
72 | } |
73 | } else { |
74 | while (height--) { |
75 | Uint8 byte = 0, bit; |
76 | for (c = 0; c < width; ++c) { |
77 | if (!(c & align)) { |
78 | byte = *src++; |
79 | } |
80 | bit = (byte >> (8 - srcbpp)) & mask; |
81 | if (1) { |
82 | *dst = map[bit]; |
83 | } |
84 | dst++; |
85 | byte <<= srcbpp; |
86 | } |
87 | src += srcskip; |
88 | dst += dstskip; |
89 | } |
90 | } |
91 | } else { |
92 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
93 | while (height--) { |
94 | Uint8 byte = 0, bit; |
95 | for (c = 0; c < width; ++c) { |
96 | if (!(c & align)) { |
97 | byte = *src++; |
98 | } |
99 | bit = (byte & mask); |
100 | if (1) { |
101 | *dst = bit; |
102 | } |
103 | dst++; |
104 | byte >>= srcbpp; |
105 | } |
106 | src += srcskip; |
107 | dst += dstskip; |
108 | } |
109 | } else { |
110 | while (height--) { |
111 | Uint8 byte = 0, bit; |
112 | for (c = 0; c < width; ++c) { |
113 | if (!(c & align)) { |
114 | byte = *src++; |
115 | } |
116 | bit = (byte >> (8 - srcbpp)) & mask; |
117 | if (1) { |
118 | *dst = bit; |
119 | } |
120 | dst++; |
121 | byte <<= srcbpp; |
122 | } |
123 | src += srcskip; |
124 | dst += dstskip; |
125 | } |
126 | } |
127 | } |
128 | } |
129 | |
130 | SDL_FORCE_INLINE void BlitBto2(SDL_BlitInfo *info, const Uint32 srcbpp) |
131 | { |
132 | const Uint32 mask = (1 << srcbpp) - 1; |
133 | const Uint32 align = (8 / srcbpp) - 1; |
134 | |
135 | int c; |
136 | int width, height; |
137 | Uint8 *src; |
138 | Uint16 *map, *dst; |
139 | int srcskip, dstskip; |
140 | |
141 | // Set up some basic variables |
142 | width = info->dst_w; |
143 | height = info->dst_h; |
144 | src = info->src; |
145 | srcskip = info->src_skip; |
146 | dst = (Uint16 *)info->dst; |
147 | dstskip = info->dst_skip / 2; |
148 | map = (Uint16 *)info->table; |
149 | |
150 | if (srcbpp == 4) |
151 | srcskip += width - (width + 1) / 2; |
152 | else if (srcbpp == 2) |
153 | srcskip += width - (width + 3) / 4; |
154 | else if (srcbpp == 1) |
155 | srcskip += width - (width + 7) / 8; |
156 | |
157 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
158 | while (height--) { |
159 | Uint8 byte = 0, bit; |
160 | for (c = 0; c < width; ++c) { |
161 | if (!(c & align)) { |
162 | byte = *src++; |
163 | } |
164 | bit = (byte & mask); |
165 | if (1) { |
166 | *dst = map[bit]; |
167 | } |
168 | byte >>= srcbpp; |
169 | dst++; |
170 | } |
171 | src += srcskip; |
172 | dst += dstskip; |
173 | } |
174 | } else { |
175 | while (height--) { |
176 | Uint8 byte = 0, bit; |
177 | for (c = 0; c < width; ++c) { |
178 | if (!(c & align)) { |
179 | byte = *src++; |
180 | } |
181 | bit = (byte >> (8 - srcbpp)) & mask; |
182 | if (1) { |
183 | *dst = map[bit]; |
184 | } |
185 | byte <<= srcbpp; |
186 | dst++; |
187 | } |
188 | src += srcskip; |
189 | dst += dstskip; |
190 | } |
191 | } |
192 | } |
193 | |
194 | SDL_FORCE_INLINE void BlitBto3(SDL_BlitInfo *info, const Uint32 srcbpp) |
195 | { |
196 | const Uint32 mask = (1 << srcbpp) - 1; |
197 | const Uint32 align = (8 / srcbpp) - 1; |
198 | |
199 | int c, o; |
200 | int width, height; |
201 | Uint8 *src, *map, *dst; |
202 | int srcskip, dstskip; |
203 | |
204 | // Set up some basic variables |
205 | width = info->dst_w; |
206 | height = info->dst_h; |
207 | src = info->src; |
208 | srcskip = info->src_skip; |
209 | dst = info->dst; |
210 | dstskip = info->dst_skip; |
211 | map = info->table; |
212 | |
213 | if (srcbpp == 4) |
214 | srcskip += width - (width + 1) / 2; |
215 | else if (srcbpp == 2) |
216 | srcskip += width - (width + 3) / 4; |
217 | else if (srcbpp == 1) |
218 | srcskip += width - (width + 7) / 8; |
219 | |
220 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
221 | while (height--) { |
222 | Uint8 byte = 0, bit; |
223 | for (c = 0; c < width; ++c) { |
224 | if (!(c & align)) { |
225 | byte = *src++; |
226 | } |
227 | bit = (byte & mask); |
228 | if (1) { |
229 | o = bit * 4; |
230 | dst[0] = map[o++]; |
231 | dst[1] = map[o++]; |
232 | dst[2] = map[o++]; |
233 | } |
234 | byte >>= srcbpp; |
235 | dst += 3; |
236 | } |
237 | src += srcskip; |
238 | dst += dstskip; |
239 | } |
240 | } else { |
241 | while (height--) { |
242 | Uint8 byte = 0, bit; |
243 | for (c = 0; c < width; ++c) { |
244 | if (!(c & align)) { |
245 | byte = *src++; |
246 | } |
247 | bit = (byte >> (8 - srcbpp)) & mask; |
248 | if (1) { |
249 | o = bit * 4; |
250 | dst[0] = map[o++]; |
251 | dst[1] = map[o++]; |
252 | dst[2] = map[o++]; |
253 | } |
254 | byte <<= srcbpp; |
255 | dst += 3; |
256 | } |
257 | src += srcskip; |
258 | dst += dstskip; |
259 | } |
260 | } |
261 | } |
262 | |
263 | SDL_FORCE_INLINE void BlitBto4(SDL_BlitInfo *info, const Uint32 srcbpp) |
264 | { |
265 | const Uint32 mask = (1 << srcbpp) - 1; |
266 | const Uint32 align = (8 / srcbpp) - 1; |
267 | |
268 | int width, height; |
269 | Uint8 *src; |
270 | Uint32 *map, *dst; |
271 | int srcskip, dstskip; |
272 | int c; |
273 | |
274 | // Set up some basic variables |
275 | width = info->dst_w; |
276 | height = info->dst_h; |
277 | src = info->src; |
278 | srcskip = info->src_skip; |
279 | dst = (Uint32 *)info->dst; |
280 | dstskip = info->dst_skip / 4; |
281 | map = (Uint32 *)info->table; |
282 | |
283 | if (srcbpp == 4) |
284 | srcskip += width - (width + 1) / 2; |
285 | else if (srcbpp == 2) |
286 | srcskip += width - (width + 3) / 4; |
287 | else if (srcbpp == 1) |
288 | srcskip += width - (width + 7) / 8; |
289 | |
290 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
291 | while (height--) { |
292 | Uint8 byte = 0, bit; |
293 | for (c = 0; c < width; ++c) { |
294 | if (!(c & align)) { |
295 | byte = *src++; |
296 | } |
297 | bit = (byte & mask); |
298 | if (1) { |
299 | *dst = map[bit]; |
300 | } |
301 | byte >>= srcbpp; |
302 | dst++; |
303 | } |
304 | src += srcskip; |
305 | dst += dstskip; |
306 | } |
307 | } else { |
308 | while (height--) { |
309 | Uint8 byte = 0, bit; |
310 | for (c = 0; c < width; ++c) { |
311 | if (!(c & align)) { |
312 | byte = *src++; |
313 | } |
314 | bit = (byte >> (8 - srcbpp)) & mask; |
315 | if (1) { |
316 | *dst = map[bit]; |
317 | } |
318 | byte <<= srcbpp; |
319 | dst++; |
320 | } |
321 | src += srcskip; |
322 | dst += dstskip; |
323 | } |
324 | } |
325 | } |
326 | |
327 | SDL_FORCE_INLINE void BlitBto1Key(SDL_BlitInfo *info, const Uint32 srcbpp) |
328 | { |
329 | const Uint32 mask = (1 << srcbpp) - 1; |
330 | const Uint32 align = (8 / srcbpp) - 1; |
331 | |
332 | int width = info->dst_w; |
333 | int height = info->dst_h; |
334 | Uint8 *src = info->src; |
335 | Uint8 *dst = info->dst; |
336 | int srcskip = info->src_skip; |
337 | int dstskip = info->dst_skip; |
338 | Uint32 ckey = info->colorkey; |
339 | Uint8 *palmap = info->table; |
340 | int c; |
341 | |
342 | // Set up some basic variables |
343 | if (srcbpp == 4) |
344 | srcskip += width - (width + 1) / 2; |
345 | else if (srcbpp == 2) |
346 | srcskip += width - (width + 3) / 4; |
347 | else if (srcbpp == 1) |
348 | srcskip += width - (width + 7) / 8; |
349 | |
350 | if (palmap) { |
351 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
352 | while (height--) { |
353 | Uint8 byte = 0, bit; |
354 | for (c = 0; c < width; ++c) { |
355 | if (!(c & align)) { |
356 | byte = *src++; |
357 | } |
358 | bit = (byte & mask); |
359 | if (bit != ckey) { |
360 | *dst = palmap[bit]; |
361 | } |
362 | dst++; |
363 | byte >>= srcbpp; |
364 | } |
365 | src += srcskip; |
366 | dst += dstskip; |
367 | } |
368 | } else { |
369 | while (height--) { |
370 | Uint8 byte = 0, bit; |
371 | for (c = 0; c < width; ++c) { |
372 | if (!(c & align)) { |
373 | byte = *src++; |
374 | } |
375 | bit = (byte >> (8 - srcbpp)) & mask; |
376 | if (bit != ckey) { |
377 | *dst = palmap[bit]; |
378 | } |
379 | dst++; |
380 | byte <<= srcbpp; |
381 | } |
382 | src += srcskip; |
383 | dst += dstskip; |
384 | } |
385 | } |
386 | } else { |
387 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
388 | while (height--) { |
389 | Uint8 byte = 0, bit; |
390 | for (c = 0; c < width; ++c) { |
391 | if (!(c & align)) { |
392 | byte = *src++; |
393 | } |
394 | bit = (byte & mask); |
395 | if (bit != ckey) { |
396 | *dst = bit; |
397 | } |
398 | dst++; |
399 | byte >>= srcbpp; |
400 | } |
401 | src += srcskip; |
402 | dst += dstskip; |
403 | } |
404 | } else { |
405 | while (height--) { |
406 | Uint8 byte = 0, bit; |
407 | for (c = 0; c < width; ++c) { |
408 | if (!(c & align)) { |
409 | byte = *src++; |
410 | } |
411 | bit = (byte >> (8 - srcbpp)) & mask; |
412 | if (bit != ckey) { |
413 | *dst = bit; |
414 | } |
415 | dst++; |
416 | byte <<= srcbpp; |
417 | } |
418 | src += srcskip; |
419 | dst += dstskip; |
420 | } |
421 | } |
422 | } |
423 | } |
424 | |
425 | SDL_FORCE_INLINE void BlitBto2Key(SDL_BlitInfo *info, const Uint32 srcbpp) |
426 | { |
427 | const Uint32 mask = (1 << srcbpp) - 1; |
428 | const Uint32 align = (8 / srcbpp) - 1; |
429 | |
430 | int width = info->dst_w; |
431 | int height = info->dst_h; |
432 | Uint8 *src = info->src; |
433 | Uint16 *dstp = (Uint16 *)info->dst; |
434 | int srcskip = info->src_skip; |
435 | int dstskip = info->dst_skip; |
436 | Uint32 ckey = info->colorkey; |
437 | Uint8 *palmap = info->table; |
438 | int c; |
439 | |
440 | // Set up some basic variables |
441 | if (srcbpp == 4) |
442 | srcskip += width - (width + 1) / 2; |
443 | else if (srcbpp == 2) |
444 | srcskip += width - (width + 3) / 4; |
445 | else if (srcbpp == 1) |
446 | srcskip += width - (width + 7) / 8; |
447 | dstskip /= 2; |
448 | |
449 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
450 | while (height--) { |
451 | Uint8 byte = 0, bit; |
452 | for (c = 0; c < width; ++c) { |
453 | if (!(c & align)) { |
454 | byte = *src++; |
455 | } |
456 | bit = (byte & mask); |
457 | if (bit != ckey) { |
458 | *dstp = ((Uint16 *)palmap)[bit]; |
459 | } |
460 | byte >>= srcbpp; |
461 | dstp++; |
462 | } |
463 | src += srcskip; |
464 | dstp += dstskip; |
465 | } |
466 | } else { |
467 | while (height--) { |
468 | Uint8 byte = 0, bit; |
469 | for (c = 0; c < width; ++c) { |
470 | if (!(c & align)) { |
471 | byte = *src++; |
472 | } |
473 | bit = (byte >> (8 - srcbpp)) & mask; |
474 | if (bit != ckey) { |
475 | *dstp = ((Uint16 *)palmap)[bit]; |
476 | } |
477 | byte <<= srcbpp; |
478 | dstp++; |
479 | } |
480 | src += srcskip; |
481 | dstp += dstskip; |
482 | } |
483 | } |
484 | } |
485 | |
486 | SDL_FORCE_INLINE void BlitBto3Key(SDL_BlitInfo *info, const Uint32 srcbpp) |
487 | { |
488 | const Uint32 mask = (1 << srcbpp) - 1; |
489 | const Uint32 align = (8 / srcbpp) - 1; |
490 | |
491 | int width = info->dst_w; |
492 | int height = info->dst_h; |
493 | Uint8 *src = info->src; |
494 | Uint8 *dst = info->dst; |
495 | int srcskip = info->src_skip; |
496 | int dstskip = info->dst_skip; |
497 | Uint32 ckey = info->colorkey; |
498 | Uint8 *palmap = info->table; |
499 | int c; |
500 | |
501 | // Set up some basic variables |
502 | if (srcbpp == 4) |
503 | srcskip += width - (width + 1) / 2; |
504 | else if (srcbpp == 2) |
505 | srcskip += width - (width + 3) / 4; |
506 | else if (srcbpp == 1) |
507 | srcskip += width - (width + 7) / 8; |
508 | |
509 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
510 | while (height--) { |
511 | Uint8 byte = 0, bit; |
512 | for (c = 0; c < width; ++c) { |
513 | if (!(c & align)) { |
514 | byte = *src++; |
515 | } |
516 | bit = (byte & mask); |
517 | if (bit != ckey) { |
518 | SDL_memcpy(dst, &palmap[bit * 4], 3); |
519 | } |
520 | byte >>= srcbpp; |
521 | dst += 3; |
522 | } |
523 | src += srcskip; |
524 | dst += dstskip; |
525 | } |
526 | } else { |
527 | while (height--) { |
528 | Uint8 byte = 0, bit; |
529 | for (c = 0; c < width; ++c) { |
530 | if (!(c & align)) { |
531 | byte = *src++; |
532 | } |
533 | bit = (byte >> (8 - srcbpp)) & mask; |
534 | if (bit != ckey) { |
535 | SDL_memcpy(dst, &palmap[bit * 4], 3); |
536 | } |
537 | byte <<= srcbpp; |
538 | dst += 3; |
539 | } |
540 | src += srcskip; |
541 | dst += dstskip; |
542 | } |
543 | } |
544 | } |
545 | |
546 | SDL_FORCE_INLINE void BlitBto4Key(SDL_BlitInfo *info, const Uint32 srcbpp) |
547 | { |
548 | const Uint32 mask = (1 << srcbpp) - 1; |
549 | const Uint32 align = (8 / srcbpp) - 1; |
550 | |
551 | int width = info->dst_w; |
552 | int height = info->dst_h; |
553 | Uint8 *src = info->src; |
554 | Uint32 *dstp = (Uint32 *)info->dst; |
555 | int srcskip = info->src_skip; |
556 | int dstskip = info->dst_skip; |
557 | Uint32 ckey = info->colorkey; |
558 | Uint8 *palmap = info->table; |
559 | int c; |
560 | |
561 | // Set up some basic variables |
562 | if (srcbpp == 4) |
563 | srcskip += width - (width + 1) / 2; |
564 | else if (srcbpp == 2) |
565 | srcskip += width - (width + 3) / 4; |
566 | else if (srcbpp == 1) |
567 | srcskip += width - (width + 7) / 8; |
568 | dstskip /= 4; |
569 | |
570 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
571 | while (height--) { |
572 | Uint8 byte = 0, bit; |
573 | for (c = 0; c < width; ++c) { |
574 | if (!(c & align)) { |
575 | byte = *src++; |
576 | } |
577 | bit = (byte & mask); |
578 | if (bit != ckey) { |
579 | *dstp = ((Uint32 *)palmap)[bit]; |
580 | } |
581 | byte >>= srcbpp; |
582 | dstp++; |
583 | } |
584 | src += srcskip; |
585 | dstp += dstskip; |
586 | } |
587 | } else { |
588 | while (height--) { |
589 | Uint8 byte = 0, bit; |
590 | for (c = 0; c < width; ++c) { |
591 | if (!(c & align)) { |
592 | byte = *src++; |
593 | } |
594 | bit = (byte >> (8 - srcbpp)) & mask; |
595 | if (bit != ckey) { |
596 | *dstp = ((Uint32 *)palmap)[bit]; |
597 | } |
598 | byte <<= srcbpp; |
599 | dstp++; |
600 | } |
601 | src += srcskip; |
602 | dstp += dstskip; |
603 | } |
604 | } |
605 | } |
606 | |
607 | static void BlitBtoNAlpha(SDL_BlitInfo *info) |
608 | { |
609 | int width = info->dst_w; |
610 | int height = info->dst_h; |
611 | Uint8 *src = info->src; |
612 | Uint8 *dst = info->dst; |
613 | int srcskip = info->src_skip; |
614 | int dstskip = info->dst_skip; |
615 | const SDL_Color *srcpal = info->src_pal->colors; |
616 | const SDL_PixelFormatDetails *srcfmt = info->src_fmt; |
617 | const SDL_PixelFormatDetails *dstfmt = info->dst_fmt; |
618 | int srcbpp, dstbpp; |
619 | int c; |
620 | Uint32 pixel, mask, align; |
621 | unsigned sR, sG, sB; |
622 | unsigned dR, dG, dB, dA; |
623 | const unsigned A = info->a; |
624 | |
625 | // Set up some basic variables |
626 | srcbpp = srcfmt->bytes_per_pixel; |
627 | dstbpp = dstfmt->bytes_per_pixel; |
628 | if (srcbpp == 4) |
629 | srcskip += width - (width + 1) / 2; |
630 | else if (srcbpp == 2) |
631 | srcskip += width - (width + 3) / 4; |
632 | else if (srcbpp == 1) |
633 | srcskip += width - (width + 7) / 8; |
634 | mask = (1 << srcbpp) - 1; |
635 | align = (8 / srcbpp) - 1; |
636 | |
637 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
638 | while (height--) { |
639 | Uint8 byte = 0, bit; |
640 | for (c = 0; c < width; ++c) { |
641 | if (!(c & align)) { |
642 | byte = *src++; |
643 | } |
644 | bit = (byte & mask); |
645 | if (1) { |
646 | sR = srcpal[bit].r; |
647 | sG = srcpal[bit].g; |
648 | sB = srcpal[bit].b; |
649 | DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); |
650 | ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); |
651 | ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); |
652 | } |
653 | byte >>= srcbpp; |
654 | dst += dstbpp; |
655 | } |
656 | src += srcskip; |
657 | dst += dstskip; |
658 | } |
659 | } else { |
660 | while (height--) { |
661 | Uint8 byte = 0, bit; |
662 | for (c = 0; c < width; ++c) { |
663 | if (!(c & align)) { |
664 | byte = *src++; |
665 | } |
666 | bit = (byte >> (8 - srcbpp)) & mask; |
667 | if (1) { |
668 | sR = srcpal[bit].r; |
669 | sG = srcpal[bit].g; |
670 | sB = srcpal[bit].b; |
671 | DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); |
672 | ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); |
673 | ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); |
674 | } |
675 | byte <<= srcbpp; |
676 | dst += dstbpp; |
677 | } |
678 | src += srcskip; |
679 | dst += dstskip; |
680 | } |
681 | } |
682 | } |
683 | |
684 | static void BlitBtoNAlphaKey(SDL_BlitInfo *info) |
685 | { |
686 | int width = info->dst_w; |
687 | int height = info->dst_h; |
688 | Uint8 *src = info->src; |
689 | Uint8 *dst = info->dst; |
690 | int srcskip = info->src_skip; |
691 | int dstskip = info->dst_skip; |
692 | const SDL_PixelFormatDetails *srcfmt = info->src_fmt; |
693 | const SDL_PixelFormatDetails *dstfmt = info->dst_fmt; |
694 | const SDL_Color *srcpal = info->src_pal->colors; |
695 | int srcbpp, dstbpp; |
696 | int c; |
697 | Uint32 pixel, mask, align; |
698 | unsigned sR, sG, sB; |
699 | unsigned dR, dG, dB, dA; |
700 | const unsigned A = info->a; |
701 | Uint32 ckey = info->colorkey; |
702 | |
703 | // Set up some basic variables |
704 | srcbpp = srcfmt->bytes_per_pixel; |
705 | dstbpp = dstfmt->bytes_per_pixel; |
706 | if (srcbpp == 4) |
707 | srcskip += width - (width + 1) / 2; |
708 | else if (srcbpp == 2) |
709 | srcskip += width - (width + 3) / 4; |
710 | else if (srcbpp == 1) |
711 | srcskip += width - (width + 7) / 8; |
712 | mask = (1 << srcbpp) - 1; |
713 | align = (8 / srcbpp) - 1; |
714 | |
715 | if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { |
716 | while (height--) { |
717 | Uint8 byte = 0, bit; |
718 | for (c = 0; c < width; ++c) { |
719 | if (!(c & align)) { |
720 | byte = *src++; |
721 | } |
722 | bit = (byte & mask); |
723 | if (bit != ckey) { |
724 | sR = srcpal[bit].r; |
725 | sG = srcpal[bit].g; |
726 | sB = srcpal[bit].b; |
727 | DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); |
728 | ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); |
729 | ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); |
730 | } |
731 | byte >>= srcbpp; |
732 | dst += dstbpp; |
733 | } |
734 | src += srcskip; |
735 | dst += dstskip; |
736 | } |
737 | } else { |
738 | while (height--) { |
739 | Uint8 byte = 0, bit; |
740 | for (c = 0; c < width; ++c) { |
741 | if (!(c & align)) { |
742 | byte = *src++; |
743 | } |
744 | bit = (byte >> (8 - srcbpp)) & mask; |
745 | if (bit != ckey) { |
746 | sR = srcpal[bit].r; |
747 | sG = srcpal[bit].g; |
748 | sB = srcpal[bit].b; |
749 | DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); |
750 | ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); |
751 | ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); |
752 | } |
753 | byte <<= srcbpp; |
754 | dst += dstbpp; |
755 | } |
756 | src += srcskip; |
757 | dst += dstskip; |
758 | } |
759 | } |
760 | } |
761 | |
762 | |
763 | |
764 | static void Blit1bto1(SDL_BlitInfo *info) { |
765 | BlitBto1(info, 1); |
766 | } |
767 | |
768 | static void Blit1bto2(SDL_BlitInfo *info) { |
769 | BlitBto2(info, 1); |
770 | } |
771 | |
772 | static void Blit1bto3(SDL_BlitInfo *info) { |
773 | BlitBto3(info, 1); |
774 | } |
775 | |
776 | static void Blit1bto4(SDL_BlitInfo *info) { |
777 | BlitBto4(info, 1); |
778 | } |
779 | |
780 | static const SDL_BlitFunc bitmap_blit_1b[] = { |
781 | (SDL_BlitFunc)NULL, Blit1bto1, Blit1bto2, Blit1bto3, Blit1bto4 |
782 | }; |
783 | |
784 | static void Blit1bto1Key(SDL_BlitInfo *info) { |
785 | BlitBto1Key(info, 1); |
786 | } |
787 | |
788 | static void Blit1bto2Key(SDL_BlitInfo *info) { |
789 | BlitBto2Key(info, 1); |
790 | } |
791 | |
792 | static void Blit1bto3Key(SDL_BlitInfo *info) { |
793 | BlitBto3Key(info, 1); |
794 | } |
795 | |
796 | static void Blit1bto4Key(SDL_BlitInfo *info) { |
797 | BlitBto4Key(info, 1); |
798 | } |
799 | |
800 | static const SDL_BlitFunc colorkey_blit_1b[] = { |
801 | (SDL_BlitFunc)NULL, Blit1bto1Key, Blit1bto2Key, Blit1bto3Key, Blit1bto4Key |
802 | }; |
803 | |
804 | |
805 | |
806 | static void Blit2bto1(SDL_BlitInfo *info) { |
807 | BlitBto1(info, 2); |
808 | } |
809 | |
810 | static void Blit2bto2(SDL_BlitInfo *info) { |
811 | BlitBto2(info, 2); |
812 | } |
813 | |
814 | static void Blit2bto3(SDL_BlitInfo *info) { |
815 | BlitBto3(info, 2); |
816 | } |
817 | |
818 | static void Blit2bto4(SDL_BlitInfo *info) { |
819 | BlitBto4(info, 2); |
820 | } |
821 | |
822 | static const SDL_BlitFunc bitmap_blit_2b[] = { |
823 | (SDL_BlitFunc)NULL, Blit2bto1, Blit2bto2, Blit2bto3, Blit2bto4 |
824 | }; |
825 | |
826 | static void Blit2bto1Key(SDL_BlitInfo *info) { |
827 | BlitBto1Key(info, 2); |
828 | } |
829 | |
830 | static void Blit2bto2Key(SDL_BlitInfo *info) { |
831 | BlitBto2Key(info, 2); |
832 | } |
833 | |
834 | static void Blit2bto3Key(SDL_BlitInfo *info) { |
835 | BlitBto3Key(info, 2); |
836 | } |
837 | |
838 | static void Blit2bto4Key(SDL_BlitInfo *info) { |
839 | BlitBto4Key(info, 2); |
840 | } |
841 | |
842 | static const SDL_BlitFunc colorkey_blit_2b[] = { |
843 | (SDL_BlitFunc)NULL, Blit2bto1Key, Blit2bto2Key, Blit2bto3Key, Blit2bto4Key |
844 | }; |
845 | |
846 | |
847 | |
848 | static void Blit4bto1(SDL_BlitInfo *info) { |
849 | BlitBto1(info, 4); |
850 | } |
851 | |
852 | static void Blit4bto2(SDL_BlitInfo *info) { |
853 | BlitBto2(info, 4); |
854 | } |
855 | |
856 | static void Blit4bto3(SDL_BlitInfo *info) { |
857 | BlitBto3(info, 4); |
858 | } |
859 | |
860 | static void Blit4bto4(SDL_BlitInfo *info) { |
861 | BlitBto4(info, 4); |
862 | } |
863 | |
864 | static const SDL_BlitFunc bitmap_blit_4b[] = { |
865 | (SDL_BlitFunc)NULL, Blit4bto1, Blit4bto2, Blit4bto3, Blit4bto4 |
866 | }; |
867 | |
868 | static void Blit4bto1Key(SDL_BlitInfo *info) { |
869 | BlitBto1Key(info, 4); |
870 | } |
871 | |
872 | static void Blit4bto2Key(SDL_BlitInfo *info) { |
873 | BlitBto2Key(info, 4); |
874 | } |
875 | |
876 | static void Blit4bto3Key(SDL_BlitInfo *info) { |
877 | BlitBto3Key(info, 4); |
878 | } |
879 | |
880 | static void Blit4bto4Key(SDL_BlitInfo *info) { |
881 | BlitBto4Key(info, 4); |
882 | } |
883 | |
884 | static const SDL_BlitFunc colorkey_blit_4b[] = { |
885 | (SDL_BlitFunc)NULL, Blit4bto1Key, Blit4bto2Key, Blit4bto3Key, Blit4bto4Key |
886 | }; |
887 | |
888 | |
889 | |
890 | SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface) |
891 | { |
892 | int which; |
893 | |
894 | if (SDL_BITSPERPIXEL(surface->map.info.dst_fmt->format) < 8) { |
895 | which = 0; |
896 | } else { |
897 | which = SDL_BYTESPERPIXEL(surface->map.info.dst_fmt->format); |
898 | } |
899 | |
900 | if (SDL_PIXELTYPE(surface->format) == SDL_PIXELTYPE_INDEX1) { |
901 | switch (surface->map.info.flags & ~SDL_COPY_RLE_MASK) { |
902 | case 0: |
903 | if (which < SDL_arraysize(bitmap_blit_1b)) { |
904 | return bitmap_blit_1b[which]; |
905 | } |
906 | break; |
907 | |
908 | case SDL_COPY_COLORKEY: |
909 | if (which < SDL_arraysize(colorkey_blit_1b)) { |
910 | return colorkey_blit_1b[which]; |
911 | } |
912 | break; |
913 | |
914 | case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: |
915 | return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc)NULL; |
916 | |
917 | case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: |
918 | return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc)NULL; |
919 | } |
920 | return NULL; |
921 | } |
922 | |
923 | if (SDL_PIXELTYPE(surface->format) == SDL_PIXELTYPE_INDEX2) { |
924 | switch (surface->map.info.flags & ~SDL_COPY_RLE_MASK) { |
925 | case 0: |
926 | if (which < SDL_arraysize(bitmap_blit_2b)) { |
927 | return bitmap_blit_2b[which]; |
928 | } |
929 | break; |
930 | |
931 | case SDL_COPY_COLORKEY: |
932 | if (which < SDL_arraysize(colorkey_blit_2b)) { |
933 | return colorkey_blit_2b[which]; |
934 | } |
935 | break; |
936 | |
937 | case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: |
938 | return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc)NULL; |
939 | |
940 | case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: |
941 | return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc)NULL; |
942 | } |
943 | return NULL; |
944 | } |
945 | |
946 | if (SDL_PIXELTYPE(surface->format) == SDL_PIXELTYPE_INDEX4) { |
947 | switch (surface->map.info.flags & ~SDL_COPY_RLE_MASK) { |
948 | case 0: |
949 | if (which < SDL_arraysize(bitmap_blit_4b)) { |
950 | return bitmap_blit_4b[which]; |
951 | } |
952 | break; |
953 | |
954 | case SDL_COPY_COLORKEY: |
955 | if (which < SDL_arraysize(colorkey_blit_4b)) { |
956 | return colorkey_blit_4b[which]; |
957 | } |
958 | break; |
959 | |
960 | case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: |
961 | return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc)NULL; |
962 | |
963 | case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: |
964 | return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc)NULL; |
965 | } |
966 | return NULL; |
967 | } |
968 | |
969 | return NULL; |
970 | } |
971 | |
972 | #endif // SDL_HAVE_BLIT_0 |
973 | |