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