Add av_clip_uintp2() function
[ffmpeg.git] / libswscale / swscale.c
1 /*
2  * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /*
22   supported Input formats: YV12, I420/IYUV, YUY2, UYVY, BGR32, BGR32_1, BGR24, BGR16, BGR15, RGB32, RGB32_1, RGB24, Y8/Y800, YVU9/IF09, PAL8
23   supported output formats: YV12, I420/IYUV, YUY2, UYVY, {BGR,RGB}{1,4,8,15,16,24,32}, Y8/Y800, YVU9/IF09
24   {BGR,RGB}{1,4,8,15,16} support dithering
25
26   unscaled special converters (YV12=I420=IYUV, Y800=Y8)
27   YV12 -> {BGR,RGB}{1,4,8,12,15,16,24,32}
28   x -> x
29   YUV9 -> YV12
30   YUV9/YV12 -> Y800
31   Y800 -> YUV9/YV12
32   BGR24 -> BGR32 & RGB24 -> RGB32
33   BGR32 -> BGR24 & RGB32 -> RGB24
34   BGR15 -> BGR16
35 */
36
37 /*
38 tested special converters (most are tested actually, but I did not write it down ...)
39  YV12 -> BGR12/BGR16
40  YV12 -> YV12
41  BGR15 -> BGR16
42  BGR16 -> BGR16
43  YVU9 -> YV12
44
45 untested special converters
46   YV12/I420 -> BGR15/BGR24/BGR32 (it is the yuv2rgb stuff, so it should be OK)
47   YV12/I420 -> YV12/I420
48   YUY2/BGR15/BGR24/BGR32/RGB24/RGB32 -> same format
49   BGR24 -> BGR32 & RGB24 -> RGB32
50   BGR32 -> BGR24 & RGB32 -> RGB24
51   BGR24 -> YV12
52 */
53
54 #include <inttypes.h>
55 #include <string.h>
56 #include <math.h>
57 #include <stdio.h>
58 #include "config.h"
59 #include <assert.h>
60 #include "swscale.h"
61 #include "swscale_internal.h"
62 #include "rgb2rgb.h"
63 #include "libavutil/intreadwrite.h"
64 #include "libavutil/x86_cpu.h"
65 #include "libavutil/avutil.h"
66 #include "libavutil/mathematics.h"
67 #include "libavutil/bswap.h"
68 #include "libavutil/pixdesc.h"
69
70 #undef MOVNTQ
71 #undef PAVGB
72
73 //#undef HAVE_MMX2
74 //#define HAVE_AMD3DNOW
75 //#undef HAVE_MMX
76 //#undef ARCH_X86
77 #define DITHER1XBPP
78
79 #define isPacked(x)         (       \
80            (x)==PIX_FMT_PAL8        \
81         || (x)==PIX_FMT_YUYV422     \
82         || (x)==PIX_FMT_UYVY422     \
83         || (x)==PIX_FMT_Y400A       \
84         || isAnyRGB(x)              \
85     )
86
87 #define RGB2YUV_SHIFT 15
88 #define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
89 #define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5))
90 #define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
91 #define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5))
92 #define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5))
93 #define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5))
94 #define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5))
95 #define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
96 #define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5))
97
98 static const double rgb2yuv_table[8][9]={
99     {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
100     {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
101     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
102     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
103     {0.59  , 0.11  , 0.30  , -0.331, 0.5, -0.169, -0.421, -0.079, 0.5}, //FCC
104     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
105     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
106     {0.701 , 0.087 , 0.212 , -0.384, 0.5, -0.116, -0.445, -0.055, 0.5}, //SMPTE 240M
107 };
108
109 /*
110 NOTES
111 Special versions: fast Y 1:1 scaling (no interpolation in y direction)
112
113 TODO
114 more intelligent misalignment avoidance for the horizontal scaler
115 write special vertical cubic upscale version
116 optimize C code (YV12 / minmax)
117 add support for packed pixel YUV input & output
118 add support for Y8 output
119 optimize BGR24 & BGR32
120 add BGR4 output support
121 write special BGR->BGR scaler
122 */
123
124 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_4)[2][8]={
125 {  1,   3,   1,   3,   1,   3,   1,   3, },
126 {  2,   0,   2,   0,   2,   0,   2,   0, },
127 };
128
129 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
130 {  6,   2,   6,   2,   6,   2,   6,   2, },
131 {  0,   4,   0,   4,   0,   4,   0,   4, },
132 };
133
134 DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
135 {  8,   4,  11,   7,   8,   4,  11,   7, },
136 {  2,  14,   1,  13,   2,  14,   1,  13, },
137 { 10,   6,   9,   5,  10,   6,   9,   5, },
138 {  0,  12,   3,  15,   0,  12,   3,  15, },
139 };
140
141 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
142 { 17,   9,  23,  15,  16,   8,  22,  14, },
143 {  5,  29,   3,  27,   4,  28,   2,  26, },
144 { 21,  13,  19,  11,  20,  12,  18,  10, },
145 {  0,  24,   6,  30,   1,  25,   7,  31, },
146 { 16,   8,  22,  14,  17,   9,  23,  15, },
147 {  4,  28,   2,  26,   5,  29,   3,  27, },
148 { 20,  12,  18,  10,  21,  13,  19,  11, },
149 {  1,  25,   7,  31,   0,  24,   6,  30, },
150 };
151
152 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
153 {  0,  55,  14,  68,   3,  58,  17,  72, },
154 { 37,  18,  50,  32,  40,  22,  54,  35, },
155 {  9,  64,   5,  59,  13,  67,   8,  63, },
156 { 46,  27,  41,  23,  49,  31,  44,  26, },
157 {  2,  57,  16,  71,   1,  56,  15,  70, },
158 { 39,  21,  52,  34,  38,  19,  51,  33, },
159 { 11,  66,   7,  62,  10,  65,   6,  60, },
160 { 48,  30,  43,  25,  47,  29,  42,  24, },
161 };
162
163 #if 1
164 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
165 {117,  62, 158, 103, 113,  58, 155, 100, },
166 { 34, 199,  21, 186,  31, 196,  17, 182, },
167 {144,  89, 131,  76, 141,  86, 127,  72, },
168 {  0, 165,  41, 206,  10, 175,  52, 217, },
169 {110,  55, 151,  96, 120,  65, 162, 107, },
170 { 28, 193,  14, 179,  38, 203,  24, 189, },
171 {138,  83, 124,  69, 148,  93, 134,  79, },
172 {  7, 172,  48, 213,   3, 168,  45, 210, },
173 };
174 #elif 1
175 // tries to correct a gamma of 1.5
176 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
177 {  0, 143,  18, 200,   2, 156,  25, 215, },
178 { 78,  28, 125,  64,  89,  36, 138,  74, },
179 { 10, 180,   3, 161,  16, 195,   8, 175, },
180 {109,  51,  93,  38, 121,  60, 105,  47, },
181 {  1, 152,  23, 210,   0, 147,  20, 205, },
182 { 85,  33, 134,  71,  81,  30, 130,  67, },
183 { 14, 190,   6, 171,  12, 185,   5, 166, },
184 {117,  57, 101,  44, 113,  54,  97,  41, },
185 };
186 #elif 1
187 // tries to correct a gamma of 2.0
188 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
189 {  0, 124,   8, 193,   0, 140,  12, 213, },
190 { 55,  14, 104,  42,  66,  19, 119,  52, },
191 {  3, 168,   1, 145,   6, 187,   3, 162, },
192 { 86,  31,  70,  21,  99,  39,  82,  28, },
193 {  0, 134,  11, 206,   0, 129,   9, 200, },
194 { 62,  17, 114,  48,  58,  16, 109,  45, },
195 {  5, 181,   2, 157,   4, 175,   1, 151, },
196 { 95,  36,  78,  26,  90,  34,  74,  24, },
197 };
198 #else
199 // tries to correct a gamma of 2.5
200 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
201 {  0, 107,   3, 187,   0, 125,   6, 212, },
202 { 39,   7,  86,  28,  49,  11, 102,  36, },
203 {  1, 158,   0, 131,   3, 180,   1, 151, },
204 { 68,  19,  52,  12,  81,  25,  64,  17, },
205 {  0, 119,   5, 203,   0, 113,   4, 195, },
206 { 45,   9,  96,  33,  42,   8,  91,  30, },
207 {  2, 172,   1, 144,   2, 165,   0, 137, },
208 { 77,  23,  60,  15,  72,  21,  56,  14, },
209 };
210 #endif
211
212 static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
213                                                     const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
214                                                     const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest,
215                                                     int dstW, int chrDstW, int big_endian, int output_bits)
216 {
217     //FIXME Optimize (just quickly written not optimized..)
218     int i;
219     int shift = 11 + 16 - output_bits;
220
221     for (i = 0; i < dstW; i++) {
222         int val = 1 << 10;
223         int j;
224
225         for (j = 0; j < lumFilterSize; j++)
226             val += lumSrc[j][i] * lumFilter[j];
227
228         if (big_endian) {
229             AV_WB16(&dest[i], av_clip_uint16(val >> shift));
230         } else {
231             AV_WL16(&dest[i], av_clip_uint16(val >> shift));
232         }
233     }
234
235     if (uDest) {
236         for (i = 0; i < chrDstW; i++) {
237             int u = 1 << 10;
238             int v = 1 << 10;
239             int j;
240
241             for (j = 0; j < chrFilterSize; j++) {
242                 u += chrSrc[j][i       ] * chrFilter[j];
243                 v += chrSrc[j][i + VOFW] * chrFilter[j];
244             }
245
246             if (big_endian) {
247                 AV_WB16(&uDest[i], av_clip_uint16(u >> shift));
248                 AV_WB16(&vDest[i], av_clip_uint16(v >> shift));
249             } else {
250                 AV_WL16(&uDest[i], av_clip_uint16(u >> shift));
251                 AV_WL16(&vDest[i], av_clip_uint16(v >> shift));
252             }
253         }
254     }
255
256     if (CONFIG_SWSCALE_ALPHA && aDest) {
257         for (i = 0; i < dstW; i++) {
258             int val = 1 << 10;
259             int j;
260
261             for (j = 0; j < lumFilterSize; j++)
262                 val += alpSrc[j][i] * lumFilter[j];
263
264             if (big_endian) {
265                 AV_WB16(&aDest[i], av_clip_uint16(val >> shift));
266             } else {
267                 AV_WL16(&aDest[i], av_clip_uint16(val >> shift));
268             }
269         }
270     }
271 }
272
273 static inline void yuv2yuvX16inC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
274                                  const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
275                                  const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest, int dstW, int chrDstW,
276                                  enum PixelFormat dstFormat)
277 {
278 #define conv16(bits) \
279     if (isBE(dstFormat)) { \
280         yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize, \
281                                chrFilter, chrSrc, chrFilterSize, \
282                                alpSrc, \
283                                dest, uDest, vDest, aDest, \
284                                dstW, chrDstW, 1, bits); \
285     } else { \
286         yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize, \
287                                chrFilter, chrSrc, chrFilterSize, \
288                                alpSrc, \
289                                dest, uDest, vDest, aDest, \
290                                dstW, chrDstW, 0, bits); \
291     }
292     if (is16BPS(dstFormat)) {
293         conv16(16);
294     } else if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
295         conv16(9);
296     } else {
297         conv16(10);
298     }
299 #undef conv16
300 }
301
302 static inline void yuv2yuvXinC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
303                                const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
304                                const int16_t **alpSrc, uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, int dstW, int chrDstW)
305 {
306     //FIXME Optimize (just quickly written not optimized..)
307     int i;
308     for (i=0; i<dstW; i++) {
309         int val=1<<18;
310         int j;
311         for (j=0; j<lumFilterSize; j++)
312             val += lumSrc[j][i] * lumFilter[j];
313
314         dest[i]= av_clip_uint8(val>>19);
315     }
316
317     if (uDest)
318         for (i=0; i<chrDstW; i++) {
319             int u=1<<18;
320             int v=1<<18;
321             int j;
322             for (j=0; j<chrFilterSize; j++) {
323                 u += chrSrc[j][i] * chrFilter[j];
324                 v += chrSrc[j][i + VOFW] * chrFilter[j];
325             }
326
327             uDest[i]= av_clip_uint8(u>>19);
328             vDest[i]= av_clip_uint8(v>>19);
329         }
330
331     if (CONFIG_SWSCALE_ALPHA && aDest)
332         for (i=0; i<dstW; i++) {
333             int val=1<<18;
334             int j;
335             for (j=0; j<lumFilterSize; j++)
336                 val += alpSrc[j][i] * lumFilter[j];
337
338             aDest[i]= av_clip_uint8(val>>19);
339         }
340
341 }
342
343 static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
344                                 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
345                                 uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, int dstFormat)
346 {
347     //FIXME Optimize (just quickly written not optimized..)
348     int i;
349     for (i=0; i<dstW; i++) {
350         int val=1<<18;
351         int j;
352         for (j=0; j<lumFilterSize; j++)
353             val += lumSrc[j][i] * lumFilter[j];
354
355         dest[i]= av_clip_uint8(val>>19);
356     }
357
358     if (!uDest)
359         return;
360
361     if (dstFormat == PIX_FMT_NV12)
362         for (i=0; i<chrDstW; i++) {
363             int u=1<<18;
364             int v=1<<18;
365             int j;
366             for (j=0; j<chrFilterSize; j++) {
367                 u += chrSrc[j][i] * chrFilter[j];
368                 v += chrSrc[j][i + VOFW] * chrFilter[j];
369             }
370
371             uDest[2*i]= av_clip_uint8(u>>19);
372             uDest[2*i+1]= av_clip_uint8(v>>19);
373         }
374     else
375         for (i=0; i<chrDstW; i++) {
376             int u=1<<18;
377             int v=1<<18;
378             int j;
379             for (j=0; j<chrFilterSize; j++) {
380                 u += chrSrc[j][i] * chrFilter[j];
381                 v += chrSrc[j][i + VOFW] * chrFilter[j];
382             }
383
384             uDest[2*i]= av_clip_uint8(v>>19);
385             uDest[2*i+1]= av_clip_uint8(u>>19);
386         }
387 }
388
389 #define YSCALE_YUV_2_PACKEDX_NOCLIP_C(type,alpha) \
390     for (i=0; i<(dstW>>1); i++) {\
391         int j;\
392         int Y1 = 1<<18;\
393         int Y2 = 1<<18;\
394         int U  = 1<<18;\
395         int V  = 1<<18;\
396         int av_unused A1, A2;\
397         type av_unused *r, *b, *g;\
398         const int i2= 2*i;\
399         \
400         for (j=0; j<lumFilterSize; j++) {\
401             Y1 += lumSrc[j][i2] * lumFilter[j];\
402             Y2 += lumSrc[j][i2+1] * lumFilter[j];\
403         }\
404         for (j=0; j<chrFilterSize; j++) {\
405             U += chrSrc[j][i] * chrFilter[j];\
406             V += chrSrc[j][i+VOFW] * chrFilter[j];\
407         }\
408         Y1>>=19;\
409         Y2>>=19;\
410         U >>=19;\
411         V >>=19;\
412         if (alpha) {\
413             A1 = 1<<18;\
414             A2 = 1<<18;\
415             for (j=0; j<lumFilterSize; j++) {\
416                 A1 += alpSrc[j][i2  ] * lumFilter[j];\
417                 A2 += alpSrc[j][i2+1] * lumFilter[j];\
418             }\
419             A1>>=19;\
420             A2>>=19;\
421         }
422
423 #define YSCALE_YUV_2_PACKEDX_C(type,alpha) \
424         YSCALE_YUV_2_PACKEDX_NOCLIP_C(type,alpha)\
425         if ((Y1|Y2|U|V)&256) {\
426             if (Y1>255)   Y1=255; \
427             else if (Y1<0)Y1=0;   \
428             if (Y2>255)   Y2=255; \
429             else if (Y2<0)Y2=0;   \
430             if (U>255)    U=255;  \
431             else if (U<0) U=0;    \
432             if (V>255)    V=255;  \
433             else if (V<0) V=0;    \
434         }\
435         if (alpha && ((A1|A2)&256)) {\
436             A1=av_clip_uint8(A1);\
437             A2=av_clip_uint8(A2);\
438         }
439
440 #define YSCALE_YUV_2_PACKEDX_FULL_C(rnd,alpha) \
441     for (i=0; i<dstW; i++) {\
442         int j;\
443         int Y = 0;\
444         int U = -128<<19;\
445         int V = -128<<19;\
446         int av_unused A;\
447         int R,G,B;\
448         \
449         for (j=0; j<lumFilterSize; j++) {\
450             Y += lumSrc[j][i     ] * lumFilter[j];\
451         }\
452         for (j=0; j<chrFilterSize; j++) {\
453             U += chrSrc[j][i     ] * chrFilter[j];\
454             V += chrSrc[j][i+VOFW] * chrFilter[j];\
455         }\
456         Y >>=10;\
457         U >>=10;\
458         V >>=10;\
459         if (alpha) {\
460             A = rnd;\
461             for (j=0; j<lumFilterSize; j++)\
462                 A += alpSrc[j][i     ] * lumFilter[j];\
463             A >>=19;\
464             if (A&256)\
465                 A = av_clip_uint8(A);\
466         }
467
468 #define YSCALE_YUV_2_RGBX_FULL_C(rnd,alpha) \
469     YSCALE_YUV_2_PACKEDX_FULL_C(rnd>>3,alpha)\
470         Y-= c->yuv2rgb_y_offset;\
471         Y*= c->yuv2rgb_y_coeff;\
472         Y+= rnd;\
473         R= Y + V*c->yuv2rgb_v2r_coeff;\
474         G= Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;\
475         B= Y +                          U*c->yuv2rgb_u2b_coeff;\
476         if ((R|G|B)&(0xC0000000)) {\
477             if (R>=(256<<22))   R=(256<<22)-1; \
478             else if (R<0)R=0;   \
479             if (G>=(256<<22))   G=(256<<22)-1; \
480             else if (G<0)G=0;   \
481             if (B>=(256<<22))   B=(256<<22)-1; \
482             else if (B<0)B=0;   \
483         }
484
485 #define YSCALE_YUV_2_GRAY16_C \
486     for (i=0; i<(dstW>>1); i++) {\
487         int j;\
488         int Y1 = 1<<18;\
489         int Y2 = 1<<18;\
490         int U  = 1<<18;\
491         int V  = 1<<18;\
492         \
493         const int i2= 2*i;\
494         \
495         for (j=0; j<lumFilterSize; j++) {\
496             Y1 += lumSrc[j][i2] * lumFilter[j];\
497             Y2 += lumSrc[j][i2+1] * lumFilter[j];\
498         }\
499         Y1>>=11;\
500         Y2>>=11;\
501         if ((Y1|Y2|U|V)&65536) {\
502             if (Y1>65535)   Y1=65535; \
503             else if (Y1<0)Y1=0;   \
504             if (Y2>65535)   Y2=65535; \
505             else if (Y2<0)Y2=0;   \
506         }
507
508 #define YSCALE_YUV_2_RGBX_C(type,alpha) \
509     YSCALE_YUV_2_PACKEDX_C(type,alpha)  /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/\
510     r = (type *)c->table_rV[V];   \
511     g = (type *)(c->table_gU[U] + c->table_gV[V]); \
512     b = (type *)c->table_bU[U];
513
514 #define YSCALE_YUV_2_PACKED2_C(type,alpha)   \
515     for (i=0; i<(dstW>>1); i++) { \
516         const int i2= 2*i;       \
517         int Y1= (buf0[i2  ]*yalpha1+buf1[i2  ]*yalpha)>>19;           \
518         int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19;           \
519         int U= (uvbuf0[i     ]*uvalpha1+uvbuf1[i     ]*uvalpha)>>19;  \
520         int V= (uvbuf0[i+VOFW]*uvalpha1+uvbuf1[i+VOFW]*uvalpha)>>19;  \
521         type av_unused *r, *b, *g;                                    \
522         int av_unused A1, A2;                                         \
523         if (alpha) {\
524             A1= (abuf0[i2  ]*yalpha1+abuf1[i2  ]*yalpha)>>19;         \
525             A2= (abuf0[i2+1]*yalpha1+abuf1[i2+1]*yalpha)>>19;         \
526         }
527
528 #define YSCALE_YUV_2_GRAY16_2_C   \
529     for (i=0; i<(dstW>>1); i++) { \
530         const int i2= 2*i;       \
531         int Y1= (buf0[i2  ]*yalpha1+buf1[i2  ]*yalpha)>>11;           \
532         int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>11;
533
534 #define YSCALE_YUV_2_RGB2_C(type,alpha) \
535     YSCALE_YUV_2_PACKED2_C(type,alpha)\
536     r = (type *)c->table_rV[V];\
537     g = (type *)(c->table_gU[U] + c->table_gV[V]);\
538     b = (type *)c->table_bU[U];
539
540 #define YSCALE_YUV_2_PACKED1_C(type,alpha) \
541     for (i=0; i<(dstW>>1); i++) {\
542         const int i2= 2*i;\
543         int Y1= buf0[i2  ]>>7;\
544         int Y2= buf0[i2+1]>>7;\
545         int U= (uvbuf1[i     ])>>7;\
546         int V= (uvbuf1[i+VOFW])>>7;\
547         type av_unused *r, *b, *g;\
548         int av_unused A1, A2;\
549         if (alpha) {\
550             A1= abuf0[i2  ]>>7;\
551             A2= abuf0[i2+1]>>7;\
552         }
553
554 #define YSCALE_YUV_2_GRAY16_1_C \
555     for (i=0; i<(dstW>>1); i++) {\
556         const int i2= 2*i;\
557         int Y1= buf0[i2  ]<<1;\
558         int Y2= buf0[i2+1]<<1;
559
560 #define YSCALE_YUV_2_RGB1_C(type,alpha) \
561     YSCALE_YUV_2_PACKED1_C(type,alpha)\
562     r = (type *)c->table_rV[V];\
563     g = (type *)(c->table_gU[U] + c->table_gV[V]);\
564     b = (type *)c->table_bU[U];
565
566 #define YSCALE_YUV_2_PACKED1B_C(type,alpha) \
567     for (i=0; i<(dstW>>1); i++) {\
568         const int i2= 2*i;\
569         int Y1= buf0[i2  ]>>7;\
570         int Y2= buf0[i2+1]>>7;\
571         int U= (uvbuf0[i     ] + uvbuf1[i     ])>>8;\
572         int V= (uvbuf0[i+VOFW] + uvbuf1[i+VOFW])>>8;\
573         type av_unused *r, *b, *g;\
574         int av_unused A1, A2;\
575         if (alpha) {\
576             A1= abuf0[i2  ]>>7;\
577             A2= abuf0[i2+1]>>7;\
578         }
579
580 #define YSCALE_YUV_2_RGB1B_C(type,alpha) \
581     YSCALE_YUV_2_PACKED1B_C(type,alpha)\
582     r = (type *)c->table_rV[V];\
583     g = (type *)(c->table_gU[U] + c->table_gV[V]);\
584     b = (type *)c->table_bU[U];
585
586 #define YSCALE_YUV_2_MONO2_C \
587     const uint8_t * const d128=dither_8x8_220[y&7];\
588     uint8_t *g= c->table_gU[128] + c->table_gV[128];\
589     for (i=0; i<dstW-7; i+=8) {\
590         int acc;\
591         acc =       g[((buf0[i  ]*yalpha1+buf1[i  ]*yalpha)>>19) + d128[0]];\
592         acc+= acc + g[((buf0[i+1]*yalpha1+buf1[i+1]*yalpha)>>19) + d128[1]];\
593         acc+= acc + g[((buf0[i+2]*yalpha1+buf1[i+2]*yalpha)>>19) + d128[2]];\
594         acc+= acc + g[((buf0[i+3]*yalpha1+buf1[i+3]*yalpha)>>19) + d128[3]];\
595         acc+= acc + g[((buf0[i+4]*yalpha1+buf1[i+4]*yalpha)>>19) + d128[4]];\
596         acc+= acc + g[((buf0[i+5]*yalpha1+buf1[i+5]*yalpha)>>19) + d128[5]];\
597         acc+= acc + g[((buf0[i+6]*yalpha1+buf1[i+6]*yalpha)>>19) + d128[6]];\
598         acc+= acc + g[((buf0[i+7]*yalpha1+buf1[i+7]*yalpha)>>19) + d128[7]];\
599         ((uint8_t*)dest)[0]= c->dstFormat == PIX_FMT_MONOBLACK ? acc : ~acc;\
600         dest++;\
601     }
602
603 #define YSCALE_YUV_2_MONOX_C \
604     const uint8_t * const d128=dither_8x8_220[y&7];\
605     uint8_t *g= c->table_gU[128] + c->table_gV[128];\
606     int acc=0;\
607     for (i=0; i<dstW-1; i+=2) {\
608         int j;\
609         int Y1=1<<18;\
610         int Y2=1<<18;\
611 \
612         for (j=0; j<lumFilterSize; j++) {\
613             Y1 += lumSrc[j][i] * lumFilter[j];\
614             Y2 += lumSrc[j][i+1] * lumFilter[j];\
615         }\
616         Y1>>=19;\
617         Y2>>=19;\
618         if ((Y1|Y2)&256) {\
619             if (Y1>255)   Y1=255;\
620             else if (Y1<0)Y1=0;\
621             if (Y2>255)   Y2=255;\
622             else if (Y2<0)Y2=0;\
623         }\
624         acc+= acc + g[Y1+d128[(i+0)&7]];\
625         acc+= acc + g[Y2+d128[(i+1)&7]];\
626         if ((i&7)==6) {\
627             ((uint8_t*)dest)[0]= c->dstFormat == PIX_FMT_MONOBLACK ? acc : ~acc;\
628             dest++;\
629         }\
630     }
631
632 #define YSCALE_YUV_2_ANYRGB_C(func, func2, func_g16, func_monoblack)\
633     switch(c->dstFormat) {\
634     case PIX_FMT_RGB48BE:\
635     case PIX_FMT_RGB48LE:\
636         func(uint8_t,0)\
637             ((uint8_t*)dest)[ 0]= r[Y1];\
638             ((uint8_t*)dest)[ 1]= r[Y1];\
639             ((uint8_t*)dest)[ 2]= g[Y1];\
640             ((uint8_t*)dest)[ 3]= g[Y1];\
641             ((uint8_t*)dest)[ 4]= b[Y1];\
642             ((uint8_t*)dest)[ 5]= b[Y1];\
643             ((uint8_t*)dest)[ 6]= r[Y2];\
644             ((uint8_t*)dest)[ 7]= r[Y2];\
645             ((uint8_t*)dest)[ 8]= g[Y2];\
646             ((uint8_t*)dest)[ 9]= g[Y2];\
647             ((uint8_t*)dest)[10]= b[Y2];\
648             ((uint8_t*)dest)[11]= b[Y2];\
649             dest+=12;\
650         }\
651         break;\
652     case PIX_FMT_BGR48BE:\
653     case PIX_FMT_BGR48LE:\
654         func(uint8_t,0)\
655             ((uint8_t*)dest)[ 0] = ((uint8_t*)dest)[ 1] = b[Y1];\
656             ((uint8_t*)dest)[ 2] = ((uint8_t*)dest)[ 3] = g[Y1];\
657             ((uint8_t*)dest)[ 4] = ((uint8_t*)dest)[ 5] = r[Y1];\
658             ((uint8_t*)dest)[ 6] = ((uint8_t*)dest)[ 7] = b[Y2];\
659             ((uint8_t*)dest)[ 8] = ((uint8_t*)dest)[ 9] = g[Y2];\
660             ((uint8_t*)dest)[10] = ((uint8_t*)dest)[11] = r[Y2];\
661             dest+=12;\
662         }\
663         break;\
664     case PIX_FMT_RGBA:\
665     case PIX_FMT_BGRA:\
666         if (CONFIG_SMALL) {\
667             int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
668             func(uint32_t,needAlpha)\
669                 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? (A1<<24) : 0);\
670                 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? (A2<<24) : 0);\
671             }\
672         } else {\
673             if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
674                 func(uint32_t,1)\
675                     ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (A1<<24);\
676                     ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (A2<<24);\
677                 }\
678             } else {\
679                 func(uint32_t,0)\
680                     ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
681                     ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
682                 }\
683             }\
684         }\
685         break;\
686     case PIX_FMT_ARGB:\
687     case PIX_FMT_ABGR:\
688         if (CONFIG_SMALL) {\
689             int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
690             func(uint32_t,needAlpha)\
691                 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? A1 : 0);\
692                 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? A2 : 0);\
693             }\
694         } else {\
695             if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
696                 func(uint32_t,1)\
697                     ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + A1;\
698                     ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + A2;\
699                 }\
700             } else {\
701                 func(uint32_t,0)\
702                     ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
703                     ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
704                 }\
705             }\
706         }                \
707         break;\
708     case PIX_FMT_RGB24:\
709         func(uint8_t,0)\
710             ((uint8_t*)dest)[0]= r[Y1];\
711             ((uint8_t*)dest)[1]= g[Y1];\
712             ((uint8_t*)dest)[2]= b[Y1];\
713             ((uint8_t*)dest)[3]= r[Y2];\
714             ((uint8_t*)dest)[4]= g[Y2];\
715             ((uint8_t*)dest)[5]= b[Y2];\
716             dest+=6;\
717         }\
718         break;\
719     case PIX_FMT_BGR24:\
720         func(uint8_t,0)\
721             ((uint8_t*)dest)[0]= b[Y1];\
722             ((uint8_t*)dest)[1]= g[Y1];\
723             ((uint8_t*)dest)[2]= r[Y1];\
724             ((uint8_t*)dest)[3]= b[Y2];\
725             ((uint8_t*)dest)[4]= g[Y2];\
726             ((uint8_t*)dest)[5]= r[Y2];\
727             dest+=6;\
728         }\
729         break;\
730     case PIX_FMT_RGB565BE:\
731     case PIX_FMT_RGB565LE:\
732     case PIX_FMT_BGR565BE:\
733     case PIX_FMT_BGR565LE:\
734         {\
735             const int dr1= dither_2x2_8[y&1    ][0];\
736             const int dg1= dither_2x2_4[y&1    ][0];\
737             const int db1= dither_2x2_8[(y&1)^1][0];\
738             const int dr2= dither_2x2_8[y&1    ][1];\
739             const int dg2= dither_2x2_4[y&1    ][1];\
740             const int db2= dither_2x2_8[(y&1)^1][1];\
741             func(uint16_t,0)\
742                 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
743                 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
744             }\
745         }\
746         break;\
747     case PIX_FMT_RGB555BE:\
748     case PIX_FMT_RGB555LE:\
749     case PIX_FMT_BGR555BE:\
750     case PIX_FMT_BGR555LE:\
751         {\
752             const int dr1= dither_2x2_8[y&1    ][0];\
753             const int dg1= dither_2x2_8[y&1    ][1];\
754             const int db1= dither_2x2_8[(y&1)^1][0];\
755             const int dr2= dither_2x2_8[y&1    ][1];\
756             const int dg2= dither_2x2_8[y&1    ][0];\
757             const int db2= dither_2x2_8[(y&1)^1][1];\
758             func(uint16_t,0)\
759                 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
760                 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
761             }\
762         }\
763         break;\
764     case PIX_FMT_RGB444BE:\
765     case PIX_FMT_RGB444LE:\
766     case PIX_FMT_BGR444BE:\
767     case PIX_FMT_BGR444LE:\
768         {\
769             const int dr1= dither_4x4_16[y&3    ][0];\
770             const int dg1= dither_4x4_16[y&3    ][1];\
771             const int db1= dither_4x4_16[(y&3)^3][0];\
772             const int dr2= dither_4x4_16[y&3    ][1];\
773             const int dg2= dither_4x4_16[y&3    ][0];\
774             const int db2= dither_4x4_16[(y&3)^3][1];\
775             func(uint16_t,0)\
776                 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
777                 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
778             }\
779         }\
780         break;\
781     case PIX_FMT_RGB8:\
782     case PIX_FMT_BGR8:\
783         {\
784             const uint8_t * const d64= dither_8x8_73[y&7];\
785             const uint8_t * const d32= dither_8x8_32[y&7];\
786             func(uint8_t,0)\
787                 ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];\
788                 ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];\
789             }\
790         }\
791         break;\
792     case PIX_FMT_RGB4:\
793     case PIX_FMT_BGR4:\
794         {\
795             const uint8_t * const d64= dither_8x8_73 [y&7];\
796             const uint8_t * const d128=dither_8x8_220[y&7];\
797             func(uint8_t,0)\
798                 ((uint8_t*)dest)[i]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]]\
799                                  + ((r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]])<<4);\
800             }\
801         }\
802         break;\
803     case PIX_FMT_RGB4_BYTE:\
804     case PIX_FMT_BGR4_BYTE:\
805         {\
806             const uint8_t * const d64= dither_8x8_73 [y&7];\
807             const uint8_t * const d128=dither_8x8_220[y&7];\
808             func(uint8_t,0)\
809                 ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];\
810                 ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];\
811             }\
812         }\
813         break;\
814     case PIX_FMT_MONOBLACK:\
815     case PIX_FMT_MONOWHITE:\
816         {\
817             func_monoblack\
818         }\
819         break;\
820     case PIX_FMT_YUYV422:\
821         func2\
822             ((uint8_t*)dest)[2*i2+0]= Y1;\
823             ((uint8_t*)dest)[2*i2+1]= U;\
824             ((uint8_t*)dest)[2*i2+2]= Y2;\
825             ((uint8_t*)dest)[2*i2+3]= V;\
826         }                \
827         break;\
828     case PIX_FMT_UYVY422:\
829         func2\
830             ((uint8_t*)dest)[2*i2+0]= U;\
831             ((uint8_t*)dest)[2*i2+1]= Y1;\
832             ((uint8_t*)dest)[2*i2+2]= V;\
833             ((uint8_t*)dest)[2*i2+3]= Y2;\
834         }                \
835         break;\
836     case PIX_FMT_GRAY16BE:\
837         func_g16\
838             ((uint8_t*)dest)[2*i2+0]= Y1>>8;\
839             ((uint8_t*)dest)[2*i2+1]= Y1;\
840             ((uint8_t*)dest)[2*i2+2]= Y2>>8;\
841             ((uint8_t*)dest)[2*i2+3]= Y2;\
842         }                \
843         break;\
844     case PIX_FMT_GRAY16LE:\
845         func_g16\
846             ((uint8_t*)dest)[2*i2+0]= Y1;\
847             ((uint8_t*)dest)[2*i2+1]= Y1>>8;\
848             ((uint8_t*)dest)[2*i2+2]= Y2;\
849             ((uint8_t*)dest)[2*i2+3]= Y2>>8;\
850         }                \
851         break;\
852     }
853
854 static inline void yuv2packedXinC(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
855                                   const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
856                                   const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
857 {
858     int i;
859     YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C, YSCALE_YUV_2_PACKEDX_C(void,0), YSCALE_YUV_2_GRAY16_C, YSCALE_YUV_2_MONOX_C)
860 }
861
862 static inline void yuv2rgbXinC_full(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
863                                     const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
864                                     const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
865 {
866     int i;
867     int step= c->dstFormatBpp/8;
868     int aidx= 3;
869
870     switch(c->dstFormat) {
871     case PIX_FMT_ARGB:
872         dest++;
873         aidx= 0;
874     case PIX_FMT_RGB24:
875         aidx--;
876     case PIX_FMT_RGBA:
877         if (CONFIG_SMALL) {
878             int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
879             YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
880                 dest[aidx]= needAlpha ? A : 255;
881                 dest[0]= R>>22;
882                 dest[1]= G>>22;
883                 dest[2]= B>>22;
884                 dest+= step;
885             }
886         } else {
887             if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
888                 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
889                     dest[aidx]= A;
890                     dest[0]= R>>22;
891                     dest[1]= G>>22;
892                     dest[2]= B>>22;
893                     dest+= step;
894                 }
895             } else {
896                 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
897                     dest[aidx]= 255;
898                     dest[0]= R>>22;
899                     dest[1]= G>>22;
900                     dest[2]= B>>22;
901                     dest+= step;
902                 }
903             }
904         }
905         break;
906     case PIX_FMT_ABGR:
907         dest++;
908         aidx= 0;
909     case PIX_FMT_BGR24:
910         aidx--;
911     case PIX_FMT_BGRA:
912         if (CONFIG_SMALL) {
913             int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
914             YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
915                 dest[aidx]= needAlpha ? A : 255;
916                 dest[0]= B>>22;
917                 dest[1]= G>>22;
918                 dest[2]= R>>22;
919                 dest+= step;
920             }
921         } else {
922             if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
923                 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
924                     dest[aidx]= A;
925                     dest[0]= B>>22;
926                     dest[1]= G>>22;
927                     dest[2]= R>>22;
928                     dest+= step;
929                 }
930             } else {
931                 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
932                     dest[aidx]= 255;
933                     dest[0]= B>>22;
934                     dest[1]= G>>22;
935                     dest[2]= R>>22;
936                     dest+= step;
937                 }
938             }
939         }
940         break;
941     default:
942         assert(0);
943     }
944 }
945
946 static void fillPlane(uint8_t* plane, int stride, int width, int height, int y, uint8_t val)
947 {
948     int i;
949     uint8_t *ptr = plane + stride*y;
950     for (i=0; i<height; i++) {
951         memset(ptr, val, width);
952         ptr += stride;
953     }
954 }
955
956 static inline void rgb48ToY(uint8_t *dst, const uint8_t *src, long width,
957                             uint32_t *unused)
958 {
959     int i;
960     for (i = 0; i < width; i++) {
961         int r = src[i*6+0];
962         int g = src[i*6+2];
963         int b = src[i*6+4];
964
965         dst[i] = (RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
966     }
967 }
968
969 static inline void rgb48ToUV(uint8_t *dstU, uint8_t *dstV,
970                              const uint8_t *src1, const uint8_t *src2,
971                              long width, uint32_t *unused)
972 {
973     int i;
974     assert(src1==src2);
975     for (i = 0; i < width; i++) {
976         int r = src1[6*i + 0];
977         int g = src1[6*i + 2];
978         int b = src1[6*i + 4];
979
980         dstU[i] = (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
981         dstV[i] = (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
982     }
983 }
984
985 static inline void rgb48ToUV_half(uint8_t *dstU, uint8_t *dstV,
986                                   const uint8_t *src1, const uint8_t *src2,
987                                   long width, uint32_t *unused)
988 {
989     int i;
990     assert(src1==src2);
991     for (i = 0; i < width; i++) {
992         int r= src1[12*i + 0] + src1[12*i + 6];
993         int g= src1[12*i + 2] + src1[12*i + 8];
994         int b= src1[12*i + 4] + src1[12*i + 10];
995
996         dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
997         dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
998     }
999 }
1000
1001 static inline void bgr48ToY(uint8_t *dst, const uint8_t *src, long width,
1002                             uint32_t *unused)
1003 {
1004     int i;
1005     for (i = 0; i < width; i++) {
1006         int b = src[i*6+0];
1007         int g = src[i*6+2];
1008         int r = src[i*6+4];
1009
1010         dst[i] = (RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1011     }
1012 }
1013
1014 static inline void bgr48ToUV(uint8_t *dstU, uint8_t *dstV,
1015                              const uint8_t *src1, const uint8_t *src2,
1016                              long width, uint32_t *unused)
1017 {
1018     int i;
1019     for (i = 0; i < width; i++) {
1020         int b = src1[6*i + 0];
1021         int g = src1[6*i + 2];
1022         int r = src1[6*i + 4];
1023
1024         dstU[i] = (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1025         dstV[i] = (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1026     }
1027 }
1028
1029 static inline void bgr48ToUV_half(uint8_t *dstU, uint8_t *dstV,
1030                                   const uint8_t *src1, const uint8_t *src2,
1031                                   long width, uint32_t *unused)
1032 {
1033     int i;
1034     for (i = 0; i < width; i++) {
1035         int b= src1[12*i + 0] + src1[12*i + 6];
1036         int g= src1[12*i + 2] + src1[12*i + 8];
1037         int r= src1[12*i + 4] + src1[12*i + 10];
1038
1039         dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
1040         dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
1041     }
1042 }
1043
1044 #define BGR2Y(type, name, shr, shg, shb, maskr, maskg, maskb, RY, GY, BY, S)\
1045 static inline void name(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)\
1046 {\
1047     int i;\
1048     for (i=0; i<width; i++) {\
1049         int b= (((const type*)src)[i]>>shb)&maskb;\
1050         int g= (((const type*)src)[i]>>shg)&maskg;\
1051         int r= (((const type*)src)[i]>>shr)&maskr;\
1052 \
1053         dst[i]= (((RY)*r + (GY)*g + (BY)*b + (33<<((S)-1)))>>(S));\
1054     }\
1055 }
1056
1057 BGR2Y(uint32_t, bgr32ToY,16, 0, 0, 0x00FF, 0xFF00, 0x00FF, RY<< 8, GY   , BY<< 8, RGB2YUV_SHIFT+8)
1058 BGR2Y(uint32_t,bgr321ToY,16,16, 0, 0xFF00, 0x00FF, 0xFF00, RY    , GY<<8, BY    , RGB2YUV_SHIFT+8)
1059 BGR2Y(uint32_t, rgb32ToY, 0, 0,16, 0x00FF, 0xFF00, 0x00FF, RY<< 8, GY   , BY<< 8, RGB2YUV_SHIFT+8)
1060 BGR2Y(uint32_t,rgb321ToY, 0,16,16, 0xFF00, 0x00FF, 0xFF00, RY    , GY<<8, BY    , RGB2YUV_SHIFT+8)
1061 BGR2Y(uint16_t, bgr16ToY, 0, 0, 0, 0x001F, 0x07E0, 0xF800, RY<<11, GY<<5, BY    , RGB2YUV_SHIFT+8)
1062 BGR2Y(uint16_t, bgr15ToY, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, RY<<10, GY<<5, BY    , RGB2YUV_SHIFT+7)
1063 BGR2Y(uint16_t, rgb16ToY, 0, 0, 0, 0xF800, 0x07E0, 0x001F, RY    , GY<<5, BY<<11, RGB2YUV_SHIFT+8)
1064 BGR2Y(uint16_t, rgb15ToY, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, RY    , GY<<5, BY<<10, RGB2YUV_SHIFT+7)
1065
1066 static inline void abgrToA(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
1067 {
1068     int i;
1069     for (i=0; i<width; i++) {
1070         dst[i]= src[4*i];
1071     }
1072 }
1073
1074 #define BGR2UV(type, name, shr, shg, shb, shp, maskr, maskg, maskb, RU, GU, BU, RV, GV, BV, S) \
1075 static inline void name(uint8_t *dstU, uint8_t *dstV, const uint8_t *src, const uint8_t *dummy, long width, uint32_t *unused)\
1076 {\
1077     int i;\
1078     for (i=0; i<width; i++) {\
1079         int b= ((((const type*)src)[i]>>shp)&maskb)>>shb;\
1080         int g= ((((const type*)src)[i]>>shp)&maskg)>>shg;\
1081         int r= ((((const type*)src)[i]>>shp)&maskr)>>shr;\
1082 \
1083         dstU[i]= ((RU)*r + (GU)*g + (BU)*b + (257<<((S)-1)))>>(S);\
1084         dstV[i]= ((RV)*r + (GV)*g + (BV)*b + (257<<((S)-1)))>>(S);\
1085     }\
1086 }\
1087 static inline void name ## _half(uint8_t *dstU, uint8_t *dstV, const uint8_t *src, const uint8_t *dummy, long width, uint32_t *unused)\
1088 {\
1089     int i;\
1090     for (i=0; i<width; i++) {\
1091         int pix0= ((const type*)src)[2*i+0]>>shp;\
1092         int pix1= ((const type*)src)[2*i+1]>>shp;\
1093         int g= (pix0&~(maskr|maskb))+(pix1&~(maskr|maskb));\
1094         int b= ((pix0+pix1-g)&(maskb|(2*maskb)))>>shb;\
1095         int r= ((pix0+pix1-g)&(maskr|(2*maskr)))>>shr;\
1096         g&= maskg|(2*maskg);\
1097 \
1098         g>>=shg;\
1099 \
1100         dstU[i]= ((RU)*r + (GU)*g + (BU)*b + (257<<(S)))>>((S)+1);\
1101         dstV[i]= ((RV)*r + (GV)*g + (BV)*b + (257<<(S)))>>((S)+1);\
1102     }\
1103 }
1104
1105 BGR2UV(uint32_t, bgr32ToUV,16, 0, 0, 0, 0xFF0000, 0xFF00,   0x00FF, RU<< 8, GU   , BU<< 8, RV<< 8, GV   , BV<< 8, RGB2YUV_SHIFT+8)
1106 BGR2UV(uint32_t,bgr321ToUV,16, 0, 0, 8, 0xFF0000, 0xFF00,   0x00FF, RU<< 8, GU   , BU<< 8, RV<< 8, GV   , BV<< 8, RGB2YUV_SHIFT+8)
1107 BGR2UV(uint32_t, rgb32ToUV, 0, 0,16, 0,   0x00FF, 0xFF00, 0xFF0000, RU<< 8, GU   , BU<< 8, RV<< 8, GV   , BV<< 8, RGB2YUV_SHIFT+8)
1108 BGR2UV(uint32_t,rgb321ToUV, 0, 0,16, 8,   0x00FF, 0xFF00, 0xFF0000, RU<< 8, GU   , BU<< 8, RV<< 8, GV   , BV<< 8, RGB2YUV_SHIFT+8)
1109 BGR2UV(uint16_t, bgr16ToUV, 0, 0, 0, 0,   0x001F, 0x07E0,   0xF800, RU<<11, GU<<5, BU    , RV<<11, GV<<5, BV    , RGB2YUV_SHIFT+8)
1110 BGR2UV(uint16_t, bgr15ToUV, 0, 0, 0, 0,   0x001F, 0x03E0,   0x7C00, RU<<10, GU<<5, BU    , RV<<10, GV<<5, BV    , RGB2YUV_SHIFT+7)
1111 BGR2UV(uint16_t, rgb16ToUV, 0, 0, 0, 0,   0xF800, 0x07E0,   0x001F, RU    , GU<<5, BU<<11, RV    , GV<<5, BV<<11, RGB2YUV_SHIFT+8)
1112 BGR2UV(uint16_t, rgb15ToUV, 0, 0, 0, 0,   0x7C00, 0x03E0,   0x001F, RU    , GU<<5, BU<<10, RV    , GV<<5, BV<<10, RGB2YUV_SHIFT+7)
1113
1114 static inline void palToY(uint8_t *dst, const uint8_t *src, long width, uint32_t *pal)
1115 {
1116     int i;
1117     for (i=0; i<width; i++) {
1118         int d= src[i];
1119
1120         dst[i]= pal[d] & 0xFF;
1121     }
1122 }
1123
1124 static inline void palToUV(uint8_t *dstU, uint8_t *dstV,
1125                            const uint8_t *src1, const uint8_t *src2,
1126                            long width, uint32_t *pal)
1127 {
1128     int i;
1129     assert(src1 == src2);
1130     for (i=0; i<width; i++) {
1131         int p= pal[src1[i]];
1132
1133         dstU[i]= p>>8;
1134         dstV[i]= p>>16;
1135     }
1136 }
1137
1138 static inline void monowhite2Y(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
1139 {
1140     int i, j;
1141     for (i=0; i<width/8; i++) {
1142         int d= ~src[i];
1143         for(j=0; j<8; j++)
1144             dst[8*i+j]= ((d>>(7-j))&1)*255;
1145     }
1146 }
1147
1148 static inline void monoblack2Y(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
1149 {
1150     int i, j;
1151     for (i=0; i<width/8; i++) {
1152         int d= src[i];
1153         for(j=0; j<8; j++)
1154             dst[8*i+j]= ((d>>(7-j))&1)*255;
1155     }
1156 }
1157
1158 //Note: we have C, MMX, MMX2, 3DNOW versions, there is no 3DNOW+MMX2 one
1159 //Plain C versions
1160 #if CONFIG_RUNTIME_CPUDETECT
1161 #  define COMPILE_C 1
1162 #  if   ARCH_X86
1163 #    define COMPILE_MMX     HAVE_MMX
1164 #    define COMPILE_MMX2    HAVE_MMX2
1165 #    define COMPILE_3DNOW   HAVE_AMD3DNOW
1166 #  elif ARCH_PPC
1167 #    define COMPILE_ALTIVEC HAVE_ALTIVEC
1168 #  endif
1169 #else /* CONFIG_RUNTIME_CPUDETECT */
1170 #  if   ARCH_X86
1171 #    if   HAVE_MMX2
1172 #      define COMPILE_MMX2  1
1173 #    elif HAVE_AMD3DNOW
1174 #      define COMPILE_3DNOW 1
1175 #    elif HAVE_MMX
1176 #      define COMPILE_MMX   1
1177 #    else
1178 #      define COMPILE_C     1
1179 #    endif
1180 #  elif ARCH_PPC && HAVE_ALTIVEC
1181 #    define COMPILE_ALTIVEC 1
1182 #  else
1183 #    define COMPILE_C       1
1184 #  endif
1185 #endif
1186
1187 #ifndef COMPILE_C
1188 #  define COMPILE_C 0
1189 #endif
1190 #ifndef COMPILE_MMX
1191 #  define COMPILE_MMX 0
1192 #endif
1193 #ifndef COMPILE_MMX2
1194 #  define COMPILE_MMX2 0
1195 #endif
1196 #ifndef COMPILE_3DNOW
1197 #  define COMPILE_3DNOW 0
1198 #endif
1199 #ifndef COMPILE_ALTIVEC
1200 #  define COMPILE_ALTIVEC 0
1201 #endif
1202
1203 #define COMPILE_TEMPLATE_MMX 0
1204 #define COMPILE_TEMPLATE_MMX2 0
1205 #define COMPILE_TEMPLATE_AMD3DNOW 0
1206 #define COMPILE_TEMPLATE_ALTIVEC 0
1207
1208 #include "swscale_template.c"
1209
1210 #if COMPILE_ALTIVEC
1211 #undef RENAME
1212 #undef COMPILE_TEMPLATE_ALTIVEC
1213 #define COMPILE_TEMPLATE_ALTIVEC 1
1214 #define RENAME(a) a ## _altivec
1215 #include "ppc/swscale_template.c"
1216 #endif
1217
1218 #if ARCH_X86
1219
1220 //MMX versions
1221 #if COMPILE_MMX
1222 #undef RENAME
1223 #undef COMPILE_TEMPLATE_MMX
1224 #undef COMPILE_TEMPLATE_MMX2
1225 #undef COMPILE_TEMPLATE_AMD3DNOW
1226 #define COMPILE_TEMPLATE_MMX 1
1227 #define COMPILE_TEMPLATE_MMX2 0
1228 #define COMPILE_TEMPLATE_AMD3DNOW 0
1229 #define RENAME(a) a ## _MMX
1230 #include "x86/swscale_template.c"
1231 #endif
1232
1233 //MMX2 versions
1234 #if COMPILE_MMX2
1235 #undef RENAME
1236 #undef COMPILE_TEMPLATE_MMX
1237 #undef COMPILE_TEMPLATE_MMX2
1238 #undef COMPILE_TEMPLATE_AMD3DNOW
1239 #define COMPILE_TEMPLATE_MMX 1
1240 #define COMPILE_TEMPLATE_MMX2 1
1241 #define COMPILE_TEMPLATE_AMD3DNOW 0
1242 #define RENAME(a) a ## _MMX2
1243 #include "x86/swscale_template.c"
1244 #endif
1245
1246 //3DNOW versions
1247 #if COMPILE_3DNOW
1248 #undef RENAME
1249 #undef COMPILE_TEMPLATE_MMX
1250 #undef COMPILE_TEMPLATE_MMX2
1251 #undef COMPILE_TEMPLATE_AMD3DNOW
1252 #define COMPILE_TEMPLATE_MMX 1
1253 #define COMPILE_TEMPLATE_MMX2 0
1254 #define COMPILE_TEMPLATE_AMD3DNOW 1
1255 #define RENAME(a) a ## _3DNow
1256 #include "x86/swscale_template.c"
1257 #endif
1258
1259 #endif //ARCH_X86
1260
1261 SwsFunc ff_getSwsFunc(SwsContext *c)
1262 {
1263     sws_init_swScale_c(c);
1264
1265 #if CONFIG_RUNTIME_CPUDETECT
1266 #if ARCH_X86
1267     // ordered per speed fastest first
1268     if (c->flags & SWS_CPU_CAPS_MMX2) {
1269         sws_init_swScale_MMX2(c);
1270         return swScale_MMX2;
1271     } else if (c->flags & SWS_CPU_CAPS_3DNOW) {
1272         sws_init_swScale_3DNow(c);
1273         return swScale_3DNow;
1274     } else if (c->flags & SWS_CPU_CAPS_MMX) {
1275         sws_init_swScale_MMX(c);
1276         return swScale_MMX;
1277     }
1278
1279 #else
1280 #if COMPILE_ALTIVEC
1281     if (c->flags & SWS_CPU_CAPS_ALTIVEC) {
1282         sws_init_swScale_altivec(c);
1283         return swScale_altivec;
1284     }
1285 #endif
1286 #endif /* ARCH_X86 */
1287 #else //CONFIG_RUNTIME_CPUDETECT
1288 #if   COMPILE_TEMPLATE_MMX2
1289     sws_init_swScale_MMX2(c);
1290     return swScale_MMX2;
1291 #elif COMPILE_TEMPLATE_AMD3DNOW
1292     sws_init_swScale_3DNow(c);
1293     return swScale_3DNow;
1294 #elif COMPILE_TEMPLATE_MMX
1295     sws_init_swScale_MMX(c);
1296     return swScale_MMX;
1297 #elif COMPILE_TEMPLATE_ALTIVEC
1298     sws_init_swScale_altivec(c);
1299     return swScale_altivec;
1300 #endif
1301 #endif //!CONFIG_RUNTIME_CPUDETECT
1302
1303     return swScale_c;
1304 }
1305
1306 static void copyPlane(const uint8_t *src, int srcStride,
1307                       int srcSliceY, int srcSliceH, int width,
1308                       uint8_t *dst, int dstStride)
1309 {
1310     dst += dstStride * srcSliceY;
1311     if (dstStride == srcStride && srcStride > 0) {
1312         memcpy(dst, src, srcSliceH * dstStride);
1313     } else {
1314         int i;
1315         for (i=0; i<srcSliceH; i++) {
1316             memcpy(dst, src, width);
1317             src += srcStride;
1318             dst += dstStride;
1319         }
1320     }
1321 }
1322
1323 static int planarToNv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1324                                int srcSliceH, uint8_t* dstParam[], int dstStride[])
1325 {
1326     uint8_t *dst = dstParam[1] + dstStride[1]*srcSliceY/2;
1327
1328     copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
1329               dstParam[0], dstStride[0]);
1330
1331     if (c->dstFormat == PIX_FMT_NV12)
1332         interleaveBytes(src[1], src[2], dst, c->srcW/2, srcSliceH/2, srcStride[1], srcStride[2], dstStride[0]);
1333     else
1334         interleaveBytes(src[2], src[1], dst, c->srcW/2, srcSliceH/2, srcStride[2], srcStride[1], dstStride[0]);
1335
1336     return srcSliceH;
1337 }
1338
1339 static int planarToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1340                                int srcSliceH, uint8_t* dstParam[], int dstStride[])
1341 {
1342     uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
1343
1344     yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
1345
1346     return srcSliceH;
1347 }
1348
1349 static int planarToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1350                                int srcSliceH, uint8_t* dstParam[], int dstStride[])
1351 {
1352     uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
1353
1354     yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
1355
1356     return srcSliceH;
1357 }
1358
1359 static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1360                                 int srcSliceH, uint8_t* dstParam[], int dstStride[])
1361 {
1362     uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
1363
1364     yuv422ptoyuy2(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
1365
1366     return srcSliceH;
1367 }
1368
1369 static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1370                                 int srcSliceH, uint8_t* dstParam[], int dstStride[])
1371 {
1372     uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
1373
1374     yuv422ptouyvy(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
1375
1376     return srcSliceH;
1377 }
1378
1379 static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1380                                int srcSliceH, uint8_t* dstParam[], int dstStride[])
1381 {
1382     uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
1383     uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2;
1384     uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2;
1385
1386     yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
1387
1388     if (dstParam[3])
1389         fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1390
1391     return srcSliceH;
1392 }
1393
1394 static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1395                                int srcSliceH, uint8_t* dstParam[], int dstStride[])
1396 {
1397     uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
1398     uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY;
1399     uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY;
1400
1401     yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
1402
1403     return srcSliceH;
1404 }
1405
1406 static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1407                                int srcSliceH, uint8_t* dstParam[], int dstStride[])
1408 {
1409     uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
1410     uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2;
1411     uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2;
1412
1413     uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
1414
1415     if (dstParam[3])
1416         fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1417
1418     return srcSliceH;
1419 }
1420
1421 static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1422                                int srcSliceH, uint8_t* dstParam[], int dstStride[])
1423 {
1424     uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
1425     uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY;
1426     uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY;
1427
1428     uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
1429
1430     return srcSliceH;
1431 }
1432
1433 static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
1434 {
1435     long i;
1436     for (i=0; i<num_pixels; i++)
1437         ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | (src[(i<<1)+1] << 24);
1438 }
1439
1440 static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
1441 {
1442     long i;
1443
1444     for (i=0; i<num_pixels; i++)
1445         ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | src[(i<<1)+1];
1446 }
1447
1448 static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
1449 {
1450     long i;
1451
1452     for (i=0; i<num_pixels; i++) {
1453         //FIXME slow?
1454         dst[0]= palette[src[i<<1]*4+0];
1455         dst[1]= palette[src[i<<1]*4+1];
1456         dst[2]= palette[src[i<<1]*4+2];
1457         dst+= 3;
1458     }
1459 }
1460
1461 static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1462                            int srcSliceH, uint8_t* dst[], int dstStride[])
1463 {
1464     const enum PixelFormat srcFormat= c->srcFormat;
1465     const enum PixelFormat dstFormat= c->dstFormat;
1466     void (*conv)(const uint8_t *src, uint8_t *dst, long num_pixels,
1467                  const uint8_t *palette)=NULL;
1468     int i;
1469     uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
1470     const uint8_t *srcPtr= src[0];
1471
1472     if (srcFormat == PIX_FMT_Y400A) {
1473         switch (dstFormat) {
1474         case PIX_FMT_RGB32  : conv = gray8aToPacked32; break;
1475         case PIX_FMT_BGR32  : conv = gray8aToPacked32; break;
1476         case PIX_FMT_BGR32_1: conv = gray8aToPacked32_1; break;
1477         case PIX_FMT_RGB32_1: conv = gray8aToPacked32_1; break;
1478         case PIX_FMT_RGB24  : conv = gray8aToPacked24; break;
1479         case PIX_FMT_BGR24  : conv = gray8aToPacked24; break;
1480         }
1481     } else if (usePal(srcFormat)) {
1482         switch (dstFormat) {
1483         case PIX_FMT_RGB32  : conv = sws_convertPalette8ToPacked32; break;
1484         case PIX_FMT_BGR32  : conv = sws_convertPalette8ToPacked32; break;
1485         case PIX_FMT_BGR32_1: conv = sws_convertPalette8ToPacked32; break;
1486         case PIX_FMT_RGB32_1: conv = sws_convertPalette8ToPacked32; break;
1487         case PIX_FMT_RGB24  : conv = sws_convertPalette8ToPacked24; break;
1488         case PIX_FMT_BGR24  : conv = sws_convertPalette8ToPacked24; break;
1489         }
1490     }
1491
1492     if (!conv)
1493         av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
1494                sws_format_name(srcFormat), sws_format_name(dstFormat));
1495     else {
1496         for (i=0; i<srcSliceH; i++) {
1497             conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb);
1498             srcPtr+= srcStride[0];
1499             dstPtr+= dstStride[0];
1500         }
1501     }
1502
1503     return srcSliceH;
1504 }
1505
1506 #define isRGBA32(x) (            \
1507            (x) == PIX_FMT_ARGB   \
1508         || (x) == PIX_FMT_RGBA   \
1509         || (x) == PIX_FMT_BGRA   \
1510         || (x) == PIX_FMT_ABGR   \
1511         )
1512
1513 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
1514 static int rgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1515                            int srcSliceH, uint8_t* dst[], int dstStride[])
1516 {
1517     const enum PixelFormat srcFormat= c->srcFormat;
1518     const enum PixelFormat dstFormat= c->dstFormat;
1519     const int srcBpp= (c->srcFormatBpp + 7) >> 3;
1520     const int dstBpp= (c->dstFormatBpp + 7) >> 3;
1521     const int srcId= c->srcFormatBpp >> 2; /* 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 */
1522     const int dstId= c->dstFormatBpp >> 2;
1523     void (*conv)(const uint8_t *src, uint8_t *dst, long src_size)=NULL;
1524
1525 #define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst)
1526
1527     if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
1528         if (     CONV_IS(ABGR, RGBA)
1529               || CONV_IS(ARGB, BGRA)
1530               || CONV_IS(BGRA, ARGB)
1531               || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210;
1532         else if (CONV_IS(ABGR, ARGB)
1533               || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321;
1534         else if (CONV_IS(ABGR, BGRA)
1535               || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230;
1536         else if (CONV_IS(BGRA, RGBA)
1537               || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103;
1538         else if (CONV_IS(BGRA, ABGR)
1539               || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
1540     } else
1541     /* BGR -> BGR */
1542     if (  (isBGRinInt(srcFormat) && isBGRinInt(dstFormat))
1543        || (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
1544         switch(srcId | (dstId<<4)) {
1545         case 0x34: conv= rgb16to15; break;
1546         case 0x36: conv= rgb24to15; break;
1547         case 0x38: conv= rgb32to15; break;
1548         case 0x43: conv= rgb15to16; break;
1549         case 0x46: conv= rgb24to16; break;
1550         case 0x48: conv= rgb32to16; break;
1551         case 0x63: conv= rgb15to24; break;
1552         case 0x64: conv= rgb16to24; break;
1553         case 0x68: conv= rgb32to24; break;
1554         case 0x83: conv= rgb15to32; break;
1555         case 0x84: conv= rgb16to32; break;
1556         case 0x86: conv= rgb24to32; break;
1557         }
1558     } else if (  (isBGRinInt(srcFormat) && isRGBinInt(dstFormat))
1559              || (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
1560         switch(srcId | (dstId<<4)) {
1561         case 0x33: conv= rgb15tobgr15; break;
1562         case 0x34: conv= rgb16tobgr15; break;
1563         case 0x36: conv= rgb24tobgr15; break;
1564         case 0x38: conv= rgb32tobgr15; break;
1565         case 0x43: conv= rgb15tobgr16; break;
1566         case 0x44: conv= rgb16tobgr16; break;
1567         case 0x46: conv= rgb24tobgr16; break;
1568         case 0x48: conv= rgb32tobgr16; break;
1569         case 0x63: conv= rgb15tobgr24; break;
1570         case 0x64: conv= rgb16tobgr24; break;
1571         case 0x66: conv= rgb24tobgr24; break;
1572         case 0x68: conv= rgb32tobgr24; break;
1573         case 0x83: conv= rgb15tobgr32; break;
1574         case 0x84: conv= rgb16tobgr32; break;
1575         case 0x86: conv= rgb24tobgr32; break;
1576         }
1577     }
1578
1579     if (!conv) {
1580         av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
1581                sws_format_name(srcFormat), sws_format_name(dstFormat));
1582     } else {
1583         const uint8_t *srcPtr= src[0];
1584               uint8_t *dstPtr= dst[0];
1585         if ((srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1) && !isRGBA32(dstFormat))
1586             srcPtr += ALT32_CORR;
1587
1588         if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) && !isRGBA32(srcFormat))
1589             dstPtr += ALT32_CORR;
1590
1591         if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0)
1592             conv(srcPtr, dstPtr + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]);
1593         else {
1594             int i;
1595             dstPtr += dstStride[0]*srcSliceY;
1596
1597             for (i=0; i<srcSliceH; i++) {
1598                 conv(srcPtr, dstPtr, c->srcW*srcBpp);
1599                 srcPtr+= srcStride[0];
1600                 dstPtr+= dstStride[0];
1601             }
1602         }
1603     }
1604     return srcSliceH;
1605 }
1606
1607 static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1608                               int srcSliceH, uint8_t* dst[], int dstStride[])
1609 {
1610     rgb24toyv12(
1611         src[0],
1612         dst[0]+ srcSliceY    *dstStride[0],
1613         dst[1]+(srcSliceY>>1)*dstStride[1],
1614         dst[2]+(srcSliceY>>1)*dstStride[2],
1615         c->srcW, srcSliceH,
1616         dstStride[0], dstStride[1], srcStride[0]);
1617     if (dst[3])
1618         fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1619     return srcSliceH;
1620 }
1621
1622 static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1623                              int srcSliceH, uint8_t* dst[], int dstStride[])
1624 {
1625     copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
1626               dst[0], dstStride[0]);
1627
1628     planar2x(src[1], dst[1] + dstStride[1]*(srcSliceY >> 1), c->chrSrcW,
1629              srcSliceH >> 2, srcStride[1], dstStride[1]);
1630     planar2x(src[2], dst[2] + dstStride[2]*(srcSliceY >> 1), c->chrSrcW,
1631              srcSliceH >> 2, srcStride[2], dstStride[2]);
1632     if (dst[3])
1633         fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1634     return srcSliceH;
1635 }
1636
1637 /* unscaled copy like stuff (assumes nearly identical formats) */
1638 static int packedCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1639                              int srcSliceH, uint8_t* dst[], int dstStride[])
1640 {
1641     if (dstStride[0]==srcStride[0] && srcStride[0] > 0)
1642         memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]);
1643     else {
1644         int i;
1645         const uint8_t *srcPtr= src[0];
1646         uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
1647         int length=0;
1648
1649         /* universal length finder */
1650         while(length+c->srcW <= FFABS(dstStride[0])
1651            && length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW;
1652         assert(length!=0);
1653
1654         for (i=0; i<srcSliceH; i++) {
1655             memcpy(dstPtr, srcPtr, length);
1656             srcPtr+= srcStride[0];
1657             dstPtr+= dstStride[0];
1658         }
1659     }
1660     return srcSliceH;
1661 }
1662
1663 static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1664                              int srcSliceH, uint8_t* dst[], int dstStride[])
1665 {
1666     int plane, i, j;
1667     for (plane=0; plane<4; plane++) {
1668         int length= (plane==0 || plane==3) ? c->srcW  : -((-c->srcW  )>>c->chrDstHSubSample);
1669         int y=      (plane==0 || plane==3) ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample);
1670         int height= (plane==0 || plane==3) ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample);
1671         const uint8_t *srcPtr= src[plane];
1672         uint8_t *dstPtr= dst[plane] + dstStride[plane]*y;
1673
1674         if (!dst[plane]) continue;
1675         // ignore palette for GRAY8
1676         if (plane == 1 && !dst[2]) continue;
1677         if (!src[plane] || (plane == 1 && !src[2])) {
1678             if(is16BPS(c->dstFormat))
1679                 length*=2;
1680             fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128);
1681         } else {
1682             if(is9_OR_10BPS(c->srcFormat)) {
1683                 const int src_depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1+1;
1684                 const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1;
1685                 const uint16_t *srcPtr2 = (const uint16_t*)srcPtr;
1686
1687                 if (is16BPS(c->dstFormat)) {
1688                     uint16_t *dstPtr2 = (uint16_t*)dstPtr;
1689 #define COPY9_OR_10TO16(rfunc, wfunc) \
1690                     for (i = 0; i < height; i++) { \
1691                         for (j = 0; j < length; j++) { \
1692                             int srcpx = rfunc(&srcPtr2[j]); \
1693                             wfunc(&dstPtr2[j], (srcpx<<(16-src_depth)) | (srcpx>>(2*src_depth-16))); \
1694                         } \
1695                         dstPtr2 += dstStride[plane]/2; \
1696                         srcPtr2 += srcStride[plane]/2; \
1697                     }
1698                     if (isBE(c->dstFormat)) {
1699                         if (isBE(c->srcFormat)) {
1700                             COPY9_OR_10TO16(AV_RB16, AV_WB16);
1701                         } else {
1702                             COPY9_OR_10TO16(AV_RL16, AV_WB16);
1703                         }
1704                     } else {
1705                         if (isBE(c->srcFormat)) {
1706                             COPY9_OR_10TO16(AV_RB16, AV_WL16);
1707                         } else {
1708                             COPY9_OR_10TO16(AV_RL16, AV_WL16);
1709                         }
1710                     }
1711                 } else if (is9_OR_10BPS(c->dstFormat)) {
1712                     uint16_t *dstPtr2 = (uint16_t*)dstPtr;
1713 #define COPY9_OR_10TO9_OR_10(loop) \
1714                     for (i = 0; i < height; i++) { \
1715                         for (j = 0; j < length; j++) { \
1716                             loop; \
1717                         } \
1718                         dstPtr2 += dstStride[plane]/2; \
1719                         srcPtr2 += srcStride[plane]/2; \
1720                     }
1721 #define COPY9_OR_10TO9_OR_10_2(rfunc, wfunc) \
1722                     if (dst_depth > src_depth) { \
1723                         COPY9_OR_10TO9_OR_10(int srcpx = rfunc(&srcPtr2[j]); \
1724                             wfunc(&dstPtr2[j], (srcpx << 1) | (srcpx >> 9))); \
1725                     } else if (dst_depth < src_depth) { \
1726                         COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]) >> 1)); \
1727                     } else { \
1728                         COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]))); \
1729                     }
1730                     if (isBE(c->dstFormat)) {
1731                         if (isBE(c->srcFormat)) {
1732                             COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WB16);
1733                         } else {
1734                             COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WB16);
1735                         }
1736                     } else {
1737                         if (isBE(c->srcFormat)) {
1738                             COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WL16);
1739                         } else {
1740                             COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WL16);
1741                         }
1742                     }
1743                 } else {
1744                     // FIXME Maybe dither instead.
1745 #define COPY9_OR_10TO8(rfunc) \
1746                     for (i = 0; i < height; i++) { \
1747                         for (j = 0; j < length; j++) { \
1748                             dstPtr[j] = rfunc(&srcPtr2[j])>>(src_depth-8); \
1749                         } \
1750                         dstPtr  += dstStride[plane]; \
1751                         srcPtr2 += srcStride[plane]/2; \
1752                     }
1753                     if (isBE(c->srcFormat)) {
1754                         COPY9_OR_10TO8(AV_RB16);
1755                     } else {
1756                         COPY9_OR_10TO8(AV_RL16);
1757                     }
1758                 }
1759             } else if(is9_OR_10BPS(c->dstFormat)) {
1760                 const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1;
1761                 uint16_t *dstPtr2 = (uint16_t*)dstPtr;
1762
1763                 if (is16BPS(c->srcFormat)) {
1764                     const uint16_t *srcPtr2 = (const uint16_t*)srcPtr;
1765 #define COPY16TO9_OR_10(rfunc, wfunc) \
1766                     for (i = 0; i < height; i++) { \
1767                         for (j = 0; j < length; j++) { \
1768                             wfunc(&dstPtr2[j], rfunc(&srcPtr2[j])>>(16-dst_depth)); \
1769                         } \
1770                         dstPtr2 += dstStride[plane]/2; \
1771                         srcPtr2 += srcStride[plane]/2; \
1772                     }
1773                     if (isBE(c->dstFormat)) {
1774                         if (isBE(c->srcFormat)) {
1775                             COPY16TO9_OR_10(AV_RB16, AV_WB16);
1776                         } else {
1777                             COPY16TO9_OR_10(AV_RL16, AV_WB16);
1778                         }
1779                     } else {
1780                         if (isBE(c->srcFormat)) {
1781                             COPY16TO9_OR_10(AV_RB16, AV_WL16);
1782                         } else {
1783                             COPY16TO9_OR_10(AV_RL16, AV_WL16);
1784                         }
1785                     }
1786                 } else /* 8bit */ {
1787 #define COPY8TO9_OR_10(wfunc) \
1788                     for (i = 0; i < height; i++) { \
1789                         for (j = 0; j < length; j++) { \
1790                             const int srcpx = srcPtr[j]; \
1791                             wfunc(&dstPtr2[j], (srcpx<<(dst_depth-8)) | (srcpx >> (16-dst_depth))); \
1792                         } \
1793                         dstPtr2 += dstStride[plane]/2; \
1794                         srcPtr  += srcStride[plane]; \
1795                     }
1796                     if (isBE(c->dstFormat)) {
1797                         COPY8TO9_OR_10(AV_WB16);
1798                     } else {
1799                         COPY8TO9_OR_10(AV_WL16);
1800                     }
1801                 }
1802             } else if(is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
1803                 if (!isBE(c->srcFormat)) srcPtr++;
1804                 for (i=0; i<height; i++) {
1805                     for (j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1];
1806                     srcPtr+= srcStride[plane];
1807                     dstPtr+= dstStride[plane];
1808                 }
1809             } else if(!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
1810                 for (i=0; i<height; i++) {
1811                     for (j=0; j<length; j++) {
1812                         dstPtr[ j<<1   ] = srcPtr[j];
1813                         dstPtr[(j<<1)+1] = srcPtr[j];
1814                     }
1815                     srcPtr+= srcStride[plane];
1816                     dstPtr+= dstStride[plane];
1817                 }
1818             } else if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat)
1819                   && isBE(c->srcFormat) != isBE(c->dstFormat)) {
1820
1821                 for (i=0; i<height; i++) {
1822                     for (j=0; j<length; j++)
1823                         ((uint16_t*)dstPtr)[j] = av_bswap16(((const uint16_t*)srcPtr)[j]);
1824                     srcPtr+= srcStride[plane];
1825                     dstPtr+= dstStride[plane];
1826                 }
1827             } else if (dstStride[plane] == srcStride[plane] &&
1828                        srcStride[plane] > 0 && srcStride[plane] == length) {
1829                 memcpy(dst[plane] + dstStride[plane]*y, src[plane],
1830                        height*dstStride[plane]);
1831             } else {
1832                 if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
1833                     length*=2;
1834                 for (i=0; i<height; i++) {
1835                     memcpy(dstPtr, srcPtr, length);
1836                     srcPtr+= srcStride[plane];
1837                     dstPtr+= dstStride[plane];
1838                 }
1839             }
1840         }
1841     }
1842     return srcSliceH;
1843 }
1844
1845 int ff_hardcodedcpuflags(void)
1846 {
1847     int flags = 0;
1848 #if   COMPILE_TEMPLATE_MMX2
1849     flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2;
1850 #elif COMPILE_TEMPLATE_AMD3DNOW
1851     flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_3DNOW;
1852 #elif COMPILE_TEMPLATE_MMX
1853     flags |= SWS_CPU_CAPS_MMX;
1854 #elif COMPILE_TEMPLATE_ALTIVEC
1855     flags |= SWS_CPU_CAPS_ALTIVEC;
1856 #elif ARCH_BFIN
1857     flags |= SWS_CPU_CAPS_BFIN;
1858 #endif
1859     return flags;
1860 }
1861
1862 void ff_get_unscaled_swscale(SwsContext *c)
1863 {
1864     const enum PixelFormat srcFormat = c->srcFormat;
1865     const enum PixelFormat dstFormat = c->dstFormat;
1866     const int flags = c->flags;
1867     const int dstH = c->dstH;
1868     int needsDither;
1869
1870     needsDither= isAnyRGB(dstFormat)
1871         &&  c->dstFormatBpp < 24
1872         && (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat)));
1873
1874     /* yv12_to_nv12 */
1875     if ((srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) && (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21)) {
1876         c->swScale= planarToNv12Wrapper;
1877     }
1878     /* yuv2bgr */
1879     if ((srcFormat==PIX_FMT_YUV420P || srcFormat==PIX_FMT_YUV422P || srcFormat==PIX_FMT_YUVA420P) && isAnyRGB(dstFormat)
1880         && !(flags & SWS_ACCURATE_RND) && !(dstH&1)) {
1881         c->swScale= ff_yuv2rgb_get_func_ptr(c);
1882     }
1883
1884     if (srcFormat==PIX_FMT_YUV410P && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) {
1885         c->swScale= yvu9ToYv12Wrapper;
1886     }
1887
1888     /* bgr24toYV12 */
1889     if (srcFormat==PIX_FMT_BGR24 && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_ACCURATE_RND))
1890         c->swScale= bgr24ToYv12Wrapper;
1891
1892     /* RGB/BGR -> RGB/BGR (no dither needed forms) */
1893     if (   isAnyRGB(srcFormat)
1894         && isAnyRGB(dstFormat)
1895         && srcFormat != PIX_FMT_BGR8      && dstFormat != PIX_FMT_BGR8
1896         && srcFormat != PIX_FMT_RGB8      && dstFormat != PIX_FMT_RGB8
1897         && srcFormat != PIX_FMT_BGR4      && dstFormat != PIX_FMT_BGR4
1898         && srcFormat != PIX_FMT_RGB4      && dstFormat != PIX_FMT_RGB4
1899         && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE
1900         && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE
1901         && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK
1902         && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE
1903         && srcFormat != PIX_FMT_RGB48LE   && dstFormat != PIX_FMT_RGB48LE
1904         && srcFormat != PIX_FMT_RGB48BE   && dstFormat != PIX_FMT_RGB48BE
1905         && srcFormat != PIX_FMT_BGR48LE   && dstFormat != PIX_FMT_BGR48LE
1906         && srcFormat != PIX_FMT_BGR48BE   && dstFormat != PIX_FMT_BGR48BE
1907         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
1908         c->swScale= rgbToRgbWrapper;
1909
1910     if ((usePal(srcFormat) && (
1911         dstFormat == PIX_FMT_RGB32   ||
1912         dstFormat == PIX_FMT_RGB32_1 ||
1913         dstFormat == PIX_FMT_RGB24   ||
1914         dstFormat == PIX_FMT_BGR32   ||
1915         dstFormat == PIX_FMT_BGR32_1 ||
1916         dstFormat == PIX_FMT_BGR24)))
1917         c->swScale= palToRgbWrapper;
1918
1919     if (srcFormat == PIX_FMT_YUV422P) {
1920         if (dstFormat == PIX_FMT_YUYV422)
1921             c->swScale= yuv422pToYuy2Wrapper;
1922         else if (dstFormat == PIX_FMT_UYVY422)
1923             c->swScale= yuv422pToUyvyWrapper;
1924     }
1925
1926     /* LQ converters if -sws 0 or -sws 4*/
1927     if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
1928         /* yv12_to_yuy2 */
1929         if (srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) {
1930             if (dstFormat == PIX_FMT_YUYV422)
1931                 c->swScale= planarToYuy2Wrapper;
1932             else if (dstFormat == PIX_FMT_UYVY422)
1933                 c->swScale= planarToUyvyWrapper;
1934         }
1935     }
1936     if(srcFormat == PIX_FMT_YUYV422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P))
1937         c->swScale= yuyvToYuv420Wrapper;
1938     if(srcFormat == PIX_FMT_UYVY422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P))
1939         c->swScale= uyvyToYuv420Wrapper;
1940     if(srcFormat == PIX_FMT_YUYV422 && dstFormat == PIX_FMT_YUV422P)
1941         c->swScale= yuyvToYuv422Wrapper;
1942     if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P)
1943         c->swScale= uyvyToYuv422Wrapper;
1944
1945 #if COMPILE_ALTIVEC
1946     if ((c->flags & SWS_CPU_CAPS_ALTIVEC) &&
1947         !(c->flags & SWS_BITEXACT) &&
1948         srcFormat == PIX_FMT_YUV420P) {
1949         // unscaled YV12 -> packed YUV, we want speed
1950         if (dstFormat == PIX_FMT_YUYV422)
1951             c->swScale= yv12toyuy2_unscaled_altivec;
1952         else if (dstFormat == PIX_FMT_UYVY422)
1953             c->swScale= yv12touyvy_unscaled_altivec;
1954     }
1955 #endif
1956
1957     /* simple copy */
1958     if (  srcFormat == dstFormat
1959         || (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P)
1960         || (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P)
1961         || (isPlanarYUV(srcFormat) && isGray(dstFormat))
1962         || (isPlanarYUV(dstFormat) && isGray(srcFormat))
1963         || (isGray(dstFormat) && isGray(srcFormat))
1964         || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat)
1965             && c->chrDstHSubSample == c->chrSrcHSubSample
1966             && c->chrDstVSubSample == c->chrSrcVSubSample
1967             && dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21
1968             && srcFormat != PIX_FMT_NV12 && srcFormat != PIX_FMT_NV21))
1969     {
1970         if (isPacked(c->srcFormat))
1971             c->swScale= packedCopyWrapper;
1972         else /* Planar YUV or gray */
1973             c->swScale= planarCopyWrapper;
1974     }
1975 #if ARCH_BFIN
1976     if (flags & SWS_CPU_CAPS_BFIN)
1977         ff_bfin_get_unscaled_swscale (c);
1978 #endif
1979 }
1980
1981 static void reset_ptr(const uint8_t* src[], int format)
1982 {
1983     if(!isALPHA(format))
1984         src[3]=NULL;
1985     if(!isPlanarYUV(format)) {
1986         src[3]=src[2]=NULL;
1987
1988         if (!usePal(format))
1989             src[1]= NULL;
1990     }
1991 }
1992
1993 static int check_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt,
1994                                 const int linesizes[4])
1995 {
1996     const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
1997     int i;
1998
1999     for (i = 0; i < 4; i++) {
2000         int plane = desc->comp[i].plane;
2001         if (!data[plane] || !linesizes[plane])
2002             return 0;
2003     }
2004
2005     return 1;
2006 }
2007
2008 /**
2009  * swscale wrapper, so we don't need to export the SwsContext.
2010  * Assumes planar YUV to be in YUV order instead of YVU.
2011  */
2012 int sws_scale(SwsContext *c, const uint8_t* const src[], const int srcStride[], int srcSliceY,
2013               int srcSliceH, uint8_t* const dst[], const int dstStride[])
2014 {
2015     int i;
2016     const uint8_t* src2[4]= {src[0], src[1], src[2], src[3]};
2017     uint8_t* dst2[4]= {dst[0], dst[1], dst[2], dst[3]};
2018
2019     // do not mess up sliceDir if we have a "trailing" 0-size slice
2020     if (srcSliceH == 0)
2021         return 0;
2022
2023     if (!check_image_pointers(src, c->srcFormat, srcStride)) {
2024         av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
2025         return 0;
2026     }
2027     if (!check_image_pointers(dst, c->dstFormat, dstStride)) {
2028         av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
2029         return 0;
2030     }
2031
2032     if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
2033         av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
2034         return 0;
2035     }
2036     if (c->sliceDir == 0) {
2037         if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
2038     }
2039
2040     if (usePal(c->srcFormat)) {
2041         for (i=0; i<256; i++) {
2042             int p, r, g, b,y,u,v;
2043             if(c->srcFormat == PIX_FMT_PAL8) {
2044                 p=((const uint32_t*)(src[1]))[i];
2045                 r= (p>>16)&0xFF;
2046                 g= (p>> 8)&0xFF;
2047                 b=  p     &0xFF;
2048             } else if(c->srcFormat == PIX_FMT_RGB8) {
2049                 r= (i>>5    )*36;
2050                 g= ((i>>2)&7)*36;
2051                 b= (i&3     )*85;
2052             } else if(c->srcFormat == PIX_FMT_BGR8) {
2053                 b= (i>>6    )*85;
2054                 g= ((i>>3)&7)*36;
2055                 r= (i&7     )*36;
2056             } else if(c->srcFormat == PIX_FMT_RGB4_BYTE) {
2057                 r= (i>>3    )*255;
2058                 g= ((i>>1)&3)*85;
2059                 b= (i&1     )*255;
2060             } else if(c->srcFormat == PIX_FMT_GRAY8 || c->srcFormat == PIX_FMT_Y400A) {
2061                 r = g = b = i;
2062             } else {
2063                 assert(c->srcFormat == PIX_FMT_BGR4_BYTE);
2064                 b= (i>>3    )*255;
2065                 g= ((i>>1)&3)*85;
2066                 r= (i&1     )*255;
2067             }
2068             y= av_clip_uint8((RY*r + GY*g + BY*b + ( 33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
2069             u= av_clip_uint8((RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
2070             v= av_clip_uint8((RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
2071             c->pal_yuv[i]= y + (u<<8) + (v<<16);
2072
2073             switch(c->dstFormat) {
2074             case PIX_FMT_BGR32:
2075 #if !HAVE_BIGENDIAN
2076             case PIX_FMT_RGB24:
2077 #endif
2078                 c->pal_rgb[i]=  r + (g<<8) + (b<<16);
2079                 break;
2080             case PIX_FMT_BGR32_1:
2081 #if HAVE_BIGENDIAN
2082             case PIX_FMT_BGR24:
2083 #endif
2084                 c->pal_rgb[i]= (r + (g<<8) + (b<<16)) << 8;
2085                 break;
2086             case PIX_FMT_RGB32_1:
2087 #if HAVE_BIGENDIAN
2088             case PIX_FMT_RGB24:
2089 #endif
2090                 c->pal_rgb[i]= (b + (g<<8) + (r<<16)) << 8;
2091                 break;
2092             case PIX_FMT_RGB32:
2093 #if !HAVE_BIGENDIAN
2094             case PIX_FMT_BGR24:
2095 #endif
2096             default:
2097                 c->pal_rgb[i]=  b + (g<<8) + (r<<16);
2098             }
2099         }
2100     }
2101
2102     // copy strides, so they can safely be modified
2103     if (c->sliceDir == 1) {
2104         // slices go from top to bottom
2105         int srcStride2[4]= {srcStride[0], srcStride[1], srcStride[2], srcStride[3]};
2106         int dstStride2[4]= {dstStride[0], dstStride[1], dstStride[2], dstStride[3]};
2107
2108         reset_ptr(src2, c->srcFormat);
2109         reset_ptr((const uint8_t**)dst2, c->dstFormat);
2110
2111         /* reset slice direction at end of frame */
2112         if (srcSliceY + srcSliceH == c->srcH)
2113             c->sliceDir = 0;
2114
2115         return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, dstStride2);
2116     } else {
2117         // slices go from bottom to top => we flip the image internally
2118         int srcStride2[4]= {-srcStride[0], -srcStride[1], -srcStride[2], -srcStride[3]};
2119         int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2], -dstStride[3]};
2120
2121         src2[0] += (srcSliceH-1)*srcStride[0];
2122         if (!usePal(c->srcFormat))
2123             src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1];
2124         src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2];
2125         src2[3] += (srcSliceH-1)*srcStride[3];
2126         dst2[0] += ( c->dstH                      -1)*dstStride[0];
2127         dst2[1] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1];
2128         dst2[2] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2];
2129         dst2[3] += ( c->dstH                      -1)*dstStride[3];
2130
2131         reset_ptr(src2, c->srcFormat);
2132         reset_ptr((const uint8_t**)dst2, c->dstFormat);
2133
2134         /* reset slice direction at end of frame */
2135         if (!srcSliceY)
2136             c->sliceDir = 0;
2137
2138         return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2);
2139     }
2140 }
2141
2142 /* Convert the palette to the same packed 32-bit format as the palette */
2143 void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
2144 {
2145     long i;
2146
2147     for (i=0; i<num_pixels; i++)
2148         ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
2149 }
2150
2151 /* Palette format: ABCD -> dst format: ABC */
2152 void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
2153 {
2154     long i;
2155
2156     for (i=0; i<num_pixels; i++) {
2157         //FIXME slow?
2158         dst[0]= palette[src[i]*4+0];
2159         dst[1]= palette[src[i]*4+1];
2160         dst[2]= palette[src[i]*4+2];
2161         dst+= 3;
2162     }
2163 }