update
[ffmpeg.git] / postproc / rgb2rgb.c
1 /*
2  *
3  *  rgb2rgb.c, Software RGB to RGB convertor
4  *  pluralize by Software PAL8 to RGB convertor
5  *               Software YUV to YUV convertor
6  *               Software YUV to RGB convertor
7  *  Written by Nick Kurshev.
8  *  palette & yuv & runtime cpu stuff by Michael (michaelni@gmx.at) (under GPL)
9  */
10 #include <inttypes.h>
11 #include "../config.h"
12 #include "rgb2rgb.h"
13 #include "../cpudetect.h"
14 #include "../mangle.h"
15 #include "../bswap.h"
16 #include "../libvo/fastmemcpy.h"
17
18 #ifdef ARCH_X86
19 #define CAN_COMPILE_X86_ASM
20 #endif
21
22 #define FAST_BGR2YV12 // use 7 bit coeffs instead of 15bit
23
24 #ifdef CAN_COMPILE_X86_ASM
25 static const uint64_t mmx_null  __attribute__((aligned(8))) = 0x0000000000000000ULL;
26 static const uint64_t mmx_one   __attribute__((aligned(8))) = 0xFFFFFFFFFFFFFFFFULL;
27 static const uint64_t mask32b  __attribute__((aligned(8))) = 0x000000FF000000FFULL;
28 static const uint64_t mask32g  __attribute__((aligned(8))) = 0x0000FF000000FF00ULL;
29 static const uint64_t mask32r  __attribute__((aligned(8))) = 0x00FF000000FF0000ULL;
30 static const uint64_t mask32   __attribute__((aligned(8))) = 0x00FFFFFF00FFFFFFULL;
31 static const uint64_t mask24b  __attribute__((aligned(8))) = 0x00FF0000FF0000FFULL;
32 static const uint64_t mask24g  __attribute__((aligned(8))) = 0xFF0000FF0000FF00ULL;
33 static const uint64_t mask24r  __attribute__((aligned(8))) = 0x0000FF0000FF0000ULL;
34 static const uint64_t mask24l  __attribute__((aligned(8))) = 0x0000000000FFFFFFULL;
35 static const uint64_t mask24h  __attribute__((aligned(8))) = 0x0000FFFFFF000000ULL;
36 static const uint64_t mask24hh  __attribute__((aligned(8))) = 0xffff000000000000ULL;
37 static const uint64_t mask24hhh  __attribute__((aligned(8))) = 0xffffffff00000000ULL;
38 static const uint64_t mask24hhhh  __attribute__((aligned(8))) = 0xffffffffffff0000ULL;
39 static const uint64_t mask15b  __attribute__((aligned(8))) = 0x001F001F001F001FULL; /* 00000000 00011111  xxB */
40 static const uint64_t mask15rg __attribute__((aligned(8))) = 0x7FE07FE07FE07FE0ULL; /* 01111111 11100000  RGx */
41 static const uint64_t mask15s  __attribute__((aligned(8))) = 0xFFE0FFE0FFE0FFE0ULL;
42 static const uint64_t mask15g  __attribute__((aligned(8))) = 0x03E003E003E003E0ULL;
43 static const uint64_t mask15r  __attribute__((aligned(8))) = 0x7C007C007C007C00ULL;
44 #define mask16b mask15b
45 static const uint64_t mask16g  __attribute__((aligned(8))) = 0x07E007E007E007E0ULL;
46 static const uint64_t mask16r  __attribute__((aligned(8))) = 0xF800F800F800F800ULL;
47 static const uint64_t red_16mask  __attribute__((aligned(8))) = 0x0000f8000000f800ULL;
48 static const uint64_t green_16mask __attribute__((aligned(8)))= 0x000007e0000007e0ULL;
49 static const uint64_t blue_16mask __attribute__((aligned(8))) = 0x0000001f0000001fULL;
50 static const uint64_t red_15mask  __attribute__((aligned(8))) = 0x00007c000000f800ULL;
51 static const uint64_t green_15mask __attribute__((aligned(8)))= 0x000003e0000007e0ULL;
52 static const uint64_t blue_15mask __attribute__((aligned(8))) = 0x0000001f0000001fULL;
53
54 #ifdef FAST_BGR2YV12
55 static const uint64_t bgr2YCoeff  __attribute__((aligned(8))) = 0x000000210041000DULL;
56 static const uint64_t bgr2UCoeff  __attribute__((aligned(8))) = 0x0000FFEEFFDC0038ULL;
57 static const uint64_t bgr2VCoeff  __attribute__((aligned(8))) = 0x00000038FFD2FFF8ULL;
58 #else
59 static const uint64_t bgr2YCoeff  __attribute__((aligned(8))) = 0x000020E540830C8BULL;
60 static const uint64_t bgr2UCoeff  __attribute__((aligned(8))) = 0x0000ED0FDAC23831ULL;
61 static const uint64_t bgr2VCoeff  __attribute__((aligned(8))) = 0x00003831D0E6F6EAULL;
62 #endif
63 static const uint64_t bgr2YOffset __attribute__((aligned(8))) = 0x1010101010101010ULL;
64 static const uint64_t bgr2UVOffset __attribute__((aligned(8)))= 0x8080808080808080ULL;
65 static const uint64_t w1111       __attribute__((aligned(8))) = 0x0001000100010001ULL;
66
67 #if 0
68 static volatile uint64_t __attribute__((aligned(8))) b5Dither;
69 static volatile uint64_t __attribute__((aligned(8))) g5Dither;
70 static volatile uint64_t __attribute__((aligned(8))) g6Dither;
71 static volatile uint64_t __attribute__((aligned(8))) r5Dither;
72
73 static uint64_t __attribute__((aligned(8))) dither4[2]={
74         0x0103010301030103LL,
75         0x0200020002000200LL,};
76
77 static uint64_t __attribute__((aligned(8))) dither8[2]={
78         0x0602060206020602LL,
79         0x0004000400040004LL,};
80 #endif
81 #endif
82
83 #define RGB2YUV_SHIFT 8
84 #define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
85 #define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5))
86 #define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
87 #define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5))
88 #define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5))
89 #define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5))
90 #define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5))
91 #define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
92 #define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5))
93
94 //Note: we have C, MMX, MMX2, 3DNOW version therse no 3DNOW+MMX2 one
95 //Plain C versions
96 #undef HAVE_MMX
97 #undef HAVE_MMX2
98 #undef HAVE_3DNOW
99 #undef ARCH_X86
100 #undef HAVE_SSE2
101 #define RENAME(a) a ## _C
102 #include "rgb2rgb_template.c"
103
104 #ifdef CAN_COMPILE_X86_ASM
105
106 //MMX versions
107 #undef RENAME
108 #define HAVE_MMX
109 #undef HAVE_MMX2
110 #undef HAVE_3DNOW
111 #undef HAVE_SSE2
112 #define ARCH_X86
113 #define RENAME(a) a ## _MMX
114 #include "rgb2rgb_template.c"
115
116 //MMX2 versions
117 #undef RENAME
118 #define HAVE_MMX
119 #define HAVE_MMX2
120 #undef HAVE_3DNOW
121 #undef HAVE_SSE2
122 #define ARCH_X86
123 #define RENAME(a) a ## _MMX2
124 #include "rgb2rgb_template.c"
125
126 //3DNOW versions
127 #undef RENAME
128 #define HAVE_MMX
129 #undef HAVE_MMX2
130 #define HAVE_3DNOW
131 #undef HAVE_SSE2
132 #define ARCH_X86
133 #define RENAME(a) a ## _3DNow
134 #include "rgb2rgb_template.c"
135
136 #endif //CAN_COMPILE_X86_ASM
137
138 void rgb24to32(const uint8_t *src,uint8_t *dst,unsigned src_size)
139 {
140 #ifdef CAN_COMPILE_X86_ASM
141         // ordered per speed fasterst first
142         if(gCpuCaps.hasMMX2)
143                 rgb24to32_MMX2(src, dst, src_size);
144         else if(gCpuCaps.has3DNow)
145                 rgb24to32_3DNow(src, dst, src_size);
146         else if(gCpuCaps.hasMMX)
147                 rgb24to32_MMX(src, dst, src_size);
148         else
149 #endif
150                 rgb24to32_C(src, dst, src_size);
151 }
152
153 void rgb15to24(const uint8_t *src,uint8_t *dst,unsigned src_size)
154 {
155 #ifdef CAN_COMPILE_X86_ASM
156         // ordered per speed fasterst first
157         if(gCpuCaps.hasMMX2)
158                 rgb15to24_MMX2(src, dst, src_size);
159         else if(gCpuCaps.has3DNow)
160                 rgb15to24_3DNow(src, dst, src_size);
161         else if(gCpuCaps.hasMMX)
162                 rgb15to24_MMX(src, dst, src_size);
163         else
164 #endif
165                 rgb15to24_C(src, dst, src_size);
166 }
167
168 void rgb16to24(const uint8_t *src,uint8_t *dst,unsigned src_size)
169 {
170 #ifdef CAN_COMPILE_X86_ASM
171         // ordered per speed fasterst first
172         if(gCpuCaps.hasMMX2)
173                 rgb16to24_MMX2(src, dst, src_size);
174         else if(gCpuCaps.has3DNow)
175                 rgb16to24_3DNow(src, dst, src_size);
176         else if(gCpuCaps.hasMMX)
177                 rgb16to24_MMX(src, dst, src_size);
178         else
179 #endif
180                 rgb16to24_C(src, dst, src_size);
181 }
182
183 void rgb15to32(const uint8_t *src,uint8_t *dst,unsigned src_size)
184 {
185 #ifdef CAN_COMPILE_X86_ASM
186         // ordered per speed fasterst first
187         if(gCpuCaps.hasMMX2)
188                 rgb15to32_MMX2(src, dst, src_size);
189         else if(gCpuCaps.has3DNow)
190                 rgb15to32_3DNow(src, dst, src_size);
191         else if(gCpuCaps.hasMMX)
192                 rgb15to32_MMX(src, dst, src_size);
193         else
194 #endif
195                 rgb15to32_C(src, dst, src_size);
196 }
197
198 void rgb16to32(const uint8_t *src,uint8_t *dst,unsigned src_size)
199 {
200 #ifdef CAN_COMPILE_X86_ASM
201         // ordered per speed fasterst first
202         if(gCpuCaps.hasMMX2)
203                 rgb16to32_MMX2(src, dst, src_size);
204         else if(gCpuCaps.has3DNow)
205                 rgb16to32_3DNow(src, dst, src_size);
206         else if(gCpuCaps.hasMMX)
207                 rgb16to32_MMX(src, dst, src_size);
208         else
209 #endif
210                 rgb16to32_C(src, dst, src_size);
211 }
212
213 void rgb32to24(const uint8_t *src,uint8_t *dst,unsigned src_size)
214 {
215 #ifdef CAN_COMPILE_X86_ASM
216         // ordered per speed fasterst first
217         if(gCpuCaps.hasMMX2)
218                 rgb32to24_MMX2(src, dst, src_size);
219         else if(gCpuCaps.has3DNow)
220                 rgb32to24_3DNow(src, dst, src_size);
221         else if(gCpuCaps.hasMMX)
222                 rgb32to24_MMX(src, dst, src_size);
223         else
224 #endif
225                 rgb32to24_C(src, dst, src_size);
226 }
227
228 /*
229  Original by Strepto/Astral
230  ported to gcc & bugfixed : A'rpi
231  MMX2, 3DNOW optimization by Nick Kurshev
232  32bit c version, and and&add trick by Michael Niedermayer
233 */
234 void rgb15to16(const uint8_t *src,uint8_t *dst,unsigned src_size)
235 {
236 #ifdef CAN_COMPILE_X86_ASM
237         // ordered per speed fasterst first
238         if(gCpuCaps.hasMMX2)
239                 rgb15to16_MMX2(src, dst, src_size);
240         else if(gCpuCaps.has3DNow)
241                 rgb15to16_3DNow(src, dst, src_size);
242         else if(gCpuCaps.hasMMX)
243                 rgb15to16_MMX(src, dst, src_size);
244         else
245 #endif
246                 rgb15to16_C(src, dst, src_size);
247 }
248
249 void rgb16to15(const uint8_t *src,uint8_t *dst,unsigned src_size)
250 {
251 #ifdef CAN_COMPILE_X86_ASM
252         // ordered per speed fasterst first
253         if(gCpuCaps.hasMMX2)
254                 rgb16to15_MMX2(src, dst, src_size);
255         else if(gCpuCaps.has3DNow)
256                 rgb16to15_3DNow(src, dst, src_size);
257         else if(gCpuCaps.hasMMX)
258                 rgb16to15_MMX(src, dst, src_size);
259         else
260 #endif
261                 rgb16to15_C(src, dst, src_size);
262 }
263 /**
264  * Pallete is assumed to contain bgr32
265  */
266 void palette8torgb32(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)
267 {
268         unsigned i;
269
270 /*
271         for(i=0; i<num_pixels; i++)
272                 ((unsigned *)dst)[i] = ((unsigned *)palette)[ src[i] ];
273 */
274
275         for(i=0; i<num_pixels; i++)
276         {
277                 //FIXME slow?
278                 dst[0]= palette[ src[i]*4+2 ];
279                 dst[1]= palette[ src[i]*4+1 ];
280                 dst[2]= palette[ src[i]*4+0 ];
281 //              dst[3]= 0; /* do we need this cleansing? */
282                 dst+= 4;
283         }
284 }
285
286 void palette8tobgr32(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)
287 {
288         unsigned i;
289         for(i=0; i<num_pixels; i++)
290         {
291                 //FIXME slow?
292                 dst[0]= palette[ src[i]*4+0 ];
293                 dst[1]= palette[ src[i]*4+1 ];
294                 dst[2]= palette[ src[i]*4+2 ];
295 //              dst[3]= 0; /* do we need this cleansing? */
296                 dst+= 4;
297         }
298 }
299
300 /**
301  * Pallete is assumed to contain bgr32
302  */
303 void palette8torgb24(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)
304 {
305         unsigned i;
306 /*
307         writes 1 byte o much and might cause alignment issues on some architectures?
308         for(i=0; i<num_pixels; i++)
309                 ((unsigned *)(&dst[i*3])) = ((unsigned *)palette)[ src[i] ];
310 */
311         for(i=0; i<num_pixels; i++)
312         {
313                 //FIXME slow?
314                 dst[0]= palette[ src[i]*4+2 ];
315                 dst[1]= palette[ src[i]*4+1 ];
316                 dst[2]= palette[ src[i]*4+0 ];
317                 dst+= 3;
318         }
319 }
320
321 void palette8tobgr24(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)
322 {
323         unsigned i;
324 /*
325         writes 1 byte o much and might cause alignment issues on some architectures?
326         for(i=0; i<num_pixels; i++)
327                 ((unsigned *)(&dst[i*3])) = ((unsigned *)palette)[ src[i] ];
328 */
329         for(i=0; i<num_pixels; i++)
330         {
331                 //FIXME slow?
332                 dst[0]= palette[ src[i]*4+0 ];
333                 dst[1]= palette[ src[i]*4+1 ];
334                 dst[2]= palette[ src[i]*4+2 ];
335                 dst+= 3;
336         }
337 }
338
339 void bgr24torgb24(const uint8_t *src, uint8_t *dst, unsigned src_size)
340 {
341 #ifdef CAN_COMPILE_X86_ASM
342         // ordered per speed fasterst first
343         if(gCpuCaps.hasMMX2)
344                 bgr24torgb24_MMX2(src, dst, src_size);
345         else if(gCpuCaps.has3DNow)
346                 bgr24torgb24_3DNow(src, dst, src_size);
347         else if(gCpuCaps.hasMMX)
348                 bgr24torgb24_MMX(src, dst, src_size);
349         else
350                 bgr24torgb24_C(src, dst, src_size);
351 #else
352                 bgr24torgb24_C(src, dst, src_size);
353 #endif
354 }
355
356 void rgb32to16(const uint8_t *src, uint8_t *dst, unsigned src_size)
357 {
358 #ifdef CAN_COMPILE_X86_ASM
359         // ordered per speed fasterst first
360         if(gCpuCaps.hasMMX2)
361                 rgb32to16_MMX2(src, dst, src_size);
362         else if(gCpuCaps.has3DNow)
363                 rgb32to16_3DNow(src, dst, src_size);
364         else if(gCpuCaps.hasMMX)
365                 rgb32to16_MMX(src, dst, src_size);
366         else
367 #endif
368                 rgb32to16_C(src, dst, src_size);
369 }
370
371 void rgb32to15(const uint8_t *src, uint8_t *dst, unsigned src_size)
372 {
373 #ifdef CAN_COMPILE_X86_ASM
374         // ordered per speed fasterst first
375         if(gCpuCaps.hasMMX2)
376                 rgb32to15_MMX2(src, dst, src_size);
377         else if(gCpuCaps.has3DNow)
378                 rgb32to15_3DNow(src, dst, src_size);
379         else if(gCpuCaps.hasMMX)
380                 rgb32to15_MMX(src, dst, src_size);
381         else
382 #endif
383                 rgb32to15_C(src, dst, src_size);
384 }
385
386 void rgb24to16(const uint8_t *src, uint8_t *dst, unsigned src_size)
387 {
388 #ifdef CAN_COMPILE_X86_ASM
389         // ordered per speed fasterst first
390         if(gCpuCaps.hasMMX2)
391                 rgb24to16_MMX2(src, dst, src_size);
392         else if(gCpuCaps.has3DNow)
393                 rgb24to16_3DNow(src, dst, src_size);
394         else if(gCpuCaps.hasMMX)
395                 rgb24to16_MMX(src, dst, src_size);
396         else
397 #endif
398                 rgb24to16_C(src, dst, src_size);
399 }
400
401 void rgb24to15(const uint8_t *src, uint8_t *dst, unsigned src_size)
402 {
403 #ifdef CAN_COMPILE_X86_ASM
404         // ordered per speed fasterst first
405         if(gCpuCaps.hasMMX2)
406                 rgb24to15_MMX2(src, dst, src_size);
407         else if(gCpuCaps.has3DNow)
408                 rgb24to15_3DNow(src, dst, src_size);
409         else if(gCpuCaps.hasMMX)
410                 rgb24to15_MMX(src, dst, src_size);
411         else
412 #endif
413                 rgb24to15_C(src, dst, src_size);
414 }
415
416 /**
417  * Palette is assumed to contain bgr16, see rgb32to16 to convert the palette
418  */
419 void palette8torgb16(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)
420 {
421         unsigned i;
422         for(i=0; i<num_pixels; i++)
423                 ((uint16_t *)dst)[i] = ((uint16_t *)palette)[ src[i] ];
424 }
425 void palette8tobgr16(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)
426 {
427         unsigned i;
428         for(i=0; i<num_pixels; i++)
429                 ((uint16_t *)dst)[i] = bswap_16(((uint16_t *)palette)[ src[i] ]);
430 }
431
432 /**
433  * Pallete is assumed to contain bgr15, see rgb32to15 to convert the palette
434  */
435 void palette8torgb15(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)
436 {
437         unsigned i;
438         for(i=0; i<num_pixels; i++)
439                 ((uint16_t *)dst)[i] = ((uint16_t *)palette)[ src[i] ];
440 }
441 void palette8tobgr15(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)
442 {
443         unsigned i;
444         for(i=0; i<num_pixels; i++)
445                 ((uint16_t *)dst)[i] = bswap_16(((uint16_t *)palette)[ src[i] ]);
446 }
447
448 void rgb32tobgr32(const uint8_t *src, uint8_t *dst, unsigned int src_size)
449 {
450 #ifdef CAN_COMPILE_X86_ASM
451         // ordered per speed fasterst first
452         if(gCpuCaps.hasMMX2)
453                 rgb32tobgr32_MMX2(src, dst, src_size);
454         else if(gCpuCaps.has3DNow)
455                 rgb32tobgr32_3DNow(src, dst, src_size);
456         else if(gCpuCaps.hasMMX)
457                 rgb32tobgr32_MMX(src, dst, src_size);
458         else
459 #endif
460                 rgb32tobgr32_C(src, dst, src_size);
461 }
462
463 void rgb32tobgr24(const uint8_t *src, uint8_t *dst, unsigned int src_size)
464 {
465         unsigned i;
466         unsigned num_pixels = src_size >> 2;
467         for(i=0; i<num_pixels; i++)
468         {
469                 dst[3*i + 0] = src[4*i + 2];
470                 dst[3*i + 1] = src[4*i + 1];
471                 dst[3*i + 2] = src[4*i + 0];
472         }
473 }
474
475 void rgb32tobgr16(const uint8_t *src, uint8_t *dst, unsigned int src_size)
476 {
477 #ifdef CAN_COMPILE_X86_ASM
478         // ordered per speed fasterst first
479         if(gCpuCaps.hasMMX2)
480                 rgb32tobgr16_MMX2(src, dst, src_size);
481         else if(gCpuCaps.has3DNow)
482                 rgb32tobgr16_3DNow(src, dst, src_size);
483         else if(gCpuCaps.hasMMX)
484                 rgb32tobgr16_MMX(src, dst, src_size);
485         else
486 #endif
487                 rgb32tobgr16_C(src, dst, src_size);
488 }
489
490 void rgb32tobgr15(const uint8_t *src, uint8_t *dst, unsigned int src_size)
491 {
492 #ifdef CAN_COMPILE_X86_ASM
493         // ordered per speed fasterst first
494         if(gCpuCaps.hasMMX2)
495                 rgb32tobgr15_MMX2(src, dst, src_size);
496         else if(gCpuCaps.has3DNow)
497                 rgb32tobgr15_3DNow(src, dst, src_size);
498         else if(gCpuCaps.hasMMX)
499                 rgb32tobgr15_MMX(src, dst, src_size);
500         else
501 #endif
502                 rgb32tobgr15_C(src, dst, src_size);
503 }
504
505 void rgb24tobgr32(const uint8_t *src, uint8_t *dst, unsigned int src_size)
506 {
507         unsigned i;
508         for(i=0; 3*i<src_size; i++)
509         {
510                 dst[4*i + 0] = src[3*i + 2];
511                 dst[4*i + 1] = src[3*i + 1];
512                 dst[4*i + 2] = src[3*i + 0];
513                 dst[4*i + 3] = 0;
514         }
515 }
516
517 void rgb24tobgr24(const uint8_t *src, uint8_t *dst, unsigned int src_size)
518 {
519 #ifdef CAN_COMPILE_X86_ASM
520         // ordered per speed fasterst first
521         if(gCpuCaps.hasMMX2)
522                 rgb24tobgr24_MMX2(src, dst, src_size);
523         else if(gCpuCaps.has3DNow)
524                 rgb24tobgr24_3DNow(src, dst, src_size);
525         else if(gCpuCaps.hasMMX)
526                 rgb24tobgr24_MMX(src, dst, src_size);
527         else
528 #endif
529                 rgb24tobgr24_C(src, dst, src_size);
530 }
531
532 void rgb24tobgr16(const uint8_t *src, uint8_t *dst, unsigned int src_size)
533 {
534 #ifdef CAN_COMPILE_X86_ASM
535         // ordered per speed fasterst first
536         if(gCpuCaps.hasMMX2)
537                 rgb24tobgr16_MMX2(src, dst, src_size);
538         else if(gCpuCaps.has3DNow)
539                 rgb24tobgr16_3DNow(src, dst, src_size);
540         else if(gCpuCaps.hasMMX)
541                 rgb24tobgr16_MMX(src, dst, src_size);
542         else
543 #endif
544                 rgb24tobgr16_C(src, dst, src_size);
545 }
546
547 void rgb24tobgr15(const uint8_t *src, uint8_t *dst, unsigned int src_size)
548 {
549 #ifdef CAN_COMPILE_X86_ASM
550         // ordered per speed fasterst first
551         if(gCpuCaps.hasMMX2)
552                 rgb24tobgr15_MMX2(src, dst, src_size);
553         else if(gCpuCaps.has3DNow)
554                 rgb24tobgr15_3DNow(src, dst, src_size);
555         else if(gCpuCaps.hasMMX)
556                 rgb24tobgr15_MMX(src, dst, src_size);
557         else
558 #endif
559                 rgb24tobgr15_C(src, dst, src_size);
560 }
561
562 void rgb16tobgr32(const uint8_t *src, uint8_t *dst, unsigned int src_size)
563 {
564         const uint16_t *end;
565         uint8_t *d = (uint8_t *)dst;
566         const uint16_t *s = (uint16_t *)src;
567         end = s + src_size/2;
568         while(s < end)
569         {
570                 register uint16_t bgr;
571                 bgr = *s++;
572                 *d++ = (bgr&0xF800)>>8;
573                 *d++ = (bgr&0x7E0)>>3;
574                 *d++ = (bgr&0x1F)<<3;
575                 *d++ = 0;
576         }
577 }
578
579 void rgb16tobgr24(const uint8_t *src, uint8_t *dst, unsigned int src_size)
580 {
581         const uint16_t *end;
582         uint8_t *d = (uint8_t *)dst;
583         const uint16_t *s = (const uint16_t *)src;
584         end = s + src_size/2;
585         while(s < end)
586         {
587                 register uint16_t bgr;
588                 bgr = *s++;
589                 *d++ = (bgr&0xF800)>>8;
590                 *d++ = (bgr&0x7E0)>>3;
591                 *d++ = (bgr&0x1F)<<3;
592         }
593 }
594
595 void rgb16tobgr16(const uint8_t *src, uint8_t *dst, unsigned int src_size)
596 {
597         unsigned i;
598         unsigned num_pixels = src_size >> 1;
599         
600         for(i=0; i<num_pixels; i++)
601         {
602             unsigned b,g,r;
603             register uint16_t rgb;
604             rgb = src[2*i];
605             r = rgb&0x1F;
606             g = (rgb&0x7E0)>>5;
607             b = (rgb&0xF800)>>11;
608             dst[2*i] = (b&0x1F) | ((g&0x3F)<<5) | ((r&0x1F)<<11);
609         }
610 }
611
612 void rgb16tobgr15(const uint8_t *src, uint8_t *dst, unsigned int src_size)
613 {
614         unsigned i;
615         unsigned num_pixels = src_size >> 1;
616         
617         for(i=0; i<num_pixels; i++)
618         {
619             unsigned b,g,r;
620             register uint16_t rgb;
621             rgb = src[2*i];
622             r = rgb&0x1F;
623             g = (rgb&0x7E0)>>5;
624             b = (rgb&0xF800)>>11;
625             dst[2*i] = (b&0x1F) | ((g&0x1F)<<5) | ((r&0x1F)<<10);
626         }
627 }
628
629 void rgb15tobgr32(const uint8_t *src, uint8_t *dst, unsigned int src_size)
630 {
631         const uint16_t *end;
632         uint8_t *d = (uint8_t *)dst;
633         const uint16_t *s = (const uint16_t *)src;
634         end = s + src_size/2;
635         while(s < end)
636         {
637                 register uint16_t bgr;
638                 bgr = *s++;
639                 *d++ = (bgr&0x7C00)>>7;
640                 *d++ = (bgr&0x3E0)>>2;
641                 *d++ = (bgr&0x1F)<<3;
642                 *d++ = 0;
643         }
644 }
645
646 void rgb15tobgr24(const uint8_t *src, uint8_t *dst, unsigned int src_size)
647 {
648         const uint16_t *end;
649         uint8_t *d = (uint8_t *)dst;
650         const uint16_t *s = (uint16_t *)src;
651         end = s + src_size/2;
652         while(s < end)
653         {
654                 register uint16_t bgr;
655                 bgr = *s++;
656                 *d++ = (bgr&0x7C00)>>7;
657                 *d++ = (bgr&0x3E0)>>2;
658                 *d++ = (bgr&0x1F)<<3;
659         }
660 }
661
662 void rgb15tobgr16(const uint8_t *src, uint8_t *dst, unsigned int src_size)
663 {
664         unsigned i;
665         unsigned num_pixels = src_size >> 1;
666         
667         for(i=0; i<num_pixels; i++)
668         {
669             unsigned b,g,r;
670             register uint16_t rgb;
671             rgb = src[2*i];
672             r = rgb&0x1F;
673             g = (rgb&0x3E0)>>5;
674             b = (rgb&0x7C00)>>10;
675             dst[2*i] = (b&0x1F) | ((g&0x3F)<<5) | ((r&0x1F)<<11);
676         }
677 }
678
679 void rgb15tobgr15(const uint8_t *src, uint8_t *dst, unsigned int src_size)
680 {
681         unsigned i;
682         unsigned num_pixels = src_size >> 1;
683         
684         for(i=0; i<num_pixels; i++)
685         {
686             unsigned b,g,r;
687             register uint16_t rgb;
688             rgb = src[2*i];
689             r = rgb&0x1F;
690             g = (rgb&0x3E0)>>5;
691             b = (rgb&0x7C00)>>10;
692             dst[2*i] = (b&0x1F) | ((g&0x1F)<<5) | ((r&0x1F)<<10);
693         }
694 }
695
696 void rgb8tobgr8(const uint8_t *src, uint8_t *dst, unsigned int src_size)
697 {
698         unsigned i;
699         unsigned num_pixels = src_size;
700         for(i=0; i<num_pixels; i++)
701         {
702             unsigned b,g,r;
703             register uint8_t rgb;
704             rgb = src[i];
705             r = (rgb&0x07);
706             g = (rgb&0x38)>>3;
707             b = (rgb&0xC0)>>6;
708             dst[i] = ((b<<1)&0x07) | ((g&0x07)<<3) | ((r&0x03)<<6);
709         }
710 }
711
712 /**
713  *
714  * height should be a multiple of 2 and width should be a multiple of 16 (if this is a
715  * problem for anyone then tell me, and ill fix it)
716  */
717 void yv12toyuy2(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
718         unsigned int width, unsigned int height,
719         unsigned int lumStride, unsigned int chromStride, unsigned int dstStride)
720 {
721 #ifdef CAN_COMPILE_X86_ASM
722         // ordered per speed fasterst first
723         if(gCpuCaps.hasMMX2)
724                 yv12toyuy2_MMX2(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride);
725         else if(gCpuCaps.has3DNow)
726                 yv12toyuy2_3DNow(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride);
727         else if(gCpuCaps.hasMMX)
728                 yv12toyuy2_MMX(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride);
729         else
730 #endif
731                 yv12toyuy2_C(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride);
732 }
733
734 /**
735  *
736  * width should be a multiple of 16
737  */
738 void yuv422ptoyuy2(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
739         unsigned int width, unsigned int height,
740         unsigned int lumStride, unsigned int chromStride, unsigned int dstStride)
741 {
742 #ifdef CAN_COMPILE_X86_ASM
743         // ordered per speed fasterst first
744         if(gCpuCaps.hasMMX2)
745                 yuv422ptoyuy2_MMX2(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride);
746         else if(gCpuCaps.has3DNow)
747                 yuv422ptoyuy2_3DNow(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride);
748         else if(gCpuCaps.hasMMX)
749                 yuv422ptoyuy2_MMX(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride);
750         else
751 #endif
752                 yuv422ptoyuy2_C(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride);
753 }
754
755 /**
756  *
757  * height should be a multiple of 2 and width should be a multiple of 16 (if this is a
758  * problem for anyone then tell me, and ill fix it)
759  */
760 void yuy2toyv12(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
761         unsigned int width, unsigned int height,
762         unsigned int lumStride, unsigned int chromStride, unsigned int srcStride)
763 {
764 #ifdef CAN_COMPILE_X86_ASM
765         // ordered per speed fasterst first
766         if(gCpuCaps.hasMMX2)
767                 yuy2toyv12_MMX2(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
768         else if(gCpuCaps.has3DNow)
769                 yuy2toyv12_3DNow(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
770         else if(gCpuCaps.hasMMX)
771                 yuy2toyv12_MMX(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
772         else
773 #endif
774                 yuy2toyv12_C(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
775 }
776
777 /**
778  *
779  * height should be a multiple of 2 and width should be a multiple of 16 (if this is a
780  * problem for anyone then tell me, and ill fix it)
781  * chrominance data is only taken from every secound line others are ignored FIXME write HQ version
782  */
783 void uyvytoyv12(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
784         unsigned int width, unsigned int height,
785         unsigned int lumStride, unsigned int chromStride, unsigned int srcStride)
786 {
787 #ifdef CAN_COMPILE_X86_ASM
788         // ordered per speed fasterst first
789         if(gCpuCaps.hasMMX2)
790                 uyvytoyv12_MMX2(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
791         else if(gCpuCaps.has3DNow)
792                 uyvytoyv12_3DNow(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
793         else if(gCpuCaps.hasMMX)
794                 uyvytoyv12_MMX(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
795         else
796                 uyvytoyv12_C(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
797 #else
798                 uyvytoyv12_C(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
799 #endif
800 }
801
802 void yvu9toyv12(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc,
803         uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
804         unsigned int width, unsigned int height,
805         unsigned int lumStride, unsigned int chromStride)
806 {
807 #ifdef CAN_COMPILE_X86_ASM
808         // ordered per speed fasterst first
809         if(gCpuCaps.hasMMX2)
810                 yvu9toyv12_MMX2(ysrc, usrc, vsrc, ydst, udst, vdst, width, height, lumStride, chromStride);
811         else if(gCpuCaps.has3DNow)
812                 yvu9toyv12_3DNow(ysrc, usrc, vsrc, ydst, udst, vdst, width, height, lumStride, chromStride);
813         else if(gCpuCaps.hasMMX)
814                 yvu9toyv12_MMX(ysrc, usrc, vsrc, ydst, udst, vdst, width, height, lumStride, chromStride);
815         else
816                 yvu9toyv12_C(ysrc, usrc, vsrc, ydst, udst, vdst, width, height, lumStride, chromStride);
817 #else
818                 yvu9toyv12_C(ysrc, usrc, vsrc, ydst, udst, vdst, width, height, lumStride, chromStride);
819 #endif
820 }
821
822 void planar2x(const uint8_t *src, uint8_t *dst, int width, int height, int srcStride, int dstStride)
823 {
824 #ifdef CAN_COMPILE_X86_ASM
825         // ordered per speed fasterst first
826         if(gCpuCaps.hasMMX2)
827                 planar2x_MMX2(src, dst, width, height, srcStride, dstStride);
828         else if(gCpuCaps.has3DNow)
829                 planar2x_3DNow(src, dst, width, height, srcStride, dstStride);
830         else
831 #endif
832                 planar2x_C(src, dst, width, height, srcStride, dstStride);
833 }
834
835 /**
836  *
837  * height should be a multiple of 2 and width should be a multiple of 2 (if this is a
838  * problem for anyone then tell me, and ill fix it)
839  * chrominance data is only taken from every secound line others are ignored FIXME write HQ version
840  */
841 void rgb24toyv12(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
842         unsigned int width, unsigned int height,
843         unsigned int lumStride, unsigned int chromStride, unsigned int srcStride)
844 {
845 #ifdef CAN_COMPILE_X86_ASM
846         // ordered per speed fasterst first
847         if(gCpuCaps.hasMMX2)
848                 rgb24toyv12_MMX2(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
849         else if(gCpuCaps.has3DNow)
850                 rgb24toyv12_3DNow(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
851         else if(gCpuCaps.hasMMX)
852                 rgb24toyv12_MMX(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
853         else
854 #endif
855                 rgb24toyv12_C(src, ydst, udst, vdst, width,  height, lumStride, chromStride, srcStride);
856 }
857
858 void interleaveBytes(uint8_t *src1, uint8_t *src2, uint8_t *dst,
859                      unsigned width, unsigned height, unsigned src1Stride,
860                      unsigned src2Stride, unsigned dstStride)
861 {
862 #ifdef CAN_COMPILE_X86_ASM
863         // ordered per speed fasterst first
864         if(gCpuCaps.hasMMX2)
865                 interleaveBytes_MMX2(src1, src2, dst, width, height, src1Stride, src2Stride, dstStride);
866         else if(gCpuCaps.has3DNow)
867                 interleaveBytes_3DNow(src1, src2, dst, width, height, src1Stride, src2Stride, dstStride);
868         else if(gCpuCaps.hasMMX)
869                 interleaveBytes_MMX(src1, src2, dst, width, height, src1Stride, src2Stride, dstStride);
870         else
871 #endif
872                 interleaveBytes_C(src1, src2, dst, width, height, src1Stride, src2Stride, dstStride);
873 }
874
875 void vu9_to_vu12(const uint8_t *src1, const uint8_t *src2,
876                 uint8_t *dst1, uint8_t *dst2,
877                 unsigned width, unsigned height,
878                 unsigned srcStride1, unsigned srcStride2,
879                 unsigned dstStride1, unsigned dstStride2)
880 {
881 #ifdef CAN_COMPILE_X86_ASM
882         if(gCpuCaps.hasMMX2)
883                 vu9_to_vu12_MMX2(src1, src2, dst1, dst2, width, height, srcStride1, srcStride2, dstStride1, dstStride2);
884         else if(gCpuCaps.has3DNow)
885                 vu9_to_vu12_3DNow(src1, src2, dst1, dst2, width, height, srcStride1, srcStride2, dstStride1, dstStride2);
886         else if(gCpuCaps.hasMMX)
887                 vu9_to_vu12_MMX(src1, src2, dst1, dst2, width, height, srcStride1, srcStride2, dstStride1, dstStride2);
888         else
889 #endif
890                 vu9_to_vu12_C(src1, src2, dst1, dst2, width, height, srcStride1, srcStride2, dstStride1, dstStride2);
891 }
892
893 void yvu9_to_yuy2(const uint8_t *src1, const uint8_t *src2, const uint8_t *src3,
894                 uint8_t *dst,
895                 unsigned width, unsigned height,
896                 unsigned srcStride1, unsigned srcStride2,
897                 unsigned srcStride3, unsigned dstStride)
898 {
899 #ifdef CAN_COMPILE_X86_ASM
900         if(gCpuCaps.hasMMX2)
901                 yvu9_to_yuy2_MMX2(src1, src2, src3, dst, width, height, srcStride1, srcStride2, srcStride3, dstStride);
902         else if(gCpuCaps.has3DNow)
903                 yvu9_to_yuy2_3DNow(src1, src2, src3, dst, width, height, srcStride1, srcStride2, srcStride3, dstStride);
904         else if(gCpuCaps.hasMMX)
905                 yvu9_to_yuy2_MMX(src1, src2, src3, dst, width, height, srcStride1, srcStride2, srcStride3, dstStride);
906         else
907 #endif
908                 yvu9_to_yuy2_C(src1, src2, src3, dst, width, height, srcStride1, srcStride2, srcStride3, dstStride);
909 }