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