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