1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 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
28 static void
BlitBto1(SDL_BlitInfo * info)29 BlitBto1(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
83 static void
BlitBto2(SDL_BlitInfo * info)84 BlitBto2(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
120 static void
BlitBto3(SDL_BlitInfo * info)121 BlitBto3(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
159 static void
BlitBto4(SDL_BlitInfo * info)160 BlitBto4(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
196 static void
BlitBto1Key(SDL_BlitInfo * info)197 BlitBto1Key(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
249 static void
BlitBto2Key(SDL_BlitInfo * info)250 BlitBto2Key(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
284 static void
BlitBto3Key(SDL_BlitInfo * info)285 BlitBto3Key(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
318 static void
BlitBto4Key(SDL_BlitInfo * info)319 BlitBto4Key(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
353 static void
BlitBtoNAlpha(SDL_BlitInfo * info)354 BlitBtoNAlpha(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
398 static void
BlitBtoNAlphaKey(SDL_BlitInfo * info)399 BlitBtoNAlphaKey(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
445 static const SDL_BlitFunc bitmap_blit[] = {
446 (SDL_BlitFunc) NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
447 };
448
449 static const SDL_BlitFunc colorkey_blit[] = {
450 (SDL_BlitFunc) NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
451 };
452
453 SDL_BlitFunc
SDL_CalculateBlit0(SDL_Surface * surface)454 SDL_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: */
484