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