SDL  2.0
SDL_blit_N.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2019 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_endian.h"
25 #include "SDL_cpuinfo.h"
26 #include "SDL_blit.h"
27 
28 #include "SDL_assert.h"
29 
30 /* General optimized routines that write char by char */
31 #define HAVE_FAST_WRITE_INT8 1
32 
33 /* On some CPU, it's slower than combining and write a word */
34 #if defined(__MIPS__)
35 # undef HAVE_FAST_WRITE_INT8
36 # define HAVE_FAST_WRITE_INT8 0
37 #endif
38 
39 /* Functions to blit from N-bit surfaces to other surfaces */
40 
41 #if SDL_ALTIVEC_BLITTERS
42 #ifdef HAVE_ALTIVEC_H
43 #include <altivec.h>
44 #endif
45 #ifdef __MACOSX__
46 #include <sys/sysctl.h>
47 static size_t
48 GetL3CacheSize(void)
49 {
50  const char key[] = "hw.l3cachesize";
51  u_int64_t result = 0;
52  size_t typeSize = sizeof(result);
53 
54 
55  int err = sysctlbyname(key, &result, &typeSize, NULL, 0);
56  if (0 != err)
57  return 0;
58 
59  return result;
60 }
61 #else
62 static size_t
63 GetL3CacheSize(void)
64 {
65  /* XXX: Just guess G4 */
66  return 2097152;
67 }
68 #endif /* __MACOSX__ */
69 
70 #if (defined(__MACOSX__) && (__GNUC__ < 4))
71 #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
72  (vector unsigned char) ( a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p )
73 #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
74  (vector unsigned short) ( a,b,c,d,e,f,g,h )
75 #else
76 #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
77  (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p }
78 #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
79  (vector unsigned short) { a,b,c,d,e,f,g,h }
80 #endif
81 
82 #define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F)
83 #define VSWIZZLE32(a,b,c,d) (vector unsigned char) \
84  ( 0x00+a, 0x00+b, 0x00+c, 0x00+d, \
85  0x04+a, 0x04+b, 0x04+c, 0x04+d, \
86  0x08+a, 0x08+b, 0x08+c, 0x08+d, \
87  0x0C+a, 0x0C+b, 0x0C+c, 0x0C+d )
88 
89 #define MAKE8888(dstfmt, r, g, b, a) \
90  ( ((r<<dstfmt->Rshift)&dstfmt->Rmask) | \
91  ((g<<dstfmt->Gshift)&dstfmt->Gmask) | \
92  ((b<<dstfmt->Bshift)&dstfmt->Bmask) | \
93  ((a<<dstfmt->Ashift)&dstfmt->Amask) )
94 
95 /*
96  * Data Stream Touch...Altivec cache prefetching.
97  *
98  * Don't use this on a G5...however, the speed boost is very significant
99  * on a G4.
100  */
101 #define DST_CHAN_SRC 1
102 #define DST_CHAN_DEST 2
103 
104 /* macro to set DST control word value... */
105 #define DST_CTRL(size, count, stride) \
106  (((size) << 24) | ((count) << 16) | (stride))
107 
108 #define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \
109  ? vec_lvsl(0, src) \
110  : vec_add(vec_lvsl(8, src), vec_splat_u8(8)))
111 
112 /* Calculate the permute vector used for 32->32 swizzling */
113 static vector unsigned char
114 calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt)
115 {
116  /*
117  * We have to assume that the bits that aren't used by other
118  * colors is alpha, and it's one complete byte, since some formats
119  * leave alpha with a zero mask, but we should still swizzle the bits.
120  */
121  /* ARGB */
122  const static const struct SDL_PixelFormat default_pixel_format = {
123  0, NULL, 0, 0,
124  {0, 0},
125  0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
126  0, 0, 0, 0,
127  16, 8, 0, 24,
128  0, NULL
129  };
130  const vector unsigned char plus = VECUINT8_LITERAL(0x00, 0x00, 0x00, 0x00,
131  0x04, 0x04, 0x04, 0x04,
132  0x08, 0x08, 0x08, 0x08,
133  0x0C, 0x0C, 0x0C,
134  0x0C);
135  vector unsigned char vswiz;
136  vector unsigned int srcvec;
137  Uint32 rmask, gmask, bmask, amask;
138 
139  if (!srcfmt) {
140  srcfmt = &default_pixel_format;
141  }
142  if (!dstfmt) {
143  dstfmt = &default_pixel_format;
144  }
145 
146 #define RESHIFT(X) (3 - ((X) >> 3))
147  rmask = RESHIFT(srcfmt->Rshift) << (dstfmt->Rshift);
148  gmask = RESHIFT(srcfmt->Gshift) << (dstfmt->Gshift);
149  bmask = RESHIFT(srcfmt->Bshift) << (dstfmt->Bshift);
150 
151  /* Use zero for alpha if either surface doesn't have alpha */
152  if (dstfmt->Amask) {
153  amask =
154  ((srcfmt->Amask) ? RESHIFT(srcfmt->
155  Ashift) : 0x10) << (dstfmt->Ashift);
156  } else {
157  amask =
158  0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^
159  0xFFFFFFFF);
160  }
161 #undef RESHIFT
162 
163  ((unsigned int *) (char *) &srcvec)[0] = (rmask | gmask | bmask | amask);
164  vswiz = vec_add(plus, (vector unsigned char) vec_splat(srcvec, 0));
165  return (vswiz);
166 }
167 
168 static void Blit_RGB888_RGB565(SDL_BlitInfo * info);
169 static void
170 Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info)
171 {
172  int height = info->dst_h;
173  Uint8 *src = (Uint8 *) info->src;
174  int srcskip = info->src_skip;
175  Uint8 *dst = (Uint8 *) info->dst;
176  int dstskip = info->dst_skip;
177  SDL_PixelFormat *srcfmt = info->src_fmt;
178  vector unsigned char valpha = vec_splat_u8(0);
179  vector unsigned char vpermute = calc_swizzle32(srcfmt, NULL);
180  vector unsigned char vgmerge = VECUINT8_LITERAL(0x00, 0x02, 0x00, 0x06,
181  0x00, 0x0a, 0x00, 0x0e,
182  0x00, 0x12, 0x00, 0x16,
183  0x00, 0x1a, 0x00, 0x1e);
184  vector unsigned short v1 = vec_splat_u16(1);
185  vector unsigned short v3 = vec_splat_u16(3);
186  vector unsigned short v3f =
187  VECUINT16_LITERAL(0x003f, 0x003f, 0x003f, 0x003f,
188  0x003f, 0x003f, 0x003f, 0x003f);
189  vector unsigned short vfc =
190  VECUINT16_LITERAL(0x00fc, 0x00fc, 0x00fc, 0x00fc,
191  0x00fc, 0x00fc, 0x00fc, 0x00fc);
192  vector unsigned short vf800 = (vector unsigned short) vec_splat_u8(-7);
193  vf800 = vec_sl(vf800, vec_splat_u16(8));
194 
195  while (height--) {
196  vector unsigned char valigner;
197  vector unsigned char voverflow;
198  vector unsigned char vsrc;
199 
200  int width = info->dst_w;
201  int extrawidth;
202 
203  /* do scalar until we can align... */
204 #define ONE_PIXEL_BLEND(condition, widthvar) \
205  while (condition) { \
206  Uint32 Pixel; \
207  unsigned sR, sG, sB, sA; \
208  DISEMBLE_RGBA((Uint8 *)src, 4, srcfmt, Pixel, \
209  sR, sG, sB, sA); \
210  *(Uint16 *)(dst) = (((sR << 8) & 0x0000F800) | \
211  ((sG << 3) & 0x000007E0) | \
212  ((sB >> 3) & 0x0000001F)); \
213  dst += 2; \
214  src += 4; \
215  widthvar--; \
216  }
217 
218  ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
219 
220  /* After all that work, here's the vector part! */
221  extrawidth = (width % 8); /* trailing unaligned stores */
222  width -= extrawidth;
223  vsrc = vec_ld(0, src);
224  valigner = VEC_ALIGNER(src);
225 
226  while (width) {
227  vector unsigned short vpixel, vrpixel, vgpixel, vbpixel;
228  vector unsigned int vsrc1, vsrc2;
229  vector unsigned char vdst;
230 
231  voverflow = vec_ld(15, src);
232  vsrc = vec_perm(vsrc, voverflow, valigner);
233  vsrc1 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
234  src += 16;
235  vsrc = voverflow;
236  voverflow = vec_ld(15, src);
237  vsrc = vec_perm(vsrc, voverflow, valigner);
238  vsrc2 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
239  /* 1555 */
240  vpixel = (vector unsigned short) vec_packpx(vsrc1, vsrc2);
241  vgpixel = (vector unsigned short) vec_perm(vsrc1, vsrc2, vgmerge);
242  vgpixel = vec_and(vgpixel, vfc);
243  vgpixel = vec_sl(vgpixel, v3);
244  vrpixel = vec_sl(vpixel, v1);
245  vrpixel = vec_and(vrpixel, vf800);
246  vbpixel = vec_and(vpixel, v3f);
247  vdst =
248  vec_or((vector unsigned char) vrpixel,
249  (vector unsigned char) vgpixel);
250  /* 565 */
251  vdst = vec_or(vdst, (vector unsigned char) vbpixel);
252  vec_st(vdst, 0, dst);
253 
254  width -= 8;
255  src += 16;
256  dst += 16;
257  vsrc = voverflow;
258  }
259 
260  SDL_assert(width == 0);
261 
262  /* do scalar until we can align... */
263  ONE_PIXEL_BLEND((extrawidth), extrawidth);
264 #undef ONE_PIXEL_BLEND
265 
266  src += srcskip; /* move to next row, accounting for pitch. */
267  dst += dstskip;
268  }
269 
270 
271 }
272 
273 static void
274 Blit_RGB565_32Altivec(SDL_BlitInfo * info)
275 {
276  int height = info->dst_h;
277  Uint8 *src = (Uint8 *) info->src;
278  int srcskip = info->src_skip;
279  Uint8 *dst = (Uint8 *) info->dst;
280  int dstskip = info->dst_skip;
281  SDL_PixelFormat *srcfmt = info->src_fmt;
282  SDL_PixelFormat *dstfmt = info->dst_fmt;
283  unsigned alpha;
284  vector unsigned char valpha;
285  vector unsigned char vpermute;
286  vector unsigned short vf800;
287  vector unsigned int v8 = vec_splat_u32(8);
288  vector unsigned int v16 = vec_add(v8, v8);
289  vector unsigned short v2 = vec_splat_u16(2);
290  vector unsigned short v3 = vec_splat_u16(3);
291  /*
292  0x10 - 0x1f is the alpha
293  0x00 - 0x0e evens are the red
294  0x01 - 0x0f odds are zero
295  */
296  vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
297  0x10, 0x02, 0x01, 0x01,
298  0x10, 0x04, 0x01, 0x01,
299  0x10, 0x06, 0x01,
300  0x01);
301  vector unsigned char vredalpha2 =
302  (vector unsigned
303  char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
304  );
305  /*
306  0x00 - 0x0f is ARxx ARxx ARxx ARxx
307  0x11 - 0x0f odds are blue
308  */
309  vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
310  0x04, 0x05, 0x06, 0x13,
311  0x08, 0x09, 0x0a, 0x15,
312  0x0c, 0x0d, 0x0e, 0x17);
313  vector unsigned char vblue2 =
314  (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
315  );
316  /*
317  0x00 - 0x0f is ARxB ARxB ARxB ARxB
318  0x10 - 0x0e evens are green
319  */
320  vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
321  0x04, 0x05, 0x12, 0x07,
322  0x08, 0x09, 0x14, 0x0b,
323  0x0c, 0x0d, 0x16, 0x0f);
324  vector unsigned char vgreen2 =
325  (vector unsigned
326  char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
327  );
328 
329  SDL_assert(srcfmt->BytesPerPixel == 2);
330  SDL_assert(dstfmt->BytesPerPixel == 4);
331 
332  vf800 = (vector unsigned short) vec_splat_u8(-7);
333  vf800 = vec_sl(vf800, vec_splat_u16(8));
334 
335  if (dstfmt->Amask && info->a) {
336  ((unsigned char *) &valpha)[0] = alpha = info->a;
337  valpha = vec_splat(valpha, 0);
338  } else {
339  alpha = 0;
340  valpha = vec_splat_u8(0);
341  }
342 
343  vpermute = calc_swizzle32(NULL, dstfmt);
344  while (height--) {
345  vector unsigned char valigner;
346  vector unsigned char voverflow;
347  vector unsigned char vsrc;
348 
349  int width = info->dst_w;
350  int extrawidth;
351 
352  /* do scalar until we can align... */
353 #define ONE_PIXEL_BLEND(condition, widthvar) \
354  while (condition) { \
355  unsigned sR, sG, sB; \
356  unsigned short Pixel = *((unsigned short *)src); \
357  sR = (Pixel >> 8) & 0xf8; \
358  sG = (Pixel >> 3) & 0xfc; \
359  sB = (Pixel << 3) & 0xf8; \
360  ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
361  src += 2; \
362  dst += 4; \
363  widthvar--; \
364  }
365  ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
366 
367  /* After all that work, here's the vector part! */
368  extrawidth = (width % 8); /* trailing unaligned stores */
369  width -= extrawidth;
370  vsrc = vec_ld(0, src);
371  valigner = VEC_ALIGNER(src);
372 
373  while (width) {
374  vector unsigned short vR, vG, vB;
375  vector unsigned char vdst1, vdst2;
376 
377  voverflow = vec_ld(15, src);
378  vsrc = vec_perm(vsrc, voverflow, valigner);
379 
380  vR = vec_and((vector unsigned short) vsrc, vf800);
381  vB = vec_sl((vector unsigned short) vsrc, v3);
382  vG = vec_sl(vB, v2);
383 
384  vdst1 =
385  (vector unsigned char) vec_perm((vector unsigned char) vR,
386  valpha, vredalpha1);
387  vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
388  vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
389  vdst1 = vec_perm(vdst1, valpha, vpermute);
390  vec_st(vdst1, 0, dst);
391 
392  vdst2 =
393  (vector unsigned char) vec_perm((vector unsigned char) vR,
394  valpha, vredalpha2);
395  vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
396  vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
397  vdst2 = vec_perm(vdst2, valpha, vpermute);
398  vec_st(vdst2, 16, dst);
399 
400  width -= 8;
401  dst += 32;
402  src += 16;
403  vsrc = voverflow;
404  }
405 
406  SDL_assert(width == 0);
407 
408 
409  /* do scalar until we can align... */
410  ONE_PIXEL_BLEND((extrawidth), extrawidth);
411 #undef ONE_PIXEL_BLEND
412 
413  src += srcskip; /* move to next row, accounting for pitch. */
414  dst += dstskip;
415  }
416 
417 }
418 
419 
420 static void
421 Blit_RGB555_32Altivec(SDL_BlitInfo * info)
422 {
423  int height = info->dst_h;
424  Uint8 *src = (Uint8 *) info->src;
425  int srcskip = info->src_skip;
426  Uint8 *dst = (Uint8 *) info->dst;
427  int dstskip = info->dst_skip;
428  SDL_PixelFormat *srcfmt = info->src_fmt;
429  SDL_PixelFormat *dstfmt = info->dst_fmt;
430  unsigned alpha;
431  vector unsigned char valpha;
432  vector unsigned char vpermute;
433  vector unsigned short vf800;
434  vector unsigned int v8 = vec_splat_u32(8);
435  vector unsigned int v16 = vec_add(v8, v8);
436  vector unsigned short v1 = vec_splat_u16(1);
437  vector unsigned short v3 = vec_splat_u16(3);
438  /*
439  0x10 - 0x1f is the alpha
440  0x00 - 0x0e evens are the red
441  0x01 - 0x0f odds are zero
442  */
443  vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
444  0x10, 0x02, 0x01, 0x01,
445  0x10, 0x04, 0x01, 0x01,
446  0x10, 0x06, 0x01,
447  0x01);
448  vector unsigned char vredalpha2 =
449  (vector unsigned
450  char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
451  );
452  /*
453  0x00 - 0x0f is ARxx ARxx ARxx ARxx
454  0x11 - 0x0f odds are blue
455  */
456  vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
457  0x04, 0x05, 0x06, 0x13,
458  0x08, 0x09, 0x0a, 0x15,
459  0x0c, 0x0d, 0x0e, 0x17);
460  vector unsigned char vblue2 =
461  (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
462  );
463  /*
464  0x00 - 0x0f is ARxB ARxB ARxB ARxB
465  0x10 - 0x0e evens are green
466  */
467  vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
468  0x04, 0x05, 0x12, 0x07,
469  0x08, 0x09, 0x14, 0x0b,
470  0x0c, 0x0d, 0x16, 0x0f);
471  vector unsigned char vgreen2 =
472  (vector unsigned
473  char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
474  );
475 
476  SDL_assert(srcfmt->BytesPerPixel == 2);
477  SDL_assert(dstfmt->BytesPerPixel == 4);
478 
479  vf800 = (vector unsigned short) vec_splat_u8(-7);
480  vf800 = vec_sl(vf800, vec_splat_u16(8));
481 
482  if (dstfmt->Amask && info->a) {
483  ((unsigned char *) &valpha)[0] = alpha = info->a;
484  valpha = vec_splat(valpha, 0);
485  } else {
486  alpha = 0;
487  valpha = vec_splat_u8(0);
488  }
489 
490  vpermute = calc_swizzle32(NULL, dstfmt);
491  while (height--) {
492  vector unsigned char valigner;
493  vector unsigned char voverflow;
494  vector unsigned char vsrc;
495 
496  int width = info->dst_w;
497  int extrawidth;
498 
499  /* do scalar until we can align... */
500 #define ONE_PIXEL_BLEND(condition, widthvar) \
501  while (condition) { \
502  unsigned sR, sG, sB; \
503  unsigned short Pixel = *((unsigned short *)src); \
504  sR = (Pixel >> 7) & 0xf8; \
505  sG = (Pixel >> 2) & 0xf8; \
506  sB = (Pixel << 3) & 0xf8; \
507  ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
508  src += 2; \
509  dst += 4; \
510  widthvar--; \
511  }
512  ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
513 
514  /* After all that work, here's the vector part! */
515  extrawidth = (width % 8); /* trailing unaligned stores */
516  width -= extrawidth;
517  vsrc = vec_ld(0, src);
518  valigner = VEC_ALIGNER(src);
519 
520  while (width) {
521  vector unsigned short vR, vG, vB;
522  vector unsigned char vdst1, vdst2;
523 
524  voverflow = vec_ld(15, src);
525  vsrc = vec_perm(vsrc, voverflow, valigner);
526 
527  vR = vec_and(vec_sl((vector unsigned short) vsrc, v1), vf800);
528  vB = vec_sl((vector unsigned short) vsrc, v3);
529  vG = vec_sl(vB, v3);
530 
531  vdst1 =
532  (vector unsigned char) vec_perm((vector unsigned char) vR,
533  valpha, vredalpha1);
534  vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
535  vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
536  vdst1 = vec_perm(vdst1, valpha, vpermute);
537  vec_st(vdst1, 0, dst);
538 
539  vdst2 =
540  (vector unsigned char) vec_perm((vector unsigned char) vR,
541  valpha, vredalpha2);
542  vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
543  vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
544  vdst2 = vec_perm(vdst2, valpha, vpermute);
545  vec_st(vdst2, 16, dst);
546 
547  width -= 8;
548  dst += 32;
549  src += 16;
550  vsrc = voverflow;
551  }
552 
553  SDL_assert(width == 0);
554 
555 
556  /* do scalar until we can align... */
557  ONE_PIXEL_BLEND((extrawidth), extrawidth);
558 #undef ONE_PIXEL_BLEND
559 
560  src += srcskip; /* move to next row, accounting for pitch. */
561  dst += dstskip;
562  }
563 
564 }
565 
566 static void BlitNtoNKey(SDL_BlitInfo * info);
567 static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info);
568 static void
569 Blit32to32KeyAltivec(SDL_BlitInfo * info)
570 {
571  int height = info->dst_h;
572  Uint32 *srcp = (Uint32 *) info->src;
573  int srcskip = info->src_skip / 4;
574  Uint32 *dstp = (Uint32 *) info->dst;
575  int dstskip = info->dst_skip / 4;
576  SDL_PixelFormat *srcfmt = info->src_fmt;
577  int srcbpp = srcfmt->BytesPerPixel;
578  SDL_PixelFormat *dstfmt = info->dst_fmt;
579  int dstbpp = dstfmt->BytesPerPixel;
580  int copy_alpha = (srcfmt->Amask && dstfmt->Amask);
581  unsigned alpha = dstfmt->Amask ? info->a : 0;
582  Uint32 rgbmask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
583  Uint32 ckey = info->colorkey;
584  vector unsigned int valpha;
585  vector unsigned char vpermute;
586  vector unsigned char vzero;
587  vector unsigned int vckey;
588  vector unsigned int vrgbmask;
589  vpermute = calc_swizzle32(srcfmt, dstfmt);
590  if (info->dst_w < 16) {
591  if (copy_alpha) {
592  BlitNtoNKeyCopyAlpha(info);
593  } else {
594  BlitNtoNKey(info);
595  }
596  return;
597  }
598  vzero = vec_splat_u8(0);
599  if (alpha) {
600  ((unsigned char *) &valpha)[0] = (unsigned char) alpha;
601  valpha =
602  (vector unsigned int) vec_splat((vector unsigned char) valpha, 0);
603  } else {
604  valpha = (vector unsigned int) vzero;
605  }
606  ckey &= rgbmask;
607  ((unsigned int *) (char *) &vckey)[0] = ckey;
608  vckey = vec_splat(vckey, 0);
609  ((unsigned int *) (char *) &vrgbmask)[0] = rgbmask;
610  vrgbmask = vec_splat(vrgbmask, 0);
611 
612  while (height--) {
613 #define ONE_PIXEL_BLEND(condition, widthvar) \
614  if (copy_alpha) { \
615  while (condition) { \
616  Uint32 Pixel; \
617  unsigned sR, sG, sB, sA; \
618  DISEMBLE_RGBA((Uint8 *)srcp, srcbpp, srcfmt, Pixel, \
619  sR, sG, sB, sA); \
620  if ( (Pixel & rgbmask) != ckey ) { \
621  ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
622  sR, sG, sB, sA); \
623  } \
624  dstp = (Uint32 *) (((Uint8 *) dstp) + dstbpp); \
625  srcp = (Uint32 *) (((Uint8 *) srcp) + srcbpp); \
626  widthvar--; \
627  } \
628  } else { \
629  while (condition) { \
630  Uint32 Pixel; \
631  unsigned sR, sG, sB; \
632  RETRIEVE_RGB_PIXEL((Uint8 *)srcp, srcbpp, Pixel); \
633  if ( Pixel != ckey ) { \
634  RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \
635  ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
636  sR, sG, sB, alpha); \
637  } \
638  dstp = (Uint32 *) (((Uint8 *)dstp) + dstbpp); \
639  srcp = (Uint32 *) (((Uint8 *)srcp) + srcbpp); \
640  widthvar--; \
641  } \
642  }
643  int width = info->dst_w;
644  ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
645  SDL_assert(width > 0);
646  if (width > 0) {
647  int extrawidth = (width % 4);
648  vector unsigned char valigner = VEC_ALIGNER(srcp);
649  vector unsigned int vs = vec_ld(0, srcp);
650  width -= extrawidth;
651  SDL_assert(width >= 4);
652  while (width) {
653  vector unsigned char vsel;
654  vector unsigned int vd;
655  vector unsigned int voverflow = vec_ld(15, srcp);
656  /* load the source vec */
657  vs = vec_perm(vs, voverflow, valigner);
658  /* vsel is set for items that match the key */
659  vsel = (vector unsigned char) vec_and(vs, vrgbmask);
660  vsel = (vector unsigned char) vec_cmpeq(vs, vckey);
661  /* permute the src vec to the dest format */
662  vs = vec_perm(vs, valpha, vpermute);
663  /* load the destination vec */
664  vd = vec_ld(0, dstp);
665  /* select the source and dest into vs */
666  vd = (vector unsigned int) vec_sel((vector unsigned char) vs,
667  (vector unsigned char) vd,
668  vsel);
669 
670  vec_st(vd, 0, dstp);
671  srcp += 4;
672  width -= 4;
673  dstp += 4;
674  vs = voverflow;
675  }
676  ONE_PIXEL_BLEND((extrawidth), extrawidth);
677 #undef ONE_PIXEL_BLEND
678  srcp += srcskip;
679  dstp += dstskip;
680  }
681  }
682 }
683 
684 /* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
685 /* Use this on a G5 */
686 static void
687 ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info)
688 {
689  int height = info->dst_h;
690  Uint32 *src = (Uint32 *) info->src;
691  int srcskip = info->src_skip / 4;
692  Uint32 *dst = (Uint32 *) info->dst;
693  int dstskip = info->dst_skip / 4;
694  SDL_PixelFormat *srcfmt = info->src_fmt;
695  SDL_PixelFormat *dstfmt = info->dst_fmt;
696  vector unsigned int vzero = vec_splat_u32(0);
697  vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
698  if (dstfmt->Amask && !srcfmt->Amask) {
699  if (info->a) {
700  vector unsigned char valpha;
701  ((unsigned char *) &valpha)[0] = info->a;
702  vzero = (vector unsigned int) vec_splat(valpha, 0);
703  }
704  }
705 
706  SDL_assert(srcfmt->BytesPerPixel == 4);
707  SDL_assert(dstfmt->BytesPerPixel == 4);
708 
709  while (height--) {
710  vector unsigned char valigner;
711  vector unsigned int vbits;
712  vector unsigned int voverflow;
713  Uint32 bits;
714  Uint8 r, g, b, a;
715 
716  int width = info->dst_w;
717  int extrawidth;
718 
719  /* do scalar until we can align... */
720  while ((UNALIGNED_PTR(dst)) && (width)) {
721  bits = *(src++);
722  RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
723  if(!srcfmt->Amask)
724  a = info->a;
725  *(dst++) = MAKE8888(dstfmt, r, g, b, a);
726  width--;
727  }
728 
729  /* After all that work, here's the vector part! */
730  extrawidth = (width % 4);
731  width -= extrawidth;
732  valigner = VEC_ALIGNER(src);
733  vbits = vec_ld(0, src);
734 
735  while (width) {
736  voverflow = vec_ld(15, src);
737  src += 4;
738  width -= 4;
739  vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */
740  vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */
741  vec_st(vbits, 0, dst); /* store it back out. */
742  dst += 4;
743  vbits = voverflow;
744  }
745 
746  SDL_assert(width == 0);
747 
748  /* cover pixels at the end of the row that didn't fit in 16 bytes. */
749  while (extrawidth) {
750  bits = *(src++); /* max 7 pixels, don't bother with prefetch. */
751  RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
752  if(!srcfmt->Amask)
753  a = info->a;
754  *(dst++) = MAKE8888(dstfmt, r, g, b, a);
755  extrawidth--;
756  }
757 
758  src += srcskip;
759  dst += dstskip;
760  }
761 
762 }
763 
764 /* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
765 /* Use this on a G4 */
766 static void
767 ConvertAltivec32to32_prefetch(SDL_BlitInfo * info)
768 {
769  const int scalar_dst_lead = sizeof(Uint32) * 4;
770  const int vector_dst_lead = sizeof(Uint32) * 16;
771 
772  int height = info->dst_h;
773  Uint32 *src = (Uint32 *) info->src;
774  int srcskip = info->src_skip / 4;
775  Uint32 *dst = (Uint32 *) info->dst;
776  int dstskip = info->dst_skip / 4;
777  SDL_PixelFormat *srcfmt = info->src_fmt;
778  SDL_PixelFormat *dstfmt = info->dst_fmt;
779  vector unsigned int vzero = vec_splat_u32(0);
780  vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
781  if (dstfmt->Amask && !srcfmt->Amask) {
782  if (info->a) {
783  vector unsigned char valpha;
784  ((unsigned char *) &valpha)[0] = info->a;
785  vzero = (vector unsigned int) vec_splat(valpha, 0);
786  }
787  }
788 
789  SDL_assert(srcfmt->BytesPerPixel == 4);
790  SDL_assert(dstfmt->BytesPerPixel == 4);
791 
792  while (height--) {
793  vector unsigned char valigner;
794  vector unsigned int vbits;
795  vector unsigned int voverflow;
796  Uint32 bits;
797  Uint8 r, g, b, a;
798 
799  int width = info->dst_w;
800  int extrawidth;
801 
802  /* do scalar until we can align... */
803  while ((UNALIGNED_PTR(dst)) && (width)) {
804  vec_dstt(src + scalar_dst_lead, DST_CTRL(2, 32, 1024),
805  DST_CHAN_SRC);
806  vec_dstst(dst + scalar_dst_lead, DST_CTRL(2, 32, 1024),
807  DST_CHAN_DEST);
808  bits = *(src++);
809  RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
810  if(!srcfmt->Amask)
811  a = info->a;
812  *(dst++) = MAKE8888(dstfmt, r, g, b, a);
813  width--;
814  }
815 
816  /* After all that work, here's the vector part! */
817  extrawidth = (width % 4);
818  width -= extrawidth;
819  valigner = VEC_ALIGNER(src);
820  vbits = vec_ld(0, src);
821 
822  while (width) {
823  vec_dstt(src + vector_dst_lead, DST_CTRL(2, 32, 1024),
824  DST_CHAN_SRC);
825  vec_dstst(dst + vector_dst_lead, DST_CTRL(2, 32, 1024),
826  DST_CHAN_DEST);
827  voverflow = vec_ld(15, src);
828  src += 4;
829  width -= 4;
830  vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */
831  vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */
832  vec_st(vbits, 0, dst); /* store it back out. */
833  dst += 4;
834  vbits = voverflow;
835  }
836 
837  SDL_assert(width == 0);
838 
839  /* cover pixels at the end of the row that didn't fit in 16 bytes. */
840  while (extrawidth) {
841  bits = *(src++); /* max 7 pixels, don't bother with prefetch. */
842  RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
843  if(!srcfmt->Amask)
844  a = info->a;
845  *(dst++) = MAKE8888(dstfmt, r, g, b, a);
846  extrawidth--;
847  }
848 
849  src += srcskip;
850  dst += dstskip;
851  }
852 
853  vec_dss(DST_CHAN_SRC);
854  vec_dss(DST_CHAN_DEST);
855 }
856 
857 static Uint32
858 GetBlitFeatures(void)
859 {
860  static Uint32 features = 0xffffffff;
861  if (features == 0xffffffff) {
862  /* Provide an override for testing .. */
863  char *override = SDL_getenv("SDL_ALTIVEC_BLIT_FEATURES");
864  if (override) {
865  features = 0;
866  SDL_sscanf(override, "%u", &features);
867  } else {
868  features = (0
869  /* Feature 1 is has-MMX */
870  | ((SDL_HasMMX())? 1 : 0)
871  /* Feature 2 is has-AltiVec */
872  | ((SDL_HasAltiVec())? 2 : 0)
873  /* Feature 4 is dont-use-prefetch */
874  /* !!!! FIXME: Check for G5 or later, not the cache size! Always prefetch on a G4. */
875  | ((GetL3CacheSize() == 0) ? 4 : 0)
876  );
877  }
878  }
879  return features;
880 }
881 
882 #if __MWERKS__
883 #pragma altivec_model off
884 #endif
885 #else
886 /* Feature 1 is has-MMX */
887 #define GetBlitFeatures() ((Uint32)(SDL_HasMMX() ? 1 : 0))
888 #endif
889 
890 /* This is now endian dependent */
891 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
892 #define HI 1
893 #define LO 0
894 #else /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
895 #define HI 0
896 #define LO 1
897 #endif
898 
899 /* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */
900 #define RGB888_RGB332(dst, src) { \
901  dst = (Uint8)((((src)&0x00E00000)>>16)| \
902  (((src)&0x0000E000)>>11)| \
903  (((src)&0x000000C0)>>6)); \
904 }
905 static void
907 {
908 #ifndef USE_DUFFS_LOOP
909  int c;
910 #endif
911  int width, height;
912  Uint32 *src;
913  const Uint8 *map;
914  Uint8 *dst;
915  int srcskip, dstskip;
916 
917  /* Set up some basic variables */
918  width = info->dst_w;
919  height = info->dst_h;
920  src = (Uint32 *) info->src;
921  srcskip = info->src_skip / 4;
922  dst = info->dst;
923  dstskip = info->dst_skip;
924  map = info->table;
925 
926  if (map == NULL) {
927  while (height--) {
928 #ifdef USE_DUFFS_LOOP
929  /* *INDENT-OFF* */
930  DUFFS_LOOP(
931  RGB888_RGB332(*dst++, *src);
932  , width);
933  /* *INDENT-ON* */
934 #else
935  for (c = width / 4; c; --c) {
936  /* Pack RGB into 8bit pixel */
937  ++src;
938  RGB888_RGB332(*dst++, *src);
939  ++src;
940  RGB888_RGB332(*dst++, *src);
941  ++src;
942  RGB888_RGB332(*dst++, *src);
943  ++src;
944  }
945  switch (width & 3) {
946  case 3:
947  RGB888_RGB332(*dst++, *src);
948  ++src;
949  case 2:
950  RGB888_RGB332(*dst++, *src);
951  ++src;
952  case 1:
953  RGB888_RGB332(*dst++, *src);
954  ++src;
955  }
956 #endif /* USE_DUFFS_LOOP */
957  src += srcskip;
958  dst += dstskip;
959  }
960  } else {
961  int Pixel;
962 
963  while (height--) {
964 #ifdef USE_DUFFS_LOOP
965  /* *INDENT-OFF* */
966  DUFFS_LOOP(
967  RGB888_RGB332(Pixel, *src);
968  *dst++ = map[Pixel];
969  ++src;
970  , width);
971  /* *INDENT-ON* */
972 #else
973  for (c = width / 4; c; --c) {
974  /* Pack RGB into 8bit pixel */
975  RGB888_RGB332(Pixel, *src);
976  *dst++ = map[Pixel];
977  ++src;
978  RGB888_RGB332(Pixel, *src);
979  *dst++ = map[Pixel];
980  ++src;
981  RGB888_RGB332(Pixel, *src);
982  *dst++ = map[Pixel];
983  ++src;
984  RGB888_RGB332(Pixel, *src);
985  *dst++ = map[Pixel];
986  ++src;
987  }
988  switch (width & 3) {
989  case 3:
990  RGB888_RGB332(Pixel, *src);
991  *dst++ = map[Pixel];
992  ++src;
993  case 2:
994  RGB888_RGB332(Pixel, *src);
995  *dst++ = map[Pixel];
996  ++src;
997  case 1:
998  RGB888_RGB332(Pixel, *src);
999  *dst++ = map[Pixel];
1000  ++src;
1001  }
1002 #endif /* USE_DUFFS_LOOP */
1003  src += srcskip;
1004  dst += dstskip;
1005  }
1006  }
1007 }
1008 
1009 /* Special optimized blit for RGB 10-10-10 --> RGB 3-3-2 */
1010 #define RGB101010_RGB332(dst, src) { \
1011  dst = (Uint8)((((src)&0x38000000)>>22)| \
1012  (((src)&0x000E0000)>>15)| \
1013  (((src)&0x00000300)>>8)); \
1014 }
1015 static void
1017 {
1018 #ifndef USE_DUFFS_LOOP
1019  int c;
1020 #endif
1021  int width, height;
1022  Uint32 *src;
1023  const Uint8 *map;
1024  Uint8 *dst;
1025  int srcskip, dstskip;
1026 
1027  /* Set up some basic variables */
1028  width = info->dst_w;
1029  height = info->dst_h;
1030  src = (Uint32 *) info->src;
1031  srcskip = info->src_skip / 4;
1032  dst = info->dst;
1033  dstskip = info->dst_skip;
1034  map = info->table;
1035 
1036  if (map == NULL) {
1037  while (height--) {
1038 #ifdef USE_DUFFS_LOOP
1039  /* *INDENT-OFF* */
1040  DUFFS_LOOP(
1041  RGB101010_RGB332(*dst++, *src);
1042  , width);
1043  /* *INDENT-ON* */
1044 #else
1045  for (c = width / 4; c; --c) {
1046  /* Pack RGB into 8bit pixel */
1047  ++src;
1048  RGB101010_RGB332(*dst++, *src);
1049  ++src;
1050  RGB101010_RGB332(*dst++, *src);
1051  ++src;
1052  RGB101010_RGB332(*dst++, *src);
1053  ++src;
1054  }
1055  switch (width & 3) {
1056  case 3:
1057  RGB101010_RGB332(*dst++, *src);
1058  ++src;
1059  case 2:
1060  RGB101010_RGB332(*dst++, *src);
1061  ++src;
1062  case 1:
1063  RGB101010_RGB332(*dst++, *src);
1064  ++src;
1065  }
1066 #endif /* USE_DUFFS_LOOP */
1067  src += srcskip;
1068  dst += dstskip;
1069  }
1070  } else {
1071  int Pixel;
1072 
1073  while (height--) {
1074 #ifdef USE_DUFFS_LOOP
1075  /* *INDENT-OFF* */
1076  DUFFS_LOOP(
1077  RGB101010_RGB332(Pixel, *src);
1078  *dst++ = map[Pixel];
1079  ++src;
1080  , width);
1081  /* *INDENT-ON* */
1082 #else
1083  for (c = width / 4; c; --c) {
1084  /* Pack RGB into 8bit pixel */
1085  RGB101010_RGB332(Pixel, *src);
1086  *dst++ = map[Pixel];
1087  ++src;
1088  RGB101010_RGB332(Pixel, *src);
1089  *dst++ = map[Pixel];
1090  ++src;
1091  RGB101010_RGB332(Pixel, *src);
1092  *dst++ = map[Pixel];
1093  ++src;
1094  RGB101010_RGB332(Pixel, *src);
1095  *dst++ = map[Pixel];
1096  ++src;
1097  }
1098  switch (width & 3) {
1099  case 3:
1100  RGB101010_RGB332(Pixel, *src);
1101  *dst++ = map[Pixel];
1102  ++src;
1103  case 2:
1104  RGB101010_RGB332(Pixel, *src);
1105  *dst++ = map[Pixel];
1106  ++src;
1107  case 1:
1108  RGB101010_RGB332(Pixel, *src);
1109  *dst++ = map[Pixel];
1110  ++src;
1111  }
1112 #endif /* USE_DUFFS_LOOP */
1113  src += srcskip;
1114  dst += dstskip;
1115  }
1116  }
1117 }
1118 
1119 /* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */
1120 #define RGB888_RGB555(dst, src) { \
1121  *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>9)| \
1122  (((*src)&0x0000F800)>>6)| \
1123  (((*src)&0x000000F8)>>3)); \
1124 }
1125 #ifndef USE_DUFFS_LOOP
1126 #define RGB888_RGB555_TWO(dst, src) { \
1127  *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \
1128  (((src[HI])&0x0000F800)>>6)| \
1129  (((src[HI])&0x000000F8)>>3))<<16)| \
1130  (((src[LO])&0x00F80000)>>9)| \
1131  (((src[LO])&0x0000F800)>>6)| \
1132  (((src[LO])&0x000000F8)>>3); \
1133 }
1134 #endif
1135 static void
1137 {
1138 #ifndef USE_DUFFS_LOOP
1139  int c;
1140 #endif
1141  int width, height;
1142  Uint32 *src;
1143  Uint16 *dst;
1144  int srcskip, dstskip;
1145 
1146  /* Set up some basic variables */
1147  width = info->dst_w;
1148  height = info->dst_h;
1149  src = (Uint32 *) info->src;
1150  srcskip = info->src_skip / 4;
1151  dst = (Uint16 *) info->dst;
1152  dstskip = info->dst_skip / 2;
1153 
1154 #ifdef USE_DUFFS_LOOP
1155  while (height--) {
1156  /* *INDENT-OFF* */
1157  DUFFS_LOOP(
1158  RGB888_RGB555(dst, src);
1159  ++src;
1160  ++dst;
1161  , width);
1162  /* *INDENT-ON* */
1163  src += srcskip;
1164  dst += dstskip;
1165  }
1166 #else
1167  /* Memory align at 4-byte boundary, if necessary */
1168  if ((long) dst & 0x03) {
1169  /* Don't do anything if width is 0 */
1170  if (width == 0) {
1171  return;
1172  }
1173  --width;
1174 
1175  while (height--) {
1176  /* Perform copy alignment */
1177  RGB888_RGB555(dst, src);
1178  ++src;
1179  ++dst;
1180 
1181  /* Copy in 4 pixel chunks */
1182  for (c = width / 4; c; --c) {
1183  RGB888_RGB555_TWO(dst, src);
1184  src += 2;
1185  dst += 2;
1186  RGB888_RGB555_TWO(dst, src);
1187  src += 2;
1188  dst += 2;
1189  }
1190  /* Get any leftovers */
1191  switch (width & 3) {
1192  case 3:
1193  RGB888_RGB555(dst, src);
1194  ++src;
1195  ++dst;
1196  case 2:
1197  RGB888_RGB555_TWO(dst, src);
1198  src += 2;
1199  dst += 2;
1200  break;
1201  case 1:
1202  RGB888_RGB555(dst, src);
1203  ++src;
1204  ++dst;
1205  break;
1206  }
1207  src += srcskip;
1208  dst += dstskip;
1209  }
1210  } else {
1211  while (height--) {
1212  /* Copy in 4 pixel chunks */
1213  for (c = width / 4; c; --c) {
1214  RGB888_RGB555_TWO(dst, src);
1215  src += 2;
1216  dst += 2;
1217  RGB888_RGB555_TWO(dst, src);
1218  src += 2;
1219  dst += 2;
1220  }
1221  /* Get any leftovers */
1222  switch (width & 3) {
1223  case 3:
1224  RGB888_RGB555(dst, src);
1225  ++src;
1226  ++dst;
1227  case 2:
1228  RGB888_RGB555_TWO(dst, src);
1229  src += 2;
1230  dst += 2;
1231  break;
1232  case 1:
1233  RGB888_RGB555(dst, src);
1234  ++src;
1235  ++dst;
1236  break;
1237  }
1238  src += srcskip;
1239  dst += dstskip;
1240  }
1241  }
1242 #endif /* USE_DUFFS_LOOP */
1243 }
1244 
1245 /* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */
1246 #define RGB888_RGB565(dst, src) { \
1247  *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>8)| \
1248  (((*src)&0x0000FC00)>>5)| \
1249  (((*src)&0x000000F8)>>3)); \
1250 }
1251 #ifndef USE_DUFFS_LOOP
1252 #define RGB888_RGB565_TWO(dst, src) { \
1253  *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \
1254  (((src[HI])&0x0000FC00)>>5)| \
1255  (((src[HI])&0x000000F8)>>3))<<16)| \
1256  (((src[LO])&0x00F80000)>>8)| \
1257  (((src[LO])&0x0000FC00)>>5)| \
1258  (((src[LO])&0x000000F8)>>3); \
1259 }
1260 #endif
1261 static void
1263 {
1264 #ifndef USE_DUFFS_LOOP
1265  int c;
1266 #endif
1267  int width, height;
1268  Uint32 *src;
1269  Uint16 *dst;
1270  int srcskip, dstskip;
1271 
1272  /* Set up some basic variables */
1273  width = info->dst_w;
1274  height = info->dst_h;
1275  src = (Uint32 *) info->src;
1276  srcskip = info->src_skip / 4;
1277  dst = (Uint16 *) info->dst;
1278  dstskip = info->dst_skip / 2;
1279 
1280 #ifdef USE_DUFFS_LOOP
1281  while (height--) {
1282  /* *INDENT-OFF* */
1283  DUFFS_LOOP(
1284  RGB888_RGB565(dst, src);
1285  ++src;
1286  ++dst;
1287  , width);
1288  /* *INDENT-ON* */
1289  src += srcskip;
1290  dst += dstskip;
1291  }
1292 #else
1293  /* Memory align at 4-byte boundary, if necessary */
1294  if ((long) dst & 0x03) {
1295  /* Don't do anything if width is 0 */
1296  if (width == 0) {
1297  return;
1298  }
1299  --width;
1300 
1301  while (height--) {
1302  /* Perform copy alignment */
1303  RGB888_RGB565(dst, src);
1304  ++src;
1305  ++dst;
1306 
1307  /* Copy in 4 pixel chunks */
1308  for (c = width / 4; c; --c) {
1309  RGB888_RGB565_TWO(dst, src);
1310  src += 2;
1311  dst += 2;
1312  RGB888_RGB565_TWO(dst, src);
1313  src += 2;
1314  dst += 2;
1315  }
1316  /* Get any leftovers */
1317  switch (width & 3) {
1318  case 3:
1319  RGB888_RGB565(dst, src);
1320  ++src;
1321  ++dst;
1322  case 2:
1323  RGB888_RGB565_TWO(dst, src);
1324  src += 2;
1325  dst += 2;
1326  break;
1327  case 1:
1328  RGB888_RGB565(dst, src);
1329  ++src;
1330  ++dst;
1331  break;
1332  }
1333  src += srcskip;
1334  dst += dstskip;
1335  }
1336  } else {
1337  while (height--) {
1338  /* Copy in 4 pixel chunks */
1339  for (c = width / 4; c; --c) {
1340  RGB888_RGB565_TWO(dst, src);
1341  src += 2;
1342  dst += 2;
1343  RGB888_RGB565_TWO(dst, src);
1344  src += 2;
1345  dst += 2;
1346  }
1347  /* Get any leftovers */
1348  switch (width & 3) {
1349  case 3:
1350  RGB888_RGB565(dst, src);
1351  ++src;
1352  ++dst;
1353  case 2:
1354  RGB888_RGB565_TWO(dst, src);
1355  src += 2;
1356  dst += 2;
1357  break;
1358  case 1:
1359  RGB888_RGB565(dst, src);
1360  ++src;
1361  ++dst;
1362  break;
1363  }
1364  src += srcskip;
1365  dst += dstskip;
1366  }
1367  }
1368 #endif /* USE_DUFFS_LOOP */
1369 }
1370 
1371 
1372 /* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */
1373 #define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1])
1374 static void
1376 {
1377 #ifndef USE_DUFFS_LOOP
1378  int c;
1379 #endif
1380  int width, height;
1381  Uint8 *src;
1382  Uint32 *dst;
1383  int srcskip, dstskip;
1384 
1385  /* Set up some basic variables */
1386  width = info->dst_w;
1387  height = info->dst_h;
1388  src = (Uint8 *) info->src;
1389  srcskip = info->src_skip;
1390  dst = (Uint32 *) info->dst;
1391  dstskip = info->dst_skip / 4;
1392 
1393 #ifdef USE_DUFFS_LOOP
1394  while (height--) {
1395  /* *INDENT-OFF* */
1396  DUFFS_LOOP(
1397  {
1398  *dst++ = RGB565_32(dst, src, map);
1399  src += 2;
1400  },
1401  width);
1402  /* *INDENT-ON* */
1403  src += srcskip;
1404  dst += dstskip;
1405  }
1406 #else
1407  while (height--) {
1408  /* Copy in 4 pixel chunks */
1409  for (c = width / 4; c; --c) {
1410  *dst++ = RGB565_32(dst, src, map);
1411  src += 2;
1412  *dst++ = RGB565_32(dst, src, map);
1413  src += 2;
1414  *dst++ = RGB565_32(dst, src, map);
1415  src += 2;
1416  *dst++ = RGB565_32(dst, src, map);
1417  src += 2;
1418  }
1419  /* Get any leftovers */
1420  switch (width & 3) {
1421  case 3:
1422  *dst++ = RGB565_32(dst, src, map);
1423  src += 2;
1424  case 2:
1425  *dst++ = RGB565_32(dst, src, map);
1426  src += 2;
1427  case 1:
1428  *dst++ = RGB565_32(dst, src, map);
1429  src += 2;
1430  break;
1431  }
1432  src += srcskip;
1433  dst += dstskip;
1434  }
1435 #endif /* USE_DUFFS_LOOP */
1436 }
1437 
1438 /* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */
1439 static const Uint32 RGB565_ARGB8888_LUT[512] = {
1440  0x00000000, 0xff000000, 0x00000008, 0xff002000,
1441  0x00000010, 0xff004000, 0x00000018, 0xff006100,
1442  0x00000020, 0xff008100, 0x00000029, 0xff00a100,
1443  0x00000031, 0xff00c200, 0x00000039, 0xff00e200,
1444  0x00000041, 0xff080000, 0x0000004a, 0xff082000,
1445  0x00000052, 0xff084000, 0x0000005a, 0xff086100,
1446  0x00000062, 0xff088100, 0x0000006a, 0xff08a100,
1447  0x00000073, 0xff08c200, 0x0000007b, 0xff08e200,
1448  0x00000083, 0xff100000, 0x0000008b, 0xff102000,
1449  0x00000094, 0xff104000, 0x0000009c, 0xff106100,
1450  0x000000a4, 0xff108100, 0x000000ac, 0xff10a100,
1451  0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200,
1452  0x000000c5, 0xff180000, 0x000000cd, 0xff182000,
1453  0x000000d5, 0xff184000, 0x000000de, 0xff186100,
1454  0x000000e6, 0xff188100, 0x000000ee, 0xff18a100,
1455  0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200,
1456  0x00000400, 0xff200000, 0x00000408, 0xff202000,
1457  0x00000410, 0xff204000, 0x00000418, 0xff206100,
1458  0x00000420, 0xff208100, 0x00000429, 0xff20a100,
1459  0x00000431, 0xff20c200, 0x00000439, 0xff20e200,
1460  0x00000441, 0xff290000, 0x0000044a, 0xff292000,
1461  0x00000452, 0xff294000, 0x0000045a, 0xff296100,
1462  0x00000462, 0xff298100, 0x0000046a, 0xff29a100,
1463  0x00000473, 0xff29c200, 0x0000047b, 0xff29e200,
1464  0x00000483, 0xff310000, 0x0000048b, 0xff312000,
1465  0x00000494, 0xff314000, 0x0000049c, 0xff316100,
1466  0x000004a4, 0xff318100, 0x000004ac, 0xff31a100,
1467  0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200,
1468  0x000004c5, 0xff390000, 0x000004cd, 0xff392000,
1469  0x000004d5, 0xff394000, 0x000004de, 0xff396100,
1470  0x000004e6, 0xff398100, 0x000004ee, 0xff39a100,
1471  0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200,
1472  0x00000800, 0xff410000, 0x00000808, 0xff412000,
1473  0x00000810, 0xff414000, 0x00000818, 0xff416100,
1474  0x00000820, 0xff418100, 0x00000829, 0xff41a100,
1475  0x00000831, 0xff41c200, 0x00000839, 0xff41e200,
1476  0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000,
1477  0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100,
1478  0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100,
1479  0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200,
1480  0x00000883, 0xff520000, 0x0000088b, 0xff522000,
1481  0x00000894, 0xff524000, 0x0000089c, 0xff526100,
1482  0x000008a4, 0xff528100, 0x000008ac, 0xff52a100,
1483  0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200,
1484  0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000,
1485  0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100,
1486  0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100,
1487  0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200,
1488  0x00000c00, 0xff620000, 0x00000c08, 0xff622000,
1489  0x00000c10, 0xff624000, 0x00000c18, 0xff626100,
1490  0x00000c20, 0xff628100, 0x00000c29, 0xff62a100,
1491  0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200,
1492  0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000,
1493  0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100,
1494  0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100,
1495  0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200,
1496  0x00000c83, 0xff730000, 0x00000c8b, 0xff732000,
1497  0x00000c94, 0xff734000, 0x00000c9c, 0xff736100,
1498  0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100,
1499  0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200,
1500  0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000,
1501  0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100,
1502  0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100,
1503  0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200,
1504  0x00001000, 0xff830000, 0x00001008, 0xff832000,
1505  0x00001010, 0xff834000, 0x00001018, 0xff836100,
1506  0x00001020, 0xff838100, 0x00001029, 0xff83a100,
1507  0x00001031, 0xff83c200, 0x00001039, 0xff83e200,
1508  0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000,
1509  0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100,
1510  0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100,
1511  0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200,
1512  0x00001083, 0xff940000, 0x0000108b, 0xff942000,
1513  0x00001094, 0xff944000, 0x0000109c, 0xff946100,
1514  0x000010a4, 0xff948100, 0x000010ac, 0xff94a100,
1515  0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200,
1516  0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000,
1517  0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100,
1518  0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100,
1519  0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200,
1520  0x00001400, 0xffa40000, 0x00001408, 0xffa42000,
1521  0x00001410, 0xffa44000, 0x00001418, 0xffa46100,
1522  0x00001420, 0xffa48100, 0x00001429, 0xffa4a100,
1523  0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200,
1524  0x00001441, 0xffac0000, 0x0000144a, 0xffac2000,
1525  0x00001452, 0xffac4000, 0x0000145a, 0xffac6100,
1526  0x00001462, 0xffac8100, 0x0000146a, 0xffaca100,
1527  0x00001473, 0xffacc200, 0x0000147b, 0xfface200,
1528  0x00001483, 0xffb40000, 0x0000148b, 0xffb42000,
1529  0x00001494, 0xffb44000, 0x0000149c, 0xffb46100,
1530  0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100,
1531  0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200,
1532  0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000,
1533  0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100,
1534  0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100,
1535  0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200,
1536  0x00001800, 0xffc50000, 0x00001808, 0xffc52000,
1537  0x00001810, 0xffc54000, 0x00001818, 0xffc56100,
1538  0x00001820, 0xffc58100, 0x00001829, 0xffc5a100,
1539  0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200,
1540  0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000,
1541  0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100,
1542  0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100,
1543  0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200,
1544  0x00001883, 0xffd50000, 0x0000188b, 0xffd52000,
1545  0x00001894, 0xffd54000, 0x0000189c, 0xffd56100,
1546  0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100,
1547  0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200,
1548  0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000,
1549  0x000018d5, 0xffde4000, 0x000018de, 0xffde6100,
1550  0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100,
1551  0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200,
1552  0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000,
1553  0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100,
1554  0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100,
1555  0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200,
1556  0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000,
1557  0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100,
1558  0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100,
1559  0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200,
1560  0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000,
1561  0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100,
1562  0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100,
1563  0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200,
1564  0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000,
1565  0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100,
1566  0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100,
1567  0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200
1568 };
1569 
1570 static void
1572 {
1574 }
1575 
1576 /* Special optimized blit for RGB 5-6-5 --> ABGR 8-8-8-8 */
1577 static const Uint32 RGB565_ABGR8888_LUT[512] = {
1578  0xff000000, 0x00000000, 0xff080000, 0x00002000,
1579  0xff100000, 0x00004000, 0xff180000, 0x00006100,
1580  0xff200000, 0x00008100, 0xff290000, 0x0000a100,
1581  0xff310000, 0x0000c200, 0xff390000, 0x0000e200,
1582  0xff410000, 0x00000008, 0xff4a0000, 0x00002008,
1583  0xff520000, 0x00004008, 0xff5a0000, 0x00006108,
1584  0xff620000, 0x00008108, 0xff6a0000, 0x0000a108,
1585  0xff730000, 0x0000c208, 0xff7b0000, 0x0000e208,
1586  0xff830000, 0x00000010, 0xff8b0000, 0x00002010,
1587  0xff940000, 0x00004010, 0xff9c0000, 0x00006110,
1588  0xffa40000, 0x00008110, 0xffac0000, 0x0000a110,
1589  0xffb40000, 0x0000c210, 0xffbd0000, 0x0000e210,
1590  0xffc50000, 0x00000018, 0xffcd0000, 0x00002018,
1591  0xffd50000, 0x00004018, 0xffde0000, 0x00006118,
1592  0xffe60000, 0x00008118, 0xffee0000, 0x0000a118,
1593  0xfff60000, 0x0000c218, 0xffff0000, 0x0000e218,
1594  0xff000400, 0x00000020, 0xff080400, 0x00002020,
1595  0xff100400, 0x00004020, 0xff180400, 0x00006120,
1596  0xff200400, 0x00008120, 0xff290400, 0x0000a120,
1597  0xff310400, 0x0000c220, 0xff390400, 0x0000e220,
1598  0xff410400, 0x00000029, 0xff4a0400, 0x00002029,
1599  0xff520400, 0x00004029, 0xff5a0400, 0x00006129,
1600  0xff620400, 0x00008129, 0xff6a0400, 0x0000a129,
1601  0xff730400, 0x0000c229, 0xff7b0400, 0x0000e229,
1602  0xff830400, 0x00000031, 0xff8b0400, 0x00002031,
1603  0xff940400, 0x00004031, 0xff9c0400, 0x00006131,
1604  0xffa40400, 0x00008131, 0xffac0400, 0x0000a131,
1605  0xffb40400, 0x0000c231, 0xffbd0400, 0x0000e231,
1606  0xffc50400, 0x00000039, 0xffcd0400, 0x00002039,
1607  0xffd50400, 0x00004039, 0xffde0400, 0x00006139,
1608  0xffe60400, 0x00008139, 0xffee0400, 0x0000a139,
1609  0xfff60400, 0x0000c239, 0xffff0400, 0x0000e239,
1610  0xff000800, 0x00000041, 0xff080800, 0x00002041,
1611  0xff100800, 0x00004041, 0xff180800, 0x00006141,
1612  0xff200800, 0x00008141, 0xff290800, 0x0000a141,
1613  0xff310800, 0x0000c241, 0xff390800, 0x0000e241,
1614  0xff410800, 0x0000004a, 0xff4a0800, 0x0000204a,
1615  0xff520800, 0x0000404a, 0xff5a0800, 0x0000614a,
1616  0xff620800, 0x0000814a, 0xff6a0800, 0x0000a14a,
1617  0xff730800, 0x0000c24a, 0xff7b0800, 0x0000e24a,
1618  0xff830800, 0x00000052, 0xff8b0800, 0x00002052,
1619  0xff940800, 0x00004052, 0xff9c0800, 0x00006152,
1620  0xffa40800, 0x00008152, 0xffac0800, 0x0000a152,
1621  0xffb40800, 0x0000c252, 0xffbd0800, 0x0000e252,
1622  0xffc50800, 0x0000005a, 0xffcd0800, 0x0000205a,
1623  0xffd50800, 0x0000405a, 0xffde0800, 0x0000615a,
1624  0xffe60800, 0x0000815a, 0xffee0800, 0x0000a15a,
1625  0xfff60800, 0x0000c25a, 0xffff0800, 0x0000e25a,
1626  0xff000c00, 0x00000062, 0xff080c00, 0x00002062,
1627  0xff100c00, 0x00004062, 0xff180c00, 0x00006162,
1628  0xff200c00, 0x00008162, 0xff290c00, 0x0000a162,
1629  0xff310c00, 0x0000c262, 0xff390c00, 0x0000e262,
1630  0xff410c00, 0x0000006a, 0xff4a0c00, 0x0000206a,
1631  0xff520c00, 0x0000406a, 0xff5a0c00, 0x0000616a,
1632  0xff620c00, 0x0000816a, 0xff6a0c00, 0x0000a16a,
1633  0xff730c00, 0x0000c26a, 0xff7b0c00, 0x0000e26a,
1634  0xff830c00, 0x00000073, 0xff8b0c00, 0x00002073,
1635  0xff940c00, 0x00004073, 0xff9c0c00, 0x00006173,
1636  0xffa40c00, 0x00008173, 0xffac0c00, 0x0000a173,
1637  0xffb40c00, 0x0000c273, 0xffbd0c00, 0x0000e273,
1638  0xffc50c00, 0x0000007b, 0xffcd0c00, 0x0000207b,
1639  0xffd50c00, 0x0000407b, 0xffde0c00, 0x0000617b,
1640  0xffe60c00, 0x0000817b, 0xffee0c00, 0x0000a17b,
1641  0xfff60c00, 0x0000c27b, 0xffff0c00, 0x0000e27b,
1642  0xff001000, 0x00000083, 0xff081000, 0x00002083,
1643  0xff101000, 0x00004083, 0xff181000, 0x00006183,
1644  0xff201000, 0x00008183, 0xff291000, 0x0000a183,
1645  0xff311000, 0x0000c283, 0xff391000, 0x0000e283,
1646  0xff411000, 0x0000008b, 0xff4a1000, 0x0000208b,
1647  0xff521000, 0x0000408b, 0xff5a1000, 0x0000618b,
1648  0xff621000, 0x0000818b, 0xff6a1000, 0x0000a18b,
1649  0xff731000, 0x0000c28b, 0xff7b1000, 0x0000e28b,
1650  0xff831000, 0x00000094, 0xff8b1000, 0x00002094,
1651  0xff941000, 0x00004094, 0xff9c1000, 0x00006194,
1652  0xffa41000, 0x00008194, 0xffac1000, 0x0000a194,
1653  0xffb41000, 0x0000c294, 0xffbd1000, 0x0000e294,
1654  0xffc51000, 0x0000009c, 0xffcd1000, 0x0000209c,
1655  0xffd51000, 0x0000409c, 0xffde1000, 0x0000619c,
1656  0xffe61000, 0x0000819c, 0xffee1000, 0x0000a19c,
1657  0xfff61000, 0x0000c29c, 0xffff1000, 0x0000e29c,
1658  0xff001400, 0x000000a4, 0xff081400, 0x000020a4,
1659  0xff101400, 0x000040a4, 0xff181400, 0x000061a4,
1660  0xff201400, 0x000081a4, 0xff291400, 0x0000a1a4,
1661  0xff311400, 0x0000c2a4, 0xff391400, 0x0000e2a4,
1662  0xff411400, 0x000000ac, 0xff4a1400, 0x000020ac,
1663  0xff521400, 0x000040ac, 0xff5a1400, 0x000061ac,
1664  0xff621400, 0x000081ac, 0xff6a1400, 0x0000a1ac,
1665  0xff731400, 0x0000c2ac, 0xff7b1400, 0x0000e2ac,
1666  0xff831400, 0x000000b4, 0xff8b1400, 0x000020b4,
1667  0xff941400, 0x000040b4, 0xff9c1400, 0x000061b4,
1668  0xffa41400, 0x000081b4, 0xffac1400, 0x0000a1b4,
1669  0xffb41400, 0x0000c2b4, 0xffbd1400, 0x0000e2b4,
1670  0xffc51400, 0x000000bd, 0xffcd1400, 0x000020bd,
1671  0xffd51400, 0x000040bd, 0xffde1400, 0x000061bd,
1672  0xffe61400, 0x000081bd, 0xffee1400, 0x0000a1bd,
1673  0xfff61400, 0x0000c2bd, 0xffff1400, 0x0000e2bd,
1674  0xff001800, 0x000000c5, 0xff081800, 0x000020c5,
1675  0xff101800, 0x000040c5, 0xff181800, 0x000061c5,
1676  0xff201800, 0x000081c5, 0xff291800, 0x0000a1c5,
1677  0xff311800, 0x0000c2c5, 0xff391800, 0x0000e2c5,
1678  0xff411800, 0x000000cd, 0xff4a1800, 0x000020cd,
1679  0xff521800, 0x000040cd, 0xff5a1800, 0x000061cd,
1680  0xff621800, 0x000081cd, 0xff6a1800, 0x0000a1cd,
1681  0xff731800, 0x0000c2cd, 0xff7b1800, 0x0000e2cd,
1682  0xff831800, 0x000000d5, 0xff8b1800, 0x000020d5,
1683  0xff941800, 0x000040d5, 0xff9c1800, 0x000061d5,
1684  0xffa41800, 0x000081d5, 0xffac1800, 0x0000a1d5,
1685  0xffb41800, 0x0000c2d5, 0xffbd1800, 0x0000e2d5,
1686  0xffc51800, 0x000000de, 0xffcd1800, 0x000020de,
1687  0xffd51800, 0x000040de, 0xffde1800, 0x000061de,
1688  0xffe61800, 0x000081de, 0xffee1800, 0x0000a1de,
1689  0xfff61800, 0x0000c2de, 0xffff1800, 0x0000e2de,
1690  0xff001c00, 0x000000e6, 0xff081c00, 0x000020e6,
1691  0xff101c00, 0x000040e6, 0xff181c00, 0x000061e6,
1692  0xff201c00, 0x000081e6, 0xff291c00, 0x0000a1e6,
1693  0xff311c00, 0x0000c2e6, 0xff391c00, 0x0000e2e6,
1694  0xff411c00, 0x000000ee, 0xff4a1c00, 0x000020ee,
1695  0xff521c00, 0x000040ee, 0xff5a1c00, 0x000061ee,
1696  0xff621c00, 0x000081ee, 0xff6a1c00, 0x0000a1ee,
1697  0xff731c00, 0x0000c2ee, 0xff7b1c00, 0x0000e2ee,
1698  0xff831c00, 0x000000f6, 0xff8b1c00, 0x000020f6,
1699  0xff941c00, 0x000040f6, 0xff9c1c00, 0x000061f6,
1700  0xffa41c00, 0x000081f6, 0xffac1c00, 0x0000a1f6,
1701  0xffb41c00, 0x0000c2f6, 0xffbd1c00, 0x0000e2f6,
1702  0xffc51c00, 0x000000ff, 0xffcd1c00, 0x000020ff,
1703  0xffd51c00, 0x000040ff, 0xffde1c00, 0x000061ff,
1704  0xffe61c00, 0x000081ff, 0xffee1c00, 0x0000a1ff,
1705  0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff
1706 };
1707 
1708 static void
1710 {
1712 }
1713 
1714 /* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
1715 static const Uint32 RGB565_RGBA8888_LUT[512] = {
1716  0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
1717  0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
1718  0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
1719  0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
1720  0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
1721  0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
1722  0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
1723  0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
1724  0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
1725  0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
1726  0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
1727  0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
1728  0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
1729  0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
1730  0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
1731  0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
1732  0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
1733  0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
1734  0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
1735  0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
1736  0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
1737  0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
1738  0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
1739  0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
1740  0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
1741  0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
1742  0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
1743  0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
1744  0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
1745  0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
1746  0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
1747  0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
1748  0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
1749  0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
1750  0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
1751  0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
1752  0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
1753  0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
1754  0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
1755  0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
1756  0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
1757  0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
1758  0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
1759  0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
1760  0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
1761  0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
1762  0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
1763  0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
1764  0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
1765  0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
1766  0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
1767  0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
1768  0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
1769  0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
1770  0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
1771  0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
1772  0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
1773  0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
1774  0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
1775  0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
1776  0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
1777  0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
1778  0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
1779  0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
1780  0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
1781  0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
1782  0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
1783  0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
1784  0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
1785  0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
1786  0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
1787  0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
1788  0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
1789  0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
1790  0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
1791  0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
1792  0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
1793  0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
1794  0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
1795  0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
1796  0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
1797  0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
1798  0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
1799  0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
1800  0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
1801  0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
1802  0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
1803  0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
1804  0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
1805  0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
1806  0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
1807  0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
1808  0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
1809  0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
1810  0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
1811  0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
1812  0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
1813  0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
1814  0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
1815  0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
1816  0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
1817  0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
1818  0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
1819  0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
1820  0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
1821  0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
1822  0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
1823  0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
1824  0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
1825  0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
1826  0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
1827  0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
1828  0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
1829  0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
1830  0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
1831  0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
1832  0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
1833  0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
1834  0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
1835  0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
1836  0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
1837  0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
1838  0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
1839  0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
1840  0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
1841  0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
1842  0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
1843  0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
1844 };
1845 
1846 static void
1848 {
1850 }
1851 
1852 /* Special optimized blit for RGB 5-6-5 --> BGRA 8-8-8-8 */
1853 static const Uint32 RGB565_BGRA8888_LUT[512] = {
1854  0x00000000, 0x000000ff, 0x08000000, 0x002000ff,
1855  0x10000000, 0x004000ff, 0x18000000, 0x006100ff,
1856  0x20000000, 0x008100ff, 0x29000000, 0x00a100ff,
1857  0x31000000, 0x00c200ff, 0x39000000, 0x00e200ff,
1858  0x41000000, 0x000008ff, 0x4a000000, 0x002008ff,
1859  0x52000000, 0x004008ff, 0x5a000000, 0x006108ff,
1860  0x62000000, 0x008108ff, 0x6a000000, 0x00a108ff,
1861  0x73000000, 0x00c208ff, 0x7b000000, 0x00e208ff,
1862  0x83000000, 0x000010ff, 0x8b000000, 0x002010ff,
1863  0x94000000, 0x004010ff, 0x9c000000, 0x006110ff,
1864  0xa4000000, 0x008110ff, 0xac000000, 0x00a110ff,
1865  0xb4000000, 0x00c210ff, 0xbd000000, 0x00e210ff,
1866  0xc5000000, 0x000018ff, 0xcd000000, 0x002018ff,
1867  0xd5000000, 0x004018ff, 0xde000000, 0x006118ff,
1868  0xe6000000, 0x008118ff, 0xee000000, 0x00a118ff,
1869  0xf6000000, 0x00c218ff, 0xff000000, 0x00e218ff,
1870  0x00040000, 0x000020ff, 0x08040000, 0x002020ff,
1871  0x10040000, 0x004020ff, 0x18040000, 0x006120ff,
1872  0x20040000, 0x008120ff, 0x29040000, 0x00a120ff,
1873  0x31040000, 0x00c220ff, 0x39040000, 0x00e220ff,
1874  0x41040000, 0x000029ff, 0x4a040000, 0x002029ff,
1875  0x52040000, 0x004029ff, 0x5a040000, 0x006129ff,
1876  0x62040000, 0x008129ff, 0x6a040000, 0x00a129ff,
1877  0x73040000, 0x00c229ff, 0x7b040000, 0x00e229ff,
1878  0x83040000, 0x000031ff, 0x8b040000, 0x002031ff,
1879  0x94040000, 0x004031ff, 0x9c040000, 0x006131ff,
1880  0xa4040000, 0x008131ff, 0xac040000, 0x00a131ff,
1881  0xb4040000, 0x00c231ff, 0xbd040000, 0x00e231ff,
1882  0xc5040000, 0x000039ff, 0xcd040000, 0x002039ff,
1883  0xd5040000, 0x004039ff, 0xde040000, 0x006139ff,
1884  0xe6040000, 0x008139ff, 0xee040000, 0x00a139ff,
1885  0xf6040000, 0x00c239ff, 0xff040000, 0x00e239ff,
1886  0x00080000, 0x000041ff, 0x08080000, 0x002041ff,
1887  0x10080000, 0x004041ff, 0x18080000, 0x006141ff,
1888  0x20080000, 0x008141ff, 0x29080000, 0x00a141ff,
1889  0x31080000, 0x00c241ff, 0x39080000, 0x00e241ff,
1890  0x41080000, 0x00004aff, 0x4a080000, 0x00204aff,
1891  0x52080000, 0x00404aff, 0x5a080000, 0x00614aff,
1892  0x62080000, 0x00814aff, 0x6a080000, 0x00a14aff,
1893  0x73080000, 0x00c24aff, 0x7b080000, 0x00e24aff,
1894  0x83080000, 0x000052ff, 0x8b080000, 0x002052ff,
1895  0x94080000, 0x004052ff, 0x9c080000, 0x006152ff,
1896  0xa4080000, 0x008152ff, 0xac080000, 0x00a152ff,
1897  0xb4080000, 0x00c252ff, 0xbd080000, 0x00e252ff,
1898  0xc5080000, 0x00005aff, 0xcd080000, 0x00205aff,
1899  0xd5080000, 0x00405aff, 0xde080000, 0x00615aff,
1900  0xe6080000, 0x00815aff, 0xee080000, 0x00a15aff,
1901  0xf6080000, 0x00c25aff, 0xff080000, 0x00e25aff,
1902  0x000c0000, 0x000062ff, 0x080c0000, 0x002062ff,
1903  0x100c0000, 0x004062ff, 0x180c0000, 0x006162ff,
1904  0x200c0000, 0x008162ff, 0x290c0000, 0x00a162ff,
1905  0x310c0000, 0x00c262ff, 0x390c0000, 0x00e262ff,
1906  0x410c0000, 0x00006aff, 0x4a0c0000, 0x00206aff,
1907  0x520c0000, 0x00406aff, 0x5a0c0000, 0x00616aff,
1908  0x620c0000, 0x00816aff, 0x6a0c0000, 0x00a16aff,
1909  0x730c0000, 0x00c26aff, 0x7b0c0000, 0x00e26aff,
1910  0x830c0000, 0x000073ff, 0x8b0c0000, 0x002073ff,
1911  0x940c0000, 0x004073ff, 0x9c0c0000, 0x006173ff,
1912  0xa40c0000, 0x008173ff, 0xac0c0000, 0x00a173ff,
1913  0xb40c0000, 0x00c273ff, 0xbd0c0000, 0x00e273ff,
1914  0xc50c0000, 0x00007bff, 0xcd0c0000, 0x00207bff,
1915  0xd50c0000, 0x00407bff, 0xde0c0000, 0x00617bff,
1916  0xe60c0000, 0x00817bff, 0xee0c0000, 0x00a17bff,
1917  0xf60c0000, 0x00c27bff, 0xff0c0000, 0x00e27bff,
1918  0x00100000, 0x000083ff, 0x08100000, 0x002083ff,
1919  0x10100000, 0x004083ff, 0x18100000, 0x006183ff,
1920  0x20100000, 0x008183ff, 0x29100000, 0x00a183ff,
1921  0x31100000, 0x00c283ff, 0x39100000, 0x00e283ff,
1922  0x41100000, 0x00008bff, 0x4a100000, 0x00208bff,
1923  0x52100000, 0x00408bff, 0x5a100000, 0x00618bff,
1924  0x62100000, 0x00818bff, 0x6a100000, 0x00a18bff,
1925  0x73100000, 0x00c28bff, 0x7b100000, 0x00e28bff,
1926  0x83100000, 0x000094ff, 0x8b100000, 0x002094ff,
1927  0x94100000, 0x004094ff, 0x9c100000, 0x006194ff,
1928  0xa4100000, 0x008194ff, 0xac100000, 0x00a194ff,
1929  0xb4100000, 0x00c294ff, 0xbd100000, 0x00e294ff,
1930  0xc5100000, 0x00009cff, 0xcd100000, 0x00209cff,
1931  0xd5100000, 0x00409cff, 0xde100000, 0x00619cff,
1932  0xe6100000, 0x00819cff, 0xee100000, 0x00a19cff,
1933  0xf6100000, 0x00c29cff, 0xff100000, 0x00e29cff,
1934  0x00140000, 0x0000a4ff, 0x08140000, 0x0020a4ff,
1935  0x10140000, 0x0040a4ff, 0x18140000, 0x0061a4ff,
1936  0x20140000, 0x0081a4ff, 0x29140000, 0x00a1a4ff,
1937  0x31140000, 0x00c2a4ff, 0x39140000, 0x00e2a4ff,
1938  0x41140000, 0x0000acff, 0x4a140000, 0x0020acff,
1939  0x52140000, 0x0040acff, 0x5a140000, 0x0061acff,
1940  0x62140000, 0x0081acff, 0x6a140000, 0x00a1acff,
1941  0x73140000, 0x00c2acff, 0x7b140000, 0x00e2acff,
1942  0x83140000, 0x0000b4ff, 0x8b140000, 0x0020b4ff,
1943  0x94140000, 0x0040b4ff, 0x9c140000, 0x0061b4ff,
1944  0xa4140000, 0x0081b4ff, 0xac140000, 0x00a1b4ff,
1945  0xb4140000, 0x00c2b4ff, 0xbd140000, 0x00e2b4ff,
1946  0xc5140000, 0x0000bdff, 0xcd140000, 0x0020bdff,
1947  0xd5140000, 0x0040bdff, 0xde140000, 0x0061bdff,
1948  0xe6140000, 0x0081bdff, 0xee140000, 0x00a1bdff,
1949  0xf6140000, 0x00c2bdff, 0xff140000, 0x00e2bdff,
1950  0x00180000, 0x0000c5ff, 0x08180000, 0x0020c5ff,
1951  0x10180000, 0x0040c5ff, 0x18180000, 0x0061c5ff,
1952  0x20180000, 0x0081c5ff, 0x29180000, 0x00a1c5ff,
1953  0x31180000, 0x00c2c5ff, 0x39180000, 0x00e2c5ff,
1954  0x41180000, 0x0000cdff, 0x4a180000, 0x0020cdff,
1955  0x52180000, 0x0040cdff, 0x5a180000, 0x0061cdff,
1956  0x62180000, 0x0081cdff, 0x6a180000, 0x00a1cdff,
1957  0x73180000, 0x00c2cdff, 0x7b180000, 0x00e2cdff,
1958  0x83180000, 0x0000d5ff, 0x8b180000, 0x0020d5ff,
1959  0x94180000, 0x0040d5ff, 0x9c180000, 0x0061d5ff,
1960  0xa4180000, 0x0081d5ff, 0xac180000, 0x00a1d5ff,
1961  0xb4180000, 0x00c2d5ff, 0xbd180000, 0x00e2d5ff,
1962  0xc5180000, 0x0000deff, 0xcd180000, 0x0020deff,
1963  0xd5180000, 0x0040deff, 0xde180000, 0x0061deff,
1964  0xe6180000, 0x0081deff, 0xee180000, 0x00a1deff,
1965  0xf6180000, 0x00c2deff, 0xff180000, 0x00e2deff,
1966  0x001c0000, 0x0000e6ff, 0x081c0000, 0x0020e6ff,
1967  0x101c0000, 0x0040e6ff, 0x181c0000, 0x0061e6ff,
1968  0x201c0000, 0x0081e6ff, 0x291c0000, 0x00a1e6ff,
1969  0x311c0000, 0x00c2e6ff, 0x391c0000, 0x00e2e6ff,
1970  0x411c0000, 0x0000eeff, 0x4a1c0000, 0x0020eeff,
1971  0x521c0000, 0x0040eeff, 0x5a1c0000, 0x0061eeff,
1972  0x621c0000, 0x0081eeff, 0x6a1c0000, 0x00a1eeff,
1973  0x731c0000, 0x00c2eeff, 0x7b1c0000, 0x00e2eeff,
1974  0x831c0000, 0x0000f6ff, 0x8b1c0000, 0x0020f6ff,
1975  0x941c0000, 0x0040f6ff, 0x9c1c0000, 0x0061f6ff,
1976  0xa41c0000, 0x0081f6ff, 0xac1c0000, 0x00a1f6ff,
1977  0xb41c0000, 0x00c2f6ff, 0xbd1c0000, 0x00e2f6ff,
1978  0xc51c0000, 0x0000ffff, 0xcd1c0000, 0x0020ffff,
1979  0xd51c0000, 0x0040ffff, 0xde1c0000, 0x0061ffff,
1980  0xe61c0000, 0x0081ffff, 0xee1c0000, 0x00a1ffff,
1981  0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff
1982 };
1983 
1984 static void
1986 {
1988 }
1989 
1990 static void
1992 {
1993 #ifndef USE_DUFFS_LOOP
1994  int c;
1995 #endif
1996  int width, height;
1997  Uint8 *src;
1998  const Uint8 *map;
1999  Uint8 *dst;
2000  int srcskip, dstskip;
2001  int srcbpp;
2002  Uint32 Pixel;
2003  int sR, sG, sB;
2004  SDL_PixelFormat *srcfmt;
2005 
2006  /* Set up some basic variables */
2007  width = info->dst_w;
2008  height = info->dst_h;
2009  src = info->src;
2010  srcskip = info->src_skip;
2011  dst = info->dst;
2012  dstskip = info->dst_skip;
2013  map = info->table;
2014  srcfmt = info->src_fmt;
2015  srcbpp = srcfmt->BytesPerPixel;
2016 
2017  if (map == NULL) {
2018  while (height--) {
2019 #ifdef USE_DUFFS_LOOP
2020  /* *INDENT-OFF* */
2021  DUFFS_LOOP(
2022  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
2023  sR, sG, sB);
2024  if ( 1 ) {
2025  /* Pack RGB into 8bit pixel */
2026  *dst = ((sR>>5)<<(3+2))|
2027  ((sG>>5)<<(2)) |
2028  ((sB>>6)<<(0)) ;
2029  }
2030  dst++;
2031  src += srcbpp;
2032  , width);
2033  /* *INDENT-ON* */
2034 #else
2035  for (c = width; c; --c) {
2036  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
2037  if (1) {
2038  /* Pack RGB into 8bit pixel */
2039  *dst = ((sR >> 5) << (3 + 2)) |
2040  ((sG >> 5) << (2)) | ((sB >> 6) << (0));
2041  }
2042  dst++;
2043  src += srcbpp;
2044  }
2045 #endif
2046  src += srcskip;
2047  dst += dstskip;
2048  }
2049  } else {
2050  while (height--) {
2051 #ifdef USE_DUFFS_LOOP
2052  /* *INDENT-OFF* */
2053  DUFFS_LOOP(
2054  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
2055  sR, sG, sB);
2056  if ( 1 ) {
2057  /* Pack RGB into 8bit pixel */
2058  *dst = map[((sR>>5)<<(3+2))|
2059  ((sG>>5)<<(2)) |
2060  ((sB>>6)<<(0)) ];
2061  }
2062  dst++;
2063  src += srcbpp;
2064  , width);
2065  /* *INDENT-ON* */
2066 #else
2067  for (c = width; c; --c) {
2068  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
2069  if (1) {
2070  /* Pack RGB into 8bit pixel */
2071  *dst = map[((sR >> 5) << (3 + 2)) |
2072  ((sG >> 5) << (2)) | ((sB >> 6) << (0))];
2073  }
2074  dst++;
2075  src += srcbpp;
2076  }
2077 #endif /* USE_DUFFS_LOOP */
2078  src += srcskip;
2079  dst += dstskip;
2080  }
2081  }
2082 }
2083 
2084 /* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */
2085 static void
2087 {
2088  int width = info->dst_w;
2089  int height = info->dst_h;
2090  Uint32 *src = (Uint32 *) info->src;
2091  int srcskip = info->src_skip;
2092  Uint32 *dst = (Uint32 *) info->dst;
2093  int dstskip = info->dst_skip;
2094  SDL_PixelFormat *srcfmt = info->src_fmt;
2095  SDL_PixelFormat *dstfmt = info->dst_fmt;
2096 
2097  if (dstfmt->Amask) {
2098  /* RGB->RGBA, SET_ALPHA */
2099  Uint32 mask = (info->a >> dstfmt->Aloss) << dstfmt->Ashift;
2100 
2101  while (height--) {
2102  /* *INDENT-OFF* */
2103  DUFFS_LOOP(
2104  {
2105  *dst = *src | mask;
2106  ++dst;
2107  ++src;
2108  },
2109  width);
2110  /* *INDENT-ON* */
2111  src = (Uint32 *) ((Uint8 *) src + srcskip);
2112  dst = (Uint32 *) ((Uint8 *) dst + dstskip);
2113  }
2114  } else {
2115  /* RGBA->RGB, NO_ALPHA */
2116  Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
2117 
2118  while (height--) {
2119  /* *INDENT-OFF* */
2120  DUFFS_LOOP(
2121  {
2122  *dst = *src & mask;
2123  ++dst;
2124  ++src;
2125  },
2126  width);
2127  /* *INDENT-ON* */
2128  src = (Uint32 *) ((Uint8 *) src + srcskip);
2129  dst = (Uint32 *) ((Uint8 *) dst + dstskip);
2130  }
2131  }
2132 }
2133 
2134 /* blits 32 bit RGBA<->RGBA with both surfaces having the same R,G,B,A fields */
2135 static void
2137 {
2138  int width = info->dst_w;
2139  int height = info->dst_h;
2140  Uint32 *src = (Uint32 *) info->src;
2141  int srcskip = info->src_skip;
2142  Uint32 *dst = (Uint32 *) info->dst;
2143  int dstskip = info->dst_skip;
2144 
2145  /* RGBA->RGBA, COPY_ALPHA */
2146  while (height--) {
2147  /* *INDENT-OFF* */
2148  DUFFS_LOOP(
2149  {
2150  *dst = *src;
2151  ++dst;
2152  ++src;
2153  },
2154  width);
2155  /* *INDENT-ON* */
2156  src = (Uint32 *) ((Uint8 *) src + srcskip);
2157  dst = (Uint32 *) ((Uint8 *) dst + dstskip);
2158  }
2159 }
2160 
2161 /* permutation for mapping srcfmt to dstfmt, overloading or not the alpha channel */
2162 static void
2164  int *_p0 , int *_p1, int *_p2, int *_p3, int *_alpha_channel)
2165 {
2166  int alpha_channel = 0, p0, p1, p2, p3;
2167 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
2168  int Pixel = 0x04030201; /* identity permutation */
2169 #else
2170  int Pixel = 0x01020304; /* identity permutation */
2171  int srcbpp = srcfmt->BytesPerPixel;
2172  int dstbpp = dstfmt->BytesPerPixel;
2173 #endif
2174 
2175  if (srcfmt->Amask) {
2176  RGBA_FROM_PIXEL(Pixel, srcfmt, p0, p1, p2, p3);
2177  } else {
2178  RGB_FROM_PIXEL(Pixel, srcfmt, p0, p1, p2);
2179  p3 = 0;
2180  }
2181 
2182  if (dstfmt->Amask) {
2183  if (srcfmt->Amask) {
2184  PIXEL_FROM_RGBA(Pixel, dstfmt, p0, p1, p2, p3);
2185  } else {
2186  PIXEL_FROM_RGBA(Pixel, dstfmt, p0, p1, p2, 0);
2187  }
2188  } else {
2189  PIXEL_FROM_RGB(Pixel, dstfmt, p0, p1, p2);
2190  }
2191 
2192 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
2193  p0 = Pixel & 0xFF;
2194  p1 = (Pixel >> 8) & 0xFF;
2195  p2 = (Pixel >> 16) & 0xFF;
2196  p3 = (Pixel >> 24) & 0xFF;
2197 #else
2198  p3 = Pixel & 0xFF;
2199  p2 = (Pixel >> 8) & 0xFF;
2200  p1 = (Pixel >> 16) & 0xFF;
2201  p0 = (Pixel >> 24) & 0xFF;
2202 #endif
2203 
2204  if (p0 == 0) {
2205  p0 = 1;
2206  alpha_channel = 0;
2207  } else if (p1 == 0) {
2208  p1 = 1;
2209  alpha_channel = 1;
2210  } else if (p2 == 0) {
2211  p2 = 1;
2212  alpha_channel = 2;
2213  } else if (p3 == 0) {
2214  p3 = 1;
2215  alpha_channel = 3;
2216  }
2217 
2218 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
2219 #else
2220  if (srcbpp == 3 && dstbpp == 4) {
2221  if (p0 != 1) p0--;
2222  if (p1 != 1) p1--;
2223  if (p2 != 1) p2--;
2224  if (p3 != 1) p3--;
2225  } else if (srcbpp == 4 && dstbpp == 3) {
2226  p0 = p1;
2227  p1 = p2;
2228  p2 = p3;
2229  }
2230 #endif
2231  *_p0 = p0 - 1;
2232  *_p1 = p1 - 1;
2233  *_p2 = p2 - 1;
2234  *_p3 = p3 - 1;
2235 
2236  if (_alpha_channel) {
2237  *_alpha_channel = alpha_channel;
2238  }
2239  return;
2240 }
2241 
2242 
2243 static void
2245 {
2246  int width = info->dst_w;
2247  int height = info->dst_h;
2248  Uint8 *src = info->src;
2249  int srcskip = info->src_skip;
2250  Uint8 *dst = info->dst;
2251  int dstskip = info->dst_skip;
2252  SDL_PixelFormat *srcfmt = info->src_fmt;
2253  int srcbpp = srcfmt->BytesPerPixel;
2254  SDL_PixelFormat *dstfmt = info->dst_fmt;
2255  int dstbpp = dstfmt->BytesPerPixel;
2256  unsigned alpha = dstfmt->Amask ? info->a : 0;
2257 
2258 #if HAVE_FAST_WRITE_INT8
2259  /* Blit with permutation: 4->4 */
2260  if (srcbpp == 4 && dstbpp == 4 &&
2261  srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 &&
2262  dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
2263 
2264  /* Find the appropriate permutation */
2265  int alpha_channel, p0, p1, p2, p3;
2266  get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel);
2267 
2268  while (height--) {
2269  /* *INDENT-OFF* */
2270  DUFFS_LOOP(
2271  {
2272  dst[0] = src[p0];
2273  dst[1] = src[p1];
2274  dst[2] = src[p2];
2275  dst[3] = src[p3];
2276  dst[alpha_channel] = alpha;
2277  src += 4;
2278  dst += 4;
2279  }, width);
2280  /* *INDENT-ON* */
2281  src += srcskip;
2282  dst += dstskip;
2283  }
2284  return;
2285  }
2286 #endif
2287 
2288  /* Blit with permutation: 4->3 */
2289  if (srcbpp == 4 && dstbpp == 3 &&
2290  srcfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
2291 
2292  /* Find the appropriate permutation */
2293  int p0, p1, p2, p3;
2294  get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL);
2295 
2296  while (height--) {
2297  /* *INDENT-OFF* */
2298  DUFFS_LOOP(
2299  {
2300  dst[0] = src[p0];
2301  dst[1] = src[p1];
2302  dst[2] = src[p2];
2303  src += 4;
2304  dst += 3;
2305  }, width);
2306  /* *INDENT-ON* */
2307  src += srcskip;
2308  dst += dstskip;
2309  }
2310  return;
2311  }
2312 
2313 #if HAVE_FAST_WRITE_INT8
2314  /* Blit with permutation: 3->4 */
2315  if (srcbpp == 3 && dstbpp == 4 &&
2316  dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
2317 
2318  /* Find the appropriate permutation */
2319  int alpha_channel, p0, p1, p2, p3;
2320  get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel);
2321 
2322  while (height--) {
2323  /* *INDENT-OFF* */
2324  DUFFS_LOOP(
2325  {
2326  dst[0] = src[p0];
2327  dst[1] = src[p1];
2328  dst[2] = src[p2];
2329  dst[3] = src[p3];
2330  dst[alpha_channel] = alpha;
2331  src += 3;
2332  dst += 4;
2333  }, width);
2334  /* *INDENT-ON* */
2335  src += srcskip;
2336  dst += dstskip;
2337  }
2338  return;
2339  }
2340 #endif
2341 
2342  while (height--) {
2343  /* *INDENT-OFF* */
2344  DUFFS_LOOP(
2345  {
2346  Uint32 Pixel;
2347  unsigned sR;
2348  unsigned sG;
2349  unsigned sB;
2350  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
2351  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
2352  dst += dstbpp;
2353  src += srcbpp;
2354  },
2355  width);
2356  /* *INDENT-ON* */
2357  src += srcskip;
2358  dst += dstskip;
2359  }
2360 }
2361 
2362 static void
2364 {
2365  int width = info->dst_w;
2366  int height = info->dst_h;
2367  Uint8 *src = info->src;
2368  int srcskip = info->src_skip;
2369  Uint8 *dst = info->dst;
2370  int dstskip = info->dst_skip;
2371  SDL_PixelFormat *srcfmt = info->src_fmt;
2372  int srcbpp = srcfmt->BytesPerPixel;
2373  SDL_PixelFormat *dstfmt = info->dst_fmt;
2374  int dstbpp = dstfmt->BytesPerPixel;
2375  int c;
2376 
2377 #if HAVE_FAST_WRITE_INT8
2378  /* Blit with permutation: 4->4 */
2379  if (srcbpp == 4 && dstbpp == 4 &&
2380  srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 &&
2381  dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
2382 
2383  /* Find the appropriate permutation */
2384  int p0, p1, p2, p3;
2385  get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL);
2386 
2387  while (height--) {
2388  /* *INDENT-OFF* */
2389  DUFFS_LOOP(
2390  {
2391  dst[0] = src[p0];
2392  dst[1] = src[p1];
2393  dst[2] = src[p2];
2394  dst[3] = src[p3];
2395  src += 4;
2396  dst += 4;
2397  }, width);
2398  /* *INDENT-ON* */
2399  src += srcskip;
2400  dst += dstskip;
2401  }
2402  return;
2403  }
2404 #endif
2405 
2406  while (height--) {
2407  for (c = width; c; --c) {
2408  Uint32 Pixel;
2409  unsigned sR, sG, sB, sA;
2410  DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
2411  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
2412  dst += dstbpp;
2413  src += srcbpp;
2414  }
2415  src += srcskip;
2416  dst += dstskip;
2417  }
2418 }
2419 
2420 static void
2422 {
2423  int width = info->dst_w;
2424  int height = info->dst_h;
2425  Uint8 *src = info->src;
2426  int srcskip = info->src_skip;
2427  Uint8 *dst = info->dst;
2428  int dstskip = info->dst_skip;
2429  SDL_PixelFormat *srcfmt = info->src_fmt;
2430  const Uint8 *palmap = info->table;
2431  Uint32 ckey = info->colorkey;
2432  Uint32 rgbmask = ~srcfmt->Amask;
2433  int srcbpp;
2434  Uint32 Pixel;
2435  unsigned sR, sG, sB;
2436 
2437  /* Set up some basic variables */
2438  srcbpp = srcfmt->BytesPerPixel;
2439  ckey &= rgbmask;
2440 
2441  if (palmap == NULL) {
2442  while (height--) {
2443  /* *INDENT-OFF* */
2444  DUFFS_LOOP(
2445  {
2446  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
2447  sR, sG, sB);
2448  if ( (Pixel & rgbmask) != ckey ) {
2449  /* Pack RGB into 8bit pixel */
2450  *dst = (Uint8)(((sR>>5)<<(3+2))|
2451  ((sG>>5)<<(2)) |
2452  ((sB>>6)<<(0)));
2453  }
2454  dst++;
2455  src += srcbpp;
2456  },
2457  width);
2458  /* *INDENT-ON* */
2459  src += srcskip;
2460  dst += dstskip;
2461  }
2462  } else {
2463  while (height--) {
2464  /* *INDENT-OFF* */
2465  DUFFS_LOOP(
2466  {
2467  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
2468  sR, sG, sB);
2469  if ( (Pixel & rgbmask) != ckey ) {
2470  /* Pack RGB into 8bit pixel */
2471  *dst = (Uint8)palmap[((sR>>5)<<(3+2))|
2472  ((sG>>5)<<(2)) |
2473  ((sB>>6)<<(0)) ];
2474  }
2475  dst++;
2476  src += srcbpp;
2477  },
2478  width);
2479  /* *INDENT-ON* */
2480  src += srcskip;
2481  dst += dstskip;
2482  }
2483  }
2484 }
2485 
2486 static void
2488 {
2489  int width = info->dst_w;
2490  int height = info->dst_h;
2491  Uint16 *srcp = (Uint16 *) info->src;
2492  int srcskip = info->src_skip;
2493  Uint16 *dstp = (Uint16 *) info->dst;
2494  int dstskip = info->dst_skip;
2495  Uint32 ckey = info->colorkey;
2496  Uint32 rgbmask = ~info->src_fmt->Amask;
2497 
2498  /* Set up some basic variables */
2499  srcskip /= 2;
2500  dstskip /= 2;
2501  ckey &= rgbmask;
2502 
2503  while (height--) {
2504  /* *INDENT-OFF* */
2505  DUFFS_LOOP(
2506  {
2507  if ( (*srcp & rgbmask) != ckey ) {
2508  *dstp = *srcp;
2509  }
2510  dstp++;
2511  srcp++;
2512  },
2513  width);
2514  /* *INDENT-ON* */
2515  srcp += srcskip;
2516  dstp += dstskip;
2517  }
2518 }
2519 
2520 static void
2522 {
2523  int width = info->dst_w;
2524  int height = info->dst_h;
2525  Uint8 *src = info->src;
2526  int srcskip = info->src_skip;
2527  Uint8 *dst = info->dst;
2528  int dstskip = info->dst_skip;
2529  Uint32 ckey = info->colorkey;
2530  SDL_PixelFormat *srcfmt = info->src_fmt;
2531  SDL_PixelFormat *dstfmt = info->dst_fmt;
2532  int srcbpp = srcfmt->BytesPerPixel;
2533  int dstbpp = dstfmt->BytesPerPixel;
2534  unsigned alpha = dstfmt->Amask ? info->a : 0;
2535  Uint32 rgbmask = ~srcfmt->Amask;
2536  int sfmt = srcfmt->format;
2537  int dfmt = dstfmt->format;
2538 
2539  /* Set up some basic variables */
2540  ckey &= rgbmask;
2541 
2542  /* BPP 4, same rgb */
2543  if (srcbpp == 4 && dstbpp == 4 && srcfmt->Rmask == dstfmt->Rmask && srcfmt->Gmask == dstfmt->Gmask && srcfmt->Bmask == dstfmt->Bmask) {
2544  Uint32 *src32 = (Uint32*)src;
2545  Uint32 *dst32 = (Uint32*)dst;
2546 
2547  if (dstfmt->Amask) {
2548  /* RGB->RGBA, SET_ALPHA */
2549  Uint32 mask = info->a << dstfmt->Ashift;
2550  while (height--) {
2551  /* *INDENT-OFF* */
2552  DUFFS_LOOP(
2553  {
2554  if ((*src32 & rgbmask) != ckey) {
2555  *dst32 = *src32 | mask;
2556  }
2557  ++dst32;
2558  ++src32;
2559  }, width);
2560  /* *INDENT-ON* */
2561  src32 = (Uint32 *) ((Uint8 *) src32 + srcskip);
2562  dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip);
2563  }
2564  return;
2565  } else {
2566  /* RGBA->RGB, NO_ALPHA */
2567  Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
2568  while (height--) {
2569  /* *INDENT-OFF* */
2570  DUFFS_LOOP(
2571  {
2572  if ((*src32 & rgbmask) != ckey) {
2573  *dst32 = *src32 & mask;
2574  }
2575  ++dst32;
2576  ++src32;
2577  }, width);
2578  /* *INDENT-ON* */
2579  src32 = (Uint32 *) ((Uint8 *) src32 + srcskip);
2580  dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip);
2581  }
2582  return;
2583  }
2584  }
2585 
2586 #if HAVE_FAST_WRITE_INT8
2587  /* Blit with permutation: 4->4 */
2588  if (srcbpp == 4 && dstbpp == 4 &&
2589  srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 &&
2590  dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
2591 
2592  /* Find the appropriate permutation */
2593  int alpha_channel, p0, p1, p2, p3;
2594  get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel);
2595 
2596  while (height--) {
2597  /* *INDENT-OFF* */
2598  DUFFS_LOOP(
2599  {
2600  Uint32 *src32 = (Uint32*)src;
2601 
2602  if ((*src32 & rgbmask) != ckey) {
2603  dst[0] = src[p0];
2604  dst[1] = src[p1];
2605  dst[2] = src[p2];
2606  dst[3] = src[p3];
2607  dst[alpha_channel] = alpha;
2608  }
2609  src += 4;
2610  dst += 4;
2611  }, width);
2612  /* *INDENT-ON* */
2613  src += srcskip;
2614  dst += dstskip;
2615  }
2616  return;
2617  }
2618 #endif
2619 
2620  /* BPP 3, same rgb triplet */
2621  if ((sfmt == SDL_PIXELFORMAT_RGB24 && dfmt == SDL_PIXELFORMAT_RGB24) ||
2622  (sfmt == SDL_PIXELFORMAT_BGR24 && dfmt == SDL_PIXELFORMAT_BGR24)) {
2623 
2624 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
2625  Uint8 k0 = ckey & 0xFF;
2626  Uint8 k1 = (ckey >> 8) & 0xFF;
2627  Uint8 k2 = (ckey >> 16) & 0xFF;
2628 #else
2629  Uint8 k0 = (ckey >> 16) & 0xFF;
2630  Uint8 k1 = (ckey >> 8) & 0xFF;
2631  Uint8 k2 = ckey & 0xFF;
2632 #endif
2633 
2634  while (height--) {
2635  /* *INDENT-OFF* */
2636  DUFFS_LOOP(
2637  {
2638  Uint8 s0 = src[0];
2639  Uint8 s1 = src[1];
2640  Uint8 s2 = src[2];
2641 
2642  if (k0 != s0 || k1 != s1 || k2 != s2) {
2643  dst[0] = s0;
2644  dst[1] = s1;
2645  dst[2] = s2;
2646  }
2647  src += 3;
2648  dst += 3;
2649  },
2650  width);
2651  /* *INDENT-ON* */
2652  src += srcskip;
2653  dst += dstskip;
2654  }
2655  return;
2656  }
2657 
2658  /* BPP 3, inversed rgb triplet */
2659  if ((sfmt == SDL_PIXELFORMAT_RGB24 && dfmt == SDL_PIXELFORMAT_BGR24) ||
2660  (sfmt == SDL_PIXELFORMAT_BGR24 && dfmt == SDL_PIXELFORMAT_RGB24)) {
2661 
2662 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
2663  Uint8 k0 = ckey & 0xFF;
2664  Uint8 k1 = (ckey >> 8) & 0xFF;
2665  Uint8 k2 = (ckey >> 16) & 0xFF;
2666 #else
2667  Uint8 k0 = (ckey >> 16) & 0xFF;
2668  Uint8 k1 = (ckey >> 8) & 0xFF;
2669  Uint8 k2 = ckey & 0xFF;
2670 #endif
2671 
2672  while (height--) {
2673  /* *INDENT-OFF* */
2674  DUFFS_LOOP(
2675  {
2676  Uint8 s0 = src[0];
2677  Uint8 s1 = src[1];
2678  Uint8 s2 = src[2];
2679  if (k0 != s0 || k1 != s1 || k2 != s2) {
2680  /* Inversed RGB */
2681  dst[0] = s2;
2682  dst[1] = s1;
2683  dst[2] = s0;
2684  }
2685  src += 3;
2686  dst += 3;
2687  },
2688  width);
2689  /* *INDENT-ON* */
2690  src += srcskip;
2691  dst += dstskip;
2692  }
2693  return;
2694  }
2695 
2696  /* Blit with permutation: 4->3 */
2697  if (srcbpp == 4 && dstbpp == 3 &&
2698  srcfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
2699 
2700  /* Find the appropriate permutation */
2701  int p0, p1, p2, p3;
2702  get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL);
2703 
2704  while (height--) {
2705  /* *INDENT-OFF* */
2706  DUFFS_LOOP(
2707  {
2708  Uint32 *src32 = (Uint32*)src;
2709  if ((*src32 & rgbmask) != ckey) {
2710  dst[0] = src[p0];
2711  dst[1] = src[p1];
2712  dst[2] = src[p2];
2713  }
2714  src += 4;
2715  dst += 3;
2716  }, width);
2717  /* *INDENT-ON* */
2718  src += srcskip;
2719  dst += dstskip;
2720  }
2721  return;
2722  }
2723 
2724 #if HAVE_FAST_WRITE_INT8
2725  /* Blit with permutation: 3->4 */
2726  if (srcbpp == 3 && dstbpp == 4 &&
2727  dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
2728 
2729 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
2730  Uint8 k0 = ckey & 0xFF;
2731  Uint8 k1 = (ckey >> 8) & 0xFF;
2732  Uint8 k2 = (ckey >> 16) & 0xFF;
2733 #else
2734  Uint8 k0 = (ckey >> 16) & 0xFF;
2735  Uint8 k1 = (ckey >> 8) & 0xFF;
2736  Uint8 k2 = ckey & 0xFF;
2737 #endif
2738 
2739  /* Find the appropriate permutation */
2740  int alpha_channel, p0, p1, p2, p3;
2741  get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel);
2742 
2743  while (height--) {
2744  /* *INDENT-OFF* */
2745  DUFFS_LOOP(
2746  {
2747  Uint8 s0 = src[0];
2748  Uint8 s1 = src[1];
2749  Uint8 s2 = src[2];
2750 
2751  if (k0 != s0 || k1 != s1 || k2 != s2) {
2752  dst[0] = src[p0];
2753  dst[1] = src[p1];
2754  dst[2] = src[p2];
2755  dst[3] = src[p3];
2756  dst[alpha_channel] = alpha;
2757  }
2758  src += 3;
2759  dst += 4;
2760  }, width);
2761  /* *INDENT-ON* */
2762  src += srcskip;
2763  dst += dstskip;
2764  }
2765  return;
2766  }
2767 #endif
2768 
2769  while (height--) {
2770  /* *INDENT-OFF* */
2771  DUFFS_LOOP(
2772  {
2773  Uint32 Pixel;
2774  unsigned sR;
2775  unsigned sG;
2776  unsigned sB;
2777  RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel);
2778  if ( (Pixel & rgbmask) != ckey ) {
2779  RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB);
2780  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
2781  }
2782  dst += dstbpp;
2783  src += srcbpp;
2784  },
2785  width);
2786  /* *INDENT-ON* */
2787  src += srcskip;
2788  dst += dstskip;
2789  }
2790 }
2791 
2792 static void
2794 {
2795  int width = info->dst_w;
2796  int height = info->dst_h;
2797  Uint8 *src = info->src;
2798  int srcskip = info->src_skip;
2799  Uint8 *dst = info->dst;
2800  int dstskip = info->dst_skip;
2801  Uint32 ckey = info->colorkey;
2802  SDL_PixelFormat *srcfmt = info->src_fmt;
2803  SDL_PixelFormat *dstfmt = info->dst_fmt;
2804  Uint32 rgbmask = ~srcfmt->Amask;
2805 
2806  Uint8 srcbpp;
2807  Uint8 dstbpp;
2808  Uint32 Pixel;
2809  unsigned sR, sG, sB, sA;
2810 
2811  /* Set up some basic variables */
2812  srcbpp = srcfmt->BytesPerPixel;
2813  dstbpp = dstfmt->BytesPerPixel;
2814  ckey &= rgbmask;
2815 
2816  /* Fastpath: same source/destination format, with Amask, bpp 32, loop is vectorized. ~10x faster */
2817  if (srcfmt->format == dstfmt->format) {
2818 
2819  if (srcfmt->format == SDL_PIXELFORMAT_ARGB8888 ||
2820  srcfmt->format == SDL_PIXELFORMAT_ABGR8888 ||
2821  srcfmt->format == SDL_PIXELFORMAT_BGRA8888 ||
2822  srcfmt->format == SDL_PIXELFORMAT_RGBA8888) {
2823 
2824  Uint32 *src32 = (Uint32*)src;
2825  Uint32 *dst32 = (Uint32*)dst;
2826  while (height--) {
2827  /* *INDENT-OFF* */
2828  DUFFS_LOOP(
2829  {
2830  if ((*src32 & rgbmask) != ckey) {
2831  *dst32 = *src32;
2832  }
2833  ++src32;
2834  ++dst32;
2835  },
2836  width);
2837  /* *INDENT-ON* */
2838  src32 = (Uint32 *)((Uint8 *)src32 + srcskip);
2839  dst32 = (Uint32 *)((Uint8 *)dst32 + dstskip);
2840  }
2841  }
2842  return;
2843  }
2844 
2845 #if HAVE_FAST_WRITE_INT8
2846  /* Blit with permutation: 4->4 */
2847  if (srcbpp == 4 && dstbpp == 4 &&
2848  srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 &&
2849  dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) {
2850 
2851  /* Find the appropriate permutation */
2852  int p0, p1, p2, p3;
2853  get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL);
2854 
2855  while (height--) {
2856  /* *INDENT-OFF* */
2857  DUFFS_LOOP(
2858  {
2859  Uint32 *src32 = (Uint32*)src;
2860  if ((*src32 & rgbmask) != ckey) {
2861  dst[0] = src[p0];
2862  dst[1] = src[p1];
2863  dst[2] = src[p2];
2864  dst[3] = src[p3];
2865  }
2866  src += 4;
2867  dst += 4;
2868  }, width);
2869  /* *INDENT-ON* */
2870  src += srcskip;
2871  dst += dstskip;
2872  }
2873  return;
2874  }
2875 #endif
2876 
2877  while (height--) {
2878  /* *INDENT-OFF* */
2879  DUFFS_LOOP(
2880  {
2881  DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
2882  if ( (Pixel & rgbmask) != ckey ) {
2883  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
2884  }
2885  dst += dstbpp;
2886  src += srcbpp;
2887  },
2888  width);
2889  /* *INDENT-ON* */
2890  src += srcskip;
2891  dst += dstskip;
2892  }
2893 }
2894 
2895 /* Special optimized blit for ARGB 2-10-10-10 --> RGBA */
2896 static void
2898 {
2899  int width = info->dst_w;
2900  int height = info->dst_h;
2901  Uint8 *src = info->src;
2902  int srcskip = info->src_skip;
2903  Uint8 *dst = info->dst;
2904  int dstskip = info->dst_skip;
2905  SDL_PixelFormat *dstfmt = info->dst_fmt;
2906  int dstbpp = dstfmt->BytesPerPixel;
2907  Uint32 Pixel;
2908  unsigned sR, sG, sB, sA;
2909 
2910  while (height--) {
2911  /* *INDENT-OFF* */
2912  DUFFS_LOOP(
2913  {
2914  Pixel = *(Uint32 *)src;
2915  RGBA_FROM_ARGB2101010(Pixel, sR, sG, sB, sA);
2916  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
2917  dst += dstbpp;
2918  src += 4;
2919  },
2920  width);
2921  /* *INDENT-ON* */
2922  src += srcskip;
2923  dst += dstskip;
2924  }
2925 }
2926 
2927 /* Special optimized blit for RGBA --> ARGB 2-10-10-10 */
2928 static void
2930 {
2931  int width = info->dst_w;
2932  int height = info->dst_h;
2933  Uint8 *src = info->src;
2934  int srcskip = info->src_skip;
2935  Uint8 *dst = info->dst;
2936  int dstskip = info->dst_skip;
2937  SDL_PixelFormat *srcfmt = info->src_fmt;
2938  int srcbpp = srcfmt->BytesPerPixel;
2939  Uint32 Pixel;
2940  unsigned sR, sG, sB, sA;
2941 
2942  while (height--) {
2943  /* *INDENT-OFF* */
2944  DUFFS_LOOP(
2945  {
2946  DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
2947  ARGB2101010_FROM_RGBA(Pixel, sR, sG, sB, sA);
2948  *(Uint32 *)dst = Pixel;
2949  dst += 4;
2950  src += srcbpp;
2951  },
2952  width);
2953  /* *INDENT-ON* */
2954  src += srcskip;
2955  dst += dstskip;
2956  }
2957 }
2958 
2959 /* Blit_3or4_to_3or4__same_rgb: 3 or 4 bpp, same RGB triplet */
2960 static void
2962 {
2963  int width = info->dst_w;
2964  int height = info->dst_h;
2965  Uint8 *src = info->src;
2966  int srcskip = info->src_skip;
2967  Uint8 *dst = info->dst;
2968  int dstskip = info->dst_skip;
2969  SDL_PixelFormat *srcfmt = info->src_fmt;
2970  int srcbpp = srcfmt->BytesPerPixel;
2971  SDL_PixelFormat *dstfmt = info->dst_fmt;
2972  int dstbpp = dstfmt->BytesPerPixel;
2973 
2974  if (dstfmt->Amask) {
2975  /* SET_ALPHA */
2976  Uint32 mask = info->a << dstfmt->Ashift;
2977 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
2978  int i0 = 0, i1 = 1, i2 = 2;
2979 #else
2980  int i0 = srcbpp - 1 - 0;
2981  int i1 = srcbpp - 1 - 1;
2982  int i2 = srcbpp - 1 - 2;
2983 #endif
2984  while (height--) {
2985  /* *INDENT-OFF* */
2986  DUFFS_LOOP(
2987  {
2988  Uint32 *dst32 = (Uint32*)dst;
2989  Uint8 s0 = src[i0];
2990  Uint8 s1 = src[i1];
2991  Uint8 s2 = src[i2];
2992  *dst32 = (s0) | (s1 << 8) | (s2 << 16) | mask;
2993  dst += 4;
2994  src += srcbpp;
2995  }, width);
2996  /* *INDENT-ON* */
2997  src += srcskip;
2998  dst += dstskip;
2999  }
3000  } else {
3001  /* NO_ALPHA */
3002 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
3003  int i0 = 0, i1 = 1, i2 = 2;
3004  int j0 = 0, j1 = 1, j2 = 2;
3005 #else
3006  int i0 = srcbpp - 1 - 0;
3007  int i1 = srcbpp - 1 - 1;
3008  int i2 = srcbpp - 1 - 2;
3009  int j0 = dstbpp - 1 - 0;
3010  int j1 = dstbpp - 1 - 1;
3011  int j2 = dstbpp - 1 - 2;
3012 #endif
3013  while (height--) {
3014  /* *INDENT-OFF* */
3015  DUFFS_LOOP(
3016  {
3017  Uint8 s0 = src[i0];
3018  Uint8 s1 = src[i1];
3019  Uint8 s2 = src[i2];
3020  dst[j0] = s0;
3021  dst[j1] = s1;
3022  dst[j2] = s2;
3023  dst += dstbpp;
3024  src += srcbpp;
3025  }, width);
3026  /* *INDENT-ON* */
3027  src += srcskip;
3028  dst += dstskip;
3029  }
3030  }
3031  return;
3032 }
3033 
3034 /* Blit_3or4_to_3or4__inversed_rgb: 3 or 4 bpp, inversed RGB triplet */
3035 static void
3037 {
3038  int width = info->dst_w;
3039  int height = info->dst_h;
3040  Uint8 *src = info->src;
3041  int srcskip = info->src_skip;
3042  Uint8 *dst = info->dst;
3043  int dstskip = info->dst_skip;
3044  SDL_PixelFormat *srcfmt = info->src_fmt;
3045  int srcbpp = srcfmt->BytesPerPixel;
3046  SDL_PixelFormat *dstfmt = info->dst_fmt;
3047  int dstbpp = dstfmt->BytesPerPixel;
3048 
3049  if (dstfmt->Amask) {
3050  if (srcfmt->Amask) {
3051  /* COPY_ALPHA */
3052  /* Only to switch ABGR8888 <-> ARGB8888 */
3053  while (height--) {
3054 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
3055  int i0 = 0, i1 = 1, i2 = 2, i3 = 3;
3056 #else
3057  int i0 = 3, i1 = 2, i2 = 1, i3 = 0;
3058 #endif
3059  /* *INDENT-OFF* */
3060  DUFFS_LOOP(
3061  {
3062  Uint32 *dst32 = (Uint32*)dst;
3063  Uint8 s0 = src[i0];
3064  Uint8 s1 = src[i1];
3065  Uint8 s2 = src[i2];
3066  Uint32 alphashift = src[i3] << dstfmt->Ashift;
3067  /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
3068  *dst32 = (s0 << 16) | (s1 << 8) | (s2) | alphashift;
3069  dst += 4;
3070  src += 4;
3071  }, width);
3072  /* *INDENT-ON* */
3073  src += srcskip;
3074  dst += dstskip;
3075  }
3076  } else {
3077  /* SET_ALPHA */
3078  Uint32 mask = info->a << dstfmt->Ashift;
3079 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
3080  int i0 = 0, i1 = 1, i2 = 2;
3081 #else
3082  int i0 = srcbpp - 1 - 0;
3083  int i1 = srcbpp - 1 - 1;
3084  int i2 = srcbpp - 1 - 2;
3085 #endif
3086  while (height--) {
3087  /* *INDENT-OFF* */
3088  DUFFS_LOOP(
3089  {
3090  Uint32 *dst32 = (Uint32*)dst;
3091  Uint8 s0 = src[i0];
3092  Uint8 s1 = src[i1];
3093  Uint8 s2 = src[i2];
3094  /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
3095  *dst32 = (s0 << 16) | (s1 << 8) | (s2) | mask;
3096  dst += 4;
3097  src += srcbpp;
3098  }, width);
3099  /* *INDENT-ON* */
3100  src += srcskip;
3101  dst += dstskip;
3102  }
3103  }
3104  } else {
3105  /* NO_ALPHA */
3106 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
3107  int i0 = 0, i1 = 1, i2 = 2;
3108  int j0 = 2, j1 = 1, j2 = 0;
3109 #else
3110  int i0 = srcbpp - 1 - 0;
3111  int i1 = srcbpp - 1 - 1;
3112  int i2 = srcbpp - 1 - 2;
3113  int j0 = dstbpp - 1 - 2;
3114  int j1 = dstbpp - 1 - 1;
3115  int j2 = dstbpp - 1 - 0;
3116 #endif
3117  while (height--) {
3118  /* *INDENT-OFF* */
3119  DUFFS_LOOP(
3120  {
3121  Uint8 s0 = src[i0];
3122  Uint8 s1 = src[i1];
3123  Uint8 s2 = src[i2];
3124  /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
3125  dst[j0] = s0;
3126  dst[j1] = s1;
3127  dst[j2] = s2;
3128  dst += dstbpp;
3129  src += srcbpp;
3130  }, width);
3131  /* *INDENT-ON* */
3132  src += srcskip;
3133  dst += dstskip;
3134  }
3135  }
3136  return;
3137 }
3138 
3139 /* Normal N to N optimized blitters */
3140 #define NO_ALPHA 1
3141 #define SET_ALPHA 2
3142 #define COPY_ALPHA 4
3144 {
3146  int dstbpp;
3150  Uint32 alpha; /* bitwise NO_ALPHA, SET_ALPHA, COPY_ALPHA */
3151 };
3152 static const struct blit_table normal_blit_1[] = {
3153  /* Default for 8-bit RGB source, never optimized */
3154  {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
3155 };
3156 
3157 static const struct blit_table normal_blit_2[] = {
3158 #if SDL_ALTIVEC_BLITTERS
3159  /* has-altivec */
3160  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
3161  2, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
3162  {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
3163  2, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
3164 #endif
3165  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
3167  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
3169  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, 0x0000FF00,
3171  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000,
3173 
3174  /* Default for 16-bit RGB source, used if no other blitter matches */
3175  {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
3176 };
3177 
3178 static const struct blit_table normal_blit_3[] = {
3179  /* 3->4 with same rgb triplet */
3180  {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
3182 #if HAVE_FAST_WRITE_INT8
3183  NO_ALPHA |
3184 #endif
3185  SET_ALPHA},
3186  {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
3188 #if HAVE_FAST_WRITE_INT8
3189  NO_ALPHA |
3190 #endif
3191  SET_ALPHA},
3192  /* 3->4 with inversed rgb triplet */
3193  {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
3195 #if HAVE_FAST_WRITE_INT8
3196  NO_ALPHA |
3197 #endif
3198  SET_ALPHA},
3199  {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
3201 #if HAVE_FAST_WRITE_INT8
3202  NO_ALPHA |
3203 #endif
3204  SET_ALPHA},
3205  /* 3->3 to switch RGB 24 <-> BGR 24 */
3206  {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x00FF0000, 0x0000FF00, 0x000000FF,
3208  {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
3210  /* Default for 24-bit RGB source, never optimized */
3211  {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
3212 };
3213 
3214 static const struct blit_table normal_blit_4[] = {
3215 #if SDL_ALTIVEC_BLITTERS
3216  /* has-altivec | dont-use-prefetch */
3217  {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
3218  6, ConvertAltivec32to32_noprefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
3219  /* has-altivec */
3220  {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
3221  2, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
3222  /* has-altivec */
3223  {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F,
3224  2, Blit_RGB888_RGB565Altivec, NO_ALPHA},
3225 #endif
3226  /* 4->3 with same rgb triplet */
3227  {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
3229  {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x00FF0000, 0x0000FF00, 0x000000FF,
3231  /* 4->3 with inversed rgb triplet */
3232  {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x00FF0000, 0x0000FF00, 0x000000FF,
3234  {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
3236  /* 4->4 with inversed rgb triplet, and COPY_ALPHA to switch ABGR8888 <-> ARGB8888 */
3237  {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
3239 #if HAVE_FAST_WRITE_INT8
3240  NO_ALPHA |
3241 #endif
3242  SET_ALPHA | COPY_ALPHA},
3243  {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
3245 #if HAVE_FAST_WRITE_INT8
3246  NO_ALPHA |
3247 #endif
3248  SET_ALPHA | COPY_ALPHA},
3249  /* RGB 888 and RGB 565 */
3250  {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F,
3252  {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F,
3254  /* Default for 32-bit RGB source, used if no other blitter matches */
3255  {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
3256 };
3257 
3258 static const struct blit_table *const normal_blit[] = {
3260 };
3261 
3262 /* Mask matches table, or table entry is zero */
3263 #define MASKOK(x, y) (((x) == (y)) || ((y) == 0x00000000))
3264 
3267 {
3268  SDL_PixelFormat *srcfmt;
3269  SDL_PixelFormat *dstfmt;
3270  const struct blit_table *table;
3271  int which;
3272  SDL_BlitFunc blitfun;
3273 
3274  /* Set up data for choosing the blit */
3275  srcfmt = surface->format;
3276  dstfmt = surface->map->dst->format;
3277 
3278  /* We don't support destinations less than 8-bits */
3279  if (dstfmt->BitsPerPixel < 8) {
3280  return (NULL);
3281  }
3282 
3283  switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
3284  case 0:
3285  blitfun = NULL;
3286  if (dstfmt->BitsPerPixel == 8) {
3287  if ((srcfmt->BytesPerPixel == 4) &&
3288  (srcfmt->Rmask == 0x00FF0000) &&
3289  (srcfmt->Gmask == 0x0000FF00) &&
3290  (srcfmt->Bmask == 0x000000FF)) {
3291  blitfun = Blit_RGB888_index8;
3292  } else if ((srcfmt->BytesPerPixel == 4) &&
3293  (srcfmt->Rmask == 0x3FF00000) &&
3294  (srcfmt->Gmask == 0x000FFC00) &&
3295  (srcfmt->Bmask == 0x000003FF)) {
3296  blitfun = Blit_RGB101010_index8;
3297  } else {
3298  blitfun = BlitNto1;
3299  }
3300  } else {
3301  /* Now the meat, choose the blitter we want */
3302  Uint32 a_need = NO_ALPHA;
3303  if (dstfmt->Amask)
3304  a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA;
3305  table = normal_blit[srcfmt->BytesPerPixel - 1];
3306  for (which = 0; table[which].dstbpp; ++which) {
3307  if (MASKOK(srcfmt->Rmask, table[which].srcR) &&
3308  MASKOK(srcfmt->Gmask, table[which].srcG) &&
3309  MASKOK(srcfmt->Bmask, table[which].srcB) &&
3310  MASKOK(dstfmt->Rmask, table[which].dstR) &&
3311  MASKOK(dstfmt->Gmask, table[which].dstG) &&
3312  MASKOK(dstfmt->Bmask, table[which].dstB) &&
3313  dstfmt->BytesPerPixel == table[which].dstbpp &&
3314  (a_need & table[which].alpha) == a_need &&
3315  ((table[which].blit_features & GetBlitFeatures()) ==
3316  table[which].blit_features))
3317  break;
3318  }
3319  blitfun = table[which].blitfunc;
3320 
3321  if (blitfun == BlitNtoN) { /* default C fallback catch-all. Slow! */
3322  if (srcfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
3323  blitfun = Blit2101010toN;
3324  } else if (dstfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
3325  blitfun = BlitNto2101010;
3326  } else if (srcfmt->BytesPerPixel == 4 &&
3327  dstfmt->BytesPerPixel == 4 &&
3328  srcfmt->Rmask == dstfmt->Rmask &&
3329  srcfmt->Gmask == dstfmt->Gmask &&
3330  srcfmt->Bmask == dstfmt->Bmask) {
3331  if (a_need == COPY_ALPHA) {
3332  if (srcfmt->Amask == dstfmt->Amask) {
3333  /* Fastpath C fallback: 32bit RGBA<->RGBA blit with matching RGBA */
3334  blitfun = Blit4to4CopyAlpha;
3335  } else {
3336  blitfun = BlitNtoNCopyAlpha;
3337  }
3338  } else {
3339  /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */
3340  blitfun = Blit4to4MaskAlpha;
3341  }
3342  } else if (a_need == COPY_ALPHA) {
3343  blitfun = BlitNtoNCopyAlpha;
3344  }
3345  }
3346  }
3347  return (blitfun);
3348 
3349  case SDL_COPY_COLORKEY:
3350  /* colorkey blit: Here we don't have too many options, mostly
3351  because RLE is the preferred fast way to deal with this.
3352  If a particular case turns out to be useful we'll add it. */
3353 
3354  if (srcfmt->BytesPerPixel == 2 && surface->map->identity)
3355  return Blit2to2Key;
3356  else if (dstfmt->BytesPerPixel == 1)
3357  return BlitNto1Key;
3358  else {
3359 #if SDL_ALTIVEC_BLITTERS
3360  if ((srcfmt->BytesPerPixel == 4) && (dstfmt->BytesPerPixel == 4)
3361  && SDL_HasAltiVec()) {
3362  return Blit32to32KeyAltivec;
3363  } else
3364 #endif
3365  if (srcfmt->Amask && dstfmt->Amask) {
3366  return BlitNtoNKeyCopyAlpha;
3367  } else {
3368  return BlitNtoNKey;
3369  }
3370  }
3371  }
3372 
3373  return NULL;
3374 }
3375 
3376 /* vi: set ts=4 sw=4 expandtab: */
Blit_RGB101010_index8
static void Blit_RGB101010_index8(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1016
SDL_BlitInfo::src
Uint8 * src
Definition: SDL_blit.h:57
SDL_PixelFormat::Rshift
Uint8 Rshift
Definition: SDL_pixels.h:330
SDL_BlitInfo::src_skip
int src_skip
Definition: SDL_blit.h:60
SDL_PixelFormat::Ashift
Uint8 Ashift
Definition: SDL_pixels.h:333
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
COPY_ALPHA
#define COPY_ALPHA
Definition: SDL_blit_N.c:3142
ASSEMBLE_RGBA
#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)
Definition: SDL_blit.h:402
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
Blit_RGB565_RGBA8888
static void Blit_RGB565_RGBA8888(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1847
RGB888_RGB565
#define RGB888_RGB565(dst, src)
Definition: SDL_blit_N.c:1246
SDL_PixelFormat::BitsPerPixel
Uint8 BitsPerPixel
Definition: SDL_pixels.h:319
ARGB2101010_FROM_RGBA
#define ARGB2101010_FROM_RGBA(Pixel, r, g, b, a)
Definition: SDL_blit.h:253
SDL_PixelFormat::BytesPerPixel
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
i1
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint i1
Definition: SDL_glfuncs.h:141
SDL_HasAltiVec
#define SDL_HasAltiVec
Definition: SDL_dynapi_overrides.h:104
RGB565_BGRA8888_LUT
static const Uint32 RGB565_BGRA8888_LUT[512]
Definition: SDL_blit_N.c:1853
mask
GLenum GLint GLuint mask
Definition: SDL_opengl_glext.h:657
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:70
RGB101010_RGB332
#define RGB101010_RGB332(dst, src)
Definition: SDL_blit_N.c:1010
Blit_RGB888_RGB555
static void Blit_RGB888_RGB555(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1136
RGBA_FROM_ARGB2101010
#define RGBA_FROM_ARGB2101010(Pixel, r, g, b, a)
Definition: SDL_blit.h:346
normal_blit_4
static const struct blit_table normal_blit_4[]
Definition: SDL_blit_N.c:3214
PIXEL_FROM_RGBA
#define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a)
Definition: SDL_blit.h:395
Blit_3or4_to_3or4__same_rgb
static void Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2961
NULL
#define NULL
Definition: begin_code.h:167
surface
EGLSurface surface
Definition: eglext.h:248
SDL_PixelFormat::format
Uint32 format
Definition: SDL_pixels.h:317
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
normal_blit
static const struct blit_table *const normal_blit[]
Definition: SDL_blit_N.c:3258
RETRIEVE_RGB_PIXEL
#define RETRIEVE_RGB_PIXEL(buf, bpp, Pixel)
Definition: SDL_blit.h:146
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1109
SDL_BlitInfo::dst_w
int dst_w
Definition: SDL_blit.h:62
SDL_BlitInfo
Definition: SDL_blit.h:55
MASKOK
#define MASKOK(x, y)
Definition: SDL_blit_N.c:3263
Blit_RGB888_index8
static void Blit_RGB888_index8(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:906
BlitNtoNKey
static void BlitNtoNKey(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2521
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
SDL_BlitInfo::dst_h
int dst_h
Definition: SDL_blit.h:62
v3
GLfloat GLfloat GLfloat GLfloat v3
Definition: SDL_opengl_glext.h:693
blit_table::srcG
Uint32 srcG
Definition: SDL_blit_N.c:3145
SDL_COPY_COLORKEY
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:39
SDL_endian.h
blit_table::srcR
Uint32 srcR
Definition: SDL_blit_N.c:3145
blit_table::dstB
Uint32 dstB
Definition: SDL_blit_N.c:3147
SDL_PixelFormat::Rmask
Uint32 Rmask
Definition: SDL_pixels.h:322
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
Blit_3or4_to_3or4__inversed_rgb
static void Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:3036
map
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint GLint GLint j2 GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLfloat *params GLenum GLint GLenum GLenum GLvoid *pixels GLenum GLint GLenum GLint *params GLenum GLenum GLint *params GLenum GLsizei const GLvoid *pointer GLenum GLenum const GLint *params GLenum GLfloat GLfloat GLint GLint const GLfloat *points GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat *points GLint GLfloat GLfloat GLint GLfloat GLfloat v2 GLenum GLenum const GLint *params GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum map
Definition: SDL_glfuncs.h:291
Blit2101010toN
static void Blit2101010toN(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2897
Blit4to4CopyAlpha
static void Blit4to4CopyAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2136
RGBA_FROM_8888
#define RGBA_FROM_8888(Pixel, fmt, r, g, b, a)
Definition: SDL_blit.h:311
SDL_COPY_RLE_MASK
#define SDL_COPY_RLE_MASK
Definition: SDL_blit.h:44
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9432
SDL_CalculateBlitN
SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface)
Definition: SDL_blit_N.c:3266
DISEMBLE_RGBA
#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a)
Definition: SDL_blit.h:353
i2
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint i2
Definition: SDL_glfuncs.h:141
s1
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: SDL_opengl_glext.h:8583
Blit_RGB565_ARGB8888
static void Blit_RGB565_ARGB8888(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1571
alpha
GLfloat GLfloat GLfloat alpha
Definition: SDL_opengl_glext.h:412
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
SDL_BlitInfo::dst
Uint8 * dst
Definition: SDL_blit.h:61
DUFFS_LOOP
#define DUFFS_LOOP(pixel_copy_increment, width)
Definition: SDL_blit.h:500
Blit_RGB888_RGB565
static void Blit_RGB888_RGB565(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1262
get_permutation
static void get_permutation(SDL_PixelFormat *srcfmt, SDL_PixelFormat *dstfmt, int *_p0, int *_p1, int *_p2, int *_p3, int *_alpha_channel)
Definition: SDL_blit_N.c:2163
v2
GLfloat GLfloat GLfloat v2
Definition: SDL_opengl_glext.h:692
s0
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition: SDL_opengl_glext.h:8583
BlitNtoN
static void BlitNtoN(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2244
NO_ALPHA
#define NO_ALPHA
Definition: SDL_blit_N.c:3140
SDL_BlitInfo::src_fmt
SDL_PixelFormat * src_fmt
Definition: SDL_blit.h:65
SDL_blit.h
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
SDL_cpuinfo.h
SDL_PIXELFORMAT_ARGB2101010
@ SDL_PIXELFORMAT_ARGB2101010
Definition: SDL_pixels.h:260
SDL_BlitInfo::dst_skip
int dst_skip
Definition: SDL_blit.h:64
SDL_BlitInfo::table
Uint8 * table
Definition: SDL_blit.h:67
Blit4to4MaskAlpha
static void Blit4to4MaskAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2086
SET_ALPHA
#define SET_ALPHA
Definition: SDL_blit_N.c:3141
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
RGB565_32
#define RGB565_32(dst, src, map)
Definition: SDL_blit_N.c:1373
SDL_assert.h
key
GLuint64 key
Definition: gl2ext.h:2192
blit_table::blitfunc
SDL_BlitFunc blitfunc
Definition: SDL_blit_N.c:3149
SDL_PixelFormat::Amask
Uint32 Amask
Definition: SDL_pixels.h:325
normal_blit_2
static const struct blit_table normal_blit_2[]
Definition: SDL_blit_N.c:3157
SDL_PIXELFORMAT_ARGB8888
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:248
SDL_PixelFormat
Definition: SDL_pixels.h:315
blit_table::dstG
Uint32 dstG
Definition: SDL_blit_N.c:3147
SDL_BlitInfo::a
Uint8 a
Definition: SDL_blit.h:70
blit_table::alpha
Uint32 alpha
Definition: SDL_blit_N.c:3150
SDL_PixelFormat::Gmask
Uint32 Gmask
Definition: SDL_pixels.h:323
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
blit_table::dstR
Uint32 dstR
Definition: SDL_blit_N.c:3147
SDL_sscanf
#define SDL_sscanf
Definition: SDL_dynapi_overrides.h:39
BlitNto1Key
static void BlitNto1Key(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2421
blit_table::srcB
Uint32 srcB
Definition: SDL_blit_N.c:3145
SDL_BlitInfo::dst_fmt
SDL_PixelFormat * dst_fmt
Definition: SDL_blit.h:66
GetBlitFeatures
#define GetBlitFeatures()
Definition: SDL_blit_N.c:887
normal_blit_1
static const struct blit_table normal_blit_1[]
Definition: SDL_blit_N.c:3152
DISEMBLE_RGB
#define DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b)
Definition: SDL_blit.h:177
Blit_RGB565_ABGR8888
static void Blit_RGB565_ABGR8888(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1709
SDL_HasMMX
#define SDL_HasMMX
Definition: SDL_dynapi_overrides.h:105
RGB888_RGB555
#define RGB888_RGB555(dst, src)
Definition: SDL_blit_N.c:1120
SDL_PixelFormat::Bmask
Uint32 Bmask
Definition: SDL_pixels.h:324
normal_blit_3
static const struct blit_table normal_blit_3[]
Definition: SDL_blit_N.c:3178
BlitNtoNCopyAlpha
static void BlitNtoNCopyAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2363
src
GLenum src
Definition: SDL_opengl_glext.h:1737
SDL_getenv
#define SDL_getenv
Definition: SDL_dynapi_overrides.h:378
v1
GLfloat GLfloat v1
Definition: SDL_opengl_glext.h:691
BlitNto2101010
static void BlitNto2101010(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2929
BlitNtoNKeyCopyAlpha
static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2793
SDL_PIXELFORMAT_RGBA8888
@ SDL_PIXELFORMAT_RGBA8888
Definition: SDL_pixels.h:251
PIXEL_FROM_RGB
#define PIXEL_FROM_RGB(Pixel, fmt, r, g, b)
Definition: SDL_blit.h:218
j1
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint GLint j1
Definition: SDL_glfuncs.h:141
SDL_PixelFormat::Bshift
Uint8 Bshift
Definition: SDL_pixels.h:332
blit_table::dstbpp
int dstbpp
Definition: SDL_blit_N.c:3146
SDL_PixelFormat::Aloss
Uint8 Aloss
Definition: SDL_pixels.h:329
Blit_RGB565_32
static void Blit_RGB565_32(SDL_BlitInfo *info, const Uint32 *map)
Definition: SDL_blit_N.c:1375
SDL_PIXELFORMAT_RGB24
@ SDL_PIXELFORMAT_RGB24
Definition: SDL_pixels.h:230
SDL_BlitInfo::colorkey
Uint32 colorkey
Definition: SDL_blit.h:69
Blit_RGB565_BGRA8888
static void Blit_RGB565_BGRA8888(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1985
SDL_PIXELFORMAT_BGRA8888
@ SDL_PIXELFORMAT_BGRA8888
Definition: SDL_pixels.h:257
SDL_PIXELFORMAT_BGR24
@ SDL_PIXELFORMAT_BGR24
Definition: SDL_pixels.h:233
bits
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition: SDL_opengl_glext.h:6176
RGB565_RGBA8888_LUT
static const Uint32 RGB565_RGBA8888_LUT[512]
Definition: SDL_blit_N.c:1715
SDL_video.h
RGB_FROM_PIXEL
#define RGB_FROM_PIXEL(Pixel, fmt, r, g, b)
Definition: SDL_blit.h:122
SDL_PixelFormat::Gshift
Uint8 Gshift
Definition: SDL_pixels.h:331
RGB565_ABGR8888_LUT
static const Uint32 RGB565_ABGR8888_LUT[512]
Definition: SDL_blit_N.c:1577
RGB565_ARGB8888_LUT
static const Uint32 RGB565_ARGB8888_LUT[512]
Definition: SDL_blit_N.c:1439
RGB888_RGB332
#define RGB888_RGB332(dst, src)
Definition: SDL_blit_N.c:900
blit_table
Definition: SDL_blit_N.c:3143
Blit2to2Key
static void Blit2to2Key(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2487
SDL_PIXELFORMAT_ABGR8888
@ SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:254
blit_table::blit_features
Uint32 blit_features
Definition: SDL_blit_N.c:3148
table
GLenum GLsizei GLenum GLenum const void * table
Definition: SDL_opengl_glext.h:3118
RGBA_FROM_PIXEL
#define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a)
Definition: SDL_blit.h:304
BlitNto1
static void BlitNto1(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1991
SDL_BlitFunc
void(* SDL_BlitFunc)(SDL_BlitInfo *info)
Definition: SDL_blit.h:73
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179