Mercurial > sdl-ios-xcode
annotate src/video/SDL_blit_1.c @ 1312:c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
I batch edited these files, so please let me know if I've accidentally removed anybody's
credit here.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 01 Feb 2006 06:32:25 +0000 |
parents | b8d311d90021 |
children | 450721ad5436 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
0 | 7 License as published by the Free Software Foundation; either |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
0 | 9 |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
13 Lesser General Public License for more details. |
0 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 18 |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
91
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #include <stdio.h> | |
24 | |
25 #include "SDL_types.h" | |
26 #include "SDL_video.h" | |
27 #include "SDL_blit.h" | |
28 #include "SDL_sysvideo.h" | |
29 #include "SDL_endian.h" | |
30 | |
31 /* Functions to blit from 8-bit surfaces to other surfaces */ | |
32 | |
33 static void Blit1to1(SDL_BlitInfo *info) | |
34 { | |
35 #ifndef USE_DUFFS_LOOP | |
36 int c; | |
37 #endif | |
38 int width, height; | |
39 Uint8 *src, *map, *dst; | |
40 int srcskip, dstskip; | |
41 | |
42 /* Set up some basic variables */ | |
43 width = info->d_width; | |
44 height = info->d_height; | |
45 src = info->s_pixels; | |
46 srcskip = info->s_skip; | |
47 dst = info->d_pixels; | |
48 dstskip = info->d_skip; | |
49 map = info->table; | |
50 | |
51 while ( height-- ) { | |
52 #ifdef USE_DUFFS_LOOP | |
53 DUFFS_LOOP( | |
54 { | |
55 *dst = map[*src]; | |
56 } | |
57 dst++; | |
58 src++; | |
59 , width); | |
60 #else | |
61 for ( c=width; c; --c ) { | |
62 *dst = map[*src]; | |
63 dst++; | |
64 src++; | |
65 } | |
66 #endif | |
67 src += srcskip; | |
68 dst += dstskip; | |
69 } | |
70 } | |
71 /* This is now endian dependent */ | |
72 #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) | |
73 #define HI 1 | |
74 #define LO 0 | |
75 #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */ | |
76 #define HI 0 | |
77 #define LO 1 | |
78 #endif | |
79 static void Blit1to2(SDL_BlitInfo *info) | |
80 { | |
81 #ifndef USE_DUFFS_LOOP | |
82 int c; | |
83 #endif | |
84 int width, height; | |
85 Uint8 *src, *dst; | |
86 Uint16 *map; | |
87 int srcskip, dstskip; | |
88 | |
89 /* Set up some basic variables */ | |
90 width = info->d_width; | |
91 height = info->d_height; | |
92 src = info->s_pixels; | |
93 srcskip = info->s_skip; | |
94 dst = info->d_pixels; | |
95 dstskip = info->d_skip; | |
96 map = (Uint16 *)info->table; | |
97 | |
98 #ifdef USE_DUFFS_LOOP | |
99 while ( height-- ) { | |
100 DUFFS_LOOP( | |
101 { | |
102 *(Uint16 *)dst = map[*src++]; | |
103 dst += 2; | |
104 }, | |
105 width); | |
106 src += srcskip; | |
107 dst += dstskip; | |
108 } | |
109 #else | |
110 /* Memory align at 4-byte boundary, if necessary */ | |
111 if ( (long)dst & 0x03 ) { | |
112 /* Don't do anything if width is 0 */ | |
113 if ( width == 0 ) { | |
114 return; | |
115 } | |
116 --width; | |
117 | |
118 while ( height-- ) { | |
119 /* Perform copy alignment */ | |
120 *(Uint16 *)dst = map[*src++]; | |
121 dst += 2; | |
122 | |
123 /* Copy in 4 pixel chunks */ | |
124 for ( c=width/4; c; --c ) { | |
125 *(Uint32 *)dst = | |
126 (map[src[HI]]<<16)|(map[src[LO]]); | |
127 src += 2; | |
128 dst += 4; | |
129 *(Uint32 *)dst = | |
130 (map[src[HI]]<<16)|(map[src[LO]]); | |
131 src += 2; | |
132 dst += 4; | |
133 } | |
134 /* Get any leftovers */ | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
135 switch (width & 3) { |
0 | 136 case 3: |
137 *(Uint16 *)dst = map[*src++]; | |
138 dst += 2; | |
139 case 2: | |
140 *(Uint32 *)dst = | |
141 (map[src[HI]]<<16)|(map[src[LO]]); | |
142 src += 2; | |
143 dst += 4; | |
144 break; | |
145 case 1: | |
146 *(Uint16 *)dst = map[*src++]; | |
147 dst += 2; | |
148 break; | |
149 } | |
150 src += srcskip; | |
151 dst += dstskip; | |
152 } | |
153 } else { | |
154 while ( height-- ) { | |
155 /* Copy in 4 pixel chunks */ | |
156 for ( c=width/4; c; --c ) { | |
157 *(Uint32 *)dst = | |
158 (map[src[HI]]<<16)|(map[src[LO]]); | |
159 src += 2; | |
160 dst += 4; | |
161 *(Uint32 *)dst = | |
162 (map[src[HI]]<<16)|(map[src[LO]]); | |
163 src += 2; | |
164 dst += 4; | |
165 } | |
166 /* Get any leftovers */ | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
167 switch (width & 3) { |
0 | 168 case 3: |
169 *(Uint16 *)dst = map[*src++]; | |
170 dst += 2; | |
171 case 2: | |
172 *(Uint32 *)dst = | |
173 (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 static void Blit1to3(SDL_BlitInfo *info) | |
189 { | |
190 #ifndef USE_DUFFS_LOOP | |
191 int c; | |
192 #endif | |
193 int o; | |
194 int width, height; | |
195 Uint8 *src, *map, *dst; | |
196 int srcskip, dstskip; | |
197 | |
198 /* Set up some basic variables */ | |
199 width = info->d_width; | |
200 height = info->d_height; | |
201 src = info->s_pixels; | |
202 srcskip = info->s_skip; | |
203 dst = info->d_pixels; | |
204 dstskip = info->d_skip; | |
205 map = info->table; | |
206 | |
207 while ( height-- ) { | |
208 #ifdef USE_DUFFS_LOOP | |
209 DUFFS_LOOP( | |
210 { | |
211 o = *src * 4; | |
212 dst[0] = map[o++]; | |
213 dst[1] = map[o++]; | |
214 dst[2] = map[o++]; | |
215 } | |
216 src++; | |
217 dst += 3; | |
218 , width); | |
219 #else | |
220 for ( c=width; c; --c ) { | |
221 o = *src * 4; | |
222 dst[0] = map[o++]; | |
223 dst[1] = map[o++]; | |
224 dst[2] = map[o++]; | |
225 src++; | |
226 dst += 3; | |
227 } | |
228 #endif /* USE_DUFFS_LOOP */ | |
229 src += srcskip; | |
230 dst += dstskip; | |
231 } | |
232 } | |
233 static void Blit1to4(SDL_BlitInfo *info) | |
234 { | |
235 #ifndef USE_DUFFS_LOOP | |
236 int c; | |
237 #endif | |
238 int width, height; | |
239 Uint8 *src; | |
240 Uint32 *map, *dst; | |
241 int srcskip, dstskip; | |
242 | |
243 /* Set up some basic variables */ | |
244 width = info->d_width; | |
245 height = info->d_height; | |
246 src = info->s_pixels; | |
247 srcskip = info->s_skip; | |
248 dst = (Uint32 *)info->d_pixels; | |
249 dstskip = info->d_skip/4; | |
250 map = (Uint32 *)info->table; | |
251 | |
252 while ( height-- ) { | |
253 #ifdef USE_DUFFS_LOOP | |
254 DUFFS_LOOP( | |
255 *dst++ = map[*src++]; | |
256 , width); | |
257 #else | |
258 for ( c=width/4; c; --c ) { | |
259 *dst++ = map[*src++]; | |
260 *dst++ = map[*src++]; | |
261 *dst++ = map[*src++]; | |
262 *dst++ = map[*src++]; | |
263 } | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
264 switch ( width & 3 ) { |
0 | 265 case 3: |
266 *dst++ = map[*src++]; | |
267 case 2: | |
268 *dst++ = map[*src++]; | |
269 case 1: | |
270 *dst++ = map[*src++]; | |
271 } | |
272 #endif /* USE_DUFFS_LOOP */ | |
273 src += srcskip; | |
274 dst += dstskip; | |
275 } | |
276 } | |
277 | |
278 static void Blit1to1Key(SDL_BlitInfo *info) | |
279 { | |
280 int width = info->d_width; | |
281 int height = info->d_height; | |
282 Uint8 *src = info->s_pixels; | |
283 int srcskip = info->s_skip; | |
284 Uint8 *dst = info->d_pixels; | |
285 int dstskip = info->d_skip; | |
286 Uint8 *palmap = info->table; | |
287 Uint32 ckey = info->src->colorkey; | |
288 | |
289 if ( palmap ) { | |
290 while ( height-- ) { | |
291 DUFFS_LOOP( | |
292 { | |
293 if ( *src != ckey ) { | |
294 *dst = palmap[*src]; | |
295 } | |
296 dst++; | |
297 src++; | |
298 }, | |
299 width); | |
300 src += srcskip; | |
301 dst += dstskip; | |
302 } | |
303 } else { | |
304 while ( height-- ) { | |
305 DUFFS_LOOP( | |
306 { | |
307 if ( *src != ckey ) { | |
308 *dst = *src; | |
309 } | |
310 dst++; | |
311 src++; | |
312 }, | |
313 width); | |
314 src += srcskip; | |
315 dst += dstskip; | |
316 } | |
317 } | |
318 } | |
319 | |
320 static void Blit1to2Key(SDL_BlitInfo *info) | |
321 { | |
322 int width = info->d_width; | |
323 int height = info->d_height; | |
324 Uint8 *src = info->s_pixels; | |
325 int srcskip = info->s_skip; | |
326 Uint16 *dstp = (Uint16 *)info->d_pixels; | |
327 int dstskip = info->d_skip; | |
328 Uint16 *palmap = (Uint16 *)info->table; | |
329 Uint32 ckey = info->src->colorkey; | |
330 | |
331 /* Set up some basic variables */ | |
332 dstskip /= 2; | |
333 | |
334 while ( height-- ) { | |
335 DUFFS_LOOP( | |
336 { | |
337 if ( *src != ckey ) { | |
338 *dstp=palmap[*src]; | |
339 } | |
340 src++; | |
341 dstp++; | |
342 }, | |
343 width); | |
344 src += srcskip; | |
345 dstp += dstskip; | |
346 } | |
347 } | |
348 | |
349 static void Blit1to3Key(SDL_BlitInfo *info) | |
350 { | |
351 int width = info->d_width; | |
352 int height = info->d_height; | |
353 Uint8 *src = info->s_pixels; | |
354 int srcskip = info->s_skip; | |
355 Uint8 *dst = info->d_pixels; | |
356 int dstskip = info->d_skip; | |
357 Uint8 *palmap = info->table; | |
358 Uint32 ckey = info->src->colorkey; | |
359 int o; | |
360 | |
361 while ( height-- ) { | |
362 DUFFS_LOOP( | |
363 { | |
364 if ( *src != ckey ) { | |
365 o = *src * 4; | |
366 dst[0] = palmap[o++]; | |
367 dst[1] = palmap[o++]; | |
368 dst[2] = palmap[o++]; | |
369 } | |
370 src++; | |
371 dst += 3; | |
372 }, | |
373 width); | |
374 src += srcskip; | |
375 dst += dstskip; | |
376 } | |
377 } | |
378 | |
379 static void Blit1to4Key(SDL_BlitInfo *info) | |
380 { | |
381 int width = info->d_width; | |
382 int height = info->d_height; | |
383 Uint8 *src = info->s_pixels; | |
384 int srcskip = info->s_skip; | |
385 Uint32 *dstp = (Uint32 *)info->d_pixels; | |
386 int dstskip = info->d_skip; | |
387 Uint32 *palmap = (Uint32 *)info->table; | |
388 Uint32 ckey = info->src->colorkey; | |
389 | |
390 /* Set up some basic variables */ | |
391 dstskip /= 4; | |
392 | |
393 while ( height-- ) { | |
394 DUFFS_LOOP( | |
395 { | |
396 if ( *src != ckey ) { | |
397 *dstp = palmap[*src]; | |
398 } | |
399 src++; | |
400 dstp++; | |
401 }, | |
402 width); | |
403 src += srcskip; | |
404 dstp += dstskip; | |
405 } | |
406 } | |
407 | |
408 static void Blit1toNAlpha(SDL_BlitInfo *info) | |
409 { | |
410 int width = info->d_width; | |
411 int height = info->d_height; | |
412 Uint8 *src = info->s_pixels; | |
413 int srcskip = info->s_skip; | |
414 Uint8 *dst = info->d_pixels; | |
415 int dstskip = info->d_skip; | |
416 SDL_PixelFormat *dstfmt = info->dst; | |
417 const SDL_Color *srcpal = info->src->palette->colors; | |
418 int dstbpp; | |
419 const int A = info->src->alpha; | |
420 | |
421 /* Set up some basic variables */ | |
422 dstbpp = dstfmt->BytesPerPixel; | |
423 | |
424 while ( height-- ) { | |
425 int sR, sG, sB; | |
426 int dR, dG, dB; | |
427 DUFFS_LOOP4( | |
428 { | |
429 Uint32 pixel; | |
430 sR = srcpal[*src].r; | |
431 sG = srcpal[*src].g; | |
432 sB = srcpal[*src].b; | |
433 DISEMBLE_RGB(dst, dstbpp, dstfmt, | |
434 pixel, dR, dG, dB); | |
435 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); | |
436 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); | |
437 src++; | |
438 dst += dstbpp; | |
439 }, | |
440 width); | |
441 src += srcskip; | |
442 dst += dstskip; | |
443 } | |
444 } | |
445 | |
446 static void Blit1toNAlphaKey(SDL_BlitInfo *info) | |
447 { | |
448 int width = info->d_width; | |
449 int height = info->d_height; | |
450 Uint8 *src = info->s_pixels; | |
451 int srcskip = info->s_skip; | |
452 Uint8 *dst = info->d_pixels; | |
453 int dstskip = info->d_skip; | |
454 SDL_PixelFormat *srcfmt = info->src; | |
455 SDL_PixelFormat *dstfmt = info->dst; | |
456 const SDL_Color *srcpal = info->src->palette->colors; | |
457 Uint32 ckey = srcfmt->colorkey; | |
458 int dstbpp; | |
459 const int A = srcfmt->alpha; | |
460 | |
461 /* Set up some basic variables */ | |
462 dstbpp = dstfmt->BytesPerPixel; | |
463 | |
464 while ( height-- ) { | |
465 int sR, sG, sB; | |
466 int dR, dG, dB; | |
467 DUFFS_LOOP( | |
468 { | |
469 if ( *src != ckey ) { | |
470 Uint32 pixel; | |
471 sR = srcpal[*src].r; | |
472 sG = srcpal[*src].g; | |
473 sB = srcpal[*src].b; | |
474 DISEMBLE_RGB(dst, dstbpp, dstfmt, | |
475 pixel, dR, dG, dB); | |
476 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); | |
477 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); | |
478 } | |
479 src++; | |
480 dst += dstbpp; | |
481 }, | |
482 width); | |
483 src += srcskip; | |
484 dst += dstskip; | |
485 } | |
486 } | |
487 | |
488 static SDL_loblit one_blit[] = { | |
489 NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4 | |
490 }; | |
491 | |
492 static SDL_loblit one_blitkey[] = { | |
493 NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key | |
494 }; | |
495 | |
496 SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index) | |
497 { | |
498 int which; | |
499 SDL_PixelFormat *dstfmt; | |
500 | |
501 dstfmt = surface->map->dst->format; | |
502 if ( dstfmt->BitsPerPixel < 8 ) { | |
503 which = 0; | |
504 } else { | |
505 which = dstfmt->BytesPerPixel; | |
506 } | |
507 switch(blit_index) { | |
508 case 0: /* copy */ | |
509 return one_blit[which]; | |
510 | |
511 case 1: /* colorkey */ | |
512 return one_blitkey[which]; | |
513 | |
514 case 2: /* alpha */ | |
515 /* Supporting 8bpp->8bpp alpha is doable but requires lots of | |
516 tables which consume space and takes time to precompute, | |
517 so is better left to the user */ | |
518 return which >= 2 ? Blit1toNAlpha : NULL; | |
519 | |
520 case 3: /* alpha + colorkey */ | |
521 return which >= 2 ? Blit1toNAlphaKey : NULL; | |
522 | |
523 } | |
524 return NULL; | |
525 } |