swscale: remove misplaced comment.
[ffmpeg.git] / libswscale / swscale.c
1 /*
2  * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /*
22   supported Input formats: YV12, I420/IYUV, YUY2, UYVY, BGR32, BGR32_1, BGR24, BGR16, BGR15, RGB32, RGB32_1, RGB24, Y8/Y800, YVU9/IF09, PAL8
23   supported output formats: YV12, I420/IYUV, YUY2, UYVY, {BGR,RGB}{1,4,8,15,16,24,32}, Y8/Y800, YVU9/IF09
24   {BGR,RGB}{1,4,8,15,16} support dithering
25
26   unscaled special converters (YV12=I420=IYUV, Y800=Y8)
27   YV12 -> {BGR,RGB}{1,4,8,12,15,16,24,32}
28   x -> x
29   YUV9 -> YV12
30   YUV9/YV12 -> Y800
31   Y800 -> YUV9/YV12
32   BGR24 -> BGR32 & RGB24 -> RGB32
33   BGR32 -> BGR24 & RGB32 -> RGB24
34   BGR15 -> BGR16
35 */
36
37 /*
38 tested special converters (most are tested actually, but I did not write it down ...)
39  YV12 -> BGR12/BGR16
40  YV12 -> YV12
41  BGR15 -> BGR16
42  BGR16 -> BGR16
43  YVU9 -> YV12
44
45 untested special converters
46   YV12/I420 -> BGR15/BGR24/BGR32 (it is the yuv2rgb stuff, so it should be OK)
47   YV12/I420 -> YV12/I420
48   YUY2/BGR15/BGR24/BGR32/RGB24/RGB32 -> same format
49   BGR24 -> BGR32 & RGB24 -> RGB32
50   BGR32 -> BGR24 & RGB32 -> RGB24
51   BGR24 -> YV12
52 */
53
54 #include <inttypes.h>
55 #include <string.h>
56 #include <math.h>
57 #include <stdio.h>
58 #include "config.h"
59 #include <assert.h>
60 #include "swscale.h"
61 #include "swscale_internal.h"
62 #include "rgb2rgb.h"
63 #include "libavutil/intreadwrite.h"
64 #include "libavutil/cpu.h"
65 #include "libavutil/avutil.h"
66 #include "libavutil/mathematics.h"
67 #include "libavutil/bswap.h"
68 #include "libavutil/pixdesc.h"
69
70 #define DITHER1XBPP
71
72 #define RGB2YUV_SHIFT 15
73 #define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
74 #define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5))
75 #define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
76 #define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5))
77 #define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5))
78 #define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5))
79 #define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5))
80 #define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
81 #define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5))
82
83 static const double rgb2yuv_table[8][9]={
84     {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
85     {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
86     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
87     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
88     {0.59  , 0.11  , 0.30  , -0.331, 0.5, -0.169, -0.421, -0.079, 0.5}, //FCC
89     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
90     {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
91     {0.701 , 0.087 , 0.212 , -0.384, 0.5, -0.116, -0.445, -0.055, 0.5}, //SMPTE 240M
92 };
93
94 /*
95 NOTES
96 Special versions: fast Y 1:1 scaling (no interpolation in y direction)
97
98 TODO
99 more intelligent misalignment avoidance for the horizontal scaler
100 write special vertical cubic upscale version
101 optimize C code (YV12 / minmax)
102 add support for packed pixel YUV input & output
103 add support for Y8 output
104 optimize BGR24 & BGR32
105 add BGR4 output support
106 write special BGR->BGR scaler
107 */
108
109 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_4)[2][8]={
110 {  1,   3,   1,   3,   1,   3,   1,   3, },
111 {  2,   0,   2,   0,   2,   0,   2,   0, },
112 };
113
114 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
115 {  6,   2,   6,   2,   6,   2,   6,   2, },
116 {  0,   4,   0,   4,   0,   4,   0,   4, },
117 };
118
119 DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
120 {  8,   4,  11,   7,   8,   4,  11,   7, },
121 {  2,  14,   1,  13,   2,  14,   1,  13, },
122 { 10,   6,   9,   5,  10,   6,   9,   5, },
123 {  0,  12,   3,  15,   0,  12,   3,  15, },
124 };
125
126 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
127 { 17,   9,  23,  15,  16,   8,  22,  14, },
128 {  5,  29,   3,  27,   4,  28,   2,  26, },
129 { 21,  13,  19,  11,  20,  12,  18,  10, },
130 {  0,  24,   6,  30,   1,  25,   7,  31, },
131 { 16,   8,  22,  14,  17,   9,  23,  15, },
132 {  4,  28,   2,  26,   5,  29,   3,  27, },
133 { 20,  12,  18,  10,  21,  13,  19,  11, },
134 {  1,  25,   7,  31,   0,  24,   6,  30, },
135 };
136
137 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
138 {  0,  55,  14,  68,   3,  58,  17,  72, },
139 { 37,  18,  50,  32,  40,  22,  54,  35, },
140 {  9,  64,   5,  59,  13,  67,   8,  63, },
141 { 46,  27,  41,  23,  49,  31,  44,  26, },
142 {  2,  57,  16,  71,   1,  56,  15,  70, },
143 { 39,  21,  52,  34,  38,  19,  51,  33, },
144 { 11,  66,   7,  62,  10,  65,   6,  60, },
145 { 48,  30,  43,  25,  47,  29,  42,  24, },
146 };
147
148 #if 1
149 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
150 {117,  62, 158, 103, 113,  58, 155, 100, },
151 { 34, 199,  21, 186,  31, 196,  17, 182, },
152 {144,  89, 131,  76, 141,  86, 127,  72, },
153 {  0, 165,  41, 206,  10, 175,  52, 217, },
154 {110,  55, 151,  96, 120,  65, 162, 107, },
155 { 28, 193,  14, 179,  38, 203,  24, 189, },
156 {138,  83, 124,  69, 148,  93, 134,  79, },
157 {  7, 172,  48, 213,   3, 168,  45, 210, },
158 };
159 #elif 1
160 // tries to correct a gamma of 1.5
161 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
162 {  0, 143,  18, 200,   2, 156,  25, 215, },
163 { 78,  28, 125,  64,  89,  36, 138,  74, },
164 { 10, 180,   3, 161,  16, 195,   8, 175, },
165 {109,  51,  93,  38, 121,  60, 105,  47, },
166 {  1, 152,  23, 210,   0, 147,  20, 205, },
167 { 85,  33, 134,  71,  81,  30, 130,  67, },
168 { 14, 190,   6, 171,  12, 185,   5, 166, },
169 {117,  57, 101,  44, 113,  54,  97,  41, },
170 };
171 #elif 1
172 // tries to correct a gamma of 2.0
173 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
174 {  0, 124,   8, 193,   0, 140,  12, 213, },
175 { 55,  14, 104,  42,  66,  19, 119,  52, },
176 {  3, 168,   1, 145,   6, 187,   3, 162, },
177 { 86,  31,  70,  21,  99,  39,  82,  28, },
178 {  0, 134,  11, 206,   0, 129,   9, 200, },
179 { 62,  17, 114,  48,  58,  16, 109,  45, },
180 {  5, 181,   2, 157,   4, 175,   1, 151, },
181 { 95,  36,  78,  26,  90,  34,  74,  24, },
182 };
183 #else
184 // tries to correct a gamma of 2.5
185 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
186 {  0, 107,   3, 187,   0, 125,   6, 212, },
187 { 39,   7,  86,  28,  49,  11, 102,  36, },
188 {  1, 158,   0, 131,   3, 180,   1, 151, },
189 { 68,  19,  52,  12,  81,  25,  64,  17, },
190 {  0, 119,   5, 203,   0, 113,   4, 195, },
191 { 45,   9,  96,  33,  42,   8,  91,  30, },
192 {  2, 172,   1, 144,   2, 165,   0, 137, },
193 { 77,  23,  60,  15,  72,  21,  56,  14, },
194 };
195 #endif
196
197 static av_always_inline void
198 yuv2yuvX16_c_template(const int16_t *lumFilter, const int16_t **lumSrc,
199                       int lumFilterSize, const int16_t *chrFilter,
200                       const int16_t **chrUSrc, const int16_t **chrVSrc,
201                       int chrFilterSize, const int16_t **alpSrc,
202                       uint16_t *dest, uint16_t *uDest, uint16_t *vDest,
203                       uint16_t *aDest, int dstW, int chrDstW,
204                       int big_endian, int output_bits)
205 {
206     //FIXME Optimize (just quickly written not optimized..)
207     int i;
208     int shift = 11 + 16 - output_bits;
209
210 #define output_pixel(pos, val) \
211     if (big_endian) { \
212         if (output_bits == 16) { \
213             AV_WB16(pos, av_clip_uint16(val >> shift)); \
214         } else { \
215             AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
216         } \
217     } else { \
218         if (output_bits == 16) { \
219             AV_WL16(pos, av_clip_uint16(val >> shift)); \
220         } else { \
221             AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
222         } \
223     }
224     for (i = 0; i < dstW; i++) {
225         int val = 1 << (26-output_bits);
226         int j;
227
228         for (j = 0; j < lumFilterSize; j++)
229             val += lumSrc[j][i] * lumFilter[j];
230
231         output_pixel(&dest[i], val);
232     }
233
234     if (uDest) {
235         for (i = 0; i < chrDstW; i++) {
236             int u = 1 << (26-output_bits);
237             int v = 1 << (26-output_bits);
238             int j;
239
240             for (j = 0; j < chrFilterSize; j++) {
241                 u += chrUSrc[j][i] * chrFilter[j];
242                 v += chrVSrc[j][i] * chrFilter[j];
243             }
244
245             output_pixel(&uDest[i], u);
246             output_pixel(&vDest[i], v);
247         }
248     }
249
250     if (CONFIG_SWSCALE_ALPHA && aDest) {
251         for (i = 0; i < dstW; i++) {
252             int val = 1 << (26-output_bits);
253             int j;
254
255             for (j = 0; j < lumFilterSize; j++)
256                 val += alpSrc[j][i] * lumFilter[j];
257
258             output_pixel(&aDest[i], val);
259         }
260     }
261 #undef output_pixel
262 }
263
264 #define yuv2NBPS(bits, BE_LE, is_be) \
265 static void yuv2yuvX ## bits ## BE_LE ## _c(SwsContext *c, const int16_t *lumFilter, \
266                               const int16_t **lumSrc, int lumFilterSize, \
267                               const int16_t *chrFilter, const int16_t **chrUSrc, \
268                               const int16_t **chrVSrc, \
269                               int chrFilterSize, const int16_t **alpSrc, \
270                               uint8_t *_dest, uint8_t *_uDest, uint8_t *_vDest, \
271                               uint8_t *_aDest, int dstW, int chrDstW) \
272 { \
273     uint16_t *dest  = (uint16_t *) _dest,  *uDest = (uint16_t *) _uDest, \
274              *vDest = (uint16_t *) _vDest, *aDest = (uint16_t *) _aDest; \
275     yuv2yuvX16_c_template(lumFilter, lumSrc, lumFilterSize, \
276                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
277                           alpSrc, \
278                           dest, uDest, vDest, aDest, \
279                           dstW, chrDstW, is_be, bits); \
280 }
281 yuv2NBPS( 9, BE, 1);
282 yuv2NBPS( 9, LE, 0);
283 yuv2NBPS(10, BE, 1);
284 yuv2NBPS(10, LE, 0);
285 yuv2NBPS(16, BE, 1);
286 yuv2NBPS(16, LE, 0);
287
288 static void yuv2yuvX_c(SwsContext *c, const int16_t *lumFilter,
289                        const int16_t **lumSrc, int lumFilterSize,
290                        const int16_t *chrFilter, const int16_t **chrUSrc,
291                        const int16_t **chrVSrc,
292                        int chrFilterSize, const int16_t **alpSrc,
293                        uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
294                        uint8_t *aDest, int dstW, int chrDstW)
295 {
296     //FIXME Optimize (just quickly written not optimized..)
297     int i;
298     for (i=0; i<dstW; i++) {
299         int val=1<<18;
300         int j;
301         for (j=0; j<lumFilterSize; j++)
302             val += lumSrc[j][i] * lumFilter[j];
303
304         dest[i]= av_clip_uint8(val>>19);
305     }
306
307     if (uDest)
308         for (i=0; i<chrDstW; i++) {
309             int u=1<<18;
310             int v=1<<18;
311             int j;
312             for (j=0; j<chrFilterSize; j++) {
313                 u += chrUSrc[j][i] * chrFilter[j];
314                 v += chrVSrc[j][i] * chrFilter[j];
315             }
316
317             uDest[i]= av_clip_uint8(u>>19);
318             vDest[i]= av_clip_uint8(v>>19);
319         }
320
321     if (CONFIG_SWSCALE_ALPHA && aDest)
322         for (i=0; i<dstW; i++) {
323             int val=1<<18;
324             int j;
325             for (j=0; j<lumFilterSize; j++)
326                 val += alpSrc[j][i] * lumFilter[j];
327
328             aDest[i]= av_clip_uint8(val>>19);
329         }
330 }
331
332 static void yuv2yuv1_c(SwsContext *c, const int16_t *lumSrc,
333                        const int16_t *chrUSrc, const int16_t *chrVSrc,
334                        const int16_t *alpSrc,
335                        uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
336                        uint8_t *aDest, int dstW, int chrDstW)
337 {
338     int i;
339     for (i=0; i<dstW; i++) {
340         int val= (lumSrc[i]+64)>>7;
341         dest[i]= av_clip_uint8(val);
342     }
343
344     if (uDest)
345         for (i=0; i<chrDstW; i++) {
346             int u=(chrUSrc[i]+64)>>7;
347             int v=(chrVSrc[i]+64)>>7;
348             uDest[i]= av_clip_uint8(u);
349             vDest[i]= av_clip_uint8(v);
350         }
351
352     if (CONFIG_SWSCALE_ALPHA && aDest)
353         for (i=0; i<dstW; i++) {
354             int val= (alpSrc[i]+64)>>7;
355             aDest[i]= av_clip_uint8(val);
356         }
357 }
358
359 static void yuv2nv12X_c(SwsContext *c, const int16_t *lumFilter,
360                         const int16_t **lumSrc, int lumFilterSize,
361                         const int16_t *chrFilter, const int16_t **chrUSrc,
362                         const int16_t **chrVSrc, int chrFilterSize,
363                         const int16_t **alpSrc, uint8_t *dest, uint8_t *uDest,
364                         uint8_t *vDest, uint8_t *aDest,
365                         int dstW, int chrDstW)
366 {
367     enum PixelFormat dstFormat = c->dstFormat;
368
369     //FIXME Optimize (just quickly written not optimized..)
370     int i;
371     for (i=0; i<dstW; i++) {
372         int val=1<<18;
373         int j;
374         for (j=0; j<lumFilterSize; j++)
375             val += lumSrc[j][i] * lumFilter[j];
376
377         dest[i]= av_clip_uint8(val>>19);
378     }
379
380     if (!uDest)
381         return;
382
383     if (dstFormat == PIX_FMT_NV12)
384         for (i=0; i<chrDstW; i++) {
385             int u=1<<18;
386             int v=1<<18;
387             int j;
388             for (j=0; j<chrFilterSize; j++) {
389                 u += chrUSrc[j][i] * chrFilter[j];
390                 v += chrVSrc[j][i] * chrFilter[j];
391             }
392
393             uDest[2*i]= av_clip_uint8(u>>19);
394             uDest[2*i+1]= av_clip_uint8(v>>19);
395         }
396     else
397         for (i=0; i<chrDstW; i++) {
398             int u=1<<18;
399             int v=1<<18;
400             int j;
401             for (j=0; j<chrFilterSize; j++) {
402                 u += chrUSrc[j][i] * chrFilter[j];
403                 v += chrVSrc[j][i] * chrFilter[j];
404             }
405
406             uDest[2*i]= av_clip_uint8(v>>19);
407             uDest[2*i+1]= av_clip_uint8(u>>19);
408         }
409 }
410
411 #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
1808 // bilinear / bicubic scaling
1809 static void hScale_c(int16_t *dst, int dstW, const uint8_t *src,
1810                      int srcW, int xInc,
1811                      const int16_t *filter, const int16_t *filterPos,
1812                      int filterSize)
1813 {
1814     int i;
1815     for (i=0; i<dstW; i++) {
1816         int j;
1817         int srcPos= filterPos[i];
1818         int val=0;
1819         for (j=0; j<filterSize; j++) {
1820             val += ((int)src[srcPos + j])*filter[filterSize*i + j];
1821         }
1822         //filter += hFilterSize;
1823         dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
1824         //dst[i] = val>>7;
1825     }
1826 }
1827
1828 //FIXME all pal and rgb srcFormats could do this convertion as well
1829 //FIXME all scalers more complex than bilinear could do half of this transform
1830 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1831 {
1832     int i;
1833     for (i = 0; i < width; i++) {
1834         dstU[i] = (FFMIN(dstU[i],30775)*4663 - 9289992)>>12; //-264
1835         dstV[i] = (FFMIN(dstV[i],30775)*4663 - 9289992)>>12; //-264
1836     }
1837 }
1838 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1839 {
1840     int i;
1841     for (i = 0; i < width; i++) {
1842         dstU[i] = (dstU[i]*1799 + 4081085)>>11; //1469
1843         dstV[i] = (dstV[i]*1799 + 4081085)>>11; //1469
1844     }
1845 }
1846 static void lumRangeToJpeg_c(int16_t *dst, int width)
1847 {
1848     int i;
1849     for (i = 0; i < width; i++)
1850         dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
1851 }
1852 static void lumRangeFromJpeg_c(int16_t *dst, int width)
1853 {
1854     int i;
1855     for (i = 0; i < width; i++)
1856         dst[i] = (dst[i]*14071 + 33561947)>>14;
1857 }
1858
1859 static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
1860                            const uint8_t *src, int srcW, int xInc)
1861 {
1862     int i;
1863     unsigned int xpos=0;
1864     for (i=0;i<dstWidth;i++) {
1865         register unsigned int xx=xpos>>16;
1866         register unsigned int xalpha=(xpos&0xFFFF)>>9;
1867         dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
1868         xpos+=xInc;
1869     }
1870 }
1871
1872 // *** horizontal scale Y line to temp buffer
1873 static av_always_inline void hyscale(SwsContext *c, uint16_t *dst, int dstWidth,
1874                                      const uint8_t *src, int srcW, int xInc,
1875                                      const int16_t *hLumFilter,
1876                                      const int16_t *hLumFilterPos, int hLumFilterSize,
1877                                      uint8_t *formatConvBuffer,
1878                                      uint32_t *pal, int isAlpha)
1879 {
1880     void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
1881     void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
1882
1883     if (toYV12) {
1884         toYV12(formatConvBuffer, src, srcW, pal);
1885         src= formatConvBuffer;
1886     }
1887
1888     if (!c->hyscale_fast) {
1889         c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
1890     } else { // fast bilinear upscale / crap downscale
1891         c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
1892     }
1893
1894     if (convertRange)
1895         convertRange(dst, dstWidth);
1896 }
1897
1898 static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
1899                            int dstWidth, const uint8_t *src1,
1900                            const uint8_t *src2, int srcW, int xInc)
1901 {
1902     int i;
1903     unsigned int xpos=0;
1904     for (i=0;i<dstWidth;i++) {
1905         register unsigned int xx=xpos>>16;
1906         register unsigned int xalpha=(xpos&0xFFFF)>>9;
1907         dst1[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
1908         dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
1909         xpos+=xInc;
1910     }
1911 }
1912
1913 static av_always_inline void hcscale(SwsContext *c, uint16_t *dst1, uint16_t *dst2, int dstWidth,
1914                                      const uint8_t *src1, const uint8_t *src2,
1915                                      int srcW, int xInc, const int16_t *hChrFilter,
1916                                      const int16_t *hChrFilterPos, int hChrFilterSize,
1917                                      uint8_t *formatConvBuffer, uint32_t *pal)
1918 {
1919     if (c->chrToYV12) {
1920         uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW, 16);
1921         c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
1922         src1= formatConvBuffer;
1923         src2= buf2;
1924     }
1925
1926     if (!c->hcscale_fast) {
1927         c->hScale(dst1, dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
1928         c->hScale(dst2, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
1929     } else { // fast bilinear upscale / crap downscale
1930         c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc);
1931     }
1932
1933     if (c->chrConvertRange)
1934         c->chrConvertRange(dst1, dst2, dstWidth);
1935 }
1936
1937 static av_always_inline void
1938 find_c_packed_planar_out_funcs(SwsContext *c,
1939                                yuv2planar1_fn *yuv2yuv1,    yuv2planarX_fn *yuv2yuvX,
1940                                yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2,
1941                                yuv2packedX_fn *yuv2packedX)
1942 {
1943     enum PixelFormat dstFormat = c->dstFormat;
1944
1945     if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
1946         *yuv2yuvX     = yuv2nv12X_c;
1947     } else if (is16BPS(dstFormat)) {
1948         *yuv2yuvX     = isBE(dstFormat) ? yuv2yuvX16BE_c  : yuv2yuvX16LE_c;
1949     } else if (is9_OR_10BPS(dstFormat)) {
1950         if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
1951             *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c :  yuv2yuvX9LE_c;
1952         } else {
1953             *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c;
1954         }
1955     } else {
1956         *yuv2yuv1     = yuv2yuv1_c;
1957         *yuv2yuvX     = yuv2yuvX_c;
1958     }
1959     if(c->flags & SWS_FULL_CHR_H_INT) {
1960         *yuv2packedX = yuv2rgbX_c_full;
1961     } else {
1962         switch (dstFormat) {
1963         case PIX_FMT_GRAY16BE:
1964             *yuv2packed1 = yuv2gray16BE_1_c;
1965             *yuv2packed2 = yuv2gray16BE_2_c;
1966             *yuv2packedX = yuv2gray16BE_X_c;
1967             break;
1968         case PIX_FMT_GRAY16LE:
1969             *yuv2packed1 = yuv2gray16LE_1_c;
1970             *yuv2packed2 = yuv2gray16LE_2_c;
1971             *yuv2packedX = yuv2gray16LE_X_c;
1972             break;
1973         case PIX_FMT_MONOWHITE:
1974             *yuv2packed1 = yuv2monowhite_1_c;
1975             *yuv2packed2 = yuv2monowhite_2_c;
1976             *yuv2packedX = yuv2monowhite_X_c;
1977             break;
1978         case PIX_FMT_MONOBLACK:
1979             *yuv2packed1 = yuv2monoblack_1_c;
1980             *yuv2packed2 = yuv2monoblack_2_c;
1981             *yuv2packedX = yuv2monoblack_X_c;
1982             break;
1983         case PIX_FMT_YUYV422:
1984             *yuv2packed1 = yuv2yuyv422_1_c;
1985             *yuv2packed2 = yuv2yuyv422_2_c;
1986             *yuv2packedX = yuv2yuyv422_X_c;
1987             break;
1988         case PIX_FMT_UYVY422:
1989             *yuv2packed1 = yuv2uyvy422_1_c;
1990             *yuv2packed2 = yuv2uyvy422_2_c;
1991             *yuv2packedX = yuv2uyvy422_X_c;
1992             break;
1993         case PIX_FMT_RGB48LE:
1994             //*yuv2packed1 = yuv2rgb48le_1_c;
1995             //*yuv2packed2 = yuv2rgb48le_2_c;
1996             //*yuv2packedX = yuv2rgb48le_X_c;
1997             //break;
1998         case PIX_FMT_RGB48BE:
1999             *yuv2packed1 = yuv2rgb48be_1_c;
2000             *yuv2packed2 = yuv2rgb48be_2_c;
2001             *yuv2packedX = yuv2rgb48be_X_c;
2002             break;
2003         case PIX_FMT_BGR48LE:
2004             //*yuv2packed1 = yuv2bgr48le_1_c;
2005             //*yuv2packed2 = yuv2bgr48le_2_c;
2006             //*yuv2packedX = yuv2bgr48le_X_c;
2007             //break;
2008         case PIX_FMT_BGR48BE:
2009             *yuv2packed1 = yuv2bgr48be_1_c;
2010             *yuv2packed2 = yuv2bgr48be_2_c;
2011             *yuv2packedX = yuv2bgr48be_X_c;
2012             break;
2013         default:
2014             *yuv2packed1 = yuv2packed1_c;
2015             *yuv2packed2 = yuv2packed2_c;
2016             *yuv2packedX = yuv2packedX_c;
2017             break;
2018         }
2019     }
2020 }
2021
2022 #define DEBUG_SWSCALE_BUFFERS 0
2023 #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
2024
2025 static int swScale(SwsContext *c, const uint8_t* src[],
2026                    int srcStride[], int srcSliceY,
2027                    int srcSliceH, uint8_t* dst[], int dstStride[])
2028 {
2029     /* load a few things into local vars to make the code more readable? and faster */
2030     const int srcW= c->srcW;
2031     const int dstW= c->dstW;
2032     const int dstH= c->dstH;
2033     const int chrDstW= c->chrDstW;
2034     const int chrSrcW= c->chrSrcW;
2035     const int lumXInc= c->lumXInc;
2036     const int chrXInc= c->chrXInc;
2037     const enum PixelFormat dstFormat= c->dstFormat;
2038     const int flags= c->flags;
2039     int16_t *vLumFilterPos= c->vLumFilterPos;
2040     int16_t *vChrFilterPos= c->vChrFilterPos;
2041     int16_t *hLumFilterPos= c->hLumFilterPos;
2042     int16_t *hChrFilterPos= c->hChrFilterPos;
2043     int16_t *vLumFilter= c->vLumFilter;
2044     int16_t *vChrFilter= c->vChrFilter;
2045     int16_t *hLumFilter= c->hLumFilter;
2046     int16_t *hChrFilter= c->hChrFilter;
2047     int32_t *lumMmxFilter= c->lumMmxFilter;
2048     int32_t *chrMmxFilter= c->chrMmxFilter;
2049     int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
2050     const int vLumFilterSize= c->vLumFilterSize;
2051     const int vChrFilterSize= c->vChrFilterSize;
2052     const int hLumFilterSize= c->hLumFilterSize;
2053     const int hChrFilterSize= c->hChrFilterSize;
2054     int16_t **lumPixBuf= c->lumPixBuf;
2055     int16_t **chrUPixBuf= c->chrUPixBuf;
2056     int16_t **chrVPixBuf= c->chrVPixBuf;
2057     int16_t **alpPixBuf= c->alpPixBuf;
2058     const int vLumBufSize= c->vLumBufSize;
2059     const int vChrBufSize= c->vChrBufSize;
2060     uint8_t *formatConvBuffer= c->formatConvBuffer;
2061     const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
2062     const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
2063     int lastDstY;
2064     uint32_t *pal=c->pal_yuv;
2065     yuv2planar1_fn yuv2yuv1 = c->yuv2yuv1;
2066     yuv2planarX_fn yuv2yuvX = c->yuv2yuvX;
2067     yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
2068     yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
2069     yuv2packedX_fn yuv2packedX = c->yuv2packedX;
2070
2071     /* vars which will change and which we need to store back in the context */
2072     int dstY= c->dstY;
2073     int lumBufIndex= c->lumBufIndex;
2074     int chrBufIndex= c->chrBufIndex;
2075     int lastInLumBuf= c->lastInLumBuf;
2076     int lastInChrBuf= c->lastInChrBuf;
2077
2078     if (isPacked(c->srcFormat)) {
2079         src[0]=
2080         src[1]=
2081         src[2]=
2082         src[3]= src[0];
2083         srcStride[0]=
2084         srcStride[1]=
2085         srcStride[2]=
2086         srcStride[3]= srcStride[0];
2087     }
2088     srcStride[1]<<= c->vChrDrop;
2089     srcStride[2]<<= c->vChrDrop;
2090
2091     DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
2092                   src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
2093                   dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
2094     DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
2095                    srcSliceY,    srcSliceH,    dstY,    dstH);
2096     DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
2097                    vLumFilterSize,    vLumBufSize,    vChrFilterSize,    vChrBufSize);
2098
2099     if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
2100         static int warnedAlready=0; //FIXME move this into the context perhaps
2101         if (flags & SWS_PRINT_INFO && !warnedAlready) {
2102             av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
2103                    "         ->cannot do aligned memory accesses anymore\n");
2104             warnedAlready=1;
2105         }
2106     }
2107
2108     /* Note the user might start scaling the picture in the middle so this
2109        will not get executed. This is not really intended but works
2110        currently, so people might do it. */
2111     if (srcSliceY ==0) {
2112         lumBufIndex=-1;
2113         chrBufIndex=-1;
2114         dstY=0;
2115         lastInLumBuf= -1;
2116         lastInChrBuf= -1;
2117     }
2118
2119     lastDstY= dstY;
2120
2121     for (;dstY < dstH; dstY++) {
2122         unsigned char *dest =dst[0]+dstStride[0]*dstY;
2123         const int chrDstY= dstY>>c->chrDstVSubSample;
2124         unsigned char *uDest=dst[1]+dstStride[1]*chrDstY;
2125         unsigned char *vDest=dst[2]+dstStride[2]*chrDstY;
2126         unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL;
2127
2128         const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
2129         const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
2130         const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
2131         int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
2132         int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
2133         int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
2134         int enough_lines;
2135
2136         //handle holes (FAST_BILINEAR & weird filters)
2137         if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
2138         if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
2139         assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
2140         assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
2141
2142         DEBUG_BUFFERS("dstY: %d\n", dstY);
2143         DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
2144                          firstLumSrcY,    lastLumSrcY,    lastInLumBuf);
2145         DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
2146                          firstChrSrcY,    lastChrSrcY,    lastInChrBuf);
2147
2148         // Do we have enough lines in this slice to output the dstY line
2149         enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
2150
2151         if (!enough_lines) {
2152             lastLumSrcY = srcSliceY + srcSliceH - 1;
2153             lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
2154             DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
2155                                             lastLumSrcY, lastChrSrcY);
2156         }
2157
2158         //Do horizontal scaling
2159         while(lastInLumBuf < lastLumSrcY) {
2160             const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
2161             const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
2162             lumBufIndex++;
2163             assert(lumBufIndex < 2*vLumBufSize);
2164             assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
2165             assert(lastInLumBuf + 1 - srcSliceY >= 0);
2166             hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
2167                     hLumFilter, hLumFilterPos, hLumFilterSize,
2168                     formatConvBuffer,
2169                     pal, 0);
2170             if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
2171                 hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW,
2172                         lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
2173                         formatConvBuffer,
2174                         pal, 1);
2175             lastInLumBuf++;
2176             DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
2177                                lumBufIndex,    lastInLumBuf);
2178         }
2179         while(lastInChrBuf < lastChrSrcY) {
2180             const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
2181             const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
2182             chrBufIndex++;
2183             assert(chrBufIndex < 2*vChrBufSize);
2184             assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
2185             assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
2186             //FIXME replace parameters through context struct (some at least)
2187
2188             if (c->needs_hcscale)
2189                 hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
2190                           chrDstW, src1, src2, chrSrcW, chrXInc,
2191                           hChrFilter, hChrFilterPos, hChrFilterSize,
2192                           formatConvBuffer, pal);
2193             lastInChrBuf++;
2194             DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
2195                                chrBufIndex,    lastInChrBuf);
2196         }
2197         //wrap buf index around to stay inside the ring buffer
2198         if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
2199         if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
2200         if (!enough_lines)
2201             break; //we can't output a dstY line so let's try with the next slice
2202
2203 #if HAVE_MMX
2204         updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf);
2205 #endif
2206         if (dstY >= dstH-2) {
2207             // hmm looks like we can't use MMX here without overwriting this array's tail
2208             find_c_packed_planar_out_funcs(c, &yuv2yuv1, &yuv2yuvX,
2209                                            &yuv2packed1, &yuv2packed2,
2210                                            &yuv2packedX);
2211         }
2212
2213         {
2214             const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
2215             const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2216             const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2217             const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
2218             if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
2219                 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2220                 if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
2221                 if (c->yuv2yuv1 && vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
2222                     const int16_t *lumBuf = lumSrcPtr[0];
2223                     const int16_t *chrUBuf= chrUSrcPtr[0];
2224                     const int16_t *chrVBuf= chrVSrcPtr[0];
2225                     const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
2226                     yuv2yuv1(c, lumBuf, chrUBuf, chrVBuf, alpBuf, dest,
2227                                 uDest, vDest, aDest, dstW, chrDstW);
2228                 } else { //General YV12
2229                     yuv2yuvX(c,
2230                                 vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
2231                                 vChrFilter+chrDstY*vChrFilterSize, chrUSrcPtr,
2232                                 chrVSrcPtr, vChrFilterSize,
2233                                 alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW);
2234                 }
2235             } else {
2236                 assert(lumSrcPtr  + vLumFilterSize - 1 < lumPixBuf  + vLumBufSize*2);
2237                 assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize*2);
2238                 if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
2239                     int chrAlpha= vChrFilter[2*dstY+1];
2240                     yuv2packed1(c, *lumSrcPtr, *chrUSrcPtr, *(chrUSrcPtr+1),
2241                                    *chrVSrcPtr, *(chrVSrcPtr+1),
2242                                    alpPixBuf ? *alpSrcPtr : NULL,
2243                                    dest, dstW, chrAlpha, dstFormat, flags, dstY);
2244                 } else if (c->yuv2packed2 && vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
2245                     int lumAlpha= vLumFilter[2*dstY+1];
2246                     int chrAlpha= vChrFilter[2*dstY+1];
2247                     lumMmxFilter[2]=
2248                     lumMmxFilter[3]= vLumFilter[2*dstY   ]*0x10001;
2249                     chrMmxFilter[2]=
2250                     chrMmxFilter[3]= vChrFilter[2*chrDstY]*0x10001;
2251                     yuv2packed2(c, *lumSrcPtr, *(lumSrcPtr+1), *chrUSrcPtr, *(chrUSrcPtr+1),
2252                                    *chrVSrcPtr, *(chrVSrcPtr+1),
2253                                    alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *(alpSrcPtr+1) : NULL,
2254                                    dest, dstW, lumAlpha, chrAlpha, dstY);
2255                 } else { //general RGB
2256                     yuv2packedX(c,
2257                                    vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
2258                                    vChrFilter+dstY*vChrFilterSize, chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2259                                    alpSrcPtr, dest, dstW, dstY);
2260                 }
2261             }
2262         }
2263     }
2264
2265     if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
2266         fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
2267
2268 #if HAVE_MMX2
2269     if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2)
2270         __asm__ volatile("sfence":::"memory");
2271 #endif
2272     emms_c();
2273
2274     /* store changed local vars back in the context */
2275     c->dstY= dstY;
2276     c->lumBufIndex= lumBufIndex;
2277     c->chrBufIndex= chrBufIndex;
2278     c->lastInLumBuf= lastInLumBuf;
2279     c->lastInChrBuf= lastInChrBuf;
2280
2281     return dstY - lastDstY;
2282 }
2283
2284 static av_cold void sws_init_swScale_c(SwsContext *c)
2285 {
2286     enum PixelFormat srcFormat = c->srcFormat;
2287
2288     find_c_packed_planar_out_funcs(c, &c->yuv2yuv1, &c->yuv2yuvX,
2289                                    &c->yuv2packed1, &c->yuv2packed2,
2290                                    &c->yuv2packedX);
2291
2292     c->hScale       = hScale_c;
2293
2294     if (c->flags & SWS_FAST_BILINEAR) {
2295         c->hyscale_fast = hyscale_fast_c;
2296         c->hcscale_fast = hcscale_fast_c;
2297     }
2298
2299     c->chrToYV12 = NULL;
2300     switch(srcFormat) {
2301         case PIX_FMT_YUYV422  : c->chrToYV12 = yuy2ToUV_c; break;
2302         case PIX_FMT_UYVY422  : c->chrToYV12 = uyvyToUV_c; break;
2303         case PIX_FMT_NV12     : c->chrToYV12 = nv12ToUV_c; break;
2304         case PIX_FMT_NV21     : c->chrToYV12 = nv21ToUV_c; break;
2305         case PIX_FMT_RGB8     :
2306         case PIX_FMT_BGR8     :
2307         case PIX_FMT_PAL8     :
2308         case PIX_FMT_BGR4_BYTE:
2309         case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
2310         case PIX_FMT_YUV444P9BE:
2311         case PIX_FMT_YUV420P9BE: c->chrToYV12 = BE9ToUV_c; break;
2312         case PIX_FMT_YUV444P9LE:
2313         case PIX_FMT_YUV420P9LE: c->chrToYV12 = LE9ToUV_c; break;
2314         case PIX_FMT_YUV444P10BE:
2315         case PIX_FMT_YUV422P10BE:
2316         case PIX_FMT_YUV420P10BE: c->chrToYV12 = BE10ToUV_c; break;
2317         case PIX_FMT_YUV422P10LE:
2318         case PIX_FMT_YUV444P10LE:
2319         case PIX_FMT_YUV420P10LE: c->chrToYV12 = LE10ToUV_c; break;
2320         case PIX_FMT_YUV420P16BE:
2321         case PIX_FMT_YUV422P16BE:
2322         case PIX_FMT_YUV444P16BE: c->chrToYV12 = BEToUV_c; break;
2323         case PIX_FMT_YUV420P16LE:
2324         case PIX_FMT_YUV422P16LE:
2325         case PIX_FMT_YUV444P16LE: c->chrToYV12 = LEToUV_c; break;
2326     }
2327     if (c->chrSrcHSubSample) {
2328         switch(srcFormat) {
2329         case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_half_c; break;
2330         case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_half_c; break;
2331         case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_half_c; break;
2332         case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_half_c; break;
2333         case PIX_FMT_RGB32   : c->chrToYV12 = bgr32ToUV_half_c;   break;
2334         case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_half_c;  break;
2335         case PIX_FMT_BGR24   : c->chrToYV12 = bgr24ToUV_half_c;   break;
2336         case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_half_c; break;
2337         case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_half_c; break;
2338         case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_half_c; break;
2339         case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_half_c; break;
2340         case PIX_FMT_BGR32   : c->chrToYV12 = rgb32ToUV_half_c;   break;
2341         case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_half_c;  break;
2342         case PIX_FMT_RGB24   : c->chrToYV12 = rgb24ToUV_half_c;   break;
2343         case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_half_c; break;
2344         case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_half_c; break;
2345         case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_half_c; break;
2346         case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_half_c; break;
2347         }
2348     } else {
2349         switch(srcFormat) {
2350         case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_c; break;
2351         case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_c; break;
2352         case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_c; break;
2353         case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_c; break;
2354         case PIX_FMT_RGB32   : c->chrToYV12 = bgr32ToUV_c;   break;
2355         case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_c;  break;
2356         case PIX_FMT_BGR24   : c->chrToYV12 = bgr24ToUV_c;   break;
2357         case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_c; break;
2358         case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_c; break;
2359         case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_c; break;
2360         case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_c; break;
2361         case PIX_FMT_BGR32   : c->chrToYV12 = rgb32ToUV_c;   break;
2362         case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_c;  break;
2363         case PIX_FMT_RGB24   : c->chrToYV12 = rgb24ToUV_c;   break;
2364         case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_c; break;
2365         case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_c; break;
2366         case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_c; break;
2367         case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_c; break;
2368         }
2369     }
2370
2371     c->lumToYV12 = NULL;
2372     c->alpToYV12 = NULL;
2373     switch (srcFormat) {
2374     case PIX_FMT_YUV444P9BE:
2375     case PIX_FMT_YUV420P9BE: c->lumToYV12 = BE9ToY_c; break;
2376     case PIX_FMT_YUV444P9LE:
2377     case PIX_FMT_YUV420P9LE: c->lumToYV12 = LE9ToY_c; break;
2378     case PIX_FMT_YUV444P10BE:
2379     case PIX_FMT_YUV422P10BE:
2380     case PIX_FMT_YUV420P10BE: c->lumToYV12 = BE10ToY_c; break;
2381     case PIX_FMT_YUV444P10LE:
2382     case PIX_FMT_YUV422P10LE:
2383     case PIX_FMT_YUV420P10LE: c->lumToYV12 = LE10ToY_c; break;
2384     case PIX_FMT_YUYV422  :
2385     case PIX_FMT_YUV420P16BE:
2386     case PIX_FMT_YUV422P16BE:
2387     case PIX_FMT_YUV444P16BE:
2388     case PIX_FMT_Y400A    :
2389     case PIX_FMT_GRAY16BE : c->lumToYV12 = yuy2ToY_c; break;
2390     case PIX_FMT_UYVY422  :
2391     case PIX_FMT_YUV420P16LE:
2392     case PIX_FMT_YUV422P16LE:
2393     case PIX_FMT_YUV444P16LE:
2394     case PIX_FMT_GRAY16LE : c->lumToYV12 = uyvyToY_c;    break;
2395     case PIX_FMT_BGR24    : c->lumToYV12 = bgr24ToY_c;   break;
2396     case PIX_FMT_BGR565LE : c->lumToYV12 = bgr16leToY_c; break;
2397     case PIX_FMT_BGR565BE : c->lumToYV12 = bgr16beToY_c; break;
2398     case PIX_FMT_BGR555LE : c->lumToYV12 = bgr15leToY_c; break;
2399     case PIX_FMT_BGR555BE : c->lumToYV12 = bgr15beToY_c; break;
2400     case PIX_FMT_RGB24    : c->lumToYV12 = rgb24ToY_c;   break;
2401     case PIX_FMT_RGB565LE : c->lumToYV12 = rgb16leToY_c; break;
2402     case PIX_FMT_RGB565BE : c->lumToYV12 = rgb16beToY_c; break;
2403     case PIX_FMT_RGB555LE : c->lumToYV12 = rgb15leToY_c; break;
2404     case PIX_FMT_RGB555BE : c->lumToYV12 = rgb15beToY_c; break;
2405     case PIX_FMT_RGB8     :
2406     case PIX_FMT_BGR8     :
2407     case PIX_FMT_PAL8     :
2408     case PIX_FMT_BGR4_BYTE:
2409     case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY_c; break;
2410     case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y_c; break;
2411     case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y_c; break;
2412     case PIX_FMT_RGB32  : c->lumToYV12 = bgr32ToY_c;  break;
2413     case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY_c; break;
2414     case PIX_FMT_BGR32  : c->lumToYV12 = rgb32ToY_c;  break;
2415     case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY_c; break;
2416     case PIX_FMT_RGB48BE: c->lumToYV12 = rgb48BEToY_c; break;
2417     case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break;
2418     case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break;
2419     case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break;
2420     }
2421     if (c->alpPixBuf) {
2422         switch (srcFormat) {
2423         case PIX_FMT_BGRA:
2424         case PIX_FMT_RGBA:  c->alpToYV12 = rgbaToA_c; break;
2425         case PIX_FMT_ABGR:
2426         case PIX_FMT_ARGB:  c->alpToYV12 = abgrToA_c; break;
2427         case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
2428         }
2429     }
2430
2431     if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
2432         if (c->srcRange) {
2433             c->lumConvertRange = lumRangeFromJpeg_c;
2434             c->chrConvertRange = chrRangeFromJpeg_c;
2435         } else {
2436             c->lumConvertRange = lumRangeToJpeg_c;
2437             c->chrConvertRange = chrRangeToJpeg_c;
2438         }
2439     }
2440
2441     if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
2442           srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE))
2443         c->needs_hcscale = 1;
2444 }
2445
2446 SwsFunc ff_getSwsFunc(SwsContext *c)
2447 {
2448     sws_init_swScale_c(c);
2449
2450     if (HAVE_MMX)
2451         ff_sws_init_swScale_mmx(c);
2452     if (HAVE_ALTIVEC)
2453         ff_sws_init_swScale_altivec(c);
2454
2455     return swScale;
2456 }