sws: remove hScale16N() and use ronalds reformated version of it.
[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 /*
84 NOTES
85 Special versions: fast Y 1:1 scaling (no interpolation in y direction)
86
87 TODO
88 more intelligent misalignment avoidance for the horizontal scaler
89 write special vertical cubic upscale version
90 optimize C code (YV12 / minmax)
91 add support for packed pixel YUV input & output
92 add support for Y8 output
93 optimize BGR24 & BGR32
94 add BGR4 output support
95 write special BGR->BGR scaler
96 */
97
98 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_4)[2][8]={
99 {  1,   3,   1,   3,   1,   3,   1,   3, },
100 {  2,   0,   2,   0,   2,   0,   2,   0, },
101 };
102
103 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
104 {  6,   2,   6,   2,   6,   2,   6,   2, },
105 {  0,   4,   0,   4,   0,   4,   0,   4, },
106 };
107
108 DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
109 {  8,   4,  11,   7,   8,   4,  11,   7, },
110 {  2,  14,   1,  13,   2,  14,   1,  13, },
111 { 10,   6,   9,   5,  10,   6,   9,   5, },
112 {  0,  12,   3,  15,   0,  12,   3,  15, },
113 };
114
115 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
116 { 17,   9,  23,  15,  16,   8,  22,  14, },
117 {  5,  29,   3,  27,   4,  28,   2,  26, },
118 { 21,  13,  19,  11,  20,  12,  18,  10, },
119 {  0,  24,   6,  30,   1,  25,   7,  31, },
120 { 16,   8,  22,  14,  17,   9,  23,  15, },
121 {  4,  28,   2,  26,   5,  29,   3,  27, },
122 { 20,  12,  18,  10,  21,  13,  19,  11, },
123 {  1,  25,   7,  31,   0,  24,   6,  30, },
124 };
125
126 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
127 {  0,  55,  14,  68,   3,  58,  17,  72, },
128 { 37,  18,  50,  32,  40,  22,  54,  35, },
129 {  9,  64,   5,  59,  13,  67,   8,  63, },
130 { 46,  27,  41,  23,  49,  31,  44,  26, },
131 {  2,  57,  16,  71,   1,  56,  15,  70, },
132 { 39,  21,  52,  34,  38,  19,  51,  33, },
133 { 11,  66,   7,  62,  10,  65,   6,  60, },
134 { 48,  30,  43,  25,  47,  29,  42,  24, },
135 };
136
137 #if 1
138 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
139 {117,  62, 158, 103, 113,  58, 155, 100, },
140 { 34, 199,  21, 186,  31, 196,  17, 182, },
141 {144,  89, 131,  76, 141,  86, 127,  72, },
142 {  0, 165,  41, 206,  10, 175,  52, 217, },
143 {110,  55, 151,  96, 120,  65, 162, 107, },
144 { 28, 193,  14, 179,  38, 203,  24, 189, },
145 {138,  83, 124,  69, 148,  93, 134,  79, },
146 {  7, 172,  48, 213,   3, 168,  45, 210, },
147 };
148 #elif 1
149 // tries to correct a gamma of 1.5
150 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
151 {  0, 143,  18, 200,   2, 156,  25, 215, },
152 { 78,  28, 125,  64,  89,  36, 138,  74, },
153 { 10, 180,   3, 161,  16, 195,   8, 175, },
154 {109,  51,  93,  38, 121,  60, 105,  47, },
155 {  1, 152,  23, 210,   0, 147,  20, 205, },
156 { 85,  33, 134,  71,  81,  30, 130,  67, },
157 { 14, 190,   6, 171,  12, 185,   5, 166, },
158 {117,  57, 101,  44, 113,  54,  97,  41, },
159 };
160 #elif 1
161 // tries to correct a gamma of 2.0
162 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
163 {  0, 124,   8, 193,   0, 140,  12, 213, },
164 { 55,  14, 104,  42,  66,  19, 119,  52, },
165 {  3, 168,   1, 145,   6, 187,   3, 162, },
166 { 86,  31,  70,  21,  99,  39,  82,  28, },
167 {  0, 134,  11, 206,   0, 129,   9, 200, },
168 { 62,  17, 114,  48,  58,  16, 109,  45, },
169 {  5, 181,   2, 157,   4, 175,   1, 151, },
170 { 95,  36,  78,  26,  90,  34,  74,  24, },
171 };
172 #else
173 // tries to correct a gamma of 2.5
174 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
175 {  0, 107,   3, 187,   0, 125,   6, 212, },
176 { 39,   7,  86,  28,  49,  11, 102,  36, },
177 {  1, 158,   0, 131,   3, 180,   1, 151, },
178 { 68,  19,  52,  12,  81,  25,  64,  17, },
179 {  0, 119,   5, 203,   0, 113,   4, 195, },
180 { 45,   9,  96,  33,  42,   8,  91,  30, },
181 {  2, 172,   1, 144,   2, 165,   0, 137, },
182 { 77,  23,  60,  15,  72,  21,  56,  14, },
183 };
184 #endif
185 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = {
186 {  36, 68, 60, 92, 34, 66, 58, 90,},
187 { 100,  4,124, 28, 98,  2,122, 26,},
188 {  52, 84, 44, 76, 50, 82, 42, 74,},
189 { 116, 20,108, 12,114, 18,106, 10,},
190 {  32, 64, 56, 88, 38, 70, 62, 94,},
191 {  96,  0,120, 24,102,  6,126, 30,},
192 {  48, 80, 40, 72, 54, 86, 46, 78,},
193 { 112, 16,104,  8,118, 22,110, 14,},
194 };
195 DECLARE_ALIGNED(8, const uint8_t, ff_sws_pb_64)[8] =
196 {  64, 64, 64, 64, 64, 64, 64, 64 };
197
198 DECLARE_ALIGNED(8, const uint8_t, dithers)[8][8][8]={
199 {
200   {   0,  1,  0,  1,  0,  1,  0,  1,},
201   {   1,  0,  1,  0,  1,  0,  1,  0,},
202   {   0,  1,  0,  1,  0,  1,  0,  1,},
203   {   1,  0,  1,  0,  1,  0,  1,  0,},
204   {   0,  1,  0,  1,  0,  1,  0,  1,},
205   {   1,  0,  1,  0,  1,  0,  1,  0,},
206   {   0,  1,  0,  1,  0,  1,  0,  1,},
207   {   1,  0,  1,  0,  1,  0,  1,  0,},
208 },{
209   {   1,  2,  1,  2,  1,  2,  1,  2,},
210   {   3,  0,  3,  0,  3,  0,  3,  0,},
211   {   1,  2,  1,  2,  1,  2,  1,  2,},
212   {   3,  0,  3,  0,  3,  0,  3,  0,},
213   {   1,  2,  1,  2,  1,  2,  1,  2,},
214   {   3,  0,  3,  0,  3,  0,  3,  0,},
215   {   1,  2,  1,  2,  1,  2,  1,  2,},
216   {   3,  0,  3,  0,  3,  0,  3,  0,},
217 },{
218   {   2,  4,  3,  5,  2,  4,  3,  5,},
219   {   6,  0,  7,  1,  6,  0,  7,  1,},
220   {   3,  5,  2,  4,  3,  5,  2,  4,},
221   {   7,  1,  6,  0,  7,  1,  6,  0,},
222   {   2,  4,  3,  5,  2,  4,  3,  5,},
223   {   6,  0,  7,  1,  6,  0,  7,  1,},
224   {   3,  5,  2,  4,  3,  5,  2,  4,},
225   {   7,  1,  6,  0,  7,  1,  6,  0,},
226 },{
227   {   4,  8,  7, 11,  4,  8,  7, 11,},
228   {  12,  0, 15,  3, 12,  0, 15,  3,},
229   {   6, 10,  5,  9,  6, 10,  5,  9,},
230   {  14,  2, 13,  1, 14,  2, 13,  1,},
231   {   4,  8,  7, 11,  4,  8,  7, 11,},
232   {  12,  0, 15,  3, 12,  0, 15,  3,},
233   {   6, 10,  5,  9,  6, 10,  5,  9,},
234   {  14,  2, 13,  1, 14,  2, 13,  1,},
235 },{
236   {   9, 17, 15, 23,  8, 16, 14, 22,},
237   {  25,  1, 31,  7, 24,  0, 30,  6,},
238   {  13, 21, 11, 19, 12, 20, 10, 18,},
239   {  29,  5, 27,  3, 28,  4, 26,  2,},
240   {   8, 16, 14, 22,  9, 17, 15, 23,},
241   {  24,  0, 30,  6, 25,  1, 31,  7,},
242   {  12, 20, 10, 18, 13, 21, 11, 19,},
243   {  28,  4, 26,  2, 29,  5, 27,  3,},
244 },{
245   {  18, 34, 30, 46, 17, 33, 29, 45,},
246   {  50,  2, 62, 14, 49,  1, 61, 13,},
247   {  26, 42, 22, 38, 25, 41, 21, 37,},
248   {  58, 10, 54,  6, 57,  9, 53,  5,},
249   {  16, 32, 28, 44, 19, 35, 31, 47,},
250   {  48,  0, 60, 12, 51,  3, 63, 15,},
251   {  24, 40, 20, 36, 27, 43, 23, 39,},
252   {  56,  8, 52,  4, 59, 11, 55,  7,},
253 },{
254   {  18, 34, 30, 46, 17, 33, 29, 45,},
255   {  50,  2, 62, 14, 49,  1, 61, 13,},
256   {  26, 42, 22, 38, 25, 41, 21, 37,},
257   {  58, 10, 54,  6, 57,  9, 53,  5,},
258   {  16, 32, 28, 44, 19, 35, 31, 47,},
259   {  48,  0, 60, 12, 51,  3, 63, 15,},
260   {  24, 40, 20, 36, 27, 43, 23, 39,},
261   {  56,  8, 52,  4, 59, 11, 55,  7,},
262 },{
263   {  36, 68, 60, 92, 34, 66, 58, 90,},
264   { 100,  4,124, 28, 98,  2,122, 26,},
265   {  52, 84, 44, 76, 50, 82, 42, 74,},
266   { 116, 20,108, 12,114, 18,106, 10,},
267   {  32, 64, 56, 88, 38, 70, 62, 94,},
268   {  96,  0,120, 24,102,  6,126, 30,},
269   {  48, 80, 40, 72, 54, 86, 46, 78,},
270   { 112, 16,104,  8,118, 22,110, 14,},
271 }};
272
273 static const uint8_t flat64[8]={64,64,64,64,64,64,64,64};
274
275 const uint16_t dither_scale[15][16]={
276 {    2,    3,    3,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,},
277 {    2,    3,    7,    7,   13,   13,   25,   25,   25,   25,   25,   25,   25,   25,   25,   25,},
278 {    3,    3,    4,   15,   15,   29,   57,   57,   57,  113,  113,  113,  113,  113,  113,  113,},
279 {    3,    4,    4,    5,   31,   31,   61,  121,  241,  241,  241,  241,  481,  481,  481,  481,},
280 {    3,    4,    5,    5,    6,   63,   63,  125,  249,  497,  993,  993,  993,  993,  993, 1985,},
281 {    3,    5,    6,    6,    6,    7,  127,  127,  253,  505, 1009, 2017, 4033, 4033, 4033, 4033,},
282 {    3,    5,    6,    7,    7,    7,    8,  255,  255,  509, 1017, 2033, 4065, 8129,16257,16257,},
283 {    3,    5,    6,    8,    8,    8,    8,    9,  511,  511, 1021, 2041, 4081, 8161,16321,32641,},
284 {    3,    5,    7,    8,    9,    9,    9,    9,   10, 1023, 1023, 2045, 4089, 8177,16353,32705,},
285 {    3,    5,    7,    8,   10,   10,   10,   10,   10,   11, 2047, 2047, 4093, 8185,16369,32737,},
286 {    3,    5,    7,    8,   10,   11,   11,   11,   11,   11,   12, 4095, 4095, 8189,16377,32753,},
287 {    3,    5,    7,    9,   10,   12,   12,   12,   12,   12,   12,   13, 8191, 8191,16381,32761,},
288 {    3,    5,    7,    9,   10,   12,   13,   13,   13,   13,   13,   13,   14,16383,16383,32765,},
289 {    3,    5,    7,    9,   10,   12,   14,   14,   14,   14,   14,   14,   14,   15,32767,32767,},
290 {    3,    5,    7,    9,   11,   12,   14,   15,   15,   15,   15,   15,   15,   15,   16,65535,},
291 };
292
293 static av_always_inline void
294 yuv2yuvX16_c_template(const int16_t *lumFilter, const int32_t **lumSrc,
295                       int lumFilterSize, const int16_t *chrFilter,
296                       const int32_t **chrUSrc, const int32_t **chrVSrc,
297                       int chrFilterSize, const int32_t **alpSrc,
298                       uint16_t *dest[4], 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 dword= output_bits == 16;
304     uint16_t *yDest = dest[0], *uDest = dest[1], *vDest = dest[2],
305              *aDest = CONFIG_SWSCALE_ALPHA ? dest[3] : NULL;
306     int shift = 11 + 4*dword + 16 - output_bits - 1;
307
308 #define output_pixel(pos, val) \
309     if (big_endian) { \
310         AV_WB16(pos, av_clip_uint16(val >> shift)); \
311     } else { \
312         AV_WL16(pos, av_clip_uint16(val >> shift)); \
313     }
314     for (i = 0; i < dstW; i++) {
315         int val = 1 << (26-output_bits + 4*dword - 1);
316         int j;
317
318         for (j = 0; j < lumFilterSize; j++)
319             val += ((dword ? lumSrc[j][i] : ((int16_t**)lumSrc)[j][i]) * lumFilter[j])>>1;
320
321         output_pixel(&yDest[i], val);
322     }
323
324     if (uDest) {
325         for (i = 0; i < chrDstW; i++) {
326             int u = 1 << (26-output_bits + 4*dword - 1);
327             int v = 1 << (26-output_bits + 4*dword - 1);
328             int j;
329
330             for (j = 0; j < chrFilterSize; j++) {
331                 u += ((dword ? chrUSrc[j][i] : ((int16_t**)chrUSrc)[j][i]) * chrFilter[j]) >> 1;
332                 v += ((dword ? chrVSrc[j][i] : ((int16_t**)chrVSrc)[j][i]) * chrFilter[j]) >> 1;
333             }
334
335             output_pixel(&uDest[i], u);
336             output_pixel(&vDest[i], v);
337         }
338     }
339
340     if (CONFIG_SWSCALE_ALPHA && aDest) {
341         for (i = 0; i < dstW; i++) {
342             int val = 1 << (26-output_bits + 4*dword - 1);
343             int j;
344
345             for (j = 0; j < lumFilterSize; j++)
346                 val += ((dword ? alpSrc[j][i] : ((int16_t**)alpSrc)[j][i]) * lumFilter[j]) >> 1;
347
348             output_pixel(&aDest[i], val);
349         }
350     }
351 #undef output_pixel
352 }
353
354 static av_always_inline void
355 yuv2yuvX10_c_template(const int16_t *lumFilter, const int16_t **lumSrc,
356                       int lumFilterSize, const int16_t *chrFilter,
357                       const int16_t **chrUSrc, const int16_t **chrVSrc,
358                       int chrFilterSize, const int16_t **alpSrc,
359                       uint16_t *dest[4], int dstW, int chrDstW,
360                       int big_endian, int output_bits)
361 {
362     //FIXME Optimize (just quickly written not optimized..)
363     int i;
364     uint16_t *yDest = dest[0], *uDest = dest[1], *vDest = dest[2],
365              *aDest = CONFIG_SWSCALE_ALPHA ? dest[3] : NULL;
366     int shift = 11 + 16 - output_bits - 1;
367
368 #define output_pixel(pos, val) \
369     if (big_endian) { \
370         AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
371     } else { \
372         AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
373     }
374     for (i = 0; i < dstW; i++) {
375         int val = 1 << (26-output_bits - 1);
376         int j;
377
378         for (j = 0; j < lumFilterSize; j++)
379             val += (lumSrc[j][i] * lumFilter[j]) >> 1;
380
381         output_pixel(&yDest[i], val);
382     }
383
384     if (uDest) {
385         for (i = 0; i < chrDstW; i++) {
386             int u = 1 << (26-output_bits - 1);
387             int v = 1 << (26-output_bits - 1);
388             int j;
389
390             for (j = 0; j < chrFilterSize; j++) {
391                 u += (chrUSrc[j][i] * chrFilter[j]) >> 1;
392                 v += (chrVSrc[j][i] * chrFilter[j]) >> 1;
393             }
394
395             output_pixel(&uDest[i], u);
396             output_pixel(&vDest[i], v);
397         }
398     }
399
400     if (CONFIG_SWSCALE_ALPHA && aDest) {
401         for (i = 0; i < dstW; i++) {
402             int val = 1 << (26-output_bits - 1);
403             int j;
404
405             for (j = 0; j < lumFilterSize; j++)
406                 val += (alpSrc[j][i] * lumFilter[j]) >> 1;
407
408             output_pixel(&aDest[i], val);
409         }
410     }
411 #undef output_pixel
412 }
413
414 #define yuv2NBPS(bits, BE_LE, is_be, yuv2yuvX_template_fn, typeX_t) \
415 static void yuv2yuvX ## bits ## BE_LE ## _c(SwsContext *c, const int16_t *lumFilter, \
416                               const int16_t **_lumSrc, int lumFilterSize, \
417                               const int16_t *chrFilter, const int16_t **_chrUSrc, \
418                               const int16_t **_chrVSrc, \
419                               int chrFilterSize, const int16_t **_alpSrc, \
420                               uint8_t *_dest[4], int dstW, int chrDstW) \
421 { \
422     const typeX_t **lumSrc  = (const typeX_t **) _lumSrc, \
423                   **chrUSrc = (const typeX_t **) _chrUSrc, \
424                   **chrVSrc = (const typeX_t **) _chrVSrc, \
425                   **alpSrc  = (const typeX_t **) _alpSrc; \
426     yuv2yuvX_template_fn(lumFilter, lumSrc, lumFilterSize, \
427                          chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
428                          alpSrc, (uint16_t **) _dest, \
429                          dstW, chrDstW, is_be, bits); \
430 }
431 yuv2NBPS( 9, BE, 1, yuv2yuvX10_c_template, int16_t);
432 yuv2NBPS( 9, LE, 0, yuv2yuvX10_c_template, int16_t);
433 yuv2NBPS(10, BE, 1, yuv2yuvX10_c_template, int16_t);
434 yuv2NBPS(10, LE, 0, yuv2yuvX10_c_template, int16_t);
435 yuv2NBPS(16, BE, 1, yuv2yuvX16_c_template, int32_t);
436 yuv2NBPS(16, LE, 0, yuv2yuvX16_c_template, int32_t);
437
438 static void yuv2yuvX_c(SwsContext *c, const int16_t *lumFilter,
439                        const int16_t **lumSrc, int lumFilterSize,
440                        const int16_t *chrFilter, const int16_t **chrUSrc,
441                        const int16_t **chrVSrc,
442                        int chrFilterSize, const int16_t **alpSrc,
443                        uint8_t *dest[4], int dstW, int chrDstW)
444 {
445     uint8_t *yDest = dest[0], *uDest = dest[1], *vDest = dest[2],
446             *aDest = CONFIG_SWSCALE_ALPHA ? dest[3] : NULL;
447     int i;
448     const uint8_t *lumDither = c->lumDither8, *chrDither = c->chrDither8;
449
450     //FIXME Optimize (just quickly written not optimized..)
451     for (i=0; i<dstW; i++) {
452         int val = lumDither[i & 7] << 12;
453         int j;
454         for (j=0; j<lumFilterSize; j++)
455             val += lumSrc[j][i] * lumFilter[j];
456
457         yDest[i]= av_clip_uint8(val>>19);
458     }
459
460     if (uDest)
461         for (i=0; i<chrDstW; i++) {
462             int u = chrDither[i & 7] << 12;
463             int v = chrDither[(i + 3) & 7] << 12;
464             int j;
465             for (j=0; j<chrFilterSize; j++) {
466                 u += chrUSrc[j][i] * chrFilter[j];
467                 v += chrVSrc[j][i] * chrFilter[j];
468             }
469
470             uDest[i]= av_clip_uint8(u>>19);
471             vDest[i]= av_clip_uint8(v>>19);
472         }
473
474     if (CONFIG_SWSCALE_ALPHA && aDest)
475         for (i=0; i<dstW; i++) {
476             int val = lumDither[i & 7] << 12;
477             int j;
478             for (j=0; j<lumFilterSize; j++)
479                 val += alpSrc[j][i] * lumFilter[j];
480
481             aDest[i]= av_clip_uint8(val>>19);
482         }
483 }
484
485 static void yuv2yuv1_c(SwsContext *c, const int16_t *lumSrc,
486                        const int16_t *chrUSrc, const int16_t *chrVSrc,
487                        const int16_t *alpSrc,
488                        uint8_t *dest[4], int dstW, int chrDstW)
489 {
490     uint8_t *yDest = dest[0], *uDest = dest[1], *vDest = dest[2],
491             *aDest = CONFIG_SWSCALE_ALPHA ? dest[3] : NULL;
492     int i;
493     const uint8_t *lumDither = c->lumDither8, *chrDither = c->chrDither8;
494
495     for (i=0; i<dstW; i++) {
496         int val = (lumSrc[i]+  lumDither[i & 7]) >> 7;
497         yDest[i]= av_clip_uint8(val);
498     }
499
500     if (uDest)
501         for (i=0; i<chrDstW; i++) {
502             int u = (chrUSrc[i] + chrDither[i & 7])       >> 7;
503             int v = (chrVSrc[i] + chrDither[(i + 3) & 7]) >> 7;
504             uDest[i]= av_clip_uint8(u);
505             vDest[i]= av_clip_uint8(v);
506         }
507
508     if (CONFIG_SWSCALE_ALPHA && aDest)
509         for (i=0; i<dstW; i++) {
510             int val = (alpSrc[i] + lumDither[i & 7]) >> 7;
511             aDest[i]= av_clip_uint8(val);
512         }
513 }
514
515 static void yuv2nv12X_c(SwsContext *c, const int16_t *lumFilter,
516                         const int16_t **lumSrc, int lumFilterSize,
517                         const int16_t *chrFilter, const int16_t **chrUSrc,
518                         const int16_t **chrVSrc, int chrFilterSize,
519                         const int16_t **alpSrc, uint8_t *dest[4],
520                         int dstW, int chrDstW)
521 {
522     uint8_t *yDest = dest[0], *uDest = dest[1];
523     enum PixelFormat dstFormat = c->dstFormat;
524     const uint8_t *lumDither = c->lumDither8, *chrDither = c->chrDither8;
525
526     //FIXME Optimize (just quickly written not optimized..)
527     int i;
528     for (i=0; i<dstW; i++) {
529         int val = lumDither[i & 7] << 12;
530         int j;
531         for (j=0; j<lumFilterSize; j++)
532             val += lumSrc[j][i] * lumFilter[j];
533
534         yDest[i]= av_clip_uint8(val>>19);
535     }
536
537     if (!uDest)
538         return;
539
540     if (dstFormat == PIX_FMT_NV12)
541         for (i=0; i<chrDstW; i++) {
542             int u = chrDither[i & 7] << 12;
543             int v = chrDither[(i + 3) & 7] << 12;
544             int j;
545             for (j=0; j<chrFilterSize; j++) {
546                 u += chrUSrc[j][i] * chrFilter[j];
547                 v += chrVSrc[j][i] * chrFilter[j];
548             }
549
550             uDest[2*i]= av_clip_uint8(u>>19);
551             uDest[2*i+1]= av_clip_uint8(v>>19);
552         }
553     else
554         for (i=0; i<chrDstW; i++) {
555             int u = chrDither[i & 7] << 12;
556             int v = chrDither[(i + 3) & 7] << 12;
557             int j;
558             for (j=0; j<chrFilterSize; j++) {
559                 u += chrUSrc[j][i] * chrFilter[j];
560                 v += chrVSrc[j][i] * chrFilter[j];
561             }
562
563             uDest[2*i]= av_clip_uint8(v>>19);
564             uDest[2*i+1]= av_clip_uint8(u>>19);
565         }
566 }
567
568 #define output_pixel(pos, val) \
569         if (target == PIX_FMT_GRAY16BE) { \
570             AV_WB16(pos, val); \
571         } else { \
572             AV_WL16(pos, val); \
573         }
574
575 static av_always_inline void
576 yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter,
577                         const int32_t **lumSrc, int lumFilterSize,
578                         const int16_t *chrFilter, const int32_t **chrUSrc,
579                         const int32_t **chrVSrc, int chrFilterSize,
580                         const int32_t **alpSrc, uint16_t *dest, int dstW,
581                         int y, enum PixelFormat target)
582 {
583     int i;
584
585     for (i = 0; i < (dstW >> 1); i++) {
586         int j;
587         int Y1 = 1 << 14;
588         int Y2 = 1 << 14;
589
590         for (j = 0; j < lumFilterSize; j++) {
591             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
592             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
593         }
594         Y1 >>= 15;
595         Y2 >>= 15;
596         if ((Y1 | Y2) & 0x10000) {
597             Y1 = av_clip_uint16(Y1);
598             Y2 = av_clip_uint16(Y2);
599         }
600         output_pixel(&dest[i * 2 + 0], Y1);
601         output_pixel(&dest[i * 2 + 1], Y2);
602     }
603 }
604
605 static av_always_inline void
606 yuv2gray16_2_c_template(SwsContext *c, const int32_t *buf[2],
607                         const int32_t *ubuf[2], const int32_t *vbuf[2],
608                         const int32_t *abuf[2], uint16_t *dest, int dstW,
609                         int yalpha, int uvalpha, int y,
610                         enum PixelFormat target)
611 {
612     int  yalpha1 = 4095 - yalpha;
613     int i;
614     const int32_t *buf0 = buf[0], *buf1 = buf[1];
615
616     for (i = 0; i < (dstW >> 1); i++) {
617         int Y1 = (buf0[i * 2    ] * yalpha1 + buf1[i * 2    ] * yalpha) >> 15;
618         int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 15;
619
620         output_pixel(&dest[i * 2 + 0], Y1);
621         output_pixel(&dest[i * 2 + 1], Y2);
622     }
623 }
624
625 static av_always_inline void
626 yuv2gray16_1_c_template(SwsContext *c, const int32_t *buf0,
627                         const int32_t *ubuf[2], const int32_t *vbuf[2],
628                         const int32_t *abuf0, uint16_t *dest, int dstW,
629                         int uvalpha, int y, enum PixelFormat target)
630 {
631     int i;
632
633     for (i = 0; i < (dstW >> 1); i++) {
634         int Y1 = (buf0[i * 2    ]+4)>>3;
635         int Y2 = (buf0[i * 2 + 1]+4)>>3;
636
637         output_pixel(&dest[i * 2 + 0], Y1);
638         output_pixel(&dest[i * 2 + 1], Y2);
639     }
640 }
641
642 #undef output_pixel
643
644 #define YUV2PACKED16WRAPPER(name, base, ext, fmt) \
645 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
646                         const int16_t **_lumSrc, int lumFilterSize, \
647                         const int16_t *chrFilter, const int16_t **_chrUSrc, \
648                         const int16_t **_chrVSrc, int chrFilterSize, \
649                         const int16_t **_alpSrc, uint8_t *_dest, int dstW, \
650                         int y) \
651 { \
652     const int32_t **lumSrc  = (const int32_t **) _lumSrc, \
653                   **chrUSrc = (const int32_t **) _chrUSrc, \
654                   **chrVSrc = (const int32_t **) _chrVSrc, \
655                   **alpSrc  = (const int32_t **) _alpSrc; \
656     uint16_t *dest = (uint16_t *) _dest; \
657     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
658                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
659                           alpSrc, dest, dstW, y, fmt); \
660 } \
661  \
662 static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \
663                         const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
664                         const int16_t *_abuf[2], uint8_t *_dest, int dstW, \
665                         int yalpha, int uvalpha, int y) \
666 { \
667     const int32_t **buf  = (const int32_t **) _buf, \
668                   **ubuf = (const int32_t **) _ubuf, \
669                   **vbuf = (const int32_t **) _vbuf, \
670                   **abuf = (const int32_t **) _abuf; \
671     uint16_t *dest = (uint16_t *) _dest; \
672     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
673                           dest, dstW, yalpha, uvalpha, y, fmt); \
674 } \
675  \
676 static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \
677                         const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
678                         const int16_t *_abuf0, uint8_t *_dest, int dstW, \
679                         int uvalpha, int y) \
680 { \
681     const int32_t *buf0  = (const int32_t *)  _buf0, \
682                  **ubuf  = (const int32_t **) _ubuf, \
683                  **vbuf  = (const int32_t **) _vbuf, \
684                   *abuf0 = (const int32_t *)  _abuf0; \
685     uint16_t *dest = (uint16_t *) _dest; \
686     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
687                                   dstW, uvalpha, y, fmt); \
688 }
689
690 YUV2PACKED16WRAPPER(yuv2gray16,, LE, PIX_FMT_GRAY16LE);
691 YUV2PACKED16WRAPPER(yuv2gray16,, BE, PIX_FMT_GRAY16BE);
692
693 #define output_pixel(pos, acc) \
694     if (target == PIX_FMT_MONOBLACK) { \
695         pos = acc; \
696     } else { \
697         pos = ~acc; \
698     }
699
700 static av_always_inline void
701 yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
702                       const int16_t **lumSrc, int lumFilterSize,
703                       const int16_t *chrFilter, const int16_t **chrUSrc,
704                       const int16_t **chrVSrc, int chrFilterSize,
705                       const int16_t **alpSrc, uint8_t *dest, int dstW,
706                       int y, enum PixelFormat target)
707 {
708     const uint8_t * const d128=dither_8x8_220[y&7];
709     uint8_t *g = c->table_gU[128] + c->table_gV[128];
710     int i;
711     int acc = 0;
712
713     for (i = 0; i < dstW - 1; i += 2) {
714         int j;
715         int Y1 = 1 << 18;
716         int Y2 = 1 << 18;
717
718         for (j = 0; j < lumFilterSize; j++) {
719             Y1 += lumSrc[j][i]   * lumFilter[j];
720             Y2 += lumSrc[j][i+1] * lumFilter[j];
721         }
722         Y1 >>= 19;
723         Y2 >>= 19;
724         if ((Y1 | Y2) & 0x100) {
725             Y1 = av_clip_uint8(Y1);
726             Y2 = av_clip_uint8(Y2);
727         }
728         acc += acc + g[Y1 + d128[(i + 0) & 7]];
729         acc += acc + g[Y2 + d128[(i + 1) & 7]];
730         if ((i & 7) == 6) {
731             output_pixel(*dest++, acc);
732         }
733     }
734 }
735
736 static av_always_inline void
737 yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2],
738                       const int16_t *ubuf[2], const int16_t *vbuf[2],
739                       const int16_t *abuf[2], uint8_t *dest, int dstW,
740                       int yalpha, int uvalpha, int y,
741                       enum PixelFormat target)
742 {
743     const int16_t *buf0  = buf[0],  *buf1  = buf[1];
744     const uint8_t * const d128 = dither_8x8_220[y & 7];
745     uint8_t *g = c->table_gU[128] + c->table_gV[128];
746     int  yalpha1 = 4095 - yalpha;
747     int i;
748
749     for (i = 0; i < dstW - 7; i += 8) {
750         int acc =    g[((buf0[i    ] * yalpha1 + buf1[i    ] * yalpha) >> 19) + d128[0]];
751         acc += acc + g[((buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19) + d128[1]];
752         acc += acc + g[((buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19) + d128[2]];
753         acc += acc + g[((buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19) + d128[3]];
754         acc += acc + g[((buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19) + d128[4]];
755         acc += acc + g[((buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19) + d128[5]];
756         acc += acc + g[((buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19) + d128[6]];
757         acc += acc + g[((buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19) + d128[7]];
758         output_pixel(*dest++, acc);
759     }
760 }
761
762 static av_always_inline void
763 yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0,
764                       const int16_t *ubuf[2], const int16_t *vbuf[2],
765                       const int16_t *abuf0, uint8_t *dest, int dstW,
766                       int uvalpha, int y, enum PixelFormat target)
767 {
768     const uint8_t * const d128 = dither_8x8_220[y & 7];
769     uint8_t *g = c->table_gU[128] + c->table_gV[128];
770     int i;
771
772     for (i = 0; i < dstW - 7; i += 8) {
773         int acc =    g[(buf0[i    ] >> 7) + d128[0]];
774         acc += acc + g[(buf0[i + 1] >> 7) + d128[1]];
775         acc += acc + g[(buf0[i + 2] >> 7) + d128[2]];
776         acc += acc + g[(buf0[i + 3] >> 7) + d128[3]];
777         acc += acc + g[(buf0[i + 4] >> 7) + d128[4]];
778         acc += acc + g[(buf0[i + 5] >> 7) + d128[5]];
779         acc += acc + g[(buf0[i + 6] >> 7) + d128[6]];
780         acc += acc + g[(buf0[i + 7] >> 7) + d128[7]];
781         output_pixel(*dest++, acc);
782     }
783 }
784
785 #undef output_pixel
786
787 #define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
788 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
789                                 const int16_t **lumSrc, int lumFilterSize, \
790                                 const int16_t *chrFilter, const int16_t **chrUSrc, \
791                                 const int16_t **chrVSrc, int chrFilterSize, \
792                                 const int16_t **alpSrc, uint8_t *dest, int dstW, \
793                                 int y) \
794 { \
795     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
796                                   chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
797                                   alpSrc, dest, dstW, y, fmt); \
798 } \
799  \
800 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
801                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
802                                 const int16_t *abuf[2], uint8_t *dest, int dstW, \
803                                 int yalpha, int uvalpha, int y) \
804 { \
805     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
806                                   dest, dstW, yalpha, uvalpha, y, fmt); \
807 } \
808  \
809 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
810                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
811                                 const int16_t *abuf0, uint8_t *dest, int dstW, \
812                                 int uvalpha, int y) \
813 { \
814     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, \
815                                   abuf0, dest, dstW, uvalpha, \
816                                   y, fmt); \
817 }
818
819 YUV2PACKEDWRAPPER(yuv2mono,, white, PIX_FMT_MONOWHITE);
820 YUV2PACKEDWRAPPER(yuv2mono,, black, PIX_FMT_MONOBLACK);
821
822 #define output_pixels(pos, Y1, U, Y2, V) \
823     if (target == PIX_FMT_YUYV422) { \
824         dest[pos + 0] = Y1; \
825         dest[pos + 1] = U;  \
826         dest[pos + 2] = Y2; \
827         dest[pos + 3] = V;  \
828     } else { \
829         dest[pos + 0] = U;  \
830         dest[pos + 1] = Y1; \
831         dest[pos + 2] = V;  \
832         dest[pos + 3] = Y2; \
833     }
834
835 static av_always_inline void
836 yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
837                      const int16_t **lumSrc, int lumFilterSize,
838                      const int16_t *chrFilter, const int16_t **chrUSrc,
839                      const int16_t **chrVSrc, int chrFilterSize,
840                      const int16_t **alpSrc, uint8_t *dest, int dstW,
841                      int y, enum PixelFormat target)
842 {
843     int i;
844
845     for (i = 0; i < (dstW >> 1); i++) {
846         int j;
847         int Y1 = 1 << 18;
848         int Y2 = 1 << 18;
849         int U  = 1 << 18;
850         int V  = 1 << 18;
851
852         for (j = 0; j < lumFilterSize; j++) {
853             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
854             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
855         }
856         for (j = 0; j < chrFilterSize; j++) {
857             U += chrUSrc[j][i] * chrFilter[j];
858             V += chrVSrc[j][i] * chrFilter[j];
859         }
860         Y1 >>= 19;
861         Y2 >>= 19;
862         U  >>= 19;
863         V  >>= 19;
864         if ((Y1 | Y2 | U | V) & 0x100) {
865             Y1 = av_clip_uint8(Y1);
866             Y2 = av_clip_uint8(Y2);
867             U  = av_clip_uint8(U);
868             V  = av_clip_uint8(V);
869         }
870         output_pixels(4*i, Y1, U, Y2, V);
871     }
872 }
873
874 static av_always_inline void
875 yuv2422_2_c_template(SwsContext *c, const int16_t *buf[2],
876                      const int16_t *ubuf[2], const int16_t *vbuf[2],
877                      const int16_t *abuf[2], uint8_t *dest, int dstW,
878                      int yalpha, int uvalpha, int y,
879                      enum PixelFormat target)
880 {
881     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
882                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
883                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
884     int  yalpha1 = 4095 - yalpha;
885     int uvalpha1 = 4095 - uvalpha;
886     int i;
887
888     for (i = 0; i < (dstW >> 1); i++) {
889         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
890         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
891         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
892         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
893
894         output_pixels(i * 4, Y1, U, Y2, V);
895     }
896 }
897
898 static av_always_inline void
899 yuv2422_1_c_template(SwsContext *c, const int16_t *buf0,
900                      const int16_t *ubuf[2], const int16_t *vbuf[2],
901                      const int16_t *abuf0, uint8_t *dest, int dstW,
902                      int uvalpha, int y, enum PixelFormat target)
903 {
904     const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
905                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
906     int i;
907
908     if (uvalpha < 2048) {
909         for (i = 0; i < (dstW >> 1); i++) {
910             int Y1 = buf0[i * 2]     >> 7;
911             int Y2 = buf0[i * 2 + 1] >> 7;
912             int U  = ubuf1[i]        >> 7;
913             int V  = vbuf1[i]        >> 7;
914
915             output_pixels(i * 4, Y1, U, Y2, V);
916         }
917     } else {
918         for (i = 0; i < (dstW >> 1); i++) {
919             int Y1 =  buf0[i * 2]          >> 7;
920             int Y2 =  buf0[i * 2 + 1]      >> 7;
921             int U  = (ubuf0[i] + ubuf1[i]) >> 8;
922             int V  = (vbuf0[i] + vbuf1[i]) >> 8;
923
924             output_pixels(i * 4, Y1, U, Y2, V);
925         }
926     }
927 }
928
929 #undef output_pixels
930
931 YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, PIX_FMT_YUYV422);
932 YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, PIX_FMT_UYVY422);
933
934 #define R_B ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? R : B)
935 #define B_R ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? B : R)
936 #define output_pixel(pos, val) \
937     if (isBE(target)) { \
938         AV_WB16(pos, val); \
939     } else { \
940         AV_WL16(pos, val); \
941     }
942
943 static av_always_inline void
944 yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
945                        const int32_t **lumSrc, int lumFilterSize,
946                        const int16_t *chrFilter, const int32_t **chrUSrc,
947                        const int32_t **chrVSrc, int chrFilterSize,
948                        const int32_t **alpSrc, uint16_t *dest, int dstW,
949                        int y, enum PixelFormat target)
950 {
951     int i;
952
953     for (i = 0; i < (dstW >> 1); i++) {
954         int j;
955         int Y1 = 0;
956         int Y2 = 0;
957         int U  = -128 << 23; // 19
958         int V  = -128 << 23;
959         int R, G, B;
960
961         for (j = 0; j < lumFilterSize; j++) {
962             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
963             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
964         }
965         for (j = 0; j < chrFilterSize; j++) {
966             U += chrUSrc[j][i] * chrFilter[j];
967             V += chrVSrc[j][i] * chrFilter[j];
968         }
969
970         // 8bit: 12+15=27; 16-bit: 12+19=31
971         Y1 >>= 14; // 10
972         Y2 >>= 14;
973         U  >>= 14;
974         V  >>= 14;
975
976         // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
977         Y1 -= c->yuv2rgb_y_offset;
978         Y2 -= c->yuv2rgb_y_offset;
979         Y1 *= c->yuv2rgb_y_coeff;
980         Y2 *= c->yuv2rgb_y_coeff;
981         Y1 += 1 << 13; // 21
982         Y2 += 1 << 13;
983         // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
984
985         R = V * c->yuv2rgb_v2r_coeff;
986         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
987         B =                            U * c->yuv2rgb_u2b_coeff;
988
989         // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
990         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
991         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
992         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
993         output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
994         output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
995         output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
996         dest += 6;
997     }
998 }
999
1000 static av_always_inline void
1001 yuv2rgb48_2_c_template(SwsContext *c, const int32_t *buf[2],
1002                        const int32_t *ubuf[2], const int32_t *vbuf[2],
1003                        const int32_t *abuf[2], uint16_t *dest, int dstW,
1004                        int yalpha, int uvalpha, int y,
1005                        enum PixelFormat target)
1006 {
1007     const int32_t *buf0  = buf[0],  *buf1  = buf[1],
1008                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1009                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
1010     int  yalpha1 = 4095 - yalpha;
1011     int uvalpha1 = 4095 - uvalpha;
1012     int i;
1013
1014     for (i = 0; i < (dstW >> 1); i++) {
1015         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha) >> 14;
1016         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha) >> 14;
1017         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha + (-128 << 23)) >> 14;
1018         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha + (-128 << 23)) >> 14;
1019         int R, G, B;
1020
1021         Y1 -= c->yuv2rgb_y_offset;
1022         Y2 -= c->yuv2rgb_y_offset;
1023         Y1 *= c->yuv2rgb_y_coeff;
1024         Y2 *= c->yuv2rgb_y_coeff;
1025         Y1 += 1 << 13;
1026         Y2 += 1 << 13;
1027
1028         R = V * c->yuv2rgb_v2r_coeff;
1029         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
1030         B =                            U * c->yuv2rgb_u2b_coeff;
1031
1032         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
1033         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
1034         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
1035         output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
1036         output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
1037         output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
1038         dest += 6;
1039     }
1040 }
1041
1042 static av_always_inline void
1043 yuv2rgb48_1_c_template(SwsContext *c, const int32_t *buf0,
1044                        const int32_t *ubuf[2], const int32_t *vbuf[2],
1045                        const int32_t *abuf0, uint16_t *dest, int dstW,
1046                        int uvalpha, int y, enum PixelFormat target)
1047 {
1048     const int32_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1049                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
1050     int i;
1051
1052     if (uvalpha < 2048) {
1053         for (i = 0; i < (dstW >> 1); i++) {
1054             int Y1 = (buf0[i * 2]    ) >> 2;
1055             int Y2 = (buf0[i * 2 + 1]) >> 2;
1056             int U  = (ubuf0[i] + (-128 << 11)) >> 2;
1057             int V  = (vbuf0[i] + (-128 << 11)) >> 2;
1058             int R, G, B;
1059
1060             Y1 -= c->yuv2rgb_y_offset;
1061             Y2 -= c->yuv2rgb_y_offset;
1062             Y1 *= c->yuv2rgb_y_coeff;
1063             Y2 *= c->yuv2rgb_y_coeff;
1064             Y1 += 1 << 13;
1065             Y2 += 1 << 13;
1066
1067             R = V * c->yuv2rgb_v2r_coeff;
1068             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
1069             B =                            U * c->yuv2rgb_u2b_coeff;
1070
1071             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
1072             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
1073             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
1074             output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
1075             output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
1076             output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
1077             dest += 6;
1078         }
1079     } else {
1080         for (i = 0; i < (dstW >> 1); i++) {
1081             int Y1 = (buf0[i * 2]    ) >> 2;
1082             int Y2 = (buf0[i * 2 + 1]) >> 2;
1083             int U  = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
1084             int V  = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
1085             int R, G, B;
1086
1087             Y1 -= c->yuv2rgb_y_offset;
1088             Y2 -= c->yuv2rgb_y_offset;
1089             Y1 *= c->yuv2rgb_y_coeff;
1090             Y2 *= c->yuv2rgb_y_coeff;
1091             Y1 += 1 << 13;
1092             Y2 += 1 << 13;
1093
1094             R = V * c->yuv2rgb_v2r_coeff;
1095             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
1096             B =                            U * c->yuv2rgb_u2b_coeff;
1097
1098             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
1099             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
1100             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
1101             output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
1102             output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
1103             output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
1104             dest += 6;
1105         }
1106     }
1107 }
1108
1109 #undef output_pixel
1110 #undef r_b
1111 #undef b_r
1112
1113 YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48be, PIX_FMT_RGB48BE);
1114 YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, PIX_FMT_RGB48LE);
1115 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, PIX_FMT_BGR48BE);
1116 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, PIX_FMT_BGR48LE);
1117
1118 static av_always_inline void
1119 yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2,
1120               int U, int V, int A1, int A2,
1121               const void *_r, const void *_g, const void *_b, int y,
1122               enum PixelFormat target, int hasAlpha)
1123 {
1124     if (target == PIX_FMT_ARGB || target == PIX_FMT_RGBA ||
1125         target == PIX_FMT_ABGR || target == PIX_FMT_BGRA) {
1126         uint32_t *dest = (uint32_t *) _dest;
1127         const uint32_t *r = (const uint32_t *) _r;
1128         const uint32_t *g = (const uint32_t *) _g;
1129         const uint32_t *b = (const uint32_t *) _b;
1130
1131 #if CONFIG_SMALL
1132         int sh = hasAlpha ? ((target == PIX_FMT_RGB32_1 || target == PIX_FMT_BGR32_1) ? 0 : 24) : 0;
1133
1134         dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0);
1135         dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0);
1136 #else
1137         if (hasAlpha) {
1138             int sh = (target == PIX_FMT_RGB32_1 || target == PIX_FMT_BGR32_1) ? 0 : 24;
1139
1140             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (A1 << sh);
1141             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (A2 << sh);
1142         } else {
1143             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1];
1144             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2];
1145         }
1146 #endif
1147     } else if (target == PIX_FMT_RGB24 || target == PIX_FMT_BGR24) {
1148         uint8_t *dest = (uint8_t *) _dest;
1149         const uint8_t *r = (const uint8_t *) _r;
1150         const uint8_t *g = (const uint8_t *) _g;
1151         const uint8_t *b = (const uint8_t *) _b;
1152
1153 #define r_b ((target == PIX_FMT_RGB24) ? r : b)
1154 #define b_r ((target == PIX_FMT_RGB24) ? b : r)
1155
1156         dest[i * 6 + 0] = r_b[Y1];
1157         dest[i * 6 + 1] =   g[Y1];
1158         dest[i * 6 + 2] = b_r[Y1];
1159         dest[i * 6 + 3] = r_b[Y2];
1160         dest[i * 6 + 4] =   g[Y2];
1161         dest[i * 6 + 5] = b_r[Y2];
1162 #undef r_b
1163 #undef b_r
1164     } else if (target == PIX_FMT_RGB565 || target == PIX_FMT_BGR565 ||
1165                target == PIX_FMT_RGB555 || target == PIX_FMT_BGR555 ||
1166                target == PIX_FMT_RGB444 || target == PIX_FMT_BGR444) {
1167         uint16_t *dest = (uint16_t *) _dest;
1168         const uint16_t *r = (const uint16_t *) _r;
1169         const uint16_t *g = (const uint16_t *) _g;
1170         const uint16_t *b = (const uint16_t *) _b;
1171         int dr1, dg1, db1, dr2, dg2, db2;
1172
1173         if (target == PIX_FMT_RGB565 || target == PIX_FMT_BGR565) {
1174             dr1 = dither_2x2_8[ y & 1     ][0];
1175             dg1 = dither_2x2_4[ y & 1     ][0];
1176             db1 = dither_2x2_8[(y & 1) ^ 1][0];
1177             dr2 = dither_2x2_8[ y & 1     ][1];
1178             dg2 = dither_2x2_4[ y & 1     ][1];
1179             db2 = dither_2x2_8[(y & 1) ^ 1][1];
1180         } else if (target == PIX_FMT_RGB555 || target == PIX_FMT_BGR555) {
1181             dr1 = dither_2x2_8[ y & 1     ][0];
1182             dg1 = dither_2x2_8[ y & 1     ][1];
1183             db1 = dither_2x2_8[(y & 1) ^ 1][0];
1184             dr2 = dither_2x2_8[ y & 1     ][1];
1185             dg2 = dither_2x2_8[ y & 1     ][0];
1186             db2 = dither_2x2_8[(y & 1) ^ 1][1];
1187         } else {
1188             dr1 = dither_4x4_16[ y & 3     ][0];
1189             dg1 = dither_4x4_16[ y & 3     ][1];
1190             db1 = dither_4x4_16[(y & 3) ^ 3][0];
1191             dr2 = dither_4x4_16[ y & 3     ][1];
1192             dg2 = dither_4x4_16[ y & 3     ][0];
1193             db2 = dither_4x4_16[(y & 3) ^ 3][1];
1194         }
1195
1196         dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
1197         dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
1198     } else /* 8/4-bit */ {
1199         uint8_t *dest = (uint8_t *) _dest;
1200         const uint8_t *r = (const uint8_t *) _r;
1201         const uint8_t *g = (const uint8_t *) _g;
1202         const uint8_t *b = (const uint8_t *) _b;
1203         int dr1, dg1, db1, dr2, dg2, db2;
1204
1205         if (target == PIX_FMT_RGB8 || target == PIX_FMT_BGR8) {
1206             const uint8_t * const d64 = dither_8x8_73[y & 7];
1207             const uint8_t * const d32 = dither_8x8_32[y & 7];
1208             dr1 = dg1 = d32[(i * 2 + 0) & 7];
1209             db1 =       d64[(i * 2 + 0) & 7];
1210             dr2 = dg2 = d32[(i * 2 + 1) & 7];
1211             db2 =       d64[(i * 2 + 1) & 7];
1212         } else {
1213             const uint8_t * const d64  = dither_8x8_73 [y & 7];
1214             const uint8_t * const d128 = dither_8x8_220[y & 7];
1215             dr1 = db1 = d128[(i * 2 + 0) & 7];
1216             dg1 =        d64[(i * 2 + 0) & 7];
1217             dr2 = db2 = d128[(i * 2 + 1) & 7];
1218             dg2 =        d64[(i * 2 + 1) & 7];
1219         }
1220
1221         if (target == PIX_FMT_RGB4 || target == PIX_FMT_BGR4) {
1222             dest[i] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1] +
1223                     ((r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]) << 4);
1224         } else {
1225             dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
1226             dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
1227         }
1228     }
1229 }
1230
1231 static av_always_inline void
1232 yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter,
1233                      const int16_t **lumSrc, int lumFilterSize,
1234                      const int16_t *chrFilter, const int16_t **chrUSrc,
1235                      const int16_t **chrVSrc, int chrFilterSize,
1236                      const int16_t **alpSrc, uint8_t *dest, int dstW,
1237                      int y, enum PixelFormat target, int hasAlpha)
1238 {
1239     int i;
1240
1241     for (i = 0; i < (dstW >> 1); i++) {
1242         int j;
1243         int Y1 = 1 << 18;
1244         int Y2 = 1 << 18;
1245         int U  = 1 << 18;
1246         int V  = 1 << 18;
1247         int av_unused A1, A2;
1248         const void *r, *g, *b;
1249
1250         for (j = 0; j < lumFilterSize; j++) {
1251             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
1252             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
1253         }
1254         for (j = 0; j < chrFilterSize; j++) {
1255             U += chrUSrc[j][i] * chrFilter[j];
1256             V += chrVSrc[j][i] * chrFilter[j];
1257         }
1258         Y1 >>= 19;
1259         Y2 >>= 19;
1260         U  >>= 19;
1261         V  >>= 19;
1262         if ((Y1 | Y2 | U | V) & 0x100) {
1263             Y1 = av_clip_uint8(Y1);
1264             Y2 = av_clip_uint8(Y2);
1265             U  = av_clip_uint8(U);
1266             V  = av_clip_uint8(V);
1267         }
1268         if (hasAlpha) {
1269             A1 = 1 << 18;
1270             A2 = 1 << 18;
1271             for (j = 0; j < lumFilterSize; j++) {
1272                 A1 += alpSrc[j][i * 2    ] * lumFilter[j];
1273                 A2 += alpSrc[j][i * 2 + 1] * lumFilter[j];
1274             }
1275             A1 >>= 19;
1276             A2 >>= 19;
1277             if ((A1 | A2) & 0x100) {
1278                 A1 = av_clip_uint8(A1);
1279                 A2 = av_clip_uint8(A2);
1280             }
1281         }
1282
1283         /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/
1284         r =  c->table_rV[V];
1285         g = (c->table_gU[U] + c->table_gV[V]);
1286         b =  c->table_bU[U];
1287
1288         yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1289                       r, g, b, y, target, hasAlpha);
1290     }
1291 }
1292
1293 static av_always_inline void
1294 yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
1295                      const int16_t *ubuf[2], const int16_t *vbuf[2],
1296                      const int16_t *abuf[2], uint8_t *dest, int dstW,
1297                      int yalpha, int uvalpha, int y,
1298                      enum PixelFormat target, int hasAlpha)
1299 {
1300     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
1301                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1302                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
1303                   *abuf0 = hasAlpha ? abuf[0] : NULL,
1304                   *abuf1 = hasAlpha ? abuf[1] : NULL;
1305     int  yalpha1 = 4095 - yalpha;
1306     int uvalpha1 = 4095 - uvalpha;
1307     int i;
1308
1309     for (i = 0; i < (dstW >> 1); i++) {
1310         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
1311         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
1312         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
1313         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
1314         int A1, A2;
1315         const void *r =  c->table_rV[V],
1316                    *g = (c->table_gU[U] + c->table_gV[V]),
1317                    *b =  c->table_bU[U];
1318
1319         if (hasAlpha) {
1320             A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 19;
1321             A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
1322         }
1323
1324         yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1325                       r, g, b, y, target, hasAlpha);
1326     }
1327 }
1328
1329 static av_always_inline void
1330 yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
1331                      const int16_t *ubuf[2], const int16_t *vbuf[2],
1332                      const int16_t *abuf0, uint8_t *dest, int dstW,
1333                      int uvalpha, int y, enum PixelFormat target,
1334                      int hasAlpha)
1335 {
1336     const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1337                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
1338     int i;
1339
1340     if (uvalpha < 2048) {
1341         for (i = 0; i < (dstW >> 1); i++) {
1342             int Y1 = buf0[i * 2]     >> 7;
1343             int Y2 = buf0[i * 2 + 1] >> 7;
1344             int U  = ubuf1[i]        >> 7;
1345             int V  = vbuf1[i]        >> 7;
1346             int A1, A2;
1347             const void *r =  c->table_rV[V],
1348                        *g = (c->table_gU[U] + c->table_gV[V]),
1349                        *b =  c->table_bU[U];
1350
1351             if (hasAlpha) {
1352                 A1 = abuf0[i * 2    ] >> 7;
1353                 A2 = abuf0[i * 2 + 1] >> 7;
1354             }
1355
1356             yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1357                           r, g, b, y, target, hasAlpha);
1358         }
1359     } else {
1360         for (i = 0; i < (dstW >> 1); i++) {
1361             int Y1 =  buf0[i * 2]          >> 7;
1362             int Y2 =  buf0[i * 2 + 1]      >> 7;
1363             int U  = (ubuf0[i] + ubuf1[i]) >> 8;
1364             int V  = (vbuf0[i] + vbuf1[i]) >> 8;
1365             int A1, A2;
1366             const void *r =  c->table_rV[V],
1367                        *g = (c->table_gU[U] + c->table_gV[V]),
1368                        *b =  c->table_bU[U];
1369
1370             if (hasAlpha) {
1371                 A1 = abuf0[i * 2    ] >> 7;
1372                 A2 = abuf0[i * 2 + 1] >> 7;
1373             }
1374
1375             yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1376                           r, g, b, y, target, hasAlpha);
1377         }
1378     }
1379 }
1380
1381 #define YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1382 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
1383                                 const int16_t **lumSrc, int lumFilterSize, \
1384                                 const int16_t *chrFilter, const int16_t **chrUSrc, \
1385                                 const int16_t **chrVSrc, int chrFilterSize, \
1386                                 const int16_t **alpSrc, uint8_t *dest, int dstW, \
1387                                 int y) \
1388 { \
1389     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
1390                                   chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
1391                                   alpSrc, dest, dstW, y, fmt, hasAlpha); \
1392 }
1393 #define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha) \
1394 YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1395 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
1396                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
1397                                 const int16_t *abuf[2], uint8_t *dest, int dstW, \
1398                                 int yalpha, int uvalpha, int y) \
1399 { \
1400     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
1401                                   dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
1402 } \
1403  \
1404 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
1405                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
1406                                 const int16_t *abuf0, uint8_t *dest, int dstW, \
1407                                 int uvalpha, int y) \
1408 { \
1409     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
1410                                   dstW, uvalpha, y, fmt, hasAlpha); \
1411 }
1412
1413 #if CONFIG_SMALL
1414 YUV2RGBWRAPPER(yuv2rgb,,  32_1,  PIX_FMT_RGB32_1,   CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1415 YUV2RGBWRAPPER(yuv2rgb,,  32,    PIX_FMT_RGB32,     CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1416 #else
1417 #if CONFIG_SWSCALE_ALPHA
1418 YUV2RGBWRAPPER(yuv2rgb,, a32_1,  PIX_FMT_RGB32_1,   1);
1419 YUV2RGBWRAPPER(yuv2rgb,, a32,    PIX_FMT_RGB32,     1);
1420 #endif
1421 YUV2RGBWRAPPER(yuv2rgb,, x32_1,  PIX_FMT_RGB32_1,   0);
1422 YUV2RGBWRAPPER(yuv2rgb,, x32,    PIX_FMT_RGB32,     0);
1423 #endif
1424 YUV2RGBWRAPPER(yuv2, rgb, rgb24, PIX_FMT_RGB24,   0);
1425 YUV2RGBWRAPPER(yuv2, rgb, bgr24, PIX_FMT_BGR24,   0);
1426 YUV2RGBWRAPPER(yuv2rgb,,  16,    PIX_FMT_RGB565,    0);
1427 YUV2RGBWRAPPER(yuv2rgb,,  15,    PIX_FMT_RGB555,    0);
1428 YUV2RGBWRAPPER(yuv2rgb,,  12,    PIX_FMT_RGB444,    0);
1429 YUV2RGBWRAPPER(yuv2rgb,,   8,    PIX_FMT_RGB8,      0);
1430 YUV2RGBWRAPPER(yuv2rgb,,   4,    PIX_FMT_RGB4,      0);
1431 YUV2RGBWRAPPER(yuv2rgb,,   4b,   PIX_FMT_RGB4_BYTE, 0);
1432
1433 static av_always_inline void
1434 yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
1435                           const int16_t **lumSrc, int lumFilterSize,
1436                           const int16_t *chrFilter, const int16_t **chrUSrc,
1437                           const int16_t **chrVSrc, int chrFilterSize,
1438                           const int16_t **alpSrc, uint8_t *dest,
1439                           int dstW, int y, enum PixelFormat target, int hasAlpha)
1440 {
1441     int i;
1442     int step = (target == PIX_FMT_RGB24 || target == PIX_FMT_BGR24) ? 3 : 4;
1443
1444     for (i = 0; i < dstW; i++) {
1445         int j;
1446         int Y = 1<<9;
1447         int U = (1<<9)-(128 << 19);
1448         int V = (1<<9)-(128 << 19);
1449         int av_unused A;
1450         int R, G, B;
1451
1452         for (j = 0; j < lumFilterSize; j++) {
1453             Y += lumSrc[j][i] * lumFilter[j];
1454         }
1455         for (j = 0; j < chrFilterSize; j++) {
1456             U += chrUSrc[j][i] * chrFilter[j];
1457             V += chrVSrc[j][i] * chrFilter[j];
1458         }
1459         Y >>= 10;
1460         U >>= 10;
1461         V >>= 10;
1462         if (hasAlpha) {
1463             A = 1 << 18;
1464             for (j = 0; j < lumFilterSize; j++) {
1465                 A += alpSrc[j][i] * lumFilter[j];
1466             }
1467             A >>= 19;
1468             if (A & 0x100)
1469                 A = av_clip_uint8(A);
1470         }
1471         Y -= c->yuv2rgb_y_offset;
1472         Y *= c->yuv2rgb_y_coeff;
1473         Y += 1 << 21;
1474         R = Y + V*c->yuv2rgb_v2r_coeff;
1475         G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
1476         B = Y +                          U*c->yuv2rgb_u2b_coeff;
1477         if ((R | G | B) & 0xC0000000) {
1478             R = av_clip_uintp2(R, 30);
1479             G = av_clip_uintp2(G, 30);
1480             B = av_clip_uintp2(B, 30);
1481         }
1482
1483         switch(target) {
1484         case PIX_FMT_ARGB:
1485             dest[0] = hasAlpha ? A : 255;
1486             dest[1] = R >> 22;
1487             dest[2] = G >> 22;
1488             dest[3] = B >> 22;
1489             break;
1490         case PIX_FMT_RGB24:
1491             dest[0] = R >> 22;
1492             dest[1] = G >> 22;
1493             dest[2] = B >> 22;
1494             break;
1495         case PIX_FMT_RGBA:
1496             dest[0] = R >> 22;
1497             dest[1] = G >> 22;
1498             dest[2] = B >> 22;
1499             dest[3] = hasAlpha ? A : 255;
1500             break;
1501         case PIX_FMT_ABGR:
1502             dest[0] = hasAlpha ? A : 255;
1503             dest[1] = B >> 22;
1504             dest[2] = G >> 22;
1505             dest[3] = R >> 22;
1506             break;
1507         case PIX_FMT_BGR24:
1508             dest[0] = B >> 22;
1509             dest[1] = G >> 22;
1510             dest[2] = R >> 22;
1511             break;
1512         case PIX_FMT_BGRA:
1513             dest[0] = B >> 22;
1514             dest[1] = G >> 22;
1515             dest[2] = R >> 22;
1516             dest[3] = hasAlpha ? A : 255;
1517             break;
1518         }
1519         dest += step;
1520     }
1521 }
1522
1523 #if CONFIG_SMALL
1524 YUV2RGBWRAPPERX(yuv2, rgb_full, bgra32_full, PIX_FMT_BGRA,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1525 YUV2RGBWRAPPERX(yuv2, rgb_full, abgr32_full, PIX_FMT_ABGR,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1526 YUV2RGBWRAPPERX(yuv2, rgb_full, rgba32_full, PIX_FMT_RGBA,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1527 YUV2RGBWRAPPERX(yuv2, rgb_full, argb32_full, PIX_FMT_ARGB,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1528 #else
1529 #if CONFIG_SWSCALE_ALPHA
1530 YUV2RGBWRAPPERX(yuv2, rgb_full, bgra32_full, PIX_FMT_BGRA,  1);
1531 YUV2RGBWRAPPERX(yuv2, rgb_full, abgr32_full, PIX_FMT_ABGR,  1);
1532 YUV2RGBWRAPPERX(yuv2, rgb_full, rgba32_full, PIX_FMT_RGBA,  1);
1533 YUV2RGBWRAPPERX(yuv2, rgb_full, argb32_full, PIX_FMT_ARGB,  1);
1534 #endif
1535 YUV2RGBWRAPPERX(yuv2, rgb_full, bgrx32_full, PIX_FMT_BGRA,  0);
1536 YUV2RGBWRAPPERX(yuv2, rgb_full, xbgr32_full, PIX_FMT_ABGR,  0);
1537 YUV2RGBWRAPPERX(yuv2, rgb_full, rgbx32_full, PIX_FMT_RGBA,  0);
1538 YUV2RGBWRAPPERX(yuv2, rgb_full, xrgb32_full, PIX_FMT_ARGB,  0);
1539 #endif
1540 YUV2RGBWRAPPERX(yuv2, rgb_full, bgr24_full,  PIX_FMT_BGR24, 0);
1541 YUV2RGBWRAPPERX(yuv2, rgb_full, rgb24_full,  PIX_FMT_RGB24, 0);
1542
1543 static av_always_inline void fillPlane(uint8_t* plane, int stride,
1544                                        int width, int height,
1545                                        int y, uint8_t val)
1546 {
1547     int i;
1548     uint8_t *ptr = plane + stride*y;
1549     for (i=0; i<height; i++) {
1550         memset(ptr, val, width);
1551         ptr += stride;
1552     }
1553 }
1554
1555 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1556
1557 #define r ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? b_r : r_b)
1558 #define b ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? r_b : b_r)
1559
1560 static av_always_inline void
1561 rgb48ToY_c_template(uint16_t *dst, const uint16_t *src, int width,
1562                     enum PixelFormat origin)
1563 {
1564     int i;
1565     for (i = 0; i < width; i++) {
1566         unsigned int r_b = input_pixel(&src[i*3+0]);
1567         unsigned int   g = input_pixel(&src[i*3+1]);
1568         unsigned int b_r = input_pixel(&src[i*3+2]);
1569
1570         dst[i] = (RY*r + GY*g + BY*b + (0x2001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1571     }
1572 }
1573
1574 static av_always_inline void
1575 rgb48ToUV_c_template(uint16_t *dstU, uint16_t *dstV,
1576                     const uint16_t *src1, const uint16_t *src2,
1577                     int width, enum PixelFormat origin)
1578 {
1579     int i;
1580     assert(src1==src2);
1581     for (i = 0; i < width; i++) {
1582         int r_b = input_pixel(&src1[i*3+0]);
1583         int   g = input_pixel(&src1[i*3+1]);
1584         int b_r = input_pixel(&src1[i*3+2]);
1585
1586         dstU[i] = (RU*r + GU*g + BU*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1587         dstV[i] = (RV*r + GV*g + BV*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1588     }
1589 }
1590
1591 static av_always_inline void
1592 rgb48ToUV_half_c_template(uint16_t *dstU, uint16_t *dstV,
1593                           const uint16_t *src1, const uint16_t *src2,
1594                           int width, enum PixelFormat origin)
1595 {
1596     int i;
1597     assert(src1==src2);
1598     for (i = 0; i < width; i++) {
1599         int r_b = (input_pixel(&src1[6 * i + 0]) + input_pixel(&src1[6 * i + 3]) + 1) >> 1;
1600         int   g = (input_pixel(&src1[6 * i + 1]) + input_pixel(&src1[6 * i + 4]) + 1) >> 1;
1601         int b_r = (input_pixel(&src1[6 * i + 2]) + input_pixel(&src1[6 * i + 5]) + 1) >> 1;
1602
1603         dstU[i]= (RU*r + GU*g + BU*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1604         dstV[i]= (RV*r + GV*g + BV*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1605     }
1606 }
1607
1608 #undef r
1609 #undef b
1610 #undef input_pixel
1611
1612 #define rgb48funcs(pattern, BE_LE, origin) \
1613 static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *_dst, const uint8_t *_src, \
1614                                     int width, uint32_t *unused) \
1615 { \
1616     const uint16_t *src = (const uint16_t *) _src; \
1617     uint16_t *dst = (uint16_t *) _dst; \
1618     rgb48ToY_c_template(dst, src, width, origin); \
1619 } \
1620  \
1621 static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *_dstU, uint8_t *_dstV, \
1622                                     const uint8_t *_src1, const uint8_t *_src2, \
1623                                     int width, uint32_t *unused) \
1624 { \
1625     const uint16_t *src1 = (const uint16_t *) _src1, \
1626                    *src2 = (const uint16_t *) _src2; \
1627     uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
1628     rgb48ToUV_c_template(dstU, dstV, src1, src2, width, origin); \
1629 } \
1630  \
1631 static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, \
1632                                     const uint8_t *_src1, const uint8_t *_src2, \
1633                                     int width, uint32_t *unused) \
1634 { \
1635     const uint16_t *src1 = (const uint16_t *) _src1, \
1636                    *src2 = (const uint16_t *) _src2; \
1637     uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
1638     rgb48ToUV_half_c_template(dstU, dstV, src1, src2, width, origin); \
1639 }
1640
1641 rgb48funcs(rgb, LE, PIX_FMT_RGB48LE);
1642 rgb48funcs(rgb, BE, PIX_FMT_RGB48BE);
1643 rgb48funcs(bgr, LE, PIX_FMT_BGR48LE);
1644 rgb48funcs(bgr, BE, PIX_FMT_BGR48BE);
1645
1646 #define input_pixel(i) ((origin == PIX_FMT_RGBA || origin == PIX_FMT_BGRA || \
1647                          origin == PIX_FMT_ARGB || origin == PIX_FMT_ABGR) ? AV_RN32A(&src[(i)*4]) : \
1648                         (isBE(origin) ? AV_RB16(&src[(i)*2]) : AV_RL16(&src[(i)*2])))
1649
1650 static av_always_inline void
1651 rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src,
1652                        int width, enum PixelFormat origin,
1653                        int shr,   int shg,   int shb, int shp,
1654                        int maskr, int maskg, int maskb,
1655                        int rsh,   int gsh,   int bsh, int S)
1656 {
1657     const int ry = RY << rsh, gy = GY << gsh, by = BY << bsh,
1658               rnd = (32<<((S)-1)) + (1<<(S-7));
1659     int i;
1660
1661     for (i = 0; i < width; i++) {
1662         int px = input_pixel(i) >> shp;
1663         int b = (px & maskb) >> shb;
1664         int g = (px & maskg) >> shg;
1665         int r = (px & maskr) >> shr;
1666
1667         dst[i] = (ry * r + gy * g + by * b + rnd) >> ((S)-6);
1668     }
1669 }
1670
1671 static av_always_inline void
1672 rgb16_32ToUV_c_template(int16_t *dstU, int16_t *dstV,
1673                         const uint8_t *src, int width,
1674                         enum PixelFormat origin,
1675                         int shr,   int shg,   int shb, int shp,
1676                         int maskr, int maskg, int maskb,
1677                         int rsh,   int gsh,   int bsh, int S)
1678 {
1679     const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1680               rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1681               rnd = (256<<((S)-1)) + (1<<(S-7));
1682     int i;
1683
1684     for (i = 0; i < width; i++) {
1685         int px = input_pixel(i) >> shp;
1686         int b = (px & maskb) >> shb;
1687         int g = (px & maskg) >> shg;
1688         int r = (px & maskr) >> shr;
1689
1690         dstU[i] = (ru * r + gu * g + bu * b + rnd) >> ((S)-6);
1691         dstV[i] = (rv * r + gv * g + bv * b + rnd) >> ((S)-6);
1692     }
1693 }
1694
1695 static av_always_inline void
1696 rgb16_32ToUV_half_c_template(int16_t *dstU, int16_t *dstV,
1697                              const uint8_t *src, int width,
1698                              enum PixelFormat origin,
1699                              int shr,   int shg,   int shb, int shp,
1700                              int maskr, int maskg, int maskb,
1701                              int rsh,   int gsh,   int bsh, int S)
1702 {
1703     const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1704               rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1705               rnd = (256U<<(S)) + (1<<(S-6)), maskgx = ~(maskr | maskb);
1706     int i;
1707
1708     maskr |= maskr << 1; maskb |= maskb << 1; maskg |= maskg << 1;
1709     for (i = 0; i < width; i++) {
1710         int px0 = input_pixel(2 * i + 0) >> shp;
1711         int px1 = input_pixel(2 * i + 1) >> shp;
1712         int b, r, g = (px0 & maskgx) + (px1 & maskgx);
1713         int rb = px0 + px1 - g;
1714
1715         b = (rb & maskb) >> shb;
1716         if (shp || origin == PIX_FMT_BGR565LE || origin == PIX_FMT_BGR565BE ||
1717             origin == PIX_FMT_RGB565LE || origin == PIX_FMT_RGB565BE) {
1718             g >>= shg;
1719         } else {
1720             g = (g  & maskg) >> shg;
1721         }
1722         r = (rb & maskr) >> shr;
1723
1724         dstU[i] = (ru * r + gu * g + bu * b + (unsigned)rnd) >> ((S)-6+1);
1725         dstV[i] = (rv * r + gv * g + bv * b + (unsigned)rnd) >> ((S)-6+1);
1726     }
1727 }
1728
1729 #undef input_pixel
1730
1731 #define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr, \
1732                          maskg, maskb, rsh, gsh, bsh, S) \
1733 static void name ## ToY_c(uint8_t *dst, const uint8_t *src, \
1734                           int width, uint32_t *unused) \
1735 { \
1736     rgb16_32ToY_c_template(dst, src, width, fmt, shr, shg, shb, shp, \
1737                            maskr, maskg, maskb, rsh, gsh, bsh, S); \
1738 } \
1739  \
1740 static void name ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1741                            const uint8_t *src, const uint8_t *dummy, \
1742                            int width, uint32_t *unused) \
1743 { \
1744     rgb16_32ToUV_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1745                             maskr, maskg, maskb, rsh, gsh, bsh, S); \
1746 } \
1747  \
1748 static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
1749                                 const uint8_t *src, const uint8_t *dummy, \
1750                                 int width, uint32_t *unused) \
1751 { \
1752     rgb16_32ToUV_half_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1753                                  maskr, maskg, maskb, rsh, gsh, bsh, S); \
1754 }
1755
1756 rgb16_32_wrapper(PIX_FMT_BGR32,    bgr32,  16, 0,  0, 0, 0xFF0000, 0xFF00,   0x00FF,  8, 0,  8, RGB2YUV_SHIFT+8);
1757 rgb16_32_wrapper(PIX_FMT_BGR32_1,  bgr321, 16, 0,  0, 8, 0xFF0000, 0xFF00,   0x00FF,  8, 0,  8, RGB2YUV_SHIFT+8);
1758 rgb16_32_wrapper(PIX_FMT_RGB32,    rgb32,   0, 0, 16, 0,   0x00FF, 0xFF00, 0xFF0000,  8, 0,  8, RGB2YUV_SHIFT+8);
1759 rgb16_32_wrapper(PIX_FMT_RGB32_1,  rgb321,  0, 0, 16, 8,   0x00FF, 0xFF00, 0xFF0000,  8, 0,  8, RGB2YUV_SHIFT+8);
1760 rgb16_32_wrapper(PIX_FMT_BGR565LE, bgr16le, 0, 0,  0, 0,   0x001F, 0x07E0,   0xF800, 11, 5,  0, RGB2YUV_SHIFT+8);
1761 rgb16_32_wrapper(PIX_FMT_BGR555LE, bgr15le, 0, 0,  0, 0,   0x001F, 0x03E0,   0x7C00, 10, 5,  0, RGB2YUV_SHIFT+7);
1762 rgb16_32_wrapper(PIX_FMT_RGB565LE, rgb16le, 0, 0,  0, 0,   0xF800, 0x07E0,   0x001F,  0, 5, 11, RGB2YUV_SHIFT+8);
1763 rgb16_32_wrapper(PIX_FMT_RGB555LE, rgb15le, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT+7);
1764 rgb16_32_wrapper(PIX_FMT_BGR565BE, bgr16be, 0, 0,  0, 0,   0x001F, 0x07E0,   0xF800, 11, 5,  0, RGB2YUV_SHIFT+8);
1765 rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr15be, 0, 0,  0, 0,   0x001F, 0x03E0,   0x7C00, 10, 5,  0, RGB2YUV_SHIFT+7);
1766 rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0,  0, 0,   0xF800, 0x07E0,   0x001F,  0, 5, 11, RGB2YUV_SHIFT+8);
1767 rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT+7);
1768
1769 static void abgrToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1770 {
1771     int i;
1772     for (i=0; i<width; i++) {
1773         dst[i]= src[4*i]<<6;
1774     }
1775 }
1776
1777 static void rgbaToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1778 {
1779     int i;
1780     for (i=0; i<width; i++) {
1781         dst[i]= src[4*i+3]<<6;
1782     }
1783 }
1784
1785 static void palToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *pal)
1786 {
1787     int i;
1788     for (i=0; i<width; i++) {
1789         int d= src[i];
1790
1791         dst[i]= (pal[d] >> 24)<<6;
1792     }
1793 }
1794
1795 static void palToY_c(int16_t *dst, const uint8_t *src, long width, uint32_t *pal)
1796 {
1797     int i;
1798     for (i=0; i<width; i++) {
1799         int d= src[i];
1800
1801         dst[i]= (pal[d] & 0xFF)<<6;
1802     }
1803 }
1804
1805 static void palToUV_c(uint16_t *dstU, int16_t *dstV,
1806                            const uint8_t *src1, const uint8_t *src2,
1807                            int width, uint32_t *pal)
1808 {
1809     int i;
1810     assert(src1 == src2);
1811     for (i=0; i<width; i++) {
1812         int p= pal[src1[i]];
1813
1814         dstU[i]= (uint8_t)(p>> 8)<<6;
1815         dstV[i]= (uint8_t)(p>>16)<<6;
1816     }
1817 }
1818
1819 static void monowhite2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1820 {
1821     int i, j;
1822     for (i=0; i<width/8; i++) {
1823         int d= ~src[i];
1824         for(j=0; j<8; j++)
1825             dst[8*i+j]= ((d>>(7-j))&1)*16383;
1826     }
1827     if(width&7){
1828         int d= ~src[i];
1829         for(j=0; j<(width&7); j++)
1830             dst[8*i+j]= ((d>>(7-j))&1)*16383;
1831     }
1832 }
1833
1834 static void monoblack2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1835 {
1836     int i, j;
1837     for (i=0; i<width/8; i++) {
1838         int d= src[i];
1839         for(j=0; j<8; j++)
1840             dst[8*i+j]= ((d>>(7-j))&1)*16383;
1841     }
1842     if(width&7){
1843         int d= src[i];
1844         for(j=0; j<(width&7); j++)
1845             dst[8*i+j]= ((d>>(7-j))&1)*16383;
1846     }
1847 }
1848
1849 //FIXME yuy2* can read up to 7 samples too much
1850
1851 static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, int width,
1852                       uint32_t *unused)
1853 {
1854     int i;
1855     for (i=0; i<width; i++)
1856         dst[i]= src[2*i];
1857 }
1858
1859 static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1860                        const uint8_t *src2, int width, uint32_t *unused)
1861 {
1862     int i;
1863     for (i=0; i<width; i++) {
1864         dstU[i]= src1[4*i + 1];
1865         dstV[i]= src1[4*i + 3];
1866     }
1867     assert(src1 == src2);
1868 }
1869
1870 static void bswap16Y_c(uint8_t *_dst, const uint8_t *_src, int width, uint32_t *unused)
1871 {
1872     int i;
1873     const uint16_t *src = (const uint16_t *) _src;
1874     uint16_t *dst = (uint16_t *) _dst;
1875     for (i=0; i<width; i++) {
1876         dst[i] = av_bswap16(src[i]);
1877     }
1878 }
1879
1880 static void bswap16UV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src1,
1881                         const uint8_t *_src2, int width, uint32_t *unused)
1882 {
1883     int i;
1884     const uint16_t *src1 = (const uint16_t *) _src1,
1885                    *src2 = (const uint16_t *) _src2;
1886     uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV;
1887     for (i=0; i<width; i++) {
1888         dstU[i] = av_bswap16(src1[i]);
1889         dstV[i] = av_bswap16(src2[i]);
1890     }
1891 }
1892
1893 /* This is almost identical to the previous, end exists only because
1894  * yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
1895 static void uyvyToY_c(uint8_t *dst, const uint8_t *src, int width,
1896                       uint32_t *unused)
1897 {
1898     int i;
1899     for (i=0; i<width; i++)
1900         dst[i]= src[2*i+1];
1901 }
1902
1903 static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1904                        const uint8_t *src2, int width, uint32_t *unused)
1905 {
1906     int i;
1907     for (i=0; i<width; i++) {
1908         dstU[i]= src1[4*i + 0];
1909         dstV[i]= src1[4*i + 2];
1910     }
1911     assert(src1 == src2);
1912 }
1913
1914 static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
1915                                         const uint8_t *src, int width)
1916 {
1917     int i;
1918     for (i = 0; i < width; i++) {
1919         dst1[i] = src[2*i+0];
1920         dst2[i] = src[2*i+1];
1921     }
1922 }
1923
1924 static void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
1925                        const uint8_t *src1, const uint8_t *src2,
1926                        int width, uint32_t *unused)
1927 {
1928     nvXXtoUV_c(dstU, dstV, src1, width);
1929 }
1930
1931 static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
1932                        const uint8_t *src1, const uint8_t *src2,
1933                        int width, uint32_t *unused)
1934 {
1935     nvXXtoUV_c(dstV, dstU, src1, width);
1936 }
1937
1938 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1939
1940 static void bgr24ToY_c(int16_t *dst, const uint8_t *src,
1941                        int width, uint32_t *unused)
1942 {
1943     int i;
1944     for (i=0; i<width; i++) {
1945         int b= src[i*3+0];
1946         int g= src[i*3+1];
1947         int r= src[i*3+2];
1948
1949         dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
1950     }
1951 }
1952
1953 static void bgr24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1954                         const uint8_t *src2, int width, uint32_t *unused)
1955 {
1956     int i;
1957     for (i=0; i<width; i++) {
1958         int b= src1[3*i + 0];
1959         int g= src1[3*i + 1];
1960         int r= src1[3*i + 2];
1961
1962         dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1963         dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1964     }
1965     assert(src1 == src2);
1966 }
1967
1968 static void bgr24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1969                              const uint8_t *src2, int width, uint32_t *unused)
1970 {
1971     int i;
1972     for (i=0; i<width; i++) {
1973         int b= src1[6*i + 0] + src1[6*i + 3];
1974         int g= src1[6*i + 1] + src1[6*i + 4];
1975         int r= src1[6*i + 2] + src1[6*i + 5];
1976
1977         dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1978         dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1979     }
1980     assert(src1 == src2);
1981 }
1982
1983 static void rgb24ToY_c(int16_t *dst, const uint8_t *src, int width,
1984                        uint32_t *unused)
1985 {
1986     int i;
1987     for (i=0; i<width; i++) {
1988         int r= src[i*3+0];
1989         int g= src[i*3+1];
1990         int b= src[i*3+2];
1991
1992         dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
1993     }
1994 }
1995
1996 static void rgb24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1997                         const uint8_t *src2, int width, uint32_t *unused)
1998 {
1999     int i;
2000     assert(src1==src2);
2001     for (i=0; i<width; i++) {
2002         int r= src1[3*i + 0];
2003         int g= src1[3*i + 1];
2004         int b= src1[3*i + 2];
2005
2006         dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
2007         dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
2008     }
2009 }
2010
2011 static void rgb24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
2012                                     const uint8_t *src2, int width, uint32_t *unused)
2013 {
2014     int i;
2015     assert(src1==src2);
2016     for (i=0; i<width; i++) {
2017         int r= src1[6*i + 0] + src1[6*i + 3];
2018         int g= src1[6*i + 1] + src1[6*i + 4];
2019         int b= src1[6*i + 2] + src1[6*i + 5];
2020
2021         dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
2022         dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
2023     }
2024 }
2025
2026 static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *_src,
2027                            const int16_t *filter,
2028                            const int16_t *filterPos, int filterSize)
2029 {
2030     int i;
2031     int32_t *dst = (int32_t *) _dst;
2032     const uint16_t *src = (const uint16_t *) _src;
2033     int bits = av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
2034     int sh = bits - 4;
2035
2036     if((isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8) && av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1<15)
2037         sh= 9;
2038
2039     for (i = 0; i < dstW; i++) {
2040         int j;
2041         int srcPos = filterPos[i];
2042         int val = 0;
2043
2044         for (j = 0; j < filterSize; j++) {
2045             val += src[srcPos + j] * filter[filterSize * i + j];
2046         }
2047         // filter=14 bit, input=16 bit, output=30 bit, >> 11 makes 19 bit
2048         dst[i] = FFMIN(val >> sh, (1 << 19) - 1);
2049     }
2050 }
2051
2052 static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *_src,
2053                            const int16_t *filter,
2054                            const int16_t *filterPos, int filterSize)
2055 {
2056     int i;
2057     const uint16_t *src = (const uint16_t *) _src;
2058     int sh = av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
2059
2060     if(sh<15)
2061         sh= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
2062
2063     for (i = 0; i < dstW; i++) {
2064         int j;
2065         int srcPos = filterPos[i];
2066         int val = 0;
2067
2068         for (j = 0; j < filterSize; j++) {
2069             val += src[srcPos + j] * filter[filterSize * i + j];
2070         }
2071         // filter=14 bit, input=16 bit, output=30 bit, >> 15 makes 15 bit
2072         dst[i] = FFMIN(val >> sh, (1 << 15) - 1);
2073     }
2074 }
2075
2076 // bilinear / bicubic scaling
2077 static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *src,
2078                           const int16_t *filter, const int16_t *filterPos,
2079                           int filterSize)
2080 {
2081     int i;
2082     for (i=0; i<dstW; i++) {
2083         int j;
2084         int srcPos= filterPos[i];
2085         int val=0;
2086         for (j=0; j<filterSize; j++) {
2087             val += ((int)src[srcPos + j])*filter[filterSize*i + j];
2088         }
2089         //filter += hFilterSize;
2090         dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
2091         //dst[i] = val>>7;
2092     }
2093 }
2094
2095 static inline void hScale16NX_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
2096                                     const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
2097 {
2098     int i, j;
2099     for (i=0; i<dstW; i++) {
2100         int srcPos= filterPos[i];
2101         int val=0;
2102         for (j=0; j<filterSize; j++) {
2103             val += ((int)av_bswap16(src[srcPos + j]))*filter[filterSize*i + j];
2104         }
2105         dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
2106     }
2107 }
2108
2109 static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *src,
2110                           const int16_t *filter, const int16_t *filterPos,
2111                           int filterSize)
2112 {
2113     int i;
2114     int32_t *dst = (int32_t *) _dst;
2115     for (i=0; i<dstW; i++) {
2116         int j;
2117         int srcPos= filterPos[i];
2118         int val=0;
2119         for (j=0; j<filterSize; j++) {
2120             val += ((int)src[srcPos + j])*filter[filterSize*i + j];
2121         }
2122         //filter += hFilterSize;
2123         dst[i] = FFMIN(val>>3, (1<<19)-1); // the cubic equation does overflow ...
2124         //dst[i] = val>>7;
2125     }
2126 }
2127
2128 //FIXME all pal and rgb srcFormats could do this convertion as well
2129 //FIXME all scalers more complex than bilinear could do half of this transform
2130 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
2131 {
2132     int i;
2133     for (i = 0; i < width; i++) {
2134         dstU[i] = (FFMIN(dstU[i],30775)*4663 - 9289992)>>12; //-264
2135         dstV[i] = (FFMIN(dstV[i],30775)*4663 - 9289992)>>12; //-264
2136     }
2137 }
2138 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
2139 {
2140     int i;
2141     for (i = 0; i < width; i++) {
2142         dstU[i] = (dstU[i]*1799 + 4081085)>>11; //1469
2143         dstV[i] = (dstV[i]*1799 + 4081085)>>11; //1469
2144     }
2145 }
2146 static void lumRangeToJpeg_c(int16_t *dst, int width)
2147 {
2148     int i;
2149     for (i = 0; i < width; i++)
2150         dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
2151 }
2152 static void lumRangeFromJpeg_c(int16_t *dst, int width)
2153 {
2154     int i;
2155     for (i = 0; i < width; i++)
2156         dst[i] = (dst[i]*14071 + 33561947)>>14;
2157 }
2158
2159 static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
2160 {
2161     int i;
2162     int32_t *dstU = (int32_t *) _dstU;
2163     int32_t *dstV = (int32_t *) _dstV;
2164     for (i = 0; i < width; i++) {
2165         dstU[i] = (FFMIN(dstU[i],30775<<4)*4663 - (9289992<<4))>>12; //-264
2166         dstV[i] = (FFMIN(dstV[i],30775<<4)*4663 - (9289992<<4))>>12; //-264
2167     }
2168 }
2169 static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
2170 {
2171     int i;
2172     int32_t *dstU = (int32_t *) _dstU;
2173     int32_t *dstV = (int32_t *) _dstV;
2174     for (i = 0; i < width; i++) {
2175         dstU[i] = (dstU[i]*1799 + (4081085<<4))>>11; //1469
2176         dstV[i] = (dstV[i]*1799 + (4081085<<4))>>11; //1469
2177     }
2178 }
2179 static void lumRangeToJpeg16_c(int16_t *_dst, int width)
2180 {
2181     int i;
2182     int32_t *dst = (int32_t *) _dst;
2183     for (i = 0; i < width; i++)
2184         dst[i] = (FFMIN(dst[i],30189<<4)*4769 - (39057361<<2))>>12;
2185 }
2186 static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
2187 {
2188     int i;
2189     int32_t *dst = (int32_t *) _dst;
2190     for (i = 0; i < width; i++)
2191         dst[i] = (dst[i]*(14071/4) + (33561947<<4)/4)>>12;
2192 }
2193
2194 static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
2195                            const uint8_t *src, int srcW, int xInc)
2196 {
2197     int i;
2198     unsigned int xpos=0;
2199     for (i=0;i<dstWidth;i++) {
2200         register unsigned int xx=xpos>>16;
2201         register unsigned int xalpha=(xpos&0xFFFF)>>9;
2202         dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
2203         xpos+=xInc;
2204     }
2205     for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
2206         dst[i] = src[srcW-1]*128;
2207 }
2208
2209 // *** horizontal scale Y line to temp buffer
2210 static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth,
2211                                      const uint8_t *src, int srcW, int xInc,
2212                                      const int16_t *hLumFilter,
2213                                      const int16_t *hLumFilterPos, int hLumFilterSize,
2214                                      uint8_t *formatConvBuffer,
2215                                      uint32_t *pal, int isAlpha)
2216 {
2217     void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
2218     void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
2219
2220     if (toYV12) {
2221         toYV12(formatConvBuffer, src, srcW, pal);
2222         src= formatConvBuffer;
2223     }
2224
2225     if (c->hScale16) {
2226         int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
2227         c->hScale16(dst, dstWidth, (const uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, shift);
2228     } else if (!c->hyscale_fast) {
2229         c->hScale(c, dst, dstWidth, src, hLumFilter, hLumFilterPos, hLumFilterSize);
2230     } else { // fast bilinear upscale / crap downscale
2231         c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
2232     }
2233
2234     if (convertRange)
2235         convertRange(dst, dstWidth);
2236 }
2237
2238 static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
2239                            int dstWidth, const uint8_t *src1,
2240                            const uint8_t *src2, int srcW, int xInc)
2241 {
2242     int i;
2243     unsigned int xpos=0;
2244     for (i=0;i<dstWidth;i++) {
2245         register unsigned int xx=xpos>>16;
2246         register unsigned int xalpha=(xpos&0xFFFF)>>9;
2247         dst1[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
2248         dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
2249         xpos+=xInc;
2250     }
2251     for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {
2252         dst1[i] = src1[srcW-1]*128;
2253         dst2[i] = src2[srcW-1]*128;
2254     }
2255 }
2256
2257 static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth,
2258                                      const uint8_t *src1, const uint8_t *src2,
2259                                      int srcW, int xInc, const int16_t *hChrFilter,
2260                                      const int16_t *hChrFilterPos, int hChrFilterSize,
2261                                      uint8_t *formatConvBuffer, uint32_t *pal)
2262 {
2263     if (c->chrToYV12) {
2264         uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16);
2265         c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
2266         src1= formatConvBuffer;
2267         src2= buf2;
2268     }
2269
2270     if (c->hScale16) {
2271         int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
2272         c->hScale16(dst1, dstWidth, (const uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
2273         c->hScale16(dst2, dstWidth, (const uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
2274     } else if (!c->hcscale_fast) {
2275         c->hScale(c, dst1, dstWidth, src1, hChrFilter, hChrFilterPos, hChrFilterSize);
2276         c->hScale(c, dst2, dstWidth, src2, hChrFilter, hChrFilterPos, hChrFilterSize);
2277     } else { // fast bilinear upscale / crap downscale
2278         c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc);
2279     }
2280
2281     if (c->chrConvertRange)
2282         c->chrConvertRange(dst1, dst2, dstWidth);
2283 }
2284
2285 static av_always_inline void
2286 find_c_packed_planar_out_funcs(SwsContext *c,
2287                                yuv2planar1_fn *yuv2yuv1,    yuv2planarX_fn *yuv2yuvX,
2288                                yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2,
2289                                yuv2packedX_fn *yuv2packedX)
2290 {
2291     enum PixelFormat dstFormat = c->dstFormat;
2292
2293     if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
2294         *yuv2yuvX     = yuv2nv12X_c;
2295     } else if (is16BPS(dstFormat)) {
2296         *yuv2yuvX     = isBE(dstFormat) ? yuv2yuvX16BE_c  : yuv2yuvX16LE_c;
2297     } else if (is9_OR_10BPS(dstFormat)) {
2298         if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
2299             *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c :  yuv2yuvX9LE_c;
2300         } else {
2301             *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c;
2302         }
2303     } else {
2304         *yuv2yuv1     = yuv2yuv1_c;
2305         *yuv2yuvX     = yuv2yuvX_c;
2306     }
2307     if(c->flags & SWS_FULL_CHR_H_INT) {
2308         switch (dstFormat) {
2309             case PIX_FMT_RGBA:
2310 #if CONFIG_SMALL
2311                 *yuv2packedX = yuv2rgba32_full_X_c;
2312 #else
2313 #if CONFIG_SWSCALE_ALPHA
2314                 if (c->alpPixBuf) {
2315                     *yuv2packedX = yuv2rgba32_full_X_c;
2316                 } else
2317 #endif /* CONFIG_SWSCALE_ALPHA */
2318                 {
2319                     *yuv2packedX = yuv2rgbx32_full_X_c;
2320                 }
2321 #endif /* !CONFIG_SMALL */
2322                 break;
2323             case PIX_FMT_ARGB:
2324 #if CONFIG_SMALL
2325                 *yuv2packedX = yuv2argb32_full_X_c;
2326 #else
2327 #if CONFIG_SWSCALE_ALPHA
2328                 if (c->alpPixBuf) {
2329                     *yuv2packedX = yuv2argb32_full_X_c;
2330                 } else
2331 #endif /* CONFIG_SWSCALE_ALPHA */
2332                 {
2333                     *yuv2packedX = yuv2xrgb32_full_X_c;
2334                 }
2335 #endif /* !CONFIG_SMALL */
2336                 break;
2337             case PIX_FMT_BGRA:
2338 #if CONFIG_SMALL
2339                 *yuv2packedX = yuv2bgra32_full_X_c;
2340 #else
2341 #if CONFIG_SWSCALE_ALPHA
2342                 if (c->alpPixBuf) {
2343                     *yuv2packedX = yuv2bgra32_full_X_c;
2344                 } else
2345 #endif /* CONFIG_SWSCALE_ALPHA */
2346                 {
2347                     *yuv2packedX = yuv2bgrx32_full_X_c;
2348                 }
2349 #endif /* !CONFIG_SMALL */
2350                 break;
2351             case PIX_FMT_ABGR:
2352 #if CONFIG_SMALL
2353                 *yuv2packedX = yuv2abgr32_full_X_c;
2354 #else
2355 #if CONFIG_SWSCALE_ALPHA
2356                 if (c->alpPixBuf) {
2357                     *yuv2packedX = yuv2abgr32_full_X_c;
2358                 } else
2359 #endif /* CONFIG_SWSCALE_ALPHA */
2360                 {
2361                     *yuv2packedX = yuv2xbgr32_full_X_c;
2362                 }
2363 #endif /* !CONFIG_SMALL */
2364                 break;
2365             case PIX_FMT_RGB24:
2366             *yuv2packedX = yuv2rgb24_full_X_c;
2367             break;
2368         case PIX_FMT_BGR24:
2369             *yuv2packedX = yuv2bgr24_full_X_c;
2370             break;
2371         }
2372         if(!*yuv2packedX)
2373             goto YUV_PACKED;
2374     } else {
2375         YUV_PACKED:
2376         switch (dstFormat) {
2377         case PIX_FMT_GRAY16BE:
2378             *yuv2packed1 = yuv2gray16BE_1_c;
2379             *yuv2packed2 = yuv2gray16BE_2_c;
2380             *yuv2packedX = yuv2gray16BE_X_c;
2381             break;
2382         case PIX_FMT_GRAY16LE:
2383             *yuv2packed1 = yuv2gray16LE_1_c;
2384             *yuv2packed2 = yuv2gray16LE_2_c;
2385             *yuv2packedX = yuv2gray16LE_X_c;
2386             break;
2387         case PIX_FMT_MONOWHITE:
2388             *yuv2packed1 = yuv2monowhite_1_c;
2389             *yuv2packed2 = yuv2monowhite_2_c;
2390             *yuv2packedX = yuv2monowhite_X_c;
2391             break;
2392         case PIX_FMT_MONOBLACK:
2393             *yuv2packed1 = yuv2monoblack_1_c;
2394             *yuv2packed2 = yuv2monoblack_2_c;
2395             *yuv2packedX = yuv2monoblack_X_c;
2396             break;
2397         case PIX_FMT_YUYV422:
2398             *yuv2packed1 = yuv2yuyv422_1_c;
2399             *yuv2packed2 = yuv2yuyv422_2_c;
2400             *yuv2packedX = yuv2yuyv422_X_c;
2401             break;
2402         case PIX_FMT_UYVY422:
2403             *yuv2packed1 = yuv2uyvy422_1_c;
2404             *yuv2packed2 = yuv2uyvy422_2_c;
2405             *yuv2packedX = yuv2uyvy422_X_c;
2406             break;
2407         case PIX_FMT_RGB48LE:
2408             *yuv2packed1 = yuv2rgb48le_1_c;
2409             *yuv2packed2 = yuv2rgb48le_2_c;
2410             *yuv2packedX = yuv2rgb48le_X_c;
2411             break;
2412         case PIX_FMT_RGB48BE:
2413             *yuv2packed1 = yuv2rgb48be_1_c;
2414             *yuv2packed2 = yuv2rgb48be_2_c;
2415             *yuv2packedX = yuv2rgb48be_X_c;
2416             break;
2417         case PIX_FMT_BGR48LE:
2418             *yuv2packed1 = yuv2bgr48le_1_c;
2419             *yuv2packed2 = yuv2bgr48le_2_c;
2420             *yuv2packedX = yuv2bgr48le_X_c;
2421             break;
2422         case PIX_FMT_BGR48BE:
2423             *yuv2packed1 = yuv2bgr48be_1_c;
2424             *yuv2packed2 = yuv2bgr48be_2_c;
2425             *yuv2packedX = yuv2bgr48be_X_c;
2426             break;
2427         case PIX_FMT_RGB32:
2428         case PIX_FMT_BGR32:
2429 #if CONFIG_SMALL
2430             *yuv2packed1 = yuv2rgb32_1_c;
2431             *yuv2packed2 = yuv2rgb32_2_c;
2432             *yuv2packedX = yuv2rgb32_X_c;
2433 #else
2434 #if CONFIG_SWSCALE_ALPHA
2435                 if (c->alpPixBuf) {
2436                     *yuv2packed1 = yuv2rgba32_1_c;
2437                     *yuv2packed2 = yuv2rgba32_2_c;
2438                     *yuv2packedX = yuv2rgba32_X_c;
2439                 } else
2440 #endif /* CONFIG_SWSCALE_ALPHA */
2441                 {
2442                     *yuv2packed1 = yuv2rgbx32_1_c;
2443                     *yuv2packed2 = yuv2rgbx32_2_c;
2444                     *yuv2packedX = yuv2rgbx32_X_c;
2445                 }
2446 #endif /* !CONFIG_SMALL */
2447             break;
2448         case PIX_FMT_RGB32_1:
2449         case PIX_FMT_BGR32_1:
2450 #if CONFIG_SMALL
2451                 *yuv2packed1 = yuv2rgb32_1_1_c;
2452                 *yuv2packed2 = yuv2rgb32_1_2_c;
2453                 *yuv2packedX = yuv2rgb32_1_X_c;
2454 #else
2455 #if CONFIG_SWSCALE_ALPHA
2456                 if (c->alpPixBuf) {
2457                     *yuv2packed1 = yuv2rgba32_1_1_c;
2458                     *yuv2packed2 = yuv2rgba32_1_2_c;
2459                     *yuv2packedX = yuv2rgba32_1_X_c;
2460                 } else
2461 #endif /* CONFIG_SWSCALE_ALPHA */
2462                 {
2463                     *yuv2packed1 = yuv2rgbx32_1_1_c;
2464                     *yuv2packed2 = yuv2rgbx32_1_2_c;
2465                     *yuv2packedX = yuv2rgbx32_1_X_c;
2466                 }
2467 #endif /* !CONFIG_SMALL */
2468                 break;
2469         case PIX_FMT_RGB24:
2470             *yuv2packed1 = yuv2rgb24_1_c;
2471             *yuv2packed2 = yuv2rgb24_2_c;
2472             *yuv2packedX = yuv2rgb24_X_c;
2473             break;
2474         case PIX_FMT_BGR24:
2475             *yuv2packed1 = yuv2bgr24_1_c;
2476             *yuv2packed2 = yuv2bgr24_2_c;
2477             *yuv2packedX = yuv2bgr24_X_c;
2478             break;
2479         case PIX_FMT_RGB565LE:
2480         case PIX_FMT_RGB565BE:
2481         case PIX_FMT_BGR565LE:
2482         case PIX_FMT_BGR565BE:
2483             *yuv2packed1 = yuv2rgb16_1_c;
2484             *yuv2packed2 = yuv2rgb16_2_c;
2485             *yuv2packedX = yuv2rgb16_X_c;
2486             break;
2487         case PIX_FMT_RGB555LE:
2488         case PIX_FMT_RGB555BE:
2489         case PIX_FMT_BGR555LE:
2490         case PIX_FMT_BGR555BE:
2491             *yuv2packed1 = yuv2rgb15_1_c;
2492             *yuv2packed2 = yuv2rgb15_2_c;
2493             *yuv2packedX = yuv2rgb15_X_c;
2494             break;
2495         case PIX_FMT_RGB444LE:
2496         case PIX_FMT_RGB444BE:
2497         case PIX_FMT_BGR444LE:
2498         case PIX_FMT_BGR444BE:
2499             *yuv2packed1 = yuv2rgb12_1_c;
2500             *yuv2packed2 = yuv2rgb12_2_c;
2501             *yuv2packedX = yuv2rgb12_X_c;
2502             break;
2503         case PIX_FMT_RGB8:
2504         case PIX_FMT_BGR8:
2505             *yuv2packed1 = yuv2rgb8_1_c;
2506             *yuv2packed2 = yuv2rgb8_2_c;
2507             *yuv2packedX = yuv2rgb8_X_c;
2508             break;
2509         case PIX_FMT_RGB4:
2510         case PIX_FMT_BGR4:
2511             *yuv2packed1 = yuv2rgb4_1_c;
2512             *yuv2packed2 = yuv2rgb4_2_c;
2513             *yuv2packedX = yuv2rgb4_X_c;
2514             break;
2515         case PIX_FMT_RGB4_BYTE:
2516         case PIX_FMT_BGR4_BYTE:
2517             *yuv2packed1 = yuv2rgb4b_1_c;
2518             *yuv2packed2 = yuv2rgb4b_2_c;
2519             *yuv2packedX = yuv2rgb4b_X_c;
2520             break;
2521         }
2522     }
2523 }
2524
2525 #define DEBUG_SWSCALE_BUFFERS 0
2526 #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
2527
2528 static int swScale(SwsContext *c, const uint8_t* src[],
2529                    int srcStride[], int srcSliceY,
2530                    int srcSliceH, uint8_t* dst[], int dstStride[])
2531 {
2532     /* load a few things into local vars to make the code more readable? and faster */
2533     const int srcW= c->srcW;
2534     const int dstW= c->dstW;
2535     const int dstH= c->dstH;
2536     const int chrDstW= c->chrDstW;
2537     const int chrSrcW= c->chrSrcW;
2538     const int lumXInc= c->lumXInc;
2539     const int chrXInc= c->chrXInc;
2540     const enum PixelFormat dstFormat= c->dstFormat;
2541     const int flags= c->flags;
2542     int16_t *vLumFilterPos= c->vLumFilterPos;
2543     int16_t *vChrFilterPos= c->vChrFilterPos;
2544     int16_t *hLumFilterPos= c->hLumFilterPos;
2545     int16_t *hChrFilterPos= c->hChrFilterPos;
2546     int16_t *vLumFilter= c->vLumFilter;
2547     int16_t *vChrFilter= c->vChrFilter;
2548     int16_t *hLumFilter= c->hLumFilter;
2549     int16_t *hChrFilter= c->hChrFilter;
2550     int32_t *lumMmxFilter= c->lumMmxFilter;
2551     int32_t *chrMmxFilter= c->chrMmxFilter;
2552     int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
2553     const int vLumFilterSize= c->vLumFilterSize;
2554     const int vChrFilterSize= c->vChrFilterSize;
2555     const int hLumFilterSize= c->hLumFilterSize;
2556     const int hChrFilterSize= c->hChrFilterSize;
2557     int16_t **lumPixBuf= c->lumPixBuf;
2558     int16_t **chrUPixBuf= c->chrUPixBuf;
2559     int16_t **chrVPixBuf= c->chrVPixBuf;
2560     int16_t **alpPixBuf= c->alpPixBuf;
2561     const int vLumBufSize= c->vLumBufSize;
2562     const int vChrBufSize= c->vChrBufSize;
2563     uint8_t *formatConvBuffer= c->formatConvBuffer;
2564     const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
2565     const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
2566     int lastDstY;
2567     uint32_t *pal=c->pal_yuv;
2568
2569     int should_dither= isNBPS(c->srcFormat) || is16BPS(c->srcFormat);
2570     yuv2planar1_fn yuv2yuv1 = c->yuv2yuv1;
2571     yuv2planarX_fn yuv2yuvX = c->yuv2yuvX;
2572     yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
2573     yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
2574     yuv2packedX_fn yuv2packedX = c->yuv2packedX;
2575
2576     /* vars which will change and which we need to store back in the context */
2577     int dstY= c->dstY;
2578     int lumBufIndex= c->lumBufIndex;
2579     int chrBufIndex= c->chrBufIndex;
2580     int lastInLumBuf= c->lastInLumBuf;
2581     int lastInChrBuf= c->lastInChrBuf;
2582
2583     if (isPacked(c->srcFormat)) {
2584         src[0]=
2585         src[1]=
2586         src[2]=
2587         src[3]= src[0];
2588         srcStride[0]=
2589         srcStride[1]=
2590         srcStride[2]=
2591         srcStride[3]= srcStride[0];
2592     }
2593     srcStride[1]<<= c->vChrDrop;
2594     srcStride[2]<<= c->vChrDrop;
2595
2596     DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
2597                   src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
2598                   dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
2599     DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
2600                    srcSliceY,    srcSliceH,    dstY,    dstH);
2601     DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
2602                    vLumFilterSize,    vLumBufSize,    vChrFilterSize,    vChrBufSize);
2603
2604     if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
2605         static int warnedAlready=0; //FIXME move this into the context perhaps
2606         if (flags & SWS_PRINT_INFO && !warnedAlready) {
2607             av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
2608                    "         ->cannot do aligned memory accesses anymore\n");
2609             warnedAlready=1;
2610         }
2611     }
2612
2613     /* Note the user might start scaling the picture in the middle so this
2614        will not get executed. This is not really intended but works
2615        currently, so people might do it. */
2616     if (srcSliceY ==0) {
2617         lumBufIndex=-1;
2618         chrBufIndex=-1;
2619         dstY=0;
2620         lastInLumBuf= -1;
2621         lastInChrBuf= -1;
2622     }
2623
2624     if (!should_dither) {
2625         c->chrDither8 = c->lumDither8 = ff_sws_pb_64;
2626     }
2627     lastDstY= dstY;
2628
2629     for (;dstY < dstH; dstY++) {
2630         const int chrDstY= dstY>>c->chrDstVSubSample;
2631         uint8_t *dest[4] = {
2632             dst[0] + dstStride[0] * dstY,
2633             dst[1] + dstStride[1] * chrDstY,
2634             dst[2] + dstStride[2] * chrDstY,
2635             (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3] + dstStride[3] * dstY : NULL,
2636         };
2637
2638         const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
2639         const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
2640         const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
2641         int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
2642         int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
2643         int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
2644         int enough_lines;
2645
2646         //handle holes (FAST_BILINEAR & weird filters)
2647         if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
2648         if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
2649         assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
2650         assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
2651
2652         DEBUG_BUFFERS("dstY: %d\n", dstY);
2653         DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
2654                          firstLumSrcY,    lastLumSrcY,    lastInLumBuf);
2655         DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
2656                          firstChrSrcY,    lastChrSrcY,    lastInChrBuf);
2657
2658         // Do we have enough lines in this slice to output the dstY line
2659         enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
2660
2661         if (!enough_lines) {
2662             lastLumSrcY = srcSliceY + srcSliceH - 1;
2663             lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
2664             DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
2665                                             lastLumSrcY, lastChrSrcY);
2666         }
2667
2668         //Do horizontal scaling
2669         while(lastInLumBuf < lastLumSrcY) {
2670             const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
2671             const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
2672             lumBufIndex++;
2673             assert(lumBufIndex < 2*vLumBufSize);
2674             assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
2675             assert(lastInLumBuf + 1 - srcSliceY >= 0);
2676             hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
2677                     hLumFilter, hLumFilterPos, hLumFilterSize,
2678                     formatConvBuffer,
2679                     pal, 0);
2680             if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
2681                 hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW,
2682                         lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
2683                         formatConvBuffer,
2684                         pal, 1);
2685             lastInLumBuf++;
2686             DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
2687                                lumBufIndex,    lastInLumBuf);
2688         }
2689         while(lastInChrBuf < lastChrSrcY) {
2690             const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
2691             const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
2692             chrBufIndex++;
2693             assert(chrBufIndex < 2*vChrBufSize);
2694             assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
2695             assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
2696             //FIXME replace parameters through context struct (some at least)
2697
2698             if (c->needs_hcscale)
2699                 hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
2700                           chrDstW, src1, src2, chrSrcW, chrXInc,
2701                           hChrFilter, hChrFilterPos, hChrFilterSize,
2702                           formatConvBuffer, pal);
2703             lastInChrBuf++;
2704             DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
2705                                chrBufIndex,    lastInChrBuf);
2706         }
2707         //wrap buf index around to stay inside the ring buffer
2708         if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
2709         if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
2710         if (!enough_lines)
2711             break; //we can't output a dstY line so let's try with the next slice
2712
2713 #if HAVE_MMX
2714         updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf);
2715 #endif
2716         if (should_dither) {
2717             c->chrDither8 = dither_8x8_128[chrDstY & 7];
2718             c->lumDither8 = dither_8x8_128[dstY & 7];
2719         }
2720         if (dstY >= dstH-2) {
2721             // hmm looks like we can't use MMX here without overwriting this array's tail
2722             find_c_packed_planar_out_funcs(c, &yuv2yuv1, &yuv2yuvX,
2723                                            &yuv2packed1, &yuv2packed2,
2724                                            &yuv2packedX);
2725         }
2726
2727         {
2728             const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
2729             const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2730             const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2731             const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
2732
2733             if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
2734                 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2735                 if ((dstY&chrSkipMask) || isGray(dstFormat))
2736                     dest[1] = dest[2] = NULL; //FIXME split functions in lumi / chromi
2737                 if (c->yuv2yuv1 && vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
2738                     const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
2739                     yuv2yuv1(c, lumSrcPtr[0], chrUSrcPtr[0], chrVSrcPtr[0], alpBuf,
2740                              dest, dstW, chrDstW);
2741                 } else { //General YV12
2742                     yuv2yuvX(c, vLumFilter + dstY * vLumFilterSize,
2743                              lumSrcPtr, vLumFilterSize,
2744                              vChrFilter + chrDstY * vChrFilterSize,
2745                              chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2746                              alpSrcPtr, dest, dstW, chrDstW);
2747                 }
2748             } else {
2749                 assert(lumSrcPtr  + vLumFilterSize - 1 < lumPixBuf  + vLumBufSize*2);
2750                 assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize*2);
2751                 if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
2752                     int chrAlpha = vChrFilter[2 * dstY + 1];
2753                     yuv2packed1(c, *lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
2754                                 alpPixBuf ? *alpSrcPtr : NULL,
2755                                 dest[0], dstW, chrAlpha, dstY);
2756                 } else if (c->yuv2packed2 && vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
2757                     int lumAlpha = vLumFilter[2 * dstY + 1];
2758                     int chrAlpha = vChrFilter[2 * dstY + 1];
2759                     lumMmxFilter[2] =
2760                     lumMmxFilter[3] = vLumFilter[2 * dstY   ] * 0x10001;
2761                     chrMmxFilter[2] =
2762                     chrMmxFilter[3] = vChrFilter[2 * chrDstY] * 0x10001;
2763                     yuv2packed2(c, lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
2764                                 alpPixBuf ? alpSrcPtr : NULL,
2765                                 dest[0], dstW, lumAlpha, chrAlpha, dstY);
2766                 } else { //general RGB
2767                     yuv2packedX(c, vLumFilter + dstY * vLumFilterSize,
2768                                 lumSrcPtr, vLumFilterSize,
2769                                 vChrFilter + dstY * vChrFilterSize,
2770                                 chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2771                                 alpSrcPtr, dest[0], dstW, dstY);
2772                 }
2773             }
2774         }
2775     }
2776
2777     if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
2778         fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
2779
2780 #if HAVE_MMX2
2781     if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2)
2782         __asm__ volatile("sfence":::"memory");
2783 #endif
2784     emms_c();
2785
2786     /* store changed local vars back in the context */
2787     c->dstY= dstY;
2788     c->lumBufIndex= lumBufIndex;
2789     c->chrBufIndex= chrBufIndex;
2790     c->lastInLumBuf= lastInLumBuf;
2791     c->lastInChrBuf= lastInChrBuf;
2792
2793     return dstY - lastDstY;
2794 }
2795
2796 static av_cold void sws_init_swScale_c(SwsContext *c)
2797 {
2798     enum PixelFormat srcFormat = c->srcFormat;
2799
2800     find_c_packed_planar_out_funcs(c, &c->yuv2yuv1, &c->yuv2yuvX,
2801                                    &c->yuv2packed1, &c->yuv2packed2,
2802                                    &c->yuv2packedX);
2803
2804     c->chrToYV12 = NULL;
2805     switch(srcFormat) {
2806         case PIX_FMT_YUYV422  : c->chrToYV12 = yuy2ToUV_c; break;
2807         case PIX_FMT_UYVY422  : c->chrToYV12 = uyvyToUV_c; break;
2808         case PIX_FMT_NV12     : c->chrToYV12 = nv12ToUV_c; break;
2809         case PIX_FMT_NV21     : c->chrToYV12 = nv21ToUV_c; break;
2810         case PIX_FMT_RGB8     :
2811         case PIX_FMT_BGR8     :
2812         case PIX_FMT_PAL8     :
2813         case PIX_FMT_BGR4_BYTE:
2814         case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
2815         case PIX_FMT_YUV444P9BE:
2816         case PIX_FMT_YUV420P9BE:
2817         case PIX_FMT_YUV444P10BE:
2818         case PIX_FMT_YUV422P10BE:
2819         case PIX_FMT_YUV420P10BE: c->hScale16= HAVE_BIGENDIAN ? NULL : hScale16NX_c; break;
2820         case PIX_FMT_YUV444P9LE:
2821         case PIX_FMT_YUV420P9LE:
2822         case PIX_FMT_YUV422P10LE:
2823         case PIX_FMT_YUV420P10LE:
2824         case PIX_FMT_YUV444P10LE: c->hScale16= HAVE_BIGENDIAN ? hScale16NX_c : NULL; break;
2825 #if HAVE_BIGENDIAN
2826         case PIX_FMT_YUV420P16LE:
2827         case PIX_FMT_YUV422P16LE:
2828         case PIX_FMT_YUV444P16LE: c->chrToYV12 = bswap16UV_c; break;
2829 #else
2830         case PIX_FMT_YUV420P16BE:
2831         case PIX_FMT_YUV422P16BE:
2832         case PIX_FMT_YUV444P16BE: c->chrToYV12 = bswap16UV_c; break;
2833 #endif
2834     }
2835     if (c->chrSrcHSubSample) {
2836         switch(srcFormat) {
2837         case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_half_c; break;
2838         case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_half_c; break;
2839         case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_half_c; break;
2840         case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_half_c; break;
2841         case PIX_FMT_RGB32   : c->chrToYV12 = bgr32ToUV_half_c;   break;
2842         case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_half_c;  break;
2843         case PIX_FMT_BGR24   : c->chrToYV12 = bgr24ToUV_half_c;   break;
2844         case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_half_c; break;
2845         case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_half_c; break;
2846         case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_half_c; break;
2847         case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_half_c; break;
2848         case PIX_FMT_BGR32   : c->chrToYV12 = rgb32ToUV_half_c;   break;
2849         case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_half_c;  break;
2850         case PIX_FMT_RGB24   : c->chrToYV12 = rgb24ToUV_half_c;   break;
2851         case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_half_c; break;
2852         case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_half_c; break;
2853         case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_half_c; break;
2854         case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_half_c; break;
2855         }
2856     } else {
2857         switch(srcFormat) {
2858         case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_c; break;
2859         case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_c; break;
2860         case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_c; break;
2861         case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_c; break;
2862         case PIX_FMT_RGB32   : c->chrToYV12 = bgr32ToUV_c;   break;
2863         case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_c;  break;
2864         case PIX_FMT_BGR24   : c->chrToYV12 = bgr24ToUV_c;   break;
2865         case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_c; break;
2866         case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_c; break;
2867         case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_c; break;
2868         case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_c; break;
2869         case PIX_FMT_BGR32   : c->chrToYV12 = rgb32ToUV_c;   break;
2870         case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_c;  break;
2871         case PIX_FMT_RGB24   : c->chrToYV12 = rgb24ToUV_c;   break;
2872         case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_c; break;
2873         case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_c; break;
2874         case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_c; break;
2875         case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_c; break;
2876         }
2877     }
2878
2879     c->lumToYV12 = NULL;
2880     c->alpToYV12 = NULL;
2881     switch (srcFormat) {
2882 #if HAVE_BIGENDIAN
2883     case PIX_FMT_YUV420P16LE:
2884     case PIX_FMT_YUV422P16LE:
2885     case PIX_FMT_YUV444P16LE:
2886     case PIX_FMT_GRAY16LE: c->lumToYV12 = bswap16Y_c; break;
2887 #else
2888     case PIX_FMT_YUV420P16BE:
2889     case PIX_FMT_YUV422P16BE:
2890     case PIX_FMT_YUV444P16BE:
2891     case PIX_FMT_GRAY16BE: c->lumToYV12 = bswap16Y_c; break;
2892 #endif
2893     case PIX_FMT_YUYV422  :
2894     case PIX_FMT_Y400A    : c->lumToYV12 = yuy2ToY_c; break;
2895     case PIX_FMT_UYVY422  : c->lumToYV12 = uyvyToY_c;    break;
2896     case PIX_FMT_BGR24    : c->lumToYV12 = bgr24ToY_c;   break;
2897     case PIX_FMT_BGR565LE : c->lumToYV12 = bgr16leToY_c; break;
2898     case PIX_FMT_BGR565BE : c->lumToYV12 = bgr16beToY_c; break;
2899     case PIX_FMT_BGR555LE : c->lumToYV12 = bgr15leToY_c; break;
2900     case PIX_FMT_BGR555BE : c->lumToYV12 = bgr15beToY_c; break;
2901     case PIX_FMT_RGB24    : c->lumToYV12 = rgb24ToY_c;   break;
2902     case PIX_FMT_RGB565LE : c->lumToYV12 = rgb16leToY_c; break;
2903     case PIX_FMT_RGB565BE : c->lumToYV12 = rgb16beToY_c; break;
2904     case PIX_FMT_RGB555LE : c->lumToYV12 = rgb15leToY_c; break;
2905     case PIX_FMT_RGB555BE : c->lumToYV12 = rgb15beToY_c; break;
2906     case PIX_FMT_RGB8     :
2907     case PIX_FMT_BGR8     :
2908     case PIX_FMT_PAL8     :
2909     case PIX_FMT_BGR4_BYTE:
2910     case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY_c; break;
2911     case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y_c; break;
2912     case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y_c; break;
2913     case PIX_FMT_RGB32  : c->lumToYV12 = bgr32ToY_c;  break;
2914     case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY_c; break;
2915     case PIX_FMT_BGR32  : c->lumToYV12 = rgb32ToY_c;  break;
2916     case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY_c; break;
2917     case PIX_FMT_RGB48BE: c->lumToYV12 = rgb48BEToY_c; break;
2918     case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break;
2919     case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break;
2920     case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break;
2921     }
2922     if (c->alpPixBuf) {
2923         switch (srcFormat) {
2924         case PIX_FMT_BGRA:
2925         case PIX_FMT_RGBA:  c->alpToYV12 = rgbaToA_c; break;
2926         case PIX_FMT_ABGR:
2927         case PIX_FMT_ARGB:  c->alpToYV12 = abgrToA_c; break;
2928         case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
2929         case PIX_FMT_PAL8 : c->alpToYV12 = palToA_c; break;
2930         }
2931     }
2932
2933
2934     if (c->srcBpc == 8) {
2935         if (c->dstBpc <= 10) {
2936             c->hScale       = hScale8To15_c;
2937             if (c->flags & SWS_FAST_BILINEAR) {
2938                 c->hyscale_fast = hyscale_fast_c;
2939                 c->hcscale_fast = hcscale_fast_c;
2940             }
2941         } else {
2942             c->hScale = hScale8To19_c;
2943             av_assert0(c->hScale16 != hScale16NX_c);
2944         }
2945     } else {
2946         if(c->dstBpc > 10){
2947             if(c->hScale16 == hScale16NX_c && !isAnyRGB(c->srcFormat)){
2948                 c->chrToYV12 = bswap16UV_c;
2949                 c->lumToYV12 = bswap16Y_c;
2950             }
2951             c->hScale16 = NULL;
2952         }
2953         c->hScale = c->dstBpc > 10 ? hScale16To19_c : hScale16To15_c;
2954     }
2955
2956     if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
2957         if (c->dstBpc <= 10) {
2958             if (c->srcRange) {
2959                 c->lumConvertRange = lumRangeFromJpeg_c;
2960                 c->chrConvertRange = chrRangeFromJpeg_c;
2961             } else {
2962                 c->lumConvertRange = lumRangeToJpeg_c;
2963                 c->chrConvertRange = chrRangeToJpeg_c;
2964             }
2965         } else {
2966             if (c->srcRange) {
2967                 c->lumConvertRange = lumRangeFromJpeg16_c;
2968                 c->chrConvertRange = chrRangeFromJpeg16_c;
2969             } else {
2970                 c->lumConvertRange = lumRangeToJpeg16_c;
2971                 c->chrConvertRange = chrRangeToJpeg16_c;
2972             }
2973         }
2974     }
2975
2976     if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
2977           srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE))
2978         c->needs_hcscale = 1;
2979 }
2980
2981 SwsFunc ff_getSwsFunc(SwsContext *c)
2982 {
2983     sws_init_swScale_c(c);
2984
2985     if (HAVE_MMX)
2986         ff_sws_init_swScale_mmx(c);
2987     if (HAVE_ALTIVEC)
2988         ff_sws_init_swScale_altivec(c);
2989
2990     return swScale;
2991 }