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