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