SDL-1.2.14
[sdl_omap.git] / src / video / SDL_blit_0.c
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 Sam Lantinga
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
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
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #include "SDL_video.h"
25 #include "SDL_blit.h"
26
27 /* Functions to blit from bitmaps to other surfaces */
28
29 static void 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->d_width;
38         height = info->d_height;
39         src = info->s_pixels;
40         srcskip = info->s_skip;
41         dst = info->d_pixels;
42         dstskip = info->d_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 static void BlitBto2(SDL_BlitInfo *info)
83 {
84         int c;
85         int width, height;
86         Uint8 *src;
87         Uint16 *map, *dst;
88         int srcskip, dstskip;
89
90         /* Set up some basic variables */
91         width = info->d_width;
92         height = info->d_height;
93         src = info->s_pixels;
94         srcskip = info->s_skip;
95         dst = (Uint16 *)info->d_pixels;
96         dstskip = info->d_skip/2;
97         map = (Uint16 *)info->table;
98         srcskip += width-(width+7)/8;
99
100         while ( height-- ) {
101                 Uint8 byte = 0, bit;
102                 for ( c=0; c<width; ++c ) {
103                         if ( (c&7) == 0 ) {
104                                 byte = *src++;
105                         }
106                         bit = (byte&0x80)>>7;
107                         if ( 1 ) {
108                                 *dst = map[bit];
109                         }
110                         byte <<= 1;
111                         dst++;
112                 }
113                 src += srcskip;
114                 dst += dstskip;
115         }
116 }
117 static void BlitBto3(SDL_BlitInfo *info)
118 {
119         int c, o;
120         int width, height;
121         Uint8 *src, *map, *dst;
122         int srcskip, dstskip;
123
124         /* Set up some basic variables */
125         width = info->d_width;
126         height = info->d_height;
127         src = info->s_pixels;
128         srcskip = info->s_skip;
129         dst = info->d_pixels;
130         dstskip = info->d_skip;
131         map = info->table;
132         srcskip += width-(width+7)/8;
133
134         while ( height-- ) {
135                 Uint8 byte = 0, bit;
136                 for ( c=0; c<width; ++c ) {
137                         if ( (c&7) == 0 ) {
138                                 byte = *src++;
139                         }
140                         bit = (byte&0x80)>>7;
141                         if ( 1 ) {
142                                 o = bit * 4;
143                                 dst[0] = map[o++];
144                                 dst[1] = map[o++];
145                                 dst[2] = map[o++];
146                         }
147                         byte <<= 1;
148                         dst += 3;
149                 }
150                 src += srcskip;
151                 dst += dstskip;
152         }
153 }
154 static void BlitBto4(SDL_BlitInfo *info)
155 {
156         int width, height;
157         Uint8 *src;
158         Uint32 *map, *dst;
159         int srcskip, dstskip;
160         int c;
161
162         /* Set up some basic variables */
163         width = info->d_width;
164         height = info->d_height;
165         src = info->s_pixels;
166         srcskip = info->s_skip;
167         dst = (Uint32 *)info->d_pixels;
168         dstskip = info->d_skip/4;
169         map = (Uint32 *)info->table;
170         srcskip += width-(width+7)/8;
171
172         while ( height-- ) {
173                 Uint8 byte = 0, bit;
174                 for ( c=0; c<width; ++c ) {
175                         if ( (c&7) == 0 ) {
176                                 byte = *src++;
177                         }
178                         bit = (byte&0x80)>>7;
179                         if ( 1 ) {
180                                 *dst = map[bit];
181                         }
182                         byte <<= 1;
183                         dst++;
184                 }
185                 src += srcskip;
186                 dst += dstskip;
187         }
188 }
189
190 static void BlitBto1Key(SDL_BlitInfo *info)
191 {
192         int width = info->d_width;
193         int height = info->d_height;
194         Uint8 *src = info->s_pixels;
195         Uint8 *dst = info->d_pixels;
196         int srcskip = info->s_skip;
197         int dstskip = info->d_skip;
198         Uint32 ckey = info->src->colorkey;
199         Uint8 *palmap = info->table;
200         int c;
201
202         /* Set up some basic variables */
203         srcskip += width-(width+7)/8;
204
205         if ( palmap ) {
206                 while ( height-- ) {
207                         Uint8  byte = 0, bit;
208                         for ( c=0; c<width; ++c ) {
209                                 if ( (c&7) == 0 ) {
210                                         byte = *src++;
211                                 }
212                                 bit = (byte&0x80)>>7;
213                                 if ( bit != ckey ) {
214                                   *dst = palmap[bit];
215                                 }
216                                 dst++;
217                                 byte <<= 1;
218                         }
219                         src += srcskip;
220                         dst += dstskip;
221                 }
222         } else {
223                 while ( height-- ) {
224                         Uint8  byte = 0, bit;
225                         for ( c=0; c<width; ++c ) {
226                                 if ( (c&7) == 0 ) {
227                                         byte = *src++;
228                                 }
229                                 bit = (byte&0x80)>>7;
230                                 if ( bit != ckey ) {
231                                   *dst = bit;
232                                 }
233                                 dst++;
234                                 byte <<= 1;
235                         }
236                         src += srcskip;
237                         dst += dstskip;
238                 }
239         }
240 }
241
242 static void BlitBto2Key(SDL_BlitInfo *info)
243 {
244         int width = info->d_width;
245         int height = info->d_height;
246         Uint8 *src = info->s_pixels;
247         Uint16 *dstp = (Uint16 *)info->d_pixels;
248         int srcskip = info->s_skip;
249         int dstskip = info->d_skip;
250         Uint32 ckey = info->src->colorkey;
251         Uint8 *palmap = info->table;
252         int c;
253
254         /* Set up some basic variables */
255         srcskip += width-(width+7)/8;
256         dstskip /= 2;
257
258         while ( height-- ) {
259                 Uint8 byte = 0, bit;
260                 for ( c=0; c<width; ++c ) {
261                         if ( (c&7) == 0 ) {
262                                 byte = *src++;
263                         }
264                         bit = (byte&0x80)>>7;
265                         if ( bit != ckey ) {
266                                 *dstp=((Uint16 *)palmap)[bit];
267                         }
268                         byte <<= 1;
269                         dstp++;
270                 }
271                 src += srcskip;
272                 dstp += dstskip;
273         }
274 }
275
276 static void BlitBto3Key(SDL_BlitInfo *info)
277 {
278         int width = info->d_width;
279         int height = info->d_height;
280         Uint8 *src = info->s_pixels;
281         Uint8 *dst = info->d_pixels;
282         int srcskip = info->s_skip;
283         int dstskip = info->d_skip;
284         Uint32 ckey = info->src->colorkey;
285         Uint8 *palmap = info->table;
286         int c;
287
288         /* Set up some basic variables */
289         srcskip += width-(width+7)/8;
290
291         while ( height-- ) {
292                 Uint8  byte = 0, bit;
293                 for ( c=0; c<width; ++c ) {
294                         if ( (c&7) == 0 ) {
295                                 byte = *src++;
296                         }
297                         bit = (byte&0x80)>>7;
298                         if ( bit != ckey ) {
299                                 SDL_memcpy(dst, &palmap[bit*4], 3);
300                         }
301                         byte <<= 1;
302                         dst += 3;
303                 }
304                 src += srcskip;
305                 dst += dstskip;
306         }
307 }
308
309 static void BlitBto4Key(SDL_BlitInfo *info)
310 {
311         int width = info->d_width;
312         int height = info->d_height;
313         Uint8 *src = info->s_pixels;
314         Uint32 *dstp = (Uint32 *)info->d_pixels;
315         int srcskip = info->s_skip;
316         int dstskip = info->d_skip;
317         Uint32 ckey = info->src->colorkey;
318         Uint8 *palmap = info->table;
319         int c;
320
321         /* Set up some basic variables */
322         srcskip += width-(width+7)/8;
323         dstskip /= 4;
324
325         while ( height-- ) {
326                 Uint8 byte = 0, bit;
327                 for ( c=0; c<width; ++c ) {
328                         if ( (c&7) == 0 ) {
329                                 byte = *src++;
330                         }
331                         bit = (byte&0x80)>>7;
332                         if ( bit != ckey ) {
333                                 *dstp=((Uint32 *)palmap)[bit];
334                         }
335                         byte <<= 1;
336                         dstp++;
337                 }
338                 src += srcskip;
339                 dstp += dstskip;
340         }
341 }
342
343 static void BlitBtoNAlpha(SDL_BlitInfo *info)
344 {
345         int width = info->d_width;
346         int height = info->d_height;
347         Uint8 *src = info->s_pixels;
348         Uint8 *dst = info->d_pixels;
349         int srcskip = info->s_skip;
350         int dstskip = info->d_skip;
351         const SDL_Color *srcpal = info->src->palette->colors;
352         SDL_PixelFormat *dstfmt = info->dst;
353         int  dstbpp;
354         int c;
355         const int A = info->src->alpha;
356
357         /* Set up some basic variables */
358         dstbpp = dstfmt->BytesPerPixel;
359         srcskip += width-(width+7)/8;
360
361         while ( height-- ) {
362                 Uint8 byte = 0, bit;
363                 for ( c=0; c<width; ++c ) {
364                         if ( (c&7) == 0 ) {
365                                 byte = *src++;
366                         }
367                         bit = (byte&0x80)>>7;
368                         if ( 1 ) {
369                                 Uint32 pixel;
370                                 unsigned sR, sG, sB;
371                                 unsigned dR, dG, dB;
372                                 sR = srcpal[bit].r;
373                                 sG = srcpal[bit].g;
374                                 sB = srcpal[bit].b;
375                                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
376                                                         pixel, dR, dG, dB);
377                                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
378                                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
379                         }
380                         byte <<= 1;
381                         dst += dstbpp;
382                 }
383                 src += srcskip;
384                 dst += dstskip;
385         }
386 }
387
388 static void BlitBtoNAlphaKey(SDL_BlitInfo *info)
389 {
390         int width = info->d_width;
391         int height = info->d_height;
392         Uint8 *src = info->s_pixels;
393         Uint8 *dst = info->d_pixels;
394         int srcskip = info->s_skip;
395         int dstskip = info->d_skip;
396         SDL_PixelFormat *srcfmt = info->src;
397         SDL_PixelFormat *dstfmt = info->dst;
398         const SDL_Color *srcpal = srcfmt->palette->colors;
399         int dstbpp;
400         int c;
401         const int A = srcfmt->alpha;
402         Uint32 ckey = srcfmt->colorkey;
403
404         /* Set up some basic variables */
405         dstbpp = dstfmt->BytesPerPixel;
406         srcskip += width-(width+7)/8;
407
408         while ( height-- ) {
409                 Uint8  byte = 0, bit;
410                 for ( c=0; c<width; ++c ) {
411                         if ( (c&7) == 0 ) {
412                                 byte = *src++;
413                         }
414                         bit = (byte&0x80)>>7;
415                         if ( bit != ckey ) {
416                                 int sR, sG, sB;
417                                 int dR, dG, dB;
418                                 Uint32 pixel;
419                                 sR = srcpal[bit].r;
420                                 sG = srcpal[bit].g;
421                                 sB = srcpal[bit].b;
422                                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
423                                                         pixel, dR, dG, dB);
424                                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
425                                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
426                         }
427                         byte <<= 1;
428                         dst += dstbpp;
429                 }
430                 src += srcskip;
431                 dst += dstskip;
432         }
433 }
434
435 static SDL_loblit bitmap_blit[] = {
436         NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
437 };
438
439 static SDL_loblit colorkey_blit[] = {
440     NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
441 };
442
443 SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int blit_index)
444 {
445         int which;
446
447         if ( surface->format->BitsPerPixel != 1 ) {
448                 /* We don't support sub 8-bit packed pixel modes */
449                 return NULL;
450         }
451         if ( surface->map->dst->format->BitsPerPixel < 8 ) {
452                 which = 0;
453         } else {
454                 which = surface->map->dst->format->BytesPerPixel;
455         }
456         switch(blit_index) {
457         case 0:                 /* copy */
458             return bitmap_blit[which];
459
460         case 1:                 /* colorkey */
461             return colorkey_blit[which];
462
463         case 2:                 /* alpha */
464             return which >= 2 ? BlitBtoNAlpha : NULL;
465
466         case 4:                 /* alpha + colorkey */
467             return which >= 2 ? BlitBtoNAlphaKey : NULL;
468         }
469         return NULL;
470 }
471