Merge remote-tracking branch 'qatar/master'
[ffmpeg.git] / 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/avassert.h"
64 #include "libavutil/intreadwrite.h"
65 #include "libavutil/cpu.h"
66 #include "libavutil/avutil.h"
67 #include "libavutil/mathematics.h"
68 #include "libavutil/bswap.h"
69 #include "libavutil/pixdesc.h"
70
71
72 #define RGB2YUV_SHIFT 15
73 #define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
74 #define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5))
75 #define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
76 #define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5))
77 #define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5))
78 #define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5))
79 #define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5))
80 #define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
81 #define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5))
82
83 static const double rgb2yuv_table[8][9]={
84     {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
85     {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
86     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
87     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
88     {0.59  , 0.11  , 0.30  , -0.331, 0.5, -0.169, -0.421, -0.079, 0.5}, //FCC
89     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
90     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
91     {0.701 , 0.087 , 0.212 , -0.384, 0.5, -0.116, -0.445, -0.055, 0.5}, //SMPTE 240M
92 };
93
94 /*
95 NOTES
96 Special versions: fast Y 1:1 scaling (no interpolation in y direction)
97
98 TODO
99 more intelligent misalignment avoidance for the horizontal scaler
100 write special vertical cubic upscale version
101 optimize C code (YV12 / minmax)
102 add support for packed pixel YUV input & output
103 add support for Y8 output
104 optimize BGR24 & BGR32
105 add BGR4 output support
106 write special BGR->BGR scaler
107 */
108
109 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_4)[2][8]={
110 {  1,   3,   1,   3,   1,   3,   1,   3, },
111 {  2,   0,   2,   0,   2,   0,   2,   0, },
112 };
113
114 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
115 {  6,   2,   6,   2,   6,   2,   6,   2, },
116 {  0,   4,   0,   4,   0,   4,   0,   4, },
117 };
118
119 DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
120 {  8,   4,  11,   7,   8,   4,  11,   7, },
121 {  2,  14,   1,  13,   2,  14,   1,  13, },
122 { 10,   6,   9,   5,  10,   6,   9,   5, },
123 {  0,  12,   3,  15,   0,  12,   3,  15, },
124 };
125
126 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
127 { 17,   9,  23,  15,  16,   8,  22,  14, },
128 {  5,  29,   3,  27,   4,  28,   2,  26, },
129 { 21,  13,  19,  11,  20,  12,  18,  10, },
130 {  0,  24,   6,  30,   1,  25,   7,  31, },
131 { 16,   8,  22,  14,  17,   9,  23,  15, },
132 {  4,  28,   2,  26,   5,  29,   3,  27, },
133 { 20,  12,  18,  10,  21,  13,  19,  11, },
134 {  1,  25,   7,  31,   0,  24,   6,  30, },
135 };
136
137 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
138 {  0,  55,  14,  68,   3,  58,  17,  72, },
139 { 37,  18,  50,  32,  40,  22,  54,  35, },
140 {  9,  64,   5,  59,  13,  67,   8,  63, },
141 { 46,  27,  41,  23,  49,  31,  44,  26, },
142 {  2,  57,  16,  71,   1,  56,  15,  70, },
143 { 39,  21,  52,  34,  38,  19,  51,  33, },
144 { 11,  66,   7,  62,  10,  65,   6,  60, },
145 { 48,  30,  43,  25,  47,  29,  42,  24, },
146 };
147
148 #if 1
149 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
150 {117,  62, 158, 103, 113,  58, 155, 100, },
151 { 34, 199,  21, 186,  31, 196,  17, 182, },
152 {144,  89, 131,  76, 141,  86, 127,  72, },
153 {  0, 165,  41, 206,  10, 175,  52, 217, },
154 {110,  55, 151,  96, 120,  65, 162, 107, },
155 { 28, 193,  14, 179,  38, 203,  24, 189, },
156 {138,  83, 124,  69, 148,  93, 134,  79, },
157 {  7, 172,  48, 213,   3, 168,  45, 210, },
158 };
159 #elif 1
160 // tries to correct a gamma of 1.5
161 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
162 {  0, 143,  18, 200,   2, 156,  25, 215, },
163 { 78,  28, 125,  64,  89,  36, 138,  74, },
164 { 10, 180,   3, 161,  16, 195,   8, 175, },
165 {109,  51,  93,  38, 121,  60, 105,  47, },
166 {  1, 152,  23, 210,   0, 147,  20, 205, },
167 { 85,  33, 134,  71,  81,  30, 130,  67, },
168 { 14, 190,   6, 171,  12, 185,   5, 166, },
169 {117,  57, 101,  44, 113,  54,  97,  41, },
170 };
171 #elif 1
172 // tries to correct a gamma of 2.0
173 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
174 {  0, 124,   8, 193,   0, 140,  12, 213, },
175 { 55,  14, 104,  42,  66,  19, 119,  52, },
176 {  3, 168,   1, 145,   6, 187,   3, 162, },
177 { 86,  31,  70,  21,  99,  39,  82,  28, },
178 {  0, 134,  11, 206,   0, 129,   9, 200, },
179 { 62,  17, 114,  48,  58,  16, 109,  45, },
180 {  5, 181,   2, 157,   4, 175,   1, 151, },
181 { 95,  36,  78,  26,  90,  34,  74,  24, },
182 };
183 #else
184 // tries to correct a gamma of 2.5
185 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
186 {  0, 107,   3, 187,   0, 125,   6, 212, },
187 { 39,   7,  86,  28,  49,  11, 102,  36, },
188 {  1, 158,   0, 131,   3, 180,   1, 151, },
189 { 68,  19,  52,  12,  81,  25,  64,  17, },
190 {  0, 119,   5, 203,   0, 113,   4, 195, },
191 { 45,   9,  96,  33,  42,   8,  91,  30, },
192 {  2, 172,   1, 144,   2, 165,   0, 137, },
193 { 77,  23,  60,  15,  72,  21,  56,  14, },
194 };
195 #endif
196
197 DECLARE_ALIGNED(8, const uint8_t, dithers)[8][8][8]={
198 {
199   {   0,  1,  0,  1,  0,  1,  0,  1,},
200   {   1,  0,  1,  0,  1,  0,  1,  0,},
201   {   0,  1,  0,  1,  0,  1,  0,  1,},
202   {   1,  0,  1,  0,  1,  0,  1,  0,},
203   {   0,  1,  0,  1,  0,  1,  0,  1,},
204   {   1,  0,  1,  0,  1,  0,  1,  0,},
205   {   0,  1,  0,  1,  0,  1,  0,  1,},
206   {   1,  0,  1,  0,  1,  0,  1,  0,},
207 },{
208   {   1,  2,  1,  2,  1,  2,  1,  2,},
209   {   3,  0,  3,  0,  3,  0,  3,  0,},
210   {   1,  2,  1,  2,  1,  2,  1,  2,},
211   {   3,  0,  3,  0,  3,  0,  3,  0,},
212   {   1,  2,  1,  2,  1,  2,  1,  2,},
213   {   3,  0,  3,  0,  3,  0,  3,  0,},
214   {   1,  2,  1,  2,  1,  2,  1,  2,},
215   {   3,  0,  3,  0,  3,  0,  3,  0,},
216 },{
217   {   2,  4,  3,  5,  2,  4,  3,  5,},
218   {   6,  0,  7,  1,  6,  0,  7,  1,},
219   {   3,  5,  2,  4,  3,  5,  2,  4,},
220   {   7,  1,  6,  0,  7,  1,  6,  0,},
221   {   2,  4,  3,  5,  2,  4,  3,  5,},
222   {   6,  0,  7,  1,  6,  0,  7,  1,},
223   {   3,  5,  2,  4,  3,  5,  2,  4,},
224   {   7,  1,  6,  0,  7,  1,  6,  0,},
225 },{
226   {   4,  8,  7, 11,  4,  8,  7, 11,},
227   {  12,  0, 15,  3, 12,  0, 15,  3,},
228   {   6, 10,  5,  9,  6, 10,  5,  9,},
229   {  14,  2, 13,  1, 14,  2, 13,  1,},
230   {   4,  8,  7, 11,  4,  8,  7, 11,},
231   {  12,  0, 15,  3, 12,  0, 15,  3,},
232   {   6, 10,  5,  9,  6, 10,  5,  9,},
233   {  14,  2, 13,  1, 14,  2, 13,  1,},
234 },{
235   {   9, 17, 15, 23,  8, 16, 14, 22,},
236   {  25,  1, 31,  7, 24,  0, 30,  6,},
237   {  13, 21, 11, 19, 12, 20, 10, 18,},
238   {  29,  5, 27,  3, 28,  4, 26,  2,},
239   {   8, 16, 14, 22,  9, 17, 15, 23,},
240   {  24,  0, 30,  6, 25,  1, 31,  7,},
241   {  12, 20, 10, 18, 13, 21, 11, 19,},
242   {  28,  4, 26,  2, 29,  5, 27,  3,},
243 },{
244   {  18, 34, 30, 46, 17, 33, 29, 45,},
245   {  50,  2, 62, 14, 49,  1, 61, 13,},
246   {  26, 42, 22, 38, 25, 41, 21, 37,},
247   {  58, 10, 54,  6, 57,  9, 53,  5,},
248   {  16, 32, 28, 44, 19, 35, 31, 47,},
249   {  48,  0, 60, 12, 51,  3, 63, 15,},
250   {  24, 40, 20, 36, 27, 43, 23, 39,},
251   {  56,  8, 52,  4, 59, 11, 55,  7,},
252 },{
253   {  18, 34, 30, 46, 17, 33, 29, 45,},
254   {  50,  2, 62, 14, 49,  1, 61, 13,},
255   {  26, 42, 22, 38, 25, 41, 21, 37,},
256   {  58, 10, 54,  6, 57,  9, 53,  5,},
257   {  16, 32, 28, 44, 19, 35, 31, 47,},
258   {  48,  0, 60, 12, 51,  3, 63, 15,},
259   {  24, 40, 20, 36, 27, 43, 23, 39,},
260   {  56,  8, 52,  4, 59, 11, 55,  7,},
261 },{
262   {  36, 68, 60, 92, 34, 66, 58, 90,},
263   { 100,  4,124, 28, 98,  2,122, 26,},
264   {  52, 84, 44, 76, 50, 82, 42, 74,},
265   { 116, 20,108, 12,114, 18,106, 10,},
266   {  32, 64, 56, 88, 38, 70, 62, 94,},
267   {  96,  0,120, 24,102,  6,126, 30,},
268   {  48, 80, 40, 72, 54, 86, 46, 78,},
269   { 112, 16,104,  8,118, 22,110, 14,},
270 }};
271
272 static const uint8_t flat64[8]={64,64,64,64,64,64,64,64};
273
274 const uint16_t dither_scale[15][16]={
275 {    2,    3,    3,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,},
276 {    2,    3,    7,    7,   13,   13,   25,   25,   25,   25,   25,   25,   25,   25,   25,   25,},
277 {    3,    3,    4,   15,   15,   29,   57,   57,   57,  113,  113,  113,  113,  113,  113,  113,},
278 {    3,    4,    4,    5,   31,   31,   61,  121,  241,  241,  241,  241,  481,  481,  481,  481,},
279 {    3,    4,    5,    5,    6,   63,   63,  125,  249,  497,  993,  993,  993,  993,  993, 1985,},
280 {    3,    5,    6,    6,    6,    7,  127,  127,  253,  505, 1009, 2017, 4033, 4033, 4033, 4033,},
281 {    3,    5,    6,    7,    7,    7,    8,  255,  255,  509, 1017, 2033, 4065, 8129,16257,16257,},
282 {    3,    5,    6,    8,    8,    8,    8,    9,  511,  511, 1021, 2041, 4081, 8161,16321,32641,},
283 {    3,    5,    7,    8,    9,    9,    9,    9,   10, 1023, 1023, 2045, 4089, 8177,16353,32705,},
284 {    3,    5,    7,    8,   10,   10,   10,   10,   10,   11, 2047, 2047, 4093, 8185,16369,32737,},
285 {    3,    5,    7,    8,   10,   11,   11,   11,   11,   11,   12, 4095, 4095, 8189,16377,32753,},
286 {    3,    5,    7,    9,   10,   12,   12,   12,   12,   12,   12,   13, 8191, 8191,16381,32761,},
287 {    3,    5,    7,    9,   10,   12,   13,   13,   13,   13,   13,   13,   14,16383,16383,32765,},
288 {    3,    5,    7,    9,   10,   12,   14,   14,   14,   14,   14,   14,   14,   15,32767,32767,},
289 {    3,    5,    7,    9,   11,   12,   14,   15,   15,   15,   15,   15,   15,   15,   16,65535,},
290 };
291
292 static av_always_inline void
293 yuv2yuvX16_c_template(const int16_t *lumFilter, const int16_t **lumSrc,
294                       int lumFilterSize, const int16_t *chrFilter,
295                       const int16_t **chrUSrc, const int16_t **chrVSrc,
296                       int chrFilterSize, const int16_t **alpSrc,
297                       uint16_t *dest, uint16_t *uDest, uint16_t *vDest,
298                       uint16_t *aDest, int dstW, int chrDstW,
299                       int big_endian, int output_bits)
300 {
301     //FIXME Optimize (just quickly written not optimized..)
302     int i;
303     int shift = 11 + 16 - output_bits;
304
305 #define output_pixel(pos, val) \
306     if (big_endian) { \
307         if (output_bits == 16) { \
308             AV_WB16(pos, av_clip_uint16(val >> shift)); \
309         } else { \
310             AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
311         } \
312     } else { \
313         if (output_bits == 16) { \
314             AV_WL16(pos, av_clip_uint16(val >> shift)); \
315         } else { \
316             AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
317         } \
318     }
319     for (i = 0; i < dstW; i++) {
320         int val = 1 << (26-output_bits);
321         int j;
322
323         for (j = 0; j < lumFilterSize; j++)
324             val += lumSrc[j][i] * lumFilter[j];
325
326         output_pixel(&dest[i], val);
327     }
328
329     if (uDest) {
330         for (i = 0; i < chrDstW; i++) {
331             int u = 1 << (26-output_bits);
332             int v = 1 << (26-output_bits);
333             int j;
334
335             for (j = 0; j < chrFilterSize; j++) {
336                 u += chrUSrc[j][i] * chrFilter[j];
337                 v += chrVSrc[j][i] * chrFilter[j];
338             }
339
340             output_pixel(&uDest[i], u);
341             output_pixel(&vDest[i], v);
342         }
343     }
344
345     if (CONFIG_SWSCALE_ALPHA && aDest) {
346         for (i = 0; i < dstW; i++) {
347             int val = 1 << (26-output_bits);
348             int j;
349
350             for (j = 0; j < lumFilterSize; j++)
351                 val += alpSrc[j][i] * lumFilter[j];
352
353             output_pixel(&aDest[i], val);
354         }
355     }
356 #undef output_pixel
357 }
358
359 #define yuv2NBPS(bits, BE_LE, is_be) \
360 static void yuv2yuvX ## bits ## BE_LE ## _c(SwsContext *c, const int16_t *lumFilter, \
361                               const int16_t **lumSrc, int lumFilterSize, \
362                               const int16_t *chrFilter, const int16_t **chrUSrc, \
363                               const int16_t **chrVSrc, \
364                               int chrFilterSize, const int16_t **alpSrc, \
365                               uint8_t *_dest, uint8_t *_uDest, uint8_t *_vDest, \
366                               uint8_t *_aDest, int dstW, int chrDstW) \
367 { \
368     uint16_t *dest  = (uint16_t *) _dest,  *uDest = (uint16_t *) _uDest, \
369              *vDest = (uint16_t *) _vDest, *aDest = (uint16_t *) _aDest; \
370     yuv2yuvX16_c_template(lumFilter, lumSrc, lumFilterSize, \
371                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
372                           alpSrc, \
373                           dest, uDest, vDest, aDest, \
374                           dstW, chrDstW, is_be, bits); \
375 }
376 yuv2NBPS( 9, BE, 1);
377 yuv2NBPS( 9, LE, 0);
378 yuv2NBPS(10, BE, 1);
379 yuv2NBPS(10, LE, 0);
380 yuv2NBPS(16, BE, 1);
381 yuv2NBPS(16, LE, 0);
382
383 static void yuv2yuvX_c(SwsContext *c, const int16_t *lumFilter,
384                        const int16_t **lumSrc, int lumFilterSize,
385                        const int16_t *chrFilter, const int16_t **chrUSrc,
386                        const int16_t **chrVSrc,
387                        int chrFilterSize, const int16_t **alpSrc,
388                        uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
389                        uint8_t *aDest, int dstW, int chrDstW,
390                        const uint8_t *lumDither, const uint8_t *chrDither)
391 {
392     //FIXME Optimize (just quickly written not optimized..)
393     int i;
394     for (i=0; i<dstW; i++) {
395         int val = lumDither[i&7] << 12;
396         int j;
397         for (j=0; j<lumFilterSize; j++)
398             val += lumSrc[j][i] * lumFilter[j];
399
400         dest[i]= av_clip_uint8(val>>19);
401     }
402
403     if (uDest)
404         for (i=0; i<chrDstW; i++) {
405             int u = chrDither[i&7] << 12;
406             int v = chrDither[(i+3)&7] << 12;
407             int j;
408             for (j=0; j<chrFilterSize; j++) {
409                 u += chrUSrc[j][i] * chrFilter[j];
410                 v += chrVSrc[j][i] * chrFilter[j];
411             }
412
413             uDest[i]= av_clip_uint8(u>>19);
414             vDest[i]= av_clip_uint8(v>>19);
415         }
416
417     if (CONFIG_SWSCALE_ALPHA && aDest)
418         for (i=0; i<dstW; i++) {
419             int val = lumDither[i&7] << 12;
420             int j;
421             for (j=0; j<lumFilterSize; j++)
422                 val += alpSrc[j][i] * lumFilter[j];
423
424             aDest[i]= av_clip_uint8(val>>19);
425         }
426 }
427
428 static void yuv2yuv1_c(SwsContext *c, const int16_t *lumSrc,
429                               const int16_t *chrUSrc, const int16_t *chrVSrc,
430                               const int16_t *alpSrc,
431                               uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
432                               uint8_t *aDest, int dstW, int chrDstW, const uint8_t *lumDither, const uint8_t *chrDither)
433 {
434     int i;
435
436     for (i=0; i<dstW; i++) {
437         int val= (lumSrc[i]+lumDither[i&7])>>7;
438         dest[i]= av_clip_uint8(val);
439     }
440
441     if (uDest)
442         for (i=0; i<chrDstW; i++) {
443             int u=(chrUSrc[i]+chrDither[i&7])>>7;
444             int v=(chrVSrc[i]+chrDither[(i+3)&7])>>7;
445             uDest[i]= av_clip_uint8(u);
446             vDest[i]= av_clip_uint8(v);
447         }
448
449     if (CONFIG_SWSCALE_ALPHA && aDest)
450         for (i=0; i<dstW; i++) {
451             int val= (alpSrc[i]+lumDither[i&7])>>7;
452             aDest[i]= av_clip_uint8(val);
453         }
454 }
455
456 static void yuv2nv12X_c(SwsContext *c, const int16_t *lumFilter,
457                         const int16_t **lumSrc, int lumFilterSize,
458                         const int16_t *chrFilter, const int16_t **chrUSrc,
459                         const int16_t **chrVSrc, int chrFilterSize,
460                         const int16_t **alpSrc, uint8_t *dest, uint8_t *uDest,
461                         uint8_t *vDest, uint8_t *aDest,
462                         int dstW, int chrDstW,
463                         const uint8_t *lumDither, const uint8_t *chrDither)
464 {
465     enum PixelFormat dstFormat = c->dstFormat;
466
467     //FIXME Optimize (just quickly written not optimized..)
468     int i;
469     for (i=0; i<dstW; i++) {
470         int val = lumDither[i&7]<<12;
471         int j;
472         for (j=0; j<lumFilterSize; j++)
473             val += lumSrc[j][i] * lumFilter[j];
474
475         dest[i]= av_clip_uint8(val>>19);
476     }
477
478     if (!uDest)
479         return;
480
481     if (dstFormat == PIX_FMT_NV12)
482         for (i=0; i<chrDstW; i++) {
483             int u = chrDither[i&7]<<12;
484             int v = chrDither[(i+3)&7]<<12;
485             int j;
486             for (j=0; j<chrFilterSize; j++) {
487                 u += chrUSrc[j][i] * chrFilter[j];
488                 v += chrVSrc[j][i] * chrFilter[j];
489             }
490
491             uDest[2*i]= av_clip_uint8(u>>19);
492             uDest[2*i+1]= av_clip_uint8(v>>19);
493         }
494     else
495         for (i=0; i<chrDstW; i++) {
496             int u = chrDither[i&7]<<12;
497             int v = chrDither[(i+3)&7]<<12;
498             int j;
499             for (j=0; j<chrFilterSize; j++) {
500                 u += chrUSrc[j][i] * chrFilter[j];
501                 v += chrVSrc[j][i] * chrFilter[j];
502             }
503
504             uDest[2*i]= av_clip_uint8(v>>19);
505             uDest[2*i+1]= av_clip_uint8(u>>19);
506         }
507 }
508
509 static av_always_inline void
510 yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter,
511                         const int16_t **lumSrc, int lumFilterSize,
512                         const int16_t *chrFilter, const int16_t **chrUSrc,
513                         const int16_t **chrVSrc, int chrFilterSize,
514                         const int16_t **alpSrc, uint8_t *dest, int dstW,
515                         int y, enum PixelFormat target)
516 {
517     int i;
518
519 #define output_pixel(pos, val) \
520         if (target == PIX_FMT_GRAY16BE) { \
521             AV_WB16(pos, val); \
522         } else { \
523             AV_WL16(pos, val); \
524         }
525     for (i = 0; i < (dstW >> 1); i++) {
526         int j;
527         int Y1 = 1 << 18;
528         int Y2 = 1 << 18;
529         const int i2 = 2 * i;
530
531         for (j = 0; j < lumFilterSize; j++) {
532             Y1 += lumSrc[j][i2]   * lumFilter[j];
533             Y2 += lumSrc[j][i2+1] * lumFilter[j];
534         }
535         Y1 >>= 11;
536         Y2 >>= 11;
537         if ((Y1 | Y2) & 0x10000) {
538             Y1 = av_clip_uint16(Y1);
539             Y2 = av_clip_uint16(Y2);
540         }
541         output_pixel(&dest[2 * i2 + 0], Y1);
542         output_pixel(&dest[2 * i2 + 2], Y2);
543     }
544 }
545
546 static av_always_inline void
547 yuv2gray16_2_c_template(SwsContext *c, const uint16_t *buf0,
548                         const uint16_t *buf1, const uint16_t *ubuf0,
549                         const uint16_t *ubuf1, const uint16_t *vbuf0,
550                         const uint16_t *vbuf1, const uint16_t *abuf0,
551                         const uint16_t *abuf1, uint8_t *dest, int dstW,
552                         int yalpha, int uvalpha, int y,
553                         enum PixelFormat target)
554 {
555     int  yalpha1 = 4095 - yalpha; \
556     int i;
557
558     for (i = 0; i < (dstW >> 1); i++) {
559         const int i2 = 2 * i;
560         int Y1 = (buf0[i2  ] * yalpha1 + buf1[i2  ] * yalpha) >> 11;
561         int Y2 = (buf0[i2+1] * yalpha1 + buf1[i2+1] * yalpha) >> 11;
562
563         output_pixel(&dest[2 * i2 + 0], Y1);
564         output_pixel(&dest[2 * i2 + 2], Y2);
565     }
566 }
567
568 static av_always_inline void
569 yuv2gray16_1_c_template(SwsContext *c, const uint16_t *buf0,
570                         const uint16_t *ubuf0, const uint16_t *ubuf1,
571                         const uint16_t *vbuf0, const uint16_t *vbuf1,
572                         const uint16_t *abuf0, uint8_t *dest, int dstW,
573                         int uvalpha, enum PixelFormat dstFormat,
574                         int flags, int y, enum PixelFormat target)
575 {
576     int i;
577
578     for (i = 0; i < (dstW >> 1); i++) {
579         const int i2 = 2 * i;
580         int Y1 = buf0[i2  ] << 1;
581         int Y2 = buf0[i2+1] << 1;
582
583         output_pixel(&dest[2 * i2 + 0], Y1);
584         output_pixel(&dest[2 * i2 + 2], Y2);
585     }
586 #undef output_pixel
587 }
588
589 #define YUV2PACKEDWRAPPER(name, ext, fmt) \
590 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
591                         const int16_t **lumSrc, int lumFilterSize, \
592                         const int16_t *chrFilter, const int16_t **chrUSrc, \
593                         const int16_t **chrVSrc, int chrFilterSize, \
594                         const int16_t **alpSrc, uint8_t *dest, int dstW, \
595                         int y) \
596 { \
597     name ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
598                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
599                           alpSrc, dest, dstW, y, fmt); \
600 } \
601  \
602 static void name ## ext ## _2_c(SwsContext *c, const uint16_t *buf0, \
603                         const uint16_t *buf1, const uint16_t *ubuf0, \
604                         const uint16_t *ubuf1, const uint16_t *vbuf0, \
605                         const uint16_t *vbuf1, const uint16_t *abuf0, \
606                         const uint16_t *abuf1, uint8_t *dest, int dstW, \
607                         int yalpha, int uvalpha, int y) \
608 { \
609     name ## _2_c_template(c, buf0, buf1, ubuf0, ubuf1, \
610                           vbuf0, vbuf1, abuf0, abuf1, \
611                           dest, dstW, yalpha, uvalpha, y, fmt); \
612 } \
613  \
614 static void name ## ext ## _1_c(SwsContext *c, const uint16_t *buf0, \
615                         const uint16_t *ubuf0, const uint16_t *ubuf1, \
616                         const uint16_t *vbuf0, const uint16_t *vbuf1, \
617                         const uint16_t *abuf0, uint8_t *dest, int dstW, \
618                         int uvalpha, enum PixelFormat dstFormat, \
619                         int flags, int y) \
620 { \
621     name ## _1_c_template(c, buf0, ubuf0, ubuf1, vbuf0, \
622                           vbuf1, abuf0, dest, dstW, uvalpha, \
623                           dstFormat, flags, y, fmt); \
624 }
625
626 YUV2PACKEDWRAPPER(yuv2gray16, LE, PIX_FMT_GRAY16LE);
627 YUV2PACKEDWRAPPER(yuv2gray16, BE, PIX_FMT_GRAY16BE);
628
629 static av_always_inline void
630 yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
631                       const int16_t **lumSrc, int lumFilterSize,
632                       const int16_t *chrFilter, const int16_t **chrUSrc,
633                       const int16_t **chrVSrc, int chrFilterSize,
634                       const int16_t **alpSrc, uint8_t *dest, int dstW,
635                       int y, enum PixelFormat target)
636 {
637     const uint8_t * const d128=dither_8x8_220[y&7];
638     uint8_t *g = c->table_gU[128] + c->table_gV[128];
639     int i;
640     int acc = 0;
641
642 #define output_pixel(pos, acc) \
643     if (target == PIX_FMT_MONOBLACK) { \
644         pos = acc; \
645     } else { \
646         pos = ~acc; \
647     }
648     for (i = 0; i < dstW - 1; i += 2) {
649         int j;
650         int Y1 = 1 << 18;
651         int Y2 = 1 << 18;
652
653         for (j = 0; j < lumFilterSize; j++) {
654             Y1 += lumSrc[j][i]   * lumFilter[j];
655             Y2 += lumSrc[j][i+1] * lumFilter[j];
656         }
657         Y1 >>= 19;
658         Y2 >>= 19;
659         if ((Y1 | Y2) & 0x100) {
660             Y1 = av_clip_uint8(Y1);
661             Y2 = av_clip_uint8(Y2);
662         }
663         acc += acc + g[Y1 + d128[(i + 0) & 7]];
664         acc += acc + g[Y2 + d128[(i + 1) & 7]];
665         if ((i & 7) == 6) {
666             output_pixel(*dest++, acc);
667         }
668     }
669 }
670
671 static av_always_inline void
672 yuv2mono_2_c_template(SwsContext *c, const uint16_t *buf0,
673                       const uint16_t *buf1, const uint16_t *ubuf0,
674                       const uint16_t *ubuf1, const uint16_t *vbuf0,
675                       const uint16_t *vbuf1, const uint16_t *abuf0,
676                       const uint16_t *abuf1, uint8_t *dest, int dstW,
677                       int yalpha, int uvalpha, int y,
678                       enum PixelFormat target)
679 {
680     const uint8_t * const d128 = dither_8x8_220[y & 7];
681     uint8_t *g = c->table_gU[128] + c->table_gV[128];
682     int  yalpha1 = 4095 - yalpha;
683     int i;
684
685     for (i = 0; i < dstW - 7; i += 8) {
686         int acc =    g[((buf0[i    ] * yalpha1 + buf1[i    ] * yalpha) >> 19) + d128[0]];
687         acc += acc + g[((buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19) + d128[1]];
688         acc += acc + g[((buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19) + d128[2]];
689         acc += acc + g[((buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19) + d128[3]];
690         acc += acc + g[((buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19) + d128[4]];
691         acc += acc + g[((buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19) + d128[5]];
692         acc += acc + g[((buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19) + d128[6]];
693         acc += acc + g[((buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19) + d128[7]];
694         output_pixel(*dest++, acc);
695     }
696 }
697
698 static av_always_inline void
699 yuv2mono_1_c_template(SwsContext *c, const uint16_t *buf0,
700                       const uint16_t *ubuf0, const uint16_t *ubuf1,
701                       const uint16_t *vbuf0, const uint16_t *vbuf1,
702                       const uint16_t *abuf0, uint8_t *dest, int dstW,
703                       int uvalpha, enum PixelFormat dstFormat,
704                       int flags, int y, enum PixelFormat target)
705 {
706     const uint8_t * const d128 = dither_8x8_220[y & 7];
707     uint8_t *g = c->table_gU[128] + c->table_gV[128];
708     int i;
709
710     for (i = 0; i < dstW - 7; i += 8) {
711         int acc =    g[(buf0[i    ] >> 7) + d128[0]];
712         acc += acc + g[(buf0[i + 1] >> 7) + d128[1]];
713         acc += acc + g[(buf0[i + 2] >> 7) + d128[2]];
714         acc += acc + g[(buf0[i + 3] >> 7) + d128[3]];
715         acc += acc + g[(buf0[i + 4] >> 7) + d128[4]];
716         acc += acc + g[(buf0[i + 5] >> 7) + d128[5]];
717         acc += acc + g[(buf0[i + 6] >> 7) + d128[6]];
718         acc += acc + g[(buf0[i + 7] >> 7) + d128[7]];
719         output_pixel(*dest++, acc);
720     }
721 #undef output_pixel
722 }
723
724 YUV2PACKEDWRAPPER(yuv2mono, white, PIX_FMT_MONOWHITE);
725 YUV2PACKEDWRAPPER(yuv2mono, black, PIX_FMT_MONOBLACK);
726
727 static av_always_inline void
728 yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
729                      const int16_t **lumSrc, int lumFilterSize,
730                      const int16_t *chrFilter, const int16_t **chrUSrc,
731                      const int16_t **chrVSrc, int chrFilterSize,
732                      const int16_t **alpSrc, uint8_t *dest, int dstW,
733                      int y, enum PixelFormat target)
734 {
735     int i;
736
737 #define output_pixels(pos, Y1, U, Y2, V) \
738     if (target == PIX_FMT_YUYV422) { \
739         dest[pos + 0] = Y1; \
740         dest[pos + 1] = U;  \
741         dest[pos + 2] = Y2; \
742         dest[pos + 3] = V;  \
743     } else { \
744         dest[pos + 0] = U;  \
745         dest[pos + 1] = Y1; \
746         dest[pos + 2] = V;  \
747         dest[pos + 3] = Y2; \
748     }
749
750     for (i = 0; i < (dstW >> 1); i++) {
751         int j;
752         int Y1 = 1 << 18;
753         int Y2 = 1 << 18;
754         int U  = 1 << 18;
755         int V  = 1 << 18;
756
757         for (j = 0; j < lumFilterSize; j++) {
758             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
759             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
760         }
761         for (j = 0; j < chrFilterSize; j++) {
762             U += chrUSrc[j][i] * chrFilter[j];
763             V += chrVSrc[j][i] * chrFilter[j];
764         }
765         Y1 >>= 19;
766         Y2 >>= 19;
767         U  >>= 19;
768         V  >>= 19;
769         if ((Y1 | Y2 | U | V) & 0x100) {
770             Y1 = av_clip_uint8(Y1);
771             Y2 = av_clip_uint8(Y2);
772             U  = av_clip_uint8(U);
773             V  = av_clip_uint8(V);
774         }
775         output_pixels(4*i, Y1, U, Y2, V);
776     }
777 }
778
779 static av_always_inline void
780 yuv2422_2_c_template(SwsContext *c, const uint16_t *buf0,
781                      const uint16_t *buf1, const uint16_t *ubuf0,
782                      const uint16_t *ubuf1, const uint16_t *vbuf0,
783                      const uint16_t *vbuf1, const uint16_t *abuf0,
784                      const uint16_t *abuf1, uint8_t *dest, int dstW,
785                      int yalpha, int uvalpha, int y,
786                      enum PixelFormat target)
787 {
788     int  yalpha1 = 4095 - yalpha;
789     int uvalpha1 = 4095 - uvalpha;
790     int i;
791
792     for (i = 0; i < (dstW >> 1); i++) {
793         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
794         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
795         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
796         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
797
798         output_pixels(i * 4, Y1, U, Y2, V);
799     }
800 }
801
802 static av_always_inline void
803 yuv2422_1_c_template(SwsContext *c, const uint16_t *buf0,
804                      const uint16_t *ubuf0, const uint16_t *ubuf1,
805                      const uint16_t *vbuf0, const uint16_t *vbuf1,
806                      const uint16_t *abuf0, uint8_t *dest, int dstW,
807                      int uvalpha, enum PixelFormat dstFormat,
808                      int flags, int y, enum PixelFormat target)
809 {
810     int i;
811
812     if (uvalpha < 2048) {
813         for (i = 0; i < (dstW >> 1); i++) {
814             int Y1 = buf0[i * 2]     >> 7;
815             int Y2 = buf0[i * 2 + 1] >> 7;
816             int U  = ubuf1[i]        >> 7;
817             int V  = vbuf1[i]        >> 7;
818
819             output_pixels(i * 4, Y1, U, Y2, V);
820         }
821     } else {
822         for (i = 0; i < (dstW >> 1); i++) {
823             int Y1 =  buf0[i * 2]          >> 7;
824             int Y2 =  buf0[i * 2 + 1]      >> 7;
825             int U  = (ubuf0[i] + ubuf1[i]) >> 8;
826             int V  = (vbuf0[i] + vbuf1[i]) >> 8;
827
828             output_pixels(i * 4, Y1, U, Y2, V);
829         }
830     }
831 #undef output_pixels
832 }
833
834 YUV2PACKEDWRAPPER(yuv2422, yuyv, PIX_FMT_YUYV422);
835 YUV2PACKEDWRAPPER(yuv2422, uyvy, PIX_FMT_UYVY422);
836
837 #define YSCALE_YUV_2_RGBX_C(type,alpha) \
838     for (i=0; i<(dstW>>1); i++) {\
839         int j;\
840         int Y1 = 1<<18;\
841         int Y2 = 1<<18;\
842         int U  = 1<<18;\
843         int V  = 1<<18;\
844         int av_unused A1, A2;\
845         type av_unused *r, *b, *g;\
846         const int i2= 2*i;\
847         \
848         for (j=0; j<lumFilterSize; j++) {\
849             Y1 += lumSrc[j][i2] * lumFilter[j];\
850             Y2 += lumSrc[j][i2+1] * lumFilter[j];\
851         }\
852         for (j=0; j<chrFilterSize; j++) {\
853             U += chrUSrc[j][i] * chrFilter[j];\
854             V += chrVSrc[j][i] * chrFilter[j];\
855         }\
856         Y1>>=19;\
857         Y2>>=19;\
858         U >>=19;\
859         V >>=19;\
860         if ((Y1|Y2|U|V)&0x100) {\
861             Y1 = av_clip_uint8(Y1); \
862             Y2 = av_clip_uint8(Y2); \
863             U  = av_clip_uint8(U); \
864             V  = av_clip_uint8(V); \
865         }\
866         if (alpha) {\
867             A1 = 1<<18;\
868             A2 = 1<<18;\
869             for (j=0; j<lumFilterSize; j++) {\
870                 A1 += alpSrc[j][i2  ] * lumFilter[j];\
871                 A2 += alpSrc[j][i2+1] * lumFilter[j];\
872             }\
873             A1>>=19;\
874             A2>>=19;\
875             if ((A1|A2)&0x100) {\
876                 A1 = av_clip_uint8(A1); \
877                 A2 = av_clip_uint8(A2); \
878             }\
879         }\
880         /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/\
881     r = (type *)c->table_rV[V];   \
882     g = (type *)(c->table_gU[U] + c->table_gV[V]); \
883     b = (type *)c->table_bU[U];
884
885 #define YSCALE_YUV_2_RGBX_FULL_C(rnd,alpha) \
886     for (i=0; i<dstW; i++) {\
887         int j;\
888         int Y = 1<<9;\
889         int U = (1<<9)-(128<<19);\
890         int V = (1<<9)-(128<<19);\
891         int av_unused A;\
892         int R,G,B;\
893         \
894         for (j=0; j<lumFilterSize; j++) {\
895             Y += lumSrc[j][i     ] * lumFilter[j];\
896         }\
897         for (j=0; j<chrFilterSize; j++) {\
898             U += chrUSrc[j][i] * chrFilter[j];\
899             V += chrVSrc[j][i] * chrFilter[j];\
900         }\
901         Y >>=10;\
902         U >>=10;\
903         V >>=10;\
904         if (alpha) {\
905             A = rnd>>3;\
906             for (j=0; j<lumFilterSize; j++)\
907                 A += alpSrc[j][i     ] * lumFilter[j];\
908             A >>=19;\
909             if (A&0x100)\
910                 A = av_clip_uint8(A);\
911         }\
912         Y-= c->yuv2rgb_y_offset;\
913         Y*= c->yuv2rgb_y_coeff;\
914         Y+= rnd;\
915         R= Y + V*c->yuv2rgb_v2r_coeff;\
916         G= Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;\
917         B= Y +                          U*c->yuv2rgb_u2b_coeff;\
918         if ((R|G|B)&(0xC0000000)) {\
919             R = av_clip_uintp2(R, 30); \
920             G = av_clip_uintp2(G, 30); \
921             B = av_clip_uintp2(B, 30); \
922         }
923
924 #define YSCALE_YUV_2_RGB2_C(type,alpha) \
925     for (i=0; i<(dstW>>1); i++) { \
926         const int i2= 2*i;       \
927         int Y1= (buf0[i2  ]*yalpha1+buf1[i2  ]*yalpha)>>19;           \
928         int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19;           \
929         int U= (ubuf0[i]*uvalpha1+ubuf1[i]*uvalpha)>>19;              \
930         int V= (vbuf0[i]*uvalpha1+vbuf1[i]*uvalpha)>>19;              \
931         type av_unused *r, *b, *g;                                    \
932         int av_unused A1, A2;                                         \
933         if (alpha) {\
934             A1= (abuf0[i2  ]*yalpha1+abuf1[i2  ]*yalpha)>>19;         \
935             A2= (abuf0[i2+1]*yalpha1+abuf1[i2+1]*yalpha)>>19;         \
936         }\
937     r = (type *)c->table_rV[V];\
938     g = (type *)(c->table_gU[U] + c->table_gV[V]);\
939     b = (type *)c->table_bU[U];
940
941 #define YSCALE_YUV_2_RGB1_C(type,alpha) \
942     for (i=0; i<(dstW>>1); i++) {\
943         const int i2= 2*i;\
944         int Y1= buf0[i2  ]>>7;\
945         int Y2= buf0[i2+1]>>7;\
946         int U= (ubuf1[i])>>7;\
947         int V= (vbuf1[i])>>7;\
948         type av_unused *r, *b, *g;\
949         int av_unused A1, A2;\
950         if (alpha) {\
951             A1= abuf0[i2  ]>>7;\
952             A2= abuf0[i2+1]>>7;\
953         }\
954     r = (type *)c->table_rV[V];\
955     g = (type *)(c->table_gU[U] + c->table_gV[V]);\
956     b = (type *)c->table_bU[U];
957
958 #define YSCALE_YUV_2_RGB1B_C(type,alpha) \
959     for (i=0; i<(dstW>>1); i++) {\
960         const int i2= 2*i;\
961         int Y1= buf0[i2  ]>>7;\
962         int Y2= buf0[i2+1]>>7;\
963         int U= (ubuf0[i] + ubuf1[i])>>8;\
964         int V= (vbuf0[i] + vbuf1[i])>>8;\
965         type av_unused *r, *b, *g;\
966         int av_unused A1, A2;\
967         if (alpha) {\
968             A1= abuf0[i2  ]>>7;\
969             A2= abuf0[i2+1]>>7;\
970         }\
971     r = (type *)c->table_rV[V];\
972     g = (type *)(c->table_gU[U] + c->table_gV[V]);\
973     b = (type *)c->table_bU[U];
974
975 #define YSCALE_YUV_2_ANYRGB_C(func)\
976     switch(c->dstFormat) {\
977     case PIX_FMT_RGB48BE:\
978     case PIX_FMT_RGB48LE:\
979         func(uint8_t,0)\
980             ((uint8_t*)dest)[ 0]= r[Y1];\
981             ((uint8_t*)dest)[ 1]= r[Y1];\
982             ((uint8_t*)dest)[ 2]= g[Y1];\
983             ((uint8_t*)dest)[ 3]= g[Y1];\
984             ((uint8_t*)dest)[ 4]= b[Y1];\
985             ((uint8_t*)dest)[ 5]= b[Y1];\
986             ((uint8_t*)dest)[ 6]= r[Y2];\
987             ((uint8_t*)dest)[ 7]= r[Y2];\
988             ((uint8_t*)dest)[ 8]= g[Y2];\
989             ((uint8_t*)dest)[ 9]= g[Y2];\
990             ((uint8_t*)dest)[10]= b[Y2];\
991             ((uint8_t*)dest)[11]= b[Y2];\
992             dest+=12;\
993         }\
994         break;\
995     case PIX_FMT_BGR48BE:\
996     case PIX_FMT_BGR48LE:\
997         func(uint8_t,0)\
998             ((uint8_t*)dest)[ 0] = ((uint8_t*)dest)[ 1] = b[Y1];\
999             ((uint8_t*)dest)[ 2] = ((uint8_t*)dest)[ 3] = g[Y1];\
1000             ((uint8_t*)dest)[ 4] = ((uint8_t*)dest)[ 5] = r[Y1];\
1001             ((uint8_t*)dest)[ 6] = ((uint8_t*)dest)[ 7] = b[Y2];\
1002             ((uint8_t*)dest)[ 8] = ((uint8_t*)dest)[ 9] = g[Y2];\
1003             ((uint8_t*)dest)[10] = ((uint8_t*)dest)[11] = r[Y2];\
1004             dest+=12;\
1005         }\
1006         break;\
1007     case PIX_FMT_RGBA:\
1008     case PIX_FMT_BGRA:\
1009         if (CONFIG_SMALL) {\
1010             int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
1011             func(uint32_t,needAlpha)\
1012                 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? (A1<<24) : 0);\
1013                 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? (A2<<24) : 0);\
1014             }\
1015         } else {\
1016             if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
1017                 func(uint32_t,1)\
1018                     ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (A1<<24);\
1019                     ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (A2<<24);\
1020                 }\
1021             } else {\
1022                 func(uint32_t,0)\
1023                     ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
1024                     ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
1025                 }\
1026             }\
1027         }\
1028         break;\
1029     case PIX_FMT_ARGB:\
1030     case PIX_FMT_ABGR:\
1031         if (CONFIG_SMALL) {\
1032             int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
1033             func(uint32_t,needAlpha)\
1034                 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? A1 : 0);\
1035                 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? A2 : 0);\
1036             }\
1037         } else {\
1038             if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
1039                 func(uint32_t,1)\
1040                     ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + A1;\
1041                     ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + A2;\
1042                 }\
1043             } else {\
1044                 func(uint32_t,0)\
1045                     ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
1046                     ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
1047                 }\
1048             }\
1049         }                \
1050         break;\
1051     case PIX_FMT_RGB24:\
1052         func(uint8_t,0)\
1053             ((uint8_t*)dest)[0]= r[Y1];\
1054             ((uint8_t*)dest)[1]= g[Y1];\
1055             ((uint8_t*)dest)[2]= b[Y1];\
1056             ((uint8_t*)dest)[3]= r[Y2];\
1057             ((uint8_t*)dest)[4]= g[Y2];\
1058             ((uint8_t*)dest)[5]= b[Y2];\
1059             dest+=6;\
1060         }\
1061         break;\
1062     case PIX_FMT_BGR24:\
1063         func(uint8_t,0)\
1064             ((uint8_t*)dest)[0]= b[Y1];\
1065             ((uint8_t*)dest)[1]= g[Y1];\
1066             ((uint8_t*)dest)[2]= r[Y1];\
1067             ((uint8_t*)dest)[3]= b[Y2];\
1068             ((uint8_t*)dest)[4]= g[Y2];\
1069             ((uint8_t*)dest)[5]= r[Y2];\
1070             dest+=6;\
1071         }\
1072         break;\
1073     case PIX_FMT_RGB565:\
1074     case PIX_FMT_BGR565:\
1075         {\
1076             const int dr1= dither_2x2_8[y&1    ][0];\
1077             const int dg1= dither_2x2_4[y&1    ][0];\
1078             const int db1= dither_2x2_8[(y&1)^1][0];\
1079             const int dr2= dither_2x2_8[y&1    ][1];\
1080             const int dg2= dither_2x2_4[y&1    ][1];\
1081             const int db2= dither_2x2_8[(y&1)^1][1];\
1082             func(uint16_t,0)\
1083                 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
1084                 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
1085             }\
1086         }\
1087         break;\
1088     case PIX_FMT_RGB555:\
1089     case PIX_FMT_BGR555:\
1090         {\
1091             const int dr1= dither_2x2_8[y&1    ][0];\
1092             const int dg1= dither_2x2_8[y&1    ][1];\
1093             const int db1= dither_2x2_8[(y&1)^1][0];\
1094             const int dr2= dither_2x2_8[y&1    ][1];\
1095             const int dg2= dither_2x2_8[y&1    ][0];\
1096             const int db2= dither_2x2_8[(y&1)^1][1];\
1097             func(uint16_t,0)\
1098                 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
1099                 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
1100             }\
1101         }\
1102         break;\
1103     case PIX_FMT_RGB444:\
1104     case PIX_FMT_BGR444:\
1105         {\
1106             const int dr1= dither_4x4_16[y&3    ][0];\
1107             const int dg1= dither_4x4_16[y&3    ][1];\
1108             const int db1= dither_4x4_16[(y&3)^3][0];\
1109             const int dr2= dither_4x4_16[y&3    ][1];\
1110             const int dg2= dither_4x4_16[y&3    ][0];\
1111             const int db2= dither_4x4_16[(y&3)^3][1];\
1112             func(uint16_t,0)\
1113                 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
1114                 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
1115             }\
1116         }\
1117         break;\
1118     case PIX_FMT_RGB8:\
1119     case PIX_FMT_BGR8:\
1120         {\
1121             const uint8_t * const d64= dither_8x8_73[y&7];\
1122             const uint8_t * const d32= dither_8x8_32[y&7];\
1123             func(uint8_t,0)\
1124                 ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];\
1125                 ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];\
1126             }\
1127         }\
1128         break;\
1129     case PIX_FMT_RGB4:\
1130     case PIX_FMT_BGR4:\
1131         {\
1132             const uint8_t * const d64= dither_8x8_73 [y&7];\
1133             const uint8_t * const d128=dither_8x8_220[y&7];\
1134             func(uint8_t,0)\
1135                 ((uint8_t*)dest)[i]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]]\
1136                                  + ((r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]])<<4);\
1137             }\
1138         }\
1139         break;\
1140     case PIX_FMT_RGB4_BYTE:\
1141     case PIX_FMT_BGR4_BYTE:\
1142         {\
1143             const uint8_t * const d64= dither_8x8_73 [y&7];\
1144             const uint8_t * const d128=dither_8x8_220[y&7];\
1145             func(uint8_t,0)\
1146                 ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];\
1147                 ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];\
1148             }\
1149         }\
1150         break;\
1151     }
1152
1153 static void yuv2packedX_c(SwsContext *c, const int16_t *lumFilter,
1154                           const int16_t **lumSrc, int lumFilterSize,
1155                           const int16_t *chrFilter, const int16_t **chrUSrc,
1156                           const int16_t **chrVSrc, int chrFilterSize,
1157                           const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
1158 {
1159     int i;
1160     YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C)
1161 }
1162
1163 static void yuv2rgbX_c_full(SwsContext *c, const int16_t *lumFilter,
1164                             const int16_t **lumSrc, int lumFilterSize,
1165                             const int16_t *chrFilter, const int16_t **chrUSrc,
1166                             const int16_t **chrVSrc, int chrFilterSize,
1167                             const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
1168 {
1169     int i;
1170     int step= c->dstFormatBpp/8;
1171     int aidx= 3;
1172
1173     switch(c->dstFormat) {
1174     case PIX_FMT_ARGB:
1175         dest++;
1176         aidx= 0;
1177     case PIX_FMT_RGB24:
1178         aidx--;
1179     case PIX_FMT_RGBA:
1180         if (CONFIG_SMALL) {
1181             int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
1182             YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
1183                 dest[aidx]= needAlpha ? A : 255;
1184                 dest[0]= R>>22;
1185                 dest[1]= G>>22;
1186                 dest[2]= B>>22;
1187                 dest+= step;
1188             }
1189         } else {
1190             if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
1191                 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
1192                     dest[aidx]= A;
1193                     dest[0]= R>>22;
1194                     dest[1]= G>>22;
1195                     dest[2]= B>>22;
1196                     dest+= step;
1197                 }
1198             } else {
1199                 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
1200                     dest[aidx]= 255;
1201                     dest[0]= R>>22;
1202                     dest[1]= G>>22;
1203                     dest[2]= B>>22;
1204                     dest+= step;
1205                 }
1206             }
1207         }
1208         break;
1209     case PIX_FMT_ABGR:
1210         dest++;
1211         aidx= 0;
1212     case PIX_FMT_BGR24:
1213         aidx--;
1214     case PIX_FMT_BGRA:
1215         if (CONFIG_SMALL) {
1216             int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
1217             YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
1218                 dest[aidx]= needAlpha ? A : 255;
1219                 dest[0]= B>>22;
1220                 dest[1]= G>>22;
1221                 dest[2]= R>>22;
1222                 dest+= step;
1223             }
1224         } else {
1225             if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
1226                 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
1227                     dest[aidx]= A;
1228                     dest[0]= B>>22;
1229                     dest[1]= G>>22;
1230                     dest[2]= R>>22;
1231                     dest+= step;
1232                 }
1233             } else {
1234                 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
1235                     dest[aidx]= 255;
1236                     dest[0]= B>>22;
1237                     dest[1]= G>>22;
1238                     dest[2]= R>>22;
1239                     dest+= step;
1240                 }
1241             }
1242         }
1243         break;
1244     default:
1245         assert(0);
1246     }
1247 }
1248
1249 /**
1250  * vertical bilinear scale YV12 to RGB
1251  */
1252 static void yuv2packed2_c(SwsContext *c, const uint16_t *buf0,
1253                           const uint16_t *buf1, const uint16_t *ubuf0,
1254                           const uint16_t *ubuf1, const uint16_t *vbuf0,
1255                           const uint16_t *vbuf1, const uint16_t *abuf0,
1256                           const uint16_t *abuf1, uint8_t *dest, int dstW,
1257                           int yalpha, int uvalpha, int y)
1258 {
1259     int  yalpha1=4095- yalpha;
1260     int uvalpha1=4095-uvalpha;
1261     int i;
1262
1263     YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C)
1264 }
1265
1266 /**
1267  * YV12 to RGB without scaling or interpolating
1268  */
1269 static void yuv2packed1_c(SwsContext *c, const uint16_t *buf0,
1270                           const uint16_t *ubuf0, const uint16_t *ubuf1,
1271                           const uint16_t *vbuf0, const uint16_t *vbuf1,
1272                           const uint16_t *abuf0, uint8_t *dest, int dstW,
1273                           int uvalpha, enum PixelFormat dstFormat,
1274                           int flags, int y)
1275 {
1276     int i;
1277
1278     if (uvalpha < 2048) {
1279         YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C)
1280     } else {
1281         YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C)
1282     }
1283 }
1284
1285 static av_always_inline void fillPlane(uint8_t* plane, int stride,
1286                                        int width, int height,
1287                                        int y, uint8_t val)
1288 {
1289     int i;
1290     uint8_t *ptr = plane + stride*y;
1291     for (i=0; i<height; i++) {
1292         memset(ptr, val, width);
1293         ptr += stride;
1294     }
1295 }
1296
1297 static av_always_inline void
1298 rgb48ToY_c_template(int16_t *dst, const uint16_t *src, int width,
1299                     enum PixelFormat origin)
1300 {
1301     int i;
1302     for (i = 0; i < width; i++) {
1303 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1304         int a = input_pixel(&src[i*3+0]);
1305         int g = input_pixel(&src[i*3+1]);
1306         int c = input_pixel(&src[i*3+2]);
1307
1308 #define r ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? c : a)
1309 #define b ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? a : c)
1310         dst[i] = (RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8);
1311     }
1312 }
1313
1314 static av_always_inline void
1315 rgb48ToUV_c_template(int16_t *dstU, int16_t *dstV,
1316                     const uint16_t *src1, const uint16_t *src2,
1317                     int width, enum PixelFormat origin)
1318 {
1319     int i;
1320     assert(src1==src2);
1321     for (i = 0; i < width; i++) {
1322         int a = input_pixel(&src1[3*i + 0]);
1323         int g = input_pixel(&src1[3*i + 1]);
1324         int c = input_pixel(&src1[3*i + 2]);
1325
1326         dstU[i] = (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8);
1327         dstV[i] = (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8);
1328     }
1329 }
1330
1331 static av_always_inline void
1332 rgb48ToUV_half_c_template(int16_t *dstU, int16_t *dstV,
1333                           const uint16_t *src1, const uint16_t *src2,
1334                           int width, enum PixelFormat origin)
1335 {
1336     int i;
1337     assert(src1==src2);
1338     for (i = 0; i < width; i++) {
1339         int a = (input_pixel(&src1[6*i + 0])) + (input_pixel(&src1[6*i + 3]));
1340         int g = (input_pixel(&src1[6*i + 1])) + (input_pixel(&src1[6*i + 4]));
1341         int c = (input_pixel(&src1[6*i + 2])) + (input_pixel(&src1[6*i + 5]));
1342
1343         dstU[i]= (RU*r + GU*g + BU*b + (256U<<(RGB2YUV_SHIFT+8)) + (1<<(RGB2YUV_SHIFT-6+8))) >> (RGB2YUV_SHIFT-5+8);
1344         dstV[i]= (RV*r + GV*g + BV*b + (256U<<(RGB2YUV_SHIFT+8)) + (1<<(RGB2YUV_SHIFT-6+8))) >> (RGB2YUV_SHIFT-5+8);
1345     }
1346 #undef r
1347 #undef b
1348 #undef input_pixel
1349 }
1350
1351 #define rgb48funcs(pattern, BE_LE, origin) \
1352 static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *dst, const uint8_t *src, \
1353                                     int width, uint32_t *unused) \
1354 { \
1355     rgb48ToY_c_template(dst, src, width, origin); \
1356 } \
1357  \
1358 static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1359                                     const uint8_t *src1, const uint8_t *src2, \
1360                                     int width, uint32_t *unused) \
1361 { \
1362     rgb48ToUV_c_template(dstU, dstV, src1, src2, width, origin); \
1363 } \
1364  \
1365 static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
1366                                     const uint8_t *src1, const uint8_t *src2, \
1367                                     int width, uint32_t *unused) \
1368 { \
1369     rgb48ToUV_half_c_template(dstU, dstV, src1, src2, width, origin); \
1370 }
1371
1372 rgb48funcs(rgb, LE, PIX_FMT_RGB48LE);
1373 rgb48funcs(rgb, BE, PIX_FMT_RGB48BE);
1374 rgb48funcs(bgr, LE, PIX_FMT_BGR48LE);
1375 rgb48funcs(bgr, BE, PIX_FMT_BGR48BE);
1376
1377 static av_always_inline void
1378 rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src,
1379                        int width, enum PixelFormat origin,
1380                        int shr,   int shg,   int shb, int shp,
1381                        int maskr, int maskg, int maskb,
1382                        int rsh,   int gsh,   int bsh, int S)
1383 {
1384     const int ry = RY << rsh, gy = GY << gsh, by = BY << bsh,
1385               rnd = (32<<((S)-1)) + (1<<(S-7));
1386     int i;
1387
1388     for (i = 0; i < width; i++) {
1389 #define input_pixel(i) ((origin == PIX_FMT_RGBA || origin == PIX_FMT_BGRA || \
1390                          origin == PIX_FMT_ARGB || origin == PIX_FMT_ABGR) ? AV_RN32A(&src[(i)*4]) : \
1391                         (isBE(origin) ? AV_RB16(&src[(i)*2]) : AV_RL16(&src[(i)*2])))
1392         int px = input_pixel(i) >> shp;
1393         int b = (px & maskb) >> shb;
1394         int g = (px & maskg) >> shg;
1395         int r = (px & maskr) >> shr;
1396
1397         dst[i] = (ry * r + gy * g + by * b + rnd) >> ((S)-6);
1398     }
1399 }
1400
1401 static av_always_inline void
1402 rgb16_32ToUV_c_template(int16_t *dstU, int16_t *dstV,
1403                         const uint8_t *src, int width,
1404                         enum PixelFormat origin,
1405                         int shr,   int shg,   int shb, int shp,
1406                         int maskr, int maskg, int maskb,
1407                         int rsh,   int gsh,   int bsh, int S)
1408 {
1409     const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1410               rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1411               rnd = (256<<((S)-1)) + (1<<(S-7));
1412     int i;
1413
1414     for (i = 0; i < width; i++) {
1415         int px = input_pixel(i) >> shp;
1416         int b = (px & maskb) >> shb;
1417         int g = (px & maskg) >> shg;
1418         int r = (px & maskr) >> shr;
1419
1420         dstU[i] = (ru * r + gu * g + bu * b + rnd) >> ((S)-6);
1421         dstV[i] = (rv * r + gv * g + bv * b + rnd) >> ((S)-6);
1422     }
1423 }
1424
1425 static av_always_inline void
1426 rgb16_32ToUV_half_c_template(int16_t *dstU, int16_t *dstV,
1427                              const uint8_t *src, int width,
1428                              enum PixelFormat origin,
1429                              int shr,   int shg,   int shb, int shp,
1430                              int maskr, int maskg, int maskb,
1431                              int rsh,   int gsh,   int bsh, int S)
1432 {
1433     const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1434               rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1435               rnd = (256U<<(S)) + (1<<(S-6)), maskgx = ~(maskr | maskb);
1436     int i;
1437
1438     maskr |= maskr << 1; maskb |= maskb << 1; maskg |= maskg << 1;
1439     for (i = 0; i < width; i++) {
1440         int px0 = input_pixel(2 * i + 0) >> shp;
1441         int px1 = input_pixel(2 * i + 1) >> shp;
1442         int b, r, g = (px0 & maskgx) + (px1 & maskgx);
1443         int rb = px0 + px1 - g;
1444
1445         b = (rb & maskb) >> shb;
1446         if (shp || origin == PIX_FMT_BGR565LE || origin == PIX_FMT_BGR565BE ||
1447             origin == PIX_FMT_RGB565LE || origin == PIX_FMT_RGB565BE) {
1448             g >>= shg;
1449         } else {
1450             g = (g  & maskg) >> shg;
1451         }
1452         r = (rb & maskr) >> shr;
1453
1454         dstU[i] = (ru * r + gu * g + bu * b + (unsigned)rnd) >> ((S)-6+1);
1455         dstV[i] = (rv * r + gv * g + bv * b + (unsigned)rnd) >> ((S)-6+1);
1456     }
1457 #undef input_pixel
1458 }
1459
1460 #define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr, \
1461                          maskg, maskb, rsh, gsh, bsh, S) \
1462 static void name ## ToY_c(uint8_t *dst, const uint8_t *src, \
1463                           int width, uint32_t *unused) \
1464 { \
1465     rgb16_32ToY_c_template(dst, src, width, fmt, shr, shg, shb, shp, \
1466                            maskr, maskg, maskb, rsh, gsh, bsh, S); \
1467 } \
1468  \
1469 static void name ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1470                            const uint8_t *src, const uint8_t *dummy, \
1471                            int width, uint32_t *unused) \
1472 { \
1473     rgb16_32ToUV_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1474                             maskr, maskg, maskb, rsh, gsh, bsh, S); \
1475 } \
1476  \
1477 static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
1478                                 const uint8_t *src, const uint8_t *dummy, \
1479                                 int width, uint32_t *unused) \
1480 { \
1481     rgb16_32ToUV_half_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1482                                  maskr, maskg, maskb, rsh, gsh, bsh, S); \
1483 }
1484
1485 rgb16_32_wrapper(PIX_FMT_BGR32,    bgr32,  16, 0,  0, 0, 0xFF0000, 0xFF00,   0x00FF,  8, 0,  8, RGB2YUV_SHIFT+8);
1486 rgb16_32_wrapper(PIX_FMT_BGR32_1,  bgr321, 16, 0,  0, 8, 0xFF0000, 0xFF00,   0x00FF,  8, 0,  8, RGB2YUV_SHIFT+8);
1487 rgb16_32_wrapper(PIX_FMT_RGB32,    rgb32,   0, 0, 16, 0,   0x00FF, 0xFF00, 0xFF0000,  8, 0,  8, RGB2YUV_SHIFT+8);
1488 rgb16_32_wrapper(PIX_FMT_RGB32_1,  rgb321,  0, 0, 16, 8,   0x00FF, 0xFF00, 0xFF0000,  8, 0,  8, RGB2YUV_SHIFT+8);
1489 rgb16_32_wrapper(PIX_FMT_BGR565LE, bgr16le, 0, 0,  0, 0,   0x001F, 0x07E0,   0xF800, 11, 5,  0, RGB2YUV_SHIFT+8);
1490 rgb16_32_wrapper(PIX_FMT_BGR555LE, bgr15le, 0, 0,  0, 0,   0x001F, 0x03E0,   0x7C00, 10, 5,  0, RGB2YUV_SHIFT+7);
1491 rgb16_32_wrapper(PIX_FMT_RGB565LE, rgb16le, 0, 0,  0, 0,   0xF800, 0x07E0,   0x001F,  0, 5, 11, RGB2YUV_SHIFT+8);
1492 rgb16_32_wrapper(PIX_FMT_RGB555LE, rgb15le, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT+7);
1493 rgb16_32_wrapper(PIX_FMT_BGR565BE, bgr16be, 0, 0,  0, 0,   0x001F, 0x07E0,   0xF800, 11, 5,  0, RGB2YUV_SHIFT+8);
1494 rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr15be, 0, 0,  0, 0,   0x001F, 0x03E0,   0x7C00, 10, 5,  0, RGB2YUV_SHIFT+7);
1495 rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0,  0, 0,   0xF800, 0x07E0,   0x001F,  0, 5, 11, RGB2YUV_SHIFT+8);
1496 rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT+7);
1497
1498 static void abgrToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1499 {
1500     int i;
1501     for (i=0; i<width; i++) {
1502         dst[i]= src[4*i]<<6;
1503     }
1504 }
1505
1506 static void rgbaToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1507 {
1508     int i;
1509     for (i=0; i<width; i++) {
1510         dst[i]= src[4*i+3]<<6;
1511     }
1512 }
1513
1514 static void palToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *pal)
1515 {
1516     int i;
1517     for (i=0; i<width; i++) {
1518         int d= src[i];
1519
1520         dst[i]= (pal[d] >> 24)<<6;
1521     }
1522 }
1523
1524 static void palToY_c(int16_t *dst, const uint8_t *src, long width, uint32_t *pal)
1525 {
1526     int i;
1527     for (i=0; i<width; i++) {
1528         int d= src[i];
1529
1530         dst[i]= (pal[d] & 0xFF)<<6;
1531     }
1532 }
1533
1534 static void palToUV_c(uint16_t *dstU, int16_t *dstV,
1535                            const uint8_t *src1, const uint8_t *src2,
1536                            int width, uint32_t *pal)
1537 {
1538     int i;
1539     assert(src1 == src2);
1540     for (i=0; i<width; i++) {
1541         int p= pal[src1[i]];
1542
1543         dstU[i]= (uint8_t)(p>> 8)<<6;
1544         dstV[i]= (uint8_t)(p>>16)<<6;
1545     }
1546 }
1547
1548 static void monowhite2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1549 {
1550     int i, j;
1551     for (i=0; i<width/8; i++) {
1552         int d= ~src[i];
1553         for(j=0; j<8; j++)
1554             dst[8*i+j]= ((d>>(7-j))&1)*16383;
1555     }
1556 }
1557
1558 static void monoblack2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1559 {
1560     int i, j;
1561     for (i=0; i<width/8; i++) {
1562         int d= src[i];
1563         for(j=0; j<8; j++)
1564             dst[8*i+j]= ((d>>(7-j))&1)*16383;
1565     }
1566 }
1567
1568 //FIXME yuy2* can read up to 7 samples too much
1569
1570 static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, int width,
1571                       uint32_t *unused)
1572 {
1573     int i;
1574     for (i=0; i<width; i++)
1575         dst[i]= src[2*i];
1576 }
1577
1578 static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1579                        const uint8_t *src2, int width, uint32_t *unused)
1580 {
1581     int i;
1582     for (i=0; i<width; i++) {
1583         dstU[i]= src1[4*i + 1];
1584         dstV[i]= src1[4*i + 3];
1585     }
1586     assert(src1 == src2);
1587 }
1588
1589 static void LEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1590                      const uint8_t *src2, int width, uint32_t *unused)
1591 {
1592     int i;
1593     for (i=0; i<width; i++) {
1594         dstU[i]= src1[2*i + 1];
1595         dstV[i]= src2[2*i + 1];
1596     }
1597 }
1598
1599 /* This is almost identical to the previous, end exists only because
1600  * yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
1601 static void uyvyToY_c(uint8_t *dst, const uint8_t *src, int width,
1602                       uint32_t *unused)
1603 {
1604     int i;
1605     for (i=0; i<width; i++)
1606         dst[i]= src[2*i+1];
1607 }
1608
1609 static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1610                        const uint8_t *src2, int width, uint32_t *unused)
1611 {
1612     int i;
1613     for (i=0; i<width; i++) {
1614         dstU[i]= src1[4*i + 0];
1615         dstV[i]= src1[4*i + 2];
1616     }
1617     assert(src1 == src2);
1618 }
1619
1620 static void BEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1621                      const uint8_t *src2, int width, uint32_t *unused)
1622 {
1623     int i;
1624     for (i=0; i<width; i++) {
1625         dstU[i]= src1[2*i];
1626         dstV[i]= src2[2*i];
1627     }
1628 }
1629
1630 static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
1631                                         const uint8_t *src, int width)
1632 {
1633     int i;
1634     for (i = 0; i < width; i++) {
1635         dst1[i] = src[2*i+0];
1636         dst2[i] = src[2*i+1];
1637     }
1638 }
1639
1640 // FIXME Maybe dither instead.
1641 static av_always_inline void
1642 yuv9_OR_10ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
1643                           const uint8_t *_srcU, const uint8_t *_srcV,
1644                           int width, enum PixelFormat origin, int depth)
1645 {
1646     int i;
1647     const uint16_t *srcU = (const uint16_t *) _srcU;
1648     const uint16_t *srcV = (const uint16_t *) _srcV;
1649
1650 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1651     for (i = 0; i < width; i++) {
1652         dstU[i] = input_pixel(&srcU[i]) >> (depth - 8);
1653         dstV[i] = input_pixel(&srcV[i]) >> (depth - 8);
1654     }
1655 }
1656
1657 static av_always_inline void
1658 yuv9_or_10ToY_c_template(uint8_t *dstY, const uint8_t *_srcY,
1659                          int width, enum PixelFormat origin, int depth)
1660 {
1661     int i;
1662     const uint16_t *srcY = (const uint16_t*)_srcY;
1663
1664     for (i = 0; i < width; i++)
1665         dstY[i] = input_pixel(&srcY[i]) >> (depth - 8);
1666 #undef input_pixel
1667 }
1668
1669 #define YUV_NBPS(depth, BE_LE, origin) \
1670 static void BE_LE ## depth ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1671                                      const uint8_t *srcU, const uint8_t *srcV, \
1672                                      int width, uint32_t *unused) \
1673 { \
1674     yuv9_OR_10ToUV_c_template(dstU, dstV, srcU, srcV, width, origin, depth); \
1675 } \
1676 static void BE_LE ## depth ## ToY_c(uint8_t *dstY, const uint8_t *srcY, \
1677                                     int width, uint32_t *unused) \
1678 { \
1679     yuv9_or_10ToY_c_template(dstY, srcY, width, origin, depth); \
1680 }
1681
1682 YUV_NBPS( 9, LE, PIX_FMT_YUV420P9LE);
1683 YUV_NBPS( 9, BE, PIX_FMT_YUV420P9BE);
1684 YUV_NBPS(10, LE, PIX_FMT_YUV420P10LE);
1685 YUV_NBPS(10, BE, PIX_FMT_YUV420P10BE);
1686
1687 static inline void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
1688                               const uint8_t *src1, const uint8_t *src2,
1689                               int width, uint32_t *unused)
1690 {
1691     nvXXtoUV_c(dstU, dstV, src1, width);
1692 }
1693
1694 static inline void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
1695                               const uint8_t *src1, const uint8_t *src2,
1696                               int width, uint32_t *unused)
1697 {
1698     nvXXtoUV_c(dstV, dstU, src1, width);
1699 }
1700
1701 static void bgr24ToY_c(int16_t *dst, const uint8_t *src,
1702                        int width, uint32_t *unused)
1703 {
1704     int i;
1705     for (i=0; i<width; i++) {
1706         int b= src[i*3+0];
1707         int g= src[i*3+1];
1708         int r= src[i*3+2];
1709
1710         dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
1711     }
1712 }
1713
1714 static void bgr24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1715                         const uint8_t *src2, int width, uint32_t *unused)
1716 {
1717     int i;
1718     for (i=0; i<width; i++) {
1719         int b= src1[3*i + 0];
1720         int g= src1[3*i + 1];
1721         int r= src1[3*i + 2];
1722
1723         dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1724         dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1725     }
1726     assert(src1 == src2);
1727 }
1728
1729 static void bgr24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1730                              const uint8_t *src2, int width, uint32_t *unused)
1731 {
1732     int i;
1733     for (i=0; i<width; i++) {
1734         int b= src1[6*i + 0] + src1[6*i + 3];
1735         int g= src1[6*i + 1] + src1[6*i + 4];
1736         int r= src1[6*i + 2] + src1[6*i + 5];
1737
1738         dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1739         dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1740     }
1741     assert(src1 == src2);
1742 }
1743
1744 static void rgb24ToY_c(int16_t *dst, const uint8_t *src, int width,
1745                        uint32_t *unused)
1746 {
1747     int i;
1748     for (i=0; i<width; i++) {
1749         int r= src[i*3+0];
1750         int g= src[i*3+1];
1751         int b= src[i*3+2];
1752
1753         dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
1754     }
1755 }
1756
1757 static void rgb24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1758                         const uint8_t *src2, int width, uint32_t *unused)
1759 {
1760     int i;
1761     assert(src1==src2);
1762     for (i=0; i<width; i++) {
1763         int r= src1[3*i + 0];
1764         int g= src1[3*i + 1];
1765         int b= src1[3*i + 2];
1766
1767         dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1768         dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1769     }
1770 }
1771
1772 static void rgb24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1773                                     const uint8_t *src2, int width, uint32_t *unused)
1774 {
1775     int i;
1776     assert(src1==src2);
1777     for (i=0; i<width; i++) {
1778         int r= src1[6*i + 0] + src1[6*i + 3];
1779         int g= src1[6*i + 1] + src1[6*i + 4];
1780         int b= src1[6*i + 2] + src1[6*i + 5];
1781
1782         dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1783         dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1784     }
1785 }
1786
1787
1788 // bilinear / bicubic scaling
1789 static void hScale_c(int16_t *dst, int dstW, const uint8_t *src,
1790                      int srcW, int xInc,
1791                      const int16_t *filter, const int16_t *filterPos,
1792                      int filterSize)
1793 {
1794     int i;
1795     for (i=0; i<dstW; i++) {
1796         int j;
1797         int srcPos= filterPos[i];
1798         int val=0;
1799         for (j=0; j<filterSize; j++) {
1800             val += ((int)src[srcPos + j])*filter[filterSize*i + j];
1801         }
1802         //filter += hFilterSize;
1803         dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
1804         //dst[i] = val>>7;
1805     }
1806 }
1807
1808 static inline void hScale16_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
1809                                     const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
1810 {
1811     int i, j;
1812
1813     for (i=0; i<dstW; i++) {
1814         int srcPos= filterPos[i];
1815         int val=0;
1816         for (j=0; j<filterSize; j++) {
1817             val += ((int)src[srcPos + j])*filter[filterSize*i + j];
1818         }
1819         dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
1820     }
1821 }
1822
1823 static inline void hScale16X_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
1824                                     const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
1825 {
1826     int i, j;
1827     for (i=0; i<dstW; i++) {
1828         int srcPos= filterPos[i];
1829         int val=0;
1830         for (j=0; j<filterSize; j++) {
1831             val += ((int)av_bswap16(src[srcPos + j]))*filter[filterSize*i + j];
1832         }
1833         dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
1834     }
1835 }
1836
1837 //FIXME all pal and rgb srcFormats could do this convertion as well
1838 //FIXME all scalers more complex than bilinear could do half of this transform
1839 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1840 {
1841     int i;
1842     for (i = 0; i < width; i++) {
1843         dstU[i] = (FFMIN(dstU[i],30775)*4663 - 9289992)>>12; //-264
1844         dstV[i] = (FFMIN(dstV[i],30775)*4663 - 9289992)>>12; //-264
1845     }
1846 }
1847 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1848 {
1849     int i;
1850     for (i = 0; i < width; i++) {
1851         dstU[i] = (dstU[i]*1799 + 4081085)>>11; //1469
1852         dstV[i] = (dstV[i]*1799 + 4081085)>>11; //1469
1853     }
1854 }
1855 static void lumRangeToJpeg_c(int16_t *dst, int width)
1856 {
1857     int i;
1858     for (i = 0; i < width; i++)
1859         dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
1860 }
1861 static void lumRangeFromJpeg_c(int16_t *dst, int width)
1862 {
1863     int i;
1864     for (i = 0; i < width; i++)
1865         dst[i] = (dst[i]*14071 + 33561947)>>14;
1866 }
1867
1868 static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
1869                            const uint8_t *src, int srcW, int xInc)
1870 {
1871     int i;
1872     unsigned int xpos=0;
1873     for (i=0;i<dstWidth;i++) {
1874         register unsigned int xx=xpos>>16;
1875         register unsigned int xalpha=(xpos&0xFFFF)>>9;
1876         dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
1877         xpos+=xInc;
1878     }
1879     for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
1880         dst[i] = src[srcW-1]*128;
1881 }
1882
1883 // *** horizontal scale Y line to temp buffer
1884 static av_always_inline void hyscale(SwsContext *c, uint16_t *dst, int dstWidth,
1885                                      const uint8_t *src, int srcW, int xInc,
1886                                      const int16_t *hLumFilter,
1887                                      const int16_t *hLumFilterPos, int hLumFilterSize,
1888                                      uint8_t *formatConvBuffer,
1889                                      uint32_t *pal, int isAlpha)
1890 {
1891     void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
1892     void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
1893
1894     if (toYV12) {
1895         toYV12(formatConvBuffer, src, srcW, pal);
1896         src= formatConvBuffer;
1897     }
1898
1899     if (c->hScale16) {
1900         int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
1901         c->hScale16(dst, dstWidth, (const uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, shift);
1902     } else if (!c->hyscale_fast) {
1903         c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
1904     } else { // fast bilinear upscale / crap downscale
1905         c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
1906     }
1907
1908     if (convertRange)
1909         convertRange(dst, dstWidth);
1910 }
1911
1912 static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
1913                            int dstWidth, const uint8_t *src1,
1914                            const uint8_t *src2, int srcW, int xInc)
1915 {
1916     int i;
1917     unsigned int xpos=0;
1918     for (i=0;i<dstWidth;i++) {
1919         register unsigned int xx=xpos>>16;
1920         register unsigned int xalpha=(xpos&0xFFFF)>>9;
1921         dst1[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
1922         dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
1923         xpos+=xInc;
1924     }
1925     for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {
1926         dst1[i] = src1[srcW-1]*128;
1927         dst2[i] = src2[srcW-1]*128;
1928     }
1929 }
1930
1931 static av_always_inline void hcscale(SwsContext *c, uint16_t *dst1, uint16_t *dst2, int dstWidth,
1932                                      const uint8_t *src1, const uint8_t *src2,
1933                                      int srcW, int xInc, const int16_t *hChrFilter,
1934                                      const int16_t *hChrFilterPos, int hChrFilterSize,
1935                                      uint8_t *formatConvBuffer, uint32_t *pal)
1936 {
1937     if (c->chrToYV12) {
1938         uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16);
1939         c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
1940         src1= formatConvBuffer;
1941         src2= buf2;
1942     }
1943
1944     if (c->hScale16) {
1945         int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
1946         c->hScale16(dst1, dstWidth, (const uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
1947         c->hScale16(dst2, dstWidth, (const uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
1948     } else if (!c->hcscale_fast) {
1949         c->hScale(dst1, dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
1950         c->hScale(dst2, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
1951     } else { // fast bilinear upscale / crap downscale
1952         c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc);
1953     }
1954
1955     if (c->chrConvertRange)
1956         c->chrConvertRange(dst1, dst2, dstWidth);
1957 }
1958
1959 static av_always_inline void
1960 find_c_packed_planar_out_funcs(SwsContext *c,
1961                                yuv2planar1_fn *yuv2yuv1,    yuv2planarX_fn *yuv2yuvX,
1962                                yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2,
1963                                yuv2packedX_fn *yuv2packedX)
1964 {
1965     enum PixelFormat dstFormat = c->dstFormat;
1966
1967     if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
1968         *yuv2yuvX     = yuv2nv12X_c;
1969     } else if (is16BPS(dstFormat)) {
1970         *yuv2yuvX     = isBE(dstFormat) ? yuv2yuvX16BE_c  : yuv2yuvX16LE_c;
1971     } else if (is9_OR_10BPS(dstFormat)) {
1972         if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
1973             *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c :  yuv2yuvX9LE_c;
1974         } else {
1975             *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c;
1976         }
1977     } else {
1978         *yuv2yuv1     = yuv2yuv1_c;
1979         *yuv2yuvX     = yuv2yuvX_c;
1980     }
1981     if(c->flags & SWS_FULL_CHR_H_INT) {
1982         *yuv2packedX = yuv2rgbX_c_full;
1983     } else {
1984         switch (dstFormat) {
1985         case PIX_FMT_GRAY16BE:
1986             *yuv2packed1 = yuv2gray16BE_1_c;
1987             *yuv2packed2 = yuv2gray16BE_2_c;
1988             *yuv2packedX = yuv2gray16BE_X_c;
1989             break;
1990         case PIX_FMT_GRAY16LE:
1991             *yuv2packed1 = yuv2gray16LE_1_c;
1992             *yuv2packed2 = yuv2gray16LE_2_c;
1993             *yuv2packedX = yuv2gray16LE_X_c;
1994             break;
1995         case PIX_FMT_MONOWHITE:
1996             *yuv2packed1 = yuv2monowhite_1_c;
1997             *yuv2packed2 = yuv2monowhite_2_c;
1998             *yuv2packedX = yuv2monowhite_X_c;
1999             break;
2000         case PIX_FMT_MONOBLACK:
2001             *yuv2packed1 = yuv2monoblack_1_c;
2002             *yuv2packed2 = yuv2monoblack_2_c;
2003             *yuv2packedX = yuv2monoblack_X_c;
2004             break;
2005         case PIX_FMT_YUYV422:
2006             *yuv2packed1 = yuv2422yuyv_1_c;
2007             *yuv2packed2 = yuv2422yuyv_2_c;
2008             *yuv2packedX = yuv2422yuyv_X_c;
2009             break;
2010         case PIX_FMT_UYVY422:
2011             *yuv2packed1 = yuv2422uyvy_1_c;
2012             *yuv2packed2 = yuv2422uyvy_2_c;
2013             *yuv2packedX = yuv2422uyvy_X_c;
2014             break;
2015         default:
2016             *yuv2packed1 = yuv2packed1_c;
2017             *yuv2packed2 = yuv2packed2_c;
2018             *yuv2packedX = yuv2packedX_c;
2019             break;
2020         }
2021     }
2022 }
2023
2024 #define DEBUG_SWSCALE_BUFFERS 0
2025 #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
2026
2027 static int swScale(SwsContext *c, const uint8_t* src[],
2028                    int srcStride[], int srcSliceY,
2029                    int srcSliceH, uint8_t* dst[], int dstStride[])
2030 {
2031     /* load a few things into local vars to make the code more readable? and faster */
2032     const int srcW= c->srcW;
2033     const int dstW= c->dstW;
2034     const int dstH= c->dstH;
2035     const int chrDstW= c->chrDstW;
2036     const int chrSrcW= c->chrSrcW;
2037     const int lumXInc= c->lumXInc;
2038     const int chrXInc= c->chrXInc;
2039     const enum PixelFormat dstFormat= c->dstFormat;
2040     const int flags= c->flags;
2041     int16_t *vLumFilterPos= c->vLumFilterPos;
2042     int16_t *vChrFilterPos= c->vChrFilterPos;
2043     int16_t *hLumFilterPos= c->hLumFilterPos;
2044     int16_t *hChrFilterPos= c->hChrFilterPos;
2045     int16_t *vLumFilter= c->vLumFilter;
2046     int16_t *vChrFilter= c->vChrFilter;
2047     int16_t *hLumFilter= c->hLumFilter;
2048     int16_t *hChrFilter= c->hChrFilter;
2049     int32_t *lumMmxFilter= c->lumMmxFilter;
2050     int32_t *chrMmxFilter= c->chrMmxFilter;
2051     int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
2052     const int vLumFilterSize= c->vLumFilterSize;
2053     const int vChrFilterSize= c->vChrFilterSize;
2054     const int hLumFilterSize= c->hLumFilterSize;
2055     const int hChrFilterSize= c->hChrFilterSize;
2056     int16_t **lumPixBuf= c->lumPixBuf;
2057     int16_t **chrUPixBuf= c->chrUPixBuf;
2058     int16_t **chrVPixBuf= c->chrVPixBuf;
2059     int16_t **alpPixBuf= c->alpPixBuf;
2060     const int vLumBufSize= c->vLumBufSize;
2061     const int vChrBufSize= c->vChrBufSize;
2062     uint8_t *formatConvBuffer= c->formatConvBuffer;
2063     const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
2064     const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
2065     int lastDstY;
2066     uint32_t *pal=c->pal_yuv;
2067     int should_dither= isNBPS(c->srcFormat) || is16BPS(c->srcFormat);
2068     yuv2planar1_fn yuv2yuv1 = c->yuv2yuv1;
2069     yuv2planarX_fn yuv2yuvX = c->yuv2yuvX;
2070     yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
2071     yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
2072     yuv2packedX_fn yuv2packedX = c->yuv2packedX;
2073
2074     /* vars which will change and which we need to store back in the context */
2075     int dstY= c->dstY;
2076     int lumBufIndex= c->lumBufIndex;
2077     int chrBufIndex= c->chrBufIndex;
2078     int lastInLumBuf= c->lastInLumBuf;
2079     int lastInChrBuf= c->lastInChrBuf;
2080
2081     if (isPacked(c->srcFormat)) {
2082         src[0]=
2083         src[1]=
2084         src[2]=
2085         src[3]= src[0];
2086         srcStride[0]=
2087         srcStride[1]=
2088         srcStride[2]=
2089         srcStride[3]= srcStride[0];
2090     }
2091     srcStride[1]<<= c->vChrDrop;
2092     srcStride[2]<<= c->vChrDrop;
2093
2094     DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
2095                   src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
2096                   dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
2097     DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
2098                    srcSliceY,    srcSliceH,    dstY,    dstH);
2099     DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
2100                    vLumFilterSize,    vLumBufSize,    vChrFilterSize,    vChrBufSize);
2101
2102     if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
2103         static int warnedAlready=0; //FIXME move this into the context perhaps
2104         if (flags & SWS_PRINT_INFO && !warnedAlready) {
2105             av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
2106                    "         ->cannot do aligned memory accesses anymore\n");
2107             warnedAlready=1;
2108         }
2109     }
2110
2111     /* Note the user might start scaling the picture in the middle so this
2112        will not get executed. This is not really intended but works
2113        currently, so people might do it. */
2114     if (srcSliceY ==0) {
2115         lumBufIndex=-1;
2116         chrBufIndex=-1;
2117         dstY=0;
2118         lastInLumBuf= -1;
2119         lastInChrBuf= -1;
2120     }
2121
2122     lastDstY= dstY;
2123
2124     for (;dstY < dstH; dstY++) {
2125         unsigned char *dest =dst[0]+dstStride[0]*dstY;
2126         const int chrDstY= dstY>>c->chrDstVSubSample;
2127         unsigned char *uDest=dst[1]+dstStride[1]*chrDstY;
2128         unsigned char *vDest=dst[2]+dstStride[2]*chrDstY;
2129         unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL;
2130         const uint8_t *lumDither= should_dither ? dithers[7][dstY   &7] : flat64;
2131         const uint8_t *chrDither= should_dither ? dithers[7][chrDstY&7] : flat64;
2132
2133         const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
2134         const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
2135         const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
2136         int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
2137         int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
2138         int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
2139         int enough_lines;
2140
2141         //handle holes (FAST_BILINEAR & weird filters)
2142         if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
2143         if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
2144         assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
2145         assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
2146
2147         DEBUG_BUFFERS("dstY: %d\n", dstY);
2148         DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
2149                          firstLumSrcY,    lastLumSrcY,    lastInLumBuf);
2150         DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
2151                          firstChrSrcY,    lastChrSrcY,    lastInChrBuf);
2152
2153         // Do we have enough lines in this slice to output the dstY line
2154         enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
2155
2156         if (!enough_lines) {
2157             lastLumSrcY = srcSliceY + srcSliceH - 1;
2158             lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
2159             DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
2160                                             lastLumSrcY, lastChrSrcY);
2161         }
2162
2163         //Do horizontal scaling
2164         while(lastInLumBuf < lastLumSrcY) {
2165             const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
2166             const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
2167             lumBufIndex++;
2168             assert(lumBufIndex < 2*vLumBufSize);
2169             assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
2170             assert(lastInLumBuf + 1 - srcSliceY >= 0);
2171             hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
2172                     hLumFilter, hLumFilterPos, hLumFilterSize,
2173                     formatConvBuffer,
2174                     pal, 0);
2175             if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
2176                 hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW,
2177                         lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
2178                         formatConvBuffer,
2179                         pal, 1);
2180             lastInLumBuf++;
2181             DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
2182                                lumBufIndex,    lastInLumBuf);
2183         }
2184         while(lastInChrBuf < lastChrSrcY) {
2185             const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
2186             const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
2187             chrBufIndex++;
2188             assert(chrBufIndex < 2*vChrBufSize);
2189             assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
2190             assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
2191             //FIXME replace parameters through context struct (some at least)
2192
2193             if (c->needs_hcscale)
2194                 hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
2195                           chrDstW, src1, src2, chrSrcW, chrXInc,
2196                           hChrFilter, hChrFilterPos, hChrFilterSize,
2197                           formatConvBuffer, pal);
2198             lastInChrBuf++;
2199             DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
2200                                chrBufIndex,    lastInChrBuf);
2201         }
2202         //wrap buf index around to stay inside the ring buffer
2203         if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
2204         if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
2205         if (!enough_lines)
2206             break; //we can't output a dstY line so let's try with the next slice
2207
2208 #if HAVE_MMX
2209         updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf);
2210 #endif
2211         if (dstY >= dstH-2) {
2212             // hmm looks like we can't use MMX here without overwriting this array's tail
2213             find_c_packed_planar_out_funcs(c, &yuv2yuv1, &yuv2yuvX,
2214                                            &yuv2packed1, &yuv2packed2,
2215                                            &yuv2packedX);
2216         }
2217
2218         {
2219             const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
2220             const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2221             const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2222             const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
2223
2224             if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
2225                 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2226                 if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
2227                 if (c->yuv2yuv1 && vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
2228                     const int16_t *lumBuf = lumSrcPtr[0];
2229                     const int16_t *chrUBuf= chrUSrcPtr[0];
2230                     const int16_t *chrVBuf= chrVSrcPtr[0];
2231                     const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
2232                     yuv2yuv1(c, lumBuf, chrUBuf, chrVBuf, alpBuf, dest,
2233                                 uDest, vDest, aDest, dstW, chrDstW, lumDither, chrDither);
2234                 } else { //General YV12
2235                     yuv2yuvX(c,
2236                                 vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
2237                                 vChrFilter+chrDstY*vChrFilterSize, chrUSrcPtr,
2238                                 chrVSrcPtr, vChrFilterSize,
2239                                 alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW, lumDither, chrDither);
2240                 }
2241             } else {
2242                 assert(lumSrcPtr  + vLumFilterSize - 1 < lumPixBuf  + vLumBufSize*2);
2243                 assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize*2);
2244                 if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
2245                     int chrAlpha= vChrFilter[2*dstY+1];
2246                     yuv2packed1(c, *lumSrcPtr, *chrUSrcPtr, *(chrUSrcPtr+1),
2247                                    *chrVSrcPtr, *(chrVSrcPtr+1),
2248                                    alpPixBuf ? *alpSrcPtr : NULL,
2249                                    dest, dstW, chrAlpha, dstFormat, flags, dstY);
2250                 } else if (c->yuv2packed2 && vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
2251                     int lumAlpha= vLumFilter[2*dstY+1];
2252                     int chrAlpha= vChrFilter[2*dstY+1];
2253                     lumMmxFilter[2]=
2254                     lumMmxFilter[3]= vLumFilter[2*dstY   ]*0x10001;
2255                     chrMmxFilter[2]=
2256                     chrMmxFilter[3]= vChrFilter[2*chrDstY]*0x10001;
2257                     yuv2packed2(c, *lumSrcPtr, *(lumSrcPtr+1), *chrUSrcPtr, *(chrUSrcPtr+1),
2258                                    *chrVSrcPtr, *(chrVSrcPtr+1),
2259                                    alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *(alpSrcPtr+1) : NULL,
2260                                    dest, dstW, lumAlpha, chrAlpha, dstY);
2261                 } else { //general RGB
2262                     yuv2packedX(c,
2263                                    vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
2264                                    vChrFilter+dstY*vChrFilterSize, chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2265                                    alpSrcPtr, dest, dstW, dstY);
2266                 }
2267             }
2268         }
2269     }
2270
2271     if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
2272         fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
2273
2274 #if HAVE_MMX2
2275     if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2)
2276         __asm__ volatile("sfence":::"memory");
2277 #endif
2278     emms_c();
2279
2280     /* store changed local vars back in the context */
2281     c->dstY= dstY;
2282     c->lumBufIndex= lumBufIndex;
2283     c->chrBufIndex= chrBufIndex;
2284     c->lastInLumBuf= lastInLumBuf;
2285     c->lastInChrBuf= lastInChrBuf;
2286
2287     return dstY - lastDstY;
2288 }
2289
2290 static av_cold void sws_init_swScale_c(SwsContext *c)
2291 {
2292     enum PixelFormat srcFormat = c->srcFormat;
2293
2294     find_c_packed_planar_out_funcs(c, &c->yuv2yuv1, &c->yuv2yuvX,
2295                                    &c->yuv2packed1, &c->yuv2packed2,
2296                                    &c->yuv2packedX);
2297
2298     c->hScale       = hScale_c;
2299
2300     if (c->flags & SWS_FAST_BILINEAR) {
2301         c->hyscale_fast = hyscale_fast_c;
2302         c->hcscale_fast = hcscale_fast_c;
2303     }
2304
2305     c->chrToYV12 = NULL;
2306     switch(srcFormat) {
2307         case PIX_FMT_YUYV422  : c->chrToYV12 = yuy2ToUV_c; break;
2308         case PIX_FMT_UYVY422  : c->chrToYV12 = uyvyToUV_c; break;
2309         case PIX_FMT_NV12     : c->chrToYV12 = nv12ToUV_c; break;
2310         case PIX_FMT_NV21     : c->chrToYV12 = nv21ToUV_c; break;
2311         case PIX_FMT_RGB8     :
2312         case PIX_FMT_BGR8     :
2313         case PIX_FMT_PAL8     :
2314         case PIX_FMT_BGR4_BYTE:
2315         case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
2316         case PIX_FMT_GRAY16BE :
2317         case PIX_FMT_YUV444P9BE:
2318         case PIX_FMT_YUV420P9BE:
2319         case PIX_FMT_YUV444P10BE:
2320         case PIX_FMT_YUV422P10BE:
2321         case PIX_FMT_YUV420P10BE:
2322         case PIX_FMT_YUV420P16BE:
2323         case PIX_FMT_YUV422P16BE:
2324         case PIX_FMT_YUV444P16BE: c->hScale16= HAVE_BIGENDIAN ? hScale16_c : hScale16X_c; break;
2325         case PIX_FMT_GRAY16LE :
2326         case PIX_FMT_YUV444P9LE:
2327         case PIX_FMT_YUV420P9LE:
2328         case PIX_FMT_YUV422P10LE:
2329         case PIX_FMT_YUV420P10LE:
2330         case PIX_FMT_YUV444P10LE:
2331         case PIX_FMT_YUV420P16LE:
2332         case PIX_FMT_YUV422P16LE:
2333         case PIX_FMT_YUV444P16LE: c->hScale16= HAVE_BIGENDIAN ? hScale16X_c : hScale16_c; break;
2334     }
2335     if (c->chrSrcHSubSample) {
2336         switch(srcFormat) {
2337         case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_half_c; break;
2338         case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_half_c; break;
2339         case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_half_c; break;
2340         case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_half_c; break;
2341         case PIX_FMT_RGB32   : c->chrToYV12 = bgr32ToUV_half_c;   break;
2342         case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_half_c;  break;
2343         case PIX_FMT_BGR24   : c->chrToYV12 = bgr24ToUV_half_c;   break;
2344         case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_half_c; break;
2345         case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_half_c; break;
2346         case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_half_c; break;
2347         case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_half_c; break;
2348         case PIX_FMT_BGR32   : c->chrToYV12 = rgb32ToUV_half_c;   break;
2349         case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_half_c;  break;
2350         case PIX_FMT_RGB24   : c->chrToYV12 = rgb24ToUV_half_c;   break;
2351         case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_half_c; break;
2352         case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_half_c; break;
2353         case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_half_c; break;
2354         case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_half_c; break;
2355         }
2356     } else {
2357         switch(srcFormat) {
2358         case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_c; break;
2359         case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_c; break;
2360         case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_c; break;
2361         case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_c; break;
2362         case PIX_FMT_RGB32   : c->chrToYV12 = bgr32ToUV_c;   break;
2363         case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_c;  break;
2364         case PIX_FMT_BGR24   : c->chrToYV12 = bgr24ToUV_c;   break;
2365         case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_c; break;
2366         case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_c; break;
2367         case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_c; break;
2368         case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_c; break;
2369         case PIX_FMT_BGR32   : c->chrToYV12 = rgb32ToUV_c;   break;
2370         case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_c;  break;
2371         case PIX_FMT_RGB24   : c->chrToYV12 = rgb24ToUV_c;   break;
2372         case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_c; break;
2373         case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_c; break;
2374         case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_c; break;
2375         case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_c; break;
2376         }
2377     }
2378
2379     c->lumToYV12 = NULL;
2380     c->alpToYV12 = NULL;
2381     switch (srcFormat) {
2382     case PIX_FMT_YUYV422  :
2383     case PIX_FMT_GRAY8A   :
2384                             c->lumToYV12 = yuy2ToY_c; break;
2385     case PIX_FMT_UYVY422  :
2386                             c->lumToYV12 = uyvyToY_c;    break;
2387     case PIX_FMT_BGR24    : c->lumToYV12 = bgr24ToY_c;   break;
2388     case PIX_FMT_BGR565LE : c->lumToYV12 = bgr16leToY_c; break;
2389     case PIX_FMT_BGR565BE : c->lumToYV12 = bgr16beToY_c; break;
2390     case PIX_FMT_BGR555LE : c->lumToYV12 = bgr15leToY_c; break;
2391     case PIX_FMT_BGR555BE : c->lumToYV12 = bgr15beToY_c; break;
2392     case PIX_FMT_RGB24    : c->lumToYV12 = rgb24ToY_c;   break;
2393     case PIX_FMT_RGB565LE : c->lumToYV12 = rgb16leToY_c; break;
2394     case PIX_FMT_RGB565BE : c->lumToYV12 = rgb16beToY_c; break;
2395     case PIX_FMT_RGB555LE : c->lumToYV12 = rgb15leToY_c; break;
2396     case PIX_FMT_RGB555BE : c->lumToYV12 = rgb15beToY_c; break;
2397     case PIX_FMT_RGB8     :
2398     case PIX_FMT_BGR8     :
2399     case PIX_FMT_PAL8     :
2400     case PIX_FMT_BGR4_BYTE:
2401     case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY_c; break;
2402     case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y_c; break;
2403     case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y_c; break;
2404     case PIX_FMT_RGB32  : c->lumToYV12 = bgr32ToY_c;  break;
2405     case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY_c; break;
2406     case PIX_FMT_BGR32  : c->lumToYV12 = rgb32ToY_c;  break;
2407     case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY_c; break;
2408     case PIX_FMT_RGB48BE: c->lumToYV12 = rgb48BEToY_c; break;
2409     case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break;
2410     case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break;
2411     case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break;
2412     }
2413     if (c->alpPixBuf) {
2414         switch (srcFormat) {
2415         case PIX_FMT_BGRA:
2416         case PIX_FMT_RGBA:  c->alpToYV12 = rgbaToA_c; break;
2417         case PIX_FMT_ABGR:
2418         case PIX_FMT_ARGB:  c->alpToYV12 = abgrToA_c; break;
2419         case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
2420         case PIX_FMT_PAL8 : c->alpToYV12 = palToA_c; break;
2421         }
2422     }
2423
2424     if(isAnyRGB(c->srcFormat) || c->srcFormat == PIX_FMT_PAL8)
2425         c->hScale16= hScale16_c;
2426
2427     if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
2428         if (c->srcRange) {
2429             c->lumConvertRange = lumRangeFromJpeg_c;
2430             c->chrConvertRange = chrRangeFromJpeg_c;
2431         } else {
2432             c->lumConvertRange = lumRangeToJpeg_c;
2433             c->chrConvertRange = chrRangeToJpeg_c;
2434         }
2435     }
2436
2437     if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
2438           srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE))
2439         c->needs_hcscale = 1;
2440 }
2441
2442 SwsFunc ff_getSwsFunc(SwsContext *c)
2443 {
2444     sws_init_swScale_c(c);
2445
2446     if (HAVE_MMX)
2447         ff_sws_init_swScale_mmx(c);
2448     if (HAVE_ALTIVEC)
2449         ff_sws_init_swScale_altivec(c);
2450
2451     return swScale;
2452 }