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