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