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