]> git.sesse.net Git - ffmpeg/blob - libswscale/output.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libswscale / output.c
1 /*
2  * Copyright (C) 2001-2012 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include <math.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "libavutil/attributes.h"
27 #include "libavutil/avutil.h"
28 #include "libavutil/avassert.h"
29 #include "libavutil/bswap.h"
30 #include "libavutil/cpu.h"
31 #include "libavutil/intreadwrite.h"
32 #include "libavutil/mathematics.h"
33 #include "libavutil/pixdesc.h"
34 #include "config.h"
35 #include "rgb2rgb.h"
36 #include "swscale.h"
37 #include "swscale_internal.h"
38
39 DECLARE_ALIGNED(8, const uint8_t, ff_dither_2x2_4)[][8] = {
40 {  1,   3,   1,   3,   1,   3,   1,   3, },
41 {  2,   0,   2,   0,   2,   0,   2,   0, },
42 {  1,   3,   1,   3,   1,   3,   1,   3, },
43 };
44
45 DECLARE_ALIGNED(8, const uint8_t, ff_dither_2x2_8)[][8] = {
46 {  6,   2,   6,   2,   6,   2,   6,   2, },
47 {  0,   4,   0,   4,   0,   4,   0,   4, },
48 {  6,   2,   6,   2,   6,   2,   6,   2, },
49 };
50
51 DECLARE_ALIGNED(8, const uint8_t, ff_dither_4x4_16)[][8] = {
52 {  8,   4,  11,   7,   8,   4,  11,   7, },
53 {  2,  14,   1,  13,   2,  14,   1,  13, },
54 { 10,   6,   9,   5,  10,   6,   9,   5, },
55 {  0,  12,   3,  15,   0,  12,   3,  15, },
56 {  8,   4,  11,   7,   8,   4,  11,   7, },
57 };
58
59 DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_32)[][8] = {
60 { 17,   9,  23,  15,  16,   8,  22,  14, },
61 {  5,  29,   3,  27,   4,  28,   2,  26, },
62 { 21,  13,  19,  11,  20,  12,  18,  10, },
63 {  0,  24,   6,  30,   1,  25,   7,  31, },
64 { 16,   8,  22,  14,  17,   9,  23,  15, },
65 {  4,  28,   2,  26,   5,  29,   3,  27, },
66 { 20,  12,  18,  10,  21,  13,  19,  11, },
67 {  1,  25,   7,  31,   0,  24,   6,  30, },
68 { 17,   9,  23,  15,  16,   8,  22,  14, },
69 };
70
71 DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_73)[][8] = {
72 {  0,  55,  14,  68,   3,  58,  17,  72, },
73 { 37,  18,  50,  32,  40,  22,  54,  35, },
74 {  9,  64,   5,  59,  13,  67,   8,  63, },
75 { 46,  27,  41,  23,  49,  31,  44,  26, },
76 {  2,  57,  16,  71,   1,  56,  15,  70, },
77 { 39,  21,  52,  34,  38,  19,  51,  33, },
78 { 11,  66,   7,  62,  10,  65,   6,  60, },
79 { 48,  30,  43,  25,  47,  29,  42,  24, },
80 {  0,  55,  14,  68,   3,  58,  17,  72, },
81 };
82
83 #if 1
84 DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
85 {117,  62, 158, 103, 113,  58, 155, 100, },
86 { 34, 199,  21, 186,  31, 196,  17, 182, },
87 {144,  89, 131,  76, 141,  86, 127,  72, },
88 {  0, 165,  41, 206,  10, 175,  52, 217, },
89 {110,  55, 151,  96, 120,  65, 162, 107, },
90 { 28, 193,  14, 179,  38, 203,  24, 189, },
91 {138,  83, 124,  69, 148,  93, 134,  79, },
92 {  7, 172,  48, 213,   3, 168,  45, 210, },
93 {117,  62, 158, 103, 113,  58, 155, 100, },
94 };
95 #elif 1
96 // tries to correct a gamma of 1.5
97 DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
98 {  0, 143,  18, 200,   2, 156,  25, 215, },
99 { 78,  28, 125,  64,  89,  36, 138,  74, },
100 { 10, 180,   3, 161,  16, 195,   8, 175, },
101 {109,  51,  93,  38, 121,  60, 105,  47, },
102 {  1, 152,  23, 210,   0, 147,  20, 205, },
103 { 85,  33, 134,  71,  81,  30, 130,  67, },
104 { 14, 190,   6, 171,  12, 185,   5, 166, },
105 {117,  57, 101,  44, 113,  54,  97,  41, },
106 {  0, 143,  18, 200,   2, 156,  25, 215, },
107 };
108 #elif 1
109 // tries to correct a gamma of 2.0
110 DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
111 {  0, 124,   8, 193,   0, 140,  12, 213, },
112 { 55,  14, 104,  42,  66,  19, 119,  52, },
113 {  3, 168,   1, 145,   6, 187,   3, 162, },
114 { 86,  31,  70,  21,  99,  39,  82,  28, },
115 {  0, 134,  11, 206,   0, 129,   9, 200, },
116 { 62,  17, 114,  48,  58,  16, 109,  45, },
117 {  5, 181,   2, 157,   4, 175,   1, 151, },
118 { 95,  36,  78,  26,  90,  34,  74,  24, },
119 {  0, 124,   8, 193,   0, 140,  12, 213, },
120 };
121 #else
122 // tries to correct a gamma of 2.5
123 DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
124 {  0, 107,   3, 187,   0, 125,   6, 212, },
125 { 39,   7,  86,  28,  49,  11, 102,  36, },
126 {  1, 158,   0, 131,   3, 180,   1, 151, },
127 { 68,  19,  52,  12,  81,  25,  64,  17, },
128 {  0, 119,   5, 203,   0, 113,   4, 195, },
129 { 45,   9,  96,  33,  42,   8,  91,  30, },
130 {  2, 172,   1, 144,   2, 165,   0, 137, },
131 { 77,  23,  60,  15,  72,  21,  56,  14, },
132 {  0, 107,   3, 187,   0, 125,   6, 212, },
133 };
134 #endif
135
136 #define output_pixel(pos, val, bias, signedness) \
137     if (big_endian) { \
138         AV_WB16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
139     } else { \
140         AV_WL16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
141     }
142
143 static av_always_inline void
144 yuv2plane1_16_c_template(const int32_t *src, uint16_t *dest, int dstW,
145                          int big_endian, int output_bits)
146 {
147     int i;
148     int shift = 3;
149     av_assert0(output_bits == 16);
150
151     for (i = 0; i < dstW; i++) {
152         int val = src[i] + (1 << (shift - 1));
153         output_pixel(&dest[i], val, 0, uint);
154     }
155 }
156
157 static av_always_inline void
158 yuv2planeX_16_c_template(const int16_t *filter, int filterSize,
159                          const int32_t **src, uint16_t *dest, int dstW,
160                          int big_endian, int output_bits)
161 {
162     int i;
163     int shift = 15;
164     av_assert0(output_bits == 16);
165
166     for (i = 0; i < dstW; i++) {
167         int val = 1 << (shift - 1);
168         int j;
169
170         /* range of val is [0,0x7FFFFFFF], so 31 bits, but with lanczos/spline
171          * filters (or anything with negative coeffs, the range can be slightly
172          * wider in both directions. To account for this overflow, we subtract
173          * a constant so it always fits in the signed range (assuming a
174          * reasonable filterSize), and re-add that at the end. */
175         val -= 0x40000000;
176         for (j = 0; j < filterSize; j++)
177             val += src[j][i] * (unsigned)filter[j];
178
179         output_pixel(&dest[i], val, 0x8000, int);
180     }
181 }
182
183 #undef output_pixel
184
185 #define output_pixel(pos, val) \
186     if (big_endian) { \
187         AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
188     } else { \
189         AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
190     }
191
192 static av_always_inline void
193 yuv2plane1_10_c_template(const int16_t *src, uint16_t *dest, int dstW,
194                          int big_endian, int output_bits)
195 {
196     int i;
197     int shift = 15 - output_bits;
198
199     for (i = 0; i < dstW; i++) {
200         int val = src[i] + (1 << (shift - 1));
201         output_pixel(&dest[i], val);
202     }
203 }
204
205 static av_always_inline void
206 yuv2planeX_10_c_template(const int16_t *filter, int filterSize,
207                          const int16_t **src, uint16_t *dest, int dstW,
208                          int big_endian, int output_bits)
209 {
210     int i;
211     int shift = 11 + 16 - output_bits;
212
213     for (i = 0; i < dstW; i++) {
214         int val = 1 << (shift - 1);
215         int j;
216
217         for (j = 0; j < filterSize; j++)
218             val += src[j][i] * filter[j];
219
220         output_pixel(&dest[i], val);
221     }
222 }
223
224 #undef output_pixel
225
226 #define yuv2NBPS(bits, BE_LE, is_be, template_size, typeX_t) \
227 static void yuv2plane1_ ## bits ## BE_LE ## _c(const int16_t *src, \
228                               uint8_t *dest, int dstW, \
229                               const uint8_t *dither, int offset)\
230 { \
231     yuv2plane1_ ## template_size ## _c_template((const typeX_t *) src, \
232                          (uint16_t *) dest, dstW, is_be, bits); \
233 }\
234 static void yuv2planeX_ ## bits ## BE_LE ## _c(const int16_t *filter, int filterSize, \
235                               const int16_t **src, uint8_t *dest, int dstW, \
236                               const uint8_t *dither, int offset)\
237 { \
238     yuv2planeX_## template_size ## _c_template(filter, \
239                          filterSize, (const typeX_t **) src, \
240                          (uint16_t *) dest, dstW, is_be, bits); \
241 }
242 yuv2NBPS( 9, BE, 1, 10, int16_t)
243 yuv2NBPS( 9, LE, 0, 10, int16_t)
244 yuv2NBPS(10, BE, 1, 10, int16_t)
245 yuv2NBPS(10, LE, 0, 10, int16_t)
246 yuv2NBPS(12, BE, 1, 10, int16_t)
247 yuv2NBPS(12, LE, 0, 10, int16_t)
248 yuv2NBPS(14, BE, 1, 10, int16_t)
249 yuv2NBPS(14, LE, 0, 10, int16_t)
250 yuv2NBPS(16, BE, 1, 16, int32_t)
251 yuv2NBPS(16, LE, 0, 16, int32_t)
252
253 static void yuv2planeX_8_c(const int16_t *filter, int filterSize,
254                            const int16_t **src, uint8_t *dest, int dstW,
255                            const uint8_t *dither, int offset)
256 {
257     int i;
258     for (i=0; i<dstW; i++) {
259         int val = dither[(i + offset) & 7] << 12;
260         int j;
261         for (j=0; j<filterSize; j++)
262             val += src[j][i] * filter[j];
263
264         dest[i]= av_clip_uint8(val>>19);
265     }
266 }
267
268 static void yuv2plane1_8_c(const int16_t *src, uint8_t *dest, int dstW,
269                            const uint8_t *dither, int offset)
270 {
271     int i;
272     for (i=0; i<dstW; i++) {
273         int val = (src[i] + dither[(i + offset) & 7]) >> 7;
274         dest[i]= av_clip_uint8(val);
275     }
276 }
277
278 static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize,
279                         const int16_t **chrUSrc, const int16_t **chrVSrc,
280                         uint8_t *dest, int chrDstW)
281 {
282     enum AVPixelFormat dstFormat = c->dstFormat;
283     const uint8_t *chrDither = c->chrDither8;
284     int i;
285
286     if (dstFormat == AV_PIX_FMT_NV12)
287         for (i=0; i<chrDstW; i++) {
288             int u = chrDither[i & 7] << 12;
289             int v = chrDither[(i + 3) & 7] << 12;
290             int j;
291             for (j=0; j<chrFilterSize; j++) {
292                 u += chrUSrc[j][i] * chrFilter[j];
293                 v += chrVSrc[j][i] * chrFilter[j];
294             }
295
296             dest[2*i]= av_clip_uint8(u>>19);
297             dest[2*i+1]= av_clip_uint8(v>>19);
298         }
299     else
300         for (i=0; i<chrDstW; i++) {
301             int u = chrDither[i & 7] << 12;
302             int v = chrDither[(i + 3) & 7] << 12;
303             int j;
304             for (j=0; j<chrFilterSize; j++) {
305                 u += chrUSrc[j][i] * chrFilter[j];
306                 v += chrVSrc[j][i] * chrFilter[j];
307             }
308
309             dest[2*i]= av_clip_uint8(v>>19);
310             dest[2*i+1]= av_clip_uint8(u>>19);
311         }
312 }
313
314 #define accumulate_bit(acc, val) \
315     acc <<= 1; \
316     acc |= (val) >= (128 + 110)
317 #define output_pixel(pos, acc) \
318     if (target == AV_PIX_FMT_MONOBLACK) { \
319         pos = acc; \
320     } else { \
321         pos = ~acc; \
322     }
323
324 static av_always_inline void
325 yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
326                       const int16_t **lumSrc, int lumFilterSize,
327                       const int16_t *chrFilter, const int16_t **chrUSrc,
328                       const int16_t **chrVSrc, int chrFilterSize,
329                       const int16_t **alpSrc, uint8_t *dest, int dstW,
330                       int y, enum AVPixelFormat target)
331 {
332     const uint8_t * const d128 = ff_dither_8x8_220[y&7];
333     int i;
334     unsigned acc = 0;
335     int err = 0;
336
337     for (i = 0; i < dstW; i += 2) {
338         int j;
339         int Y1 = 1 << 18;
340         int Y2 = 1 << 18;
341
342         for (j = 0; j < lumFilterSize; j++) {
343             Y1 += lumSrc[j][i]   * lumFilter[j];
344             Y2 += lumSrc[j][i+1] * lumFilter[j];
345         }
346         Y1 >>= 19;
347         Y2 >>= 19;
348         if ((Y1 | Y2) & 0x100) {
349             Y1 = av_clip_uint8(Y1);
350             Y2 = av_clip_uint8(Y2);
351         }
352         if (c->dither == SWS_DITHER_ED) {
353             Y1 += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
354             c->dither_error[0][i] = err;
355             acc = 2*acc + (Y1 >= 128);
356             Y1 -= 220*(acc&1);
357
358             err = Y2 + ((7*Y1 + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4);
359             c->dither_error[0][i+1] = Y1;
360             acc = 2*acc + (err >= 128);
361             err -= 220*(acc&1);
362         } else {
363             accumulate_bit(acc, Y1 + d128[(i + 0) & 7]);
364             accumulate_bit(acc, Y2 + d128[(i + 1) & 7]);
365         }
366         if ((i & 7) == 6) {
367             output_pixel(*dest++, acc);
368         }
369     }
370     c->dither_error[0][i] = err;
371
372     if (i & 6) {
373         output_pixel(*dest, acc);
374     }
375 }
376
377 static av_always_inline void
378 yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2],
379                       const int16_t *ubuf[2], const int16_t *vbuf[2],
380                       const int16_t *abuf[2], uint8_t *dest, int dstW,
381                       int yalpha, int uvalpha, int y,
382                       enum AVPixelFormat target)
383 {
384     const int16_t *buf0  = buf[0],  *buf1  = buf[1];
385     const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
386     int  yalpha1 = 4096 - yalpha;
387     int i;
388
389     if (c->dither == SWS_DITHER_ED) {
390         int err = 0;
391         int acc = 0;
392         for (i = 0; i < dstW; i +=2) {
393             int Y;
394
395             Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19;
396             Y += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
397             c->dither_error[0][i] = err;
398             acc = 2*acc + (Y >= 128);
399             Y -= 220*(acc&1);
400
401             err = (buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19;
402             err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4;
403             c->dither_error[0][i+1] = Y;
404             acc = 2*acc + (err >= 128);
405             err -= 220*(acc&1);
406
407             if ((i & 7) == 6)
408                 output_pixel(*dest++, acc);
409         }
410         c->dither_error[0][i] = err;
411     } else {
412     for (i = 0; i < dstW; i += 8) {
413         int Y, acc = 0;
414
415         Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19;
416         accumulate_bit(acc, Y + d128[0]);
417         Y = (buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19;
418         accumulate_bit(acc, Y + d128[1]);
419         Y = (buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19;
420         accumulate_bit(acc, Y + d128[2]);
421         Y = (buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19;
422         accumulate_bit(acc, Y + d128[3]);
423         Y = (buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19;
424         accumulate_bit(acc, Y + d128[4]);
425         Y = (buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19;
426         accumulate_bit(acc, Y + d128[5]);
427         Y = (buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19;
428         accumulate_bit(acc, Y + d128[6]);
429         Y = (buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19;
430         accumulate_bit(acc, Y + d128[7]);
431
432         output_pixel(*dest++, acc);
433     }
434     }
435 }
436
437 static av_always_inline void
438 yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0,
439                       const int16_t *ubuf[2], const int16_t *vbuf[2],
440                       const int16_t *abuf0, uint8_t *dest, int dstW,
441                       int uvalpha, int y, enum AVPixelFormat target)
442 {
443     const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
444     int i;
445
446     if (c->dither == SWS_DITHER_ED) {
447         int err = 0;
448         int acc = 0;
449         for (i = 0; i < dstW; i +=2) {
450             int Y;
451
452             Y = ((buf0[i + 0] + 64) >> 7);
453             Y += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
454             c->dither_error[0][i] = err;
455             acc = 2*acc + (Y >= 128);
456             Y -= 220*(acc&1);
457
458             err = ((buf0[i + 1] + 64) >> 7);
459             err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4;
460             c->dither_error[0][i+1] = Y;
461             acc = 2*acc + (err >= 128);
462             err -= 220*(acc&1);
463
464             if ((i & 7) == 6)
465                 output_pixel(*dest++, acc);
466         }
467         c->dither_error[0][i] = err;
468     } else {
469     for (i = 0; i < dstW; i += 8) {
470         int acc = 0;
471         accumulate_bit(acc, ((buf0[i + 0] + 64) >> 7) + d128[0]);
472         accumulate_bit(acc, ((buf0[i + 1] + 64) >> 7) + d128[1]);
473         accumulate_bit(acc, ((buf0[i + 2] + 64) >> 7) + d128[2]);
474         accumulate_bit(acc, ((buf0[i + 3] + 64) >> 7) + d128[3]);
475         accumulate_bit(acc, ((buf0[i + 4] + 64) >> 7) + d128[4]);
476         accumulate_bit(acc, ((buf0[i + 5] + 64) >> 7) + d128[5]);
477         accumulate_bit(acc, ((buf0[i + 6] + 64) >> 7) + d128[6]);
478         accumulate_bit(acc, ((buf0[i + 7] + 64) >> 7) + d128[7]);
479
480         output_pixel(*dest++, acc);
481     }
482     }
483 }
484
485 #undef output_pixel
486 #undef accumulate_bit
487
488 #define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
489 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
490                                 const int16_t **lumSrc, int lumFilterSize, \
491                                 const int16_t *chrFilter, const int16_t **chrUSrc, \
492                                 const int16_t **chrVSrc, int chrFilterSize, \
493                                 const int16_t **alpSrc, uint8_t *dest, int dstW, \
494                                 int y) \
495 { \
496     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
497                                   chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
498                                   alpSrc, dest, dstW, y, fmt); \
499 } \
500  \
501 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
502                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
503                                 const int16_t *abuf[2], uint8_t *dest, int dstW, \
504                                 int yalpha, int uvalpha, int y) \
505 { \
506     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
507                                   dest, dstW, yalpha, uvalpha, y, fmt); \
508 } \
509  \
510 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
511                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
512                                 const int16_t *abuf0, uint8_t *dest, int dstW, \
513                                 int uvalpha, int y) \
514 { \
515     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, \
516                                   abuf0, dest, dstW, uvalpha, \
517                                   y, fmt); \
518 }
519
520 YUV2PACKEDWRAPPER(yuv2mono,, white, AV_PIX_FMT_MONOWHITE)
521 YUV2PACKEDWRAPPER(yuv2mono,, black, AV_PIX_FMT_MONOBLACK)
522
523 #define output_pixels(pos, Y1, U, Y2, V) \
524     if (target == AV_PIX_FMT_YUYV422) { \
525         dest[pos + 0] = Y1; \
526         dest[pos + 1] = U;  \
527         dest[pos + 2] = Y2; \
528         dest[pos + 3] = V;  \
529     } else { \
530         dest[pos + 0] = U;  \
531         dest[pos + 1] = Y1; \
532         dest[pos + 2] = V;  \
533         dest[pos + 3] = Y2; \
534     }
535
536 static av_always_inline void
537 yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
538                      const int16_t **lumSrc, int lumFilterSize,
539                      const int16_t *chrFilter, const int16_t **chrUSrc,
540                      const int16_t **chrVSrc, int chrFilterSize,
541                      const int16_t **alpSrc, uint8_t *dest, int dstW,
542                      int y, enum AVPixelFormat target)
543 {
544     int i;
545
546     for (i = 0; i < ((dstW + 1) >> 1); i++) {
547         int j;
548         int Y1 = 1 << 18;
549         int Y2 = 1 << 18;
550         int U  = 1 << 18;
551         int V  = 1 << 18;
552
553         for (j = 0; j < lumFilterSize; j++) {
554             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
555             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
556         }
557         for (j = 0; j < chrFilterSize; j++) {
558             U += chrUSrc[j][i] * chrFilter[j];
559             V += chrVSrc[j][i] * chrFilter[j];
560         }
561         Y1 >>= 19;
562         Y2 >>= 19;
563         U  >>= 19;
564         V  >>= 19;
565         if ((Y1 | Y2 | U | V) & 0x100) {
566             Y1 = av_clip_uint8(Y1);
567             Y2 = av_clip_uint8(Y2);
568             U  = av_clip_uint8(U);
569             V  = av_clip_uint8(V);
570         }
571         output_pixels(4*i, Y1, U, Y2, V);
572     }
573 }
574
575 static av_always_inline void
576 yuv2422_2_c_template(SwsContext *c, const int16_t *buf[2],
577                      const int16_t *ubuf[2], const int16_t *vbuf[2],
578                      const int16_t *abuf[2], uint8_t *dest, int dstW,
579                      int yalpha, int uvalpha, int y,
580                      enum AVPixelFormat target)
581 {
582     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
583                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
584                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
585     int  yalpha1 = 4096 - yalpha;
586     int uvalpha1 = 4096 - uvalpha;
587     int i;
588
589     for (i = 0; i < ((dstW + 1) >> 1); i++) {
590         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
591         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
592         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
593         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
594
595         if ((Y1 | Y2 | U | V) & 0x100) {
596             Y1 = av_clip_uint8(Y1);
597             Y2 = av_clip_uint8(Y2);
598             U  = av_clip_uint8(U);
599             V  = av_clip_uint8(V);
600         }
601
602         output_pixels(i * 4, Y1, U, Y2, V);
603     }
604 }
605
606 static av_always_inline void
607 yuv2422_1_c_template(SwsContext *c, const int16_t *buf0,
608                      const int16_t *ubuf[2], const int16_t *vbuf[2],
609                      const int16_t *abuf0, uint8_t *dest, int dstW,
610                      int uvalpha, int y, enum AVPixelFormat target)
611 {
612     const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
613     int i;
614
615     if (uvalpha < 2048) {
616         for (i = 0; i < ((dstW + 1) >> 1); i++) {
617             int Y1 = (buf0[i * 2    ]+64) >> 7;
618             int Y2 = (buf0[i * 2 + 1]+64) >> 7;
619             int U  = (ubuf0[i]       +64) >> 7;
620             int V  = (vbuf0[i]       +64) >> 7;
621
622             if ((Y1 | Y2 | U | V) & 0x100) {
623                 Y1 = av_clip_uint8(Y1);
624                 Y2 = av_clip_uint8(Y2);
625                 U  = av_clip_uint8(U);
626                 V  = av_clip_uint8(V);
627             }
628
629             Y1 = av_clip_uint8(Y1);
630             Y2 = av_clip_uint8(Y2);
631             U  = av_clip_uint8(U);
632             V  = av_clip_uint8(V);
633
634             output_pixels(i * 4, Y1, U, Y2, V);
635         }
636     } else {
637         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
638         for (i = 0; i < ((dstW + 1) >> 1); i++) {
639             int Y1 = (buf0[i * 2    ]    + 64) >> 7;
640             int Y2 = (buf0[i * 2 + 1]    + 64) >> 7;
641             int U  = (ubuf0[i] + ubuf1[i]+128) >> 8;
642             int V  = (vbuf0[i] + vbuf1[i]+128) >> 8;
643
644             if ((Y1 | Y2 | U | V) & 0x100) {
645                 Y1 = av_clip_uint8(Y1);
646                 Y2 = av_clip_uint8(Y2);
647                 U  = av_clip_uint8(U);
648                 V  = av_clip_uint8(V);
649             }
650
651             Y1 = av_clip_uint8(Y1);
652             Y2 = av_clip_uint8(Y2);
653             U  = av_clip_uint8(U);
654             V  = av_clip_uint8(V);
655
656             output_pixels(i * 4, Y1, U, Y2, V);
657         }
658     }
659 }
660
661 #undef output_pixels
662
663 YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, AV_PIX_FMT_YUYV422)
664 YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, AV_PIX_FMT_UYVY422)
665
666 #define R_B ((target == AV_PIX_FMT_RGB48LE || target == AV_PIX_FMT_RGB48BE || target == AV_PIX_FMT_RGBA64LE || target == AV_PIX_FMT_RGBA64BE) ? R : B)
667 #define B_R ((target == AV_PIX_FMT_RGB48LE || target == AV_PIX_FMT_RGB48BE || target == AV_PIX_FMT_RGBA64LE || target == AV_PIX_FMT_RGBA64BE) ? B : R)
668 #define output_pixel(pos, val) \
669     if (isBE(target)) { \
670         AV_WB16(pos, val); \
671     } else { \
672         AV_WL16(pos, val); \
673     }
674
675 static av_always_inline void
676 yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter,
677                        const int32_t **lumSrc, int lumFilterSize,
678                        const int16_t *chrFilter, const int32_t **chrUSrc,
679                        const int32_t **chrVSrc, int chrFilterSize,
680                        const int32_t **alpSrc, uint16_t *dest, int dstW,
681                        int y, enum AVPixelFormat target, int hasAlpha)
682 {
683     int i;
684     int A1 = 0xffff<<14, A2 = 0xffff<<14;
685
686     for (i = 0; i < ((dstW + 1) >> 1); i++) {
687         int j;
688         int Y1 = -0x40000000;
689         int Y2 = -0x40000000;
690         int U  = -128 << 23; // 19
691         int V  = -128 << 23;
692         int R, G, B;
693
694         for (j = 0; j < lumFilterSize; j++) {
695             Y1 += lumSrc[j][i * 2]     * (unsigned)lumFilter[j];
696             Y2 += lumSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
697         }
698         for (j = 0; j < chrFilterSize; j++) {;
699             U += chrUSrc[j][i] * (unsigned)chrFilter[j];
700             V += chrVSrc[j][i] * (unsigned)chrFilter[j];
701         }
702
703         if (hasAlpha) {
704             A1 = -0x40000000;
705             A2 = -0x40000000;
706             for (j = 0; j < lumFilterSize; j++) {
707                 A1 += alpSrc[j][i * 2]     * (unsigned)lumFilter[j];
708                 A2 += alpSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
709             }
710             A1 >>= 1;
711             A1 += 0x20002000;
712             A2 >>= 1;
713             A2 += 0x20002000;
714         }
715
716         // 8bit: 12+15=27; 16-bit: 12+19=31
717         Y1 >>= 14; // 10
718         Y1 += 0x10000;
719         Y2 >>= 14;
720         Y2 += 0x10000;
721         U  >>= 14;
722         V  >>= 14;
723
724         // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
725         Y1 -= c->yuv2rgb_y_offset;
726         Y2 -= c->yuv2rgb_y_offset;
727         Y1 *= c->yuv2rgb_y_coeff;
728         Y2 *= c->yuv2rgb_y_coeff;
729         Y1 += 1 << 13; // 21
730         Y2 += 1 << 13;
731         // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
732
733         R = V * c->yuv2rgb_v2r_coeff;
734         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
735         B =                            U * c->yuv2rgb_u2b_coeff;
736
737         // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
738         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
739         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
740         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
741         output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
742         output_pixel(&dest[4], av_clip_uintp2(R_B + Y2, 30) >> 14);
743         output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
744         output_pixel(&dest[6], av_clip_uintp2(B_R + Y2, 30) >> 14);
745         output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
746         dest += 8;
747     }
748 }
749
750 static av_always_inline void
751 yuv2rgba64_2_c_template(SwsContext *c, const int32_t *buf[2],
752                        const int32_t *ubuf[2], const int32_t *vbuf[2],
753                        const int32_t *abuf[2], uint16_t *dest, int dstW,
754                        int yalpha, int uvalpha, int y,
755                        enum AVPixelFormat target, int hasAlpha)
756 {
757     const int32_t *buf0  = buf[0],  *buf1  = buf[1],
758                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
759                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
760                   *abuf0 = hasAlpha ? abuf[0] : NULL,
761                   *abuf1 = hasAlpha ? abuf[1] : NULL;
762     int  yalpha1 = 4096 - yalpha;
763     int uvalpha1 = 4096 - uvalpha;
764     int i;
765     int A1 = 0xffff<<14, A2 = 0xffff<<14;
766
767     for (i = 0; i < ((dstW + 1) >> 1); i++) {
768         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha) >> 14;
769         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha) >> 14;
770         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha + (-128 << 23)) >> 14;
771         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha + (-128 << 23)) >> 14;
772         int R, G, B;
773
774         Y1 -= c->yuv2rgb_y_offset;
775         Y2 -= c->yuv2rgb_y_offset;
776         Y1 *= c->yuv2rgb_y_coeff;
777         Y2 *= c->yuv2rgb_y_coeff;
778         Y1 += 1 << 13;
779         Y2 += 1 << 13;
780
781         R = V * c->yuv2rgb_v2r_coeff;
782         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
783         B =                            U * c->yuv2rgb_u2b_coeff;
784
785         if (hasAlpha) {
786             A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 1;
787             A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 1;
788
789             A1 += 1 << 13;
790             A2 += 1 << 13;
791         }
792
793         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
794         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
795         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
796         output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
797         output_pixel(&dest[4], av_clip_uintp2(R_B + Y2, 30) >> 14);
798         output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
799         output_pixel(&dest[6], av_clip_uintp2(B_R + Y2, 30) >> 14);
800         output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
801         dest += 8;
802     }
803 }
804
805 static av_always_inline void
806 yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0,
807                        const int32_t *ubuf[2], const int32_t *vbuf[2],
808                        const int32_t *abuf0, uint16_t *dest, int dstW,
809                        int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
810 {
811     const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
812     int i;
813     int A1 = 0xffff<<14, A2= 0xffff<<14;
814
815     if (uvalpha < 2048) {
816         for (i = 0; i < ((dstW + 1) >> 1); i++) {
817             int Y1 = (buf0[i * 2]    ) >> 2;
818             int Y2 = (buf0[i * 2 + 1]) >> 2;
819             int U  = (ubuf0[i] + (-128 << 11)) >> 2;
820             int V  = (vbuf0[i] + (-128 << 11)) >> 2;
821             int R, G, B;
822
823             Y1 -= c->yuv2rgb_y_offset;
824             Y2 -= c->yuv2rgb_y_offset;
825             Y1 *= c->yuv2rgb_y_coeff;
826             Y2 *= c->yuv2rgb_y_coeff;
827             Y1 += 1 << 13;
828             Y2 += 1 << 13;
829
830             if (hasAlpha) {
831                 A1 = abuf0[i * 2    ] << 11;
832                 A2 = abuf0[i * 2 + 1] << 11;
833
834                 A1 += 1 << 13;
835                 A2 += 1 << 13;
836             }
837
838             R = V * c->yuv2rgb_v2r_coeff;
839             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
840             B =                            U * c->yuv2rgb_u2b_coeff;
841
842             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
843             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
844             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
845             output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
846             output_pixel(&dest[4], av_clip_uintp2(R_B + Y2, 30) >> 14);
847             output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
848             output_pixel(&dest[6], av_clip_uintp2(B_R + Y2, 30) >> 14);
849             output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
850             dest += 8;
851         }
852     } else {
853         const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
854         int A1 = 0xffff<<14, A2 = 0xffff<<14;
855         for (i = 0; i < ((dstW + 1) >> 1); i++) {
856             int Y1 = (buf0[i * 2]    ) >> 2;
857             int Y2 = (buf0[i * 2 + 1]) >> 2;
858             int U  = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
859             int V  = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
860             int R, G, B;
861
862             Y1 -= c->yuv2rgb_y_offset;
863             Y2 -= c->yuv2rgb_y_offset;
864             Y1 *= c->yuv2rgb_y_coeff;
865             Y2 *= c->yuv2rgb_y_coeff;
866             Y1 += 1 << 13;
867             Y2 += 1 << 13;
868
869             if (hasAlpha) {
870                 A1 = abuf0[i * 2    ] << 11;
871                 A2 = abuf0[i * 2 + 1] << 11;
872
873                 A1 += 1 << 13;
874                 A2 += 1 << 13;
875             }
876
877             R = V * c->yuv2rgb_v2r_coeff;
878             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
879             B =                            U * c->yuv2rgb_u2b_coeff;
880
881             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
882             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
883             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
884             output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
885             output_pixel(&dest[4], av_clip_uintp2(R_B + Y2, 30) >> 14);
886             output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
887             output_pixel(&dest[6], av_clip_uintp2(B_R + Y2, 30) >> 14);
888             output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
889             dest += 8;
890         }
891     }
892 }
893
894 static av_always_inline void
895 yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
896                        const int32_t **lumSrc, int lumFilterSize,
897                        const int16_t *chrFilter, const int32_t **chrUSrc,
898                        const int32_t **chrVSrc, int chrFilterSize,
899                        const int32_t **alpSrc, uint16_t *dest, int dstW,
900                        int y, enum AVPixelFormat target, int hasAlpha)
901 {
902     int i;
903
904     for (i = 0; i < ((dstW + 1) >> 1); i++) {
905         int j;
906         int Y1 = -0x40000000;
907         int Y2 = -0x40000000;
908         int U  = -128 << 23; // 19
909         int V  = -128 << 23;
910         int R, G, B;
911
912         for (j = 0; j < lumFilterSize; j++) {
913             Y1 += lumSrc[j][i * 2]     * (unsigned)lumFilter[j];
914             Y2 += lumSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
915         }
916         for (j = 0; j < chrFilterSize; j++) {;
917             U += chrUSrc[j][i] * (unsigned)chrFilter[j];
918             V += chrVSrc[j][i] * (unsigned)chrFilter[j];
919         }
920
921         // 8bit: 12+15=27; 16-bit: 12+19=31
922         Y1 >>= 14; // 10
923         Y1 += 0x10000;
924         Y2 >>= 14;
925         Y2 += 0x10000;
926         U  >>= 14;
927         V  >>= 14;
928
929         // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
930         Y1 -= c->yuv2rgb_y_offset;
931         Y2 -= c->yuv2rgb_y_offset;
932         Y1 *= c->yuv2rgb_y_coeff;
933         Y2 *= c->yuv2rgb_y_coeff;
934         Y1 += 1 << 13; // 21
935         Y2 += 1 << 13;
936         // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
937
938         R = V * c->yuv2rgb_v2r_coeff;
939         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
940         B =                            U * c->yuv2rgb_u2b_coeff;
941
942         // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
943         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
944         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
945         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
946         output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
947         output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
948         output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
949         dest += 6;
950     }
951 }
952
953 static av_always_inline void
954 yuv2rgb48_2_c_template(SwsContext *c, const int32_t *buf[2],
955                        const int32_t *ubuf[2], const int32_t *vbuf[2],
956                        const int32_t *abuf[2], uint16_t *dest, int dstW,
957                        int yalpha, int uvalpha, int y,
958                        enum AVPixelFormat target, int hasAlpha)
959 {
960     const int32_t *buf0  = buf[0],  *buf1  = buf[1],
961                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
962                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
963     int  yalpha1 = 4096 - yalpha;
964     int uvalpha1 = 4096 - uvalpha;
965     int i;
966
967     for (i = 0; i < ((dstW + 1) >> 1); i++) {
968         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha) >> 14;
969         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha) >> 14;
970         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha + (-128 << 23)) >> 14;
971         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha + (-128 << 23)) >> 14;
972         int R, G, B;
973
974         Y1 -= c->yuv2rgb_y_offset;
975         Y2 -= c->yuv2rgb_y_offset;
976         Y1 *= c->yuv2rgb_y_coeff;
977         Y2 *= c->yuv2rgb_y_coeff;
978         Y1 += 1 << 13;
979         Y2 += 1 << 13;
980
981         R = V * c->yuv2rgb_v2r_coeff;
982         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
983         B =                            U * c->yuv2rgb_u2b_coeff;
984
985         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
986         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
987         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
988         output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
989         output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
990         output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
991         dest += 6;
992     }
993 }
994
995 static av_always_inline void
996 yuv2rgb48_1_c_template(SwsContext *c, const int32_t *buf0,
997                        const int32_t *ubuf[2], const int32_t *vbuf[2],
998                        const int32_t *abuf0, uint16_t *dest, int dstW,
999                        int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
1000 {
1001     const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
1002     int i;
1003
1004     if (uvalpha < 2048) {
1005         for (i = 0; i < ((dstW + 1) >> 1); i++) {
1006             int Y1 = (buf0[i * 2]    ) >> 2;
1007             int Y2 = (buf0[i * 2 + 1]) >> 2;
1008             int U  = (ubuf0[i] + (-128 << 11)) >> 2;
1009             int V  = (vbuf0[i] + (-128 << 11)) >> 2;
1010             int R, G, B;
1011
1012             Y1 -= c->yuv2rgb_y_offset;
1013             Y2 -= c->yuv2rgb_y_offset;
1014             Y1 *= c->yuv2rgb_y_coeff;
1015             Y2 *= c->yuv2rgb_y_coeff;
1016             Y1 += 1 << 13;
1017             Y2 += 1 << 13;
1018
1019             R = V * c->yuv2rgb_v2r_coeff;
1020             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
1021             B =                            U * c->yuv2rgb_u2b_coeff;
1022
1023             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
1024             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
1025             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
1026             output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
1027             output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
1028             output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
1029             dest += 6;
1030         }
1031     } else {
1032         const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
1033         for (i = 0; i < ((dstW + 1) >> 1); i++) {
1034             int Y1 = (buf0[i * 2]    ) >> 2;
1035             int Y2 = (buf0[i * 2 + 1]) >> 2;
1036             int U  = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
1037             int V  = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
1038             int R, G, B;
1039
1040             Y1 -= c->yuv2rgb_y_offset;
1041             Y2 -= c->yuv2rgb_y_offset;
1042             Y1 *= c->yuv2rgb_y_coeff;
1043             Y2 *= c->yuv2rgb_y_coeff;
1044             Y1 += 1 << 13;
1045             Y2 += 1 << 13;
1046
1047             R = V * c->yuv2rgb_v2r_coeff;
1048             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
1049             B =                            U * c->yuv2rgb_u2b_coeff;
1050
1051             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
1052             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
1053             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
1054             output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
1055             output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
1056             output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
1057             dest += 6;
1058         }
1059     }
1060 }
1061
1062 #undef output_pixel
1063 #undef r_b
1064 #undef b_r
1065
1066 #define YUV2PACKED16WRAPPER(name, base, ext, fmt, hasAlpha) \
1067 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
1068                         const int16_t **_lumSrc, int lumFilterSize, \
1069                         const int16_t *chrFilter, const int16_t **_chrUSrc, \
1070                         const int16_t **_chrVSrc, int chrFilterSize, \
1071                         const int16_t **_alpSrc, uint8_t *_dest, int dstW, \
1072                         int y) \
1073 { \
1074     const int32_t **lumSrc  = (const int32_t **) _lumSrc, \
1075                   **chrUSrc = (const int32_t **) _chrUSrc, \
1076                   **chrVSrc = (const int32_t **) _chrVSrc, \
1077                   **alpSrc  = (const int32_t **) _alpSrc; \
1078     uint16_t *dest = (uint16_t *) _dest; \
1079     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
1080                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
1081                           alpSrc, dest, dstW, y, fmt, hasAlpha); \
1082 } \
1083  \
1084 static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \
1085                         const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
1086                         const int16_t *_abuf[2], uint8_t *_dest, int dstW, \
1087                         int yalpha, int uvalpha, int y) \
1088 { \
1089     const int32_t **buf  = (const int32_t **) _buf, \
1090                   **ubuf = (const int32_t **) _ubuf, \
1091                   **vbuf = (const int32_t **) _vbuf, \
1092                   **abuf = (const int32_t **) _abuf; \
1093     uint16_t *dest = (uint16_t *) _dest; \
1094     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
1095                           dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
1096 } \
1097  \
1098 static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \
1099                         const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
1100                         const int16_t *_abuf0, uint8_t *_dest, int dstW, \
1101                         int uvalpha, int y) \
1102 { \
1103     const int32_t *buf0  = (const int32_t *)  _buf0, \
1104                  **ubuf  = (const int32_t **) _ubuf, \
1105                  **vbuf  = (const int32_t **) _vbuf, \
1106                   *abuf0 = (const int32_t *)  _abuf0; \
1107     uint16_t *dest = (uint16_t *) _dest; \
1108     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
1109                                   dstW, uvalpha, y, fmt, hasAlpha); \
1110 }
1111
1112 YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48be, AV_PIX_FMT_RGB48BE, 0)
1113 YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, AV_PIX_FMT_RGB48LE, 0)
1114 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, AV_PIX_FMT_BGR48BE, 0)
1115 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, AV_PIX_FMT_BGR48LE, 0)
1116 YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64be, AV_PIX_FMT_RGBA64BE, 1)
1117 YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64le, AV_PIX_FMT_RGBA64LE, 1)
1118 YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64be, AV_PIX_FMT_RGBA64BE, 0)
1119 YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64le, AV_PIX_FMT_RGBA64LE, 0)
1120 YUV2PACKED16WRAPPER(yuv2, rgba64, bgra64be, AV_PIX_FMT_BGRA64BE, 1)
1121 YUV2PACKED16WRAPPER(yuv2, rgba64, bgra64le, AV_PIX_FMT_BGRA64LE, 1)
1122 YUV2PACKED16WRAPPER(yuv2, rgba64, bgrx64be, AV_PIX_FMT_BGRA64BE, 0)
1123 YUV2PACKED16WRAPPER(yuv2, rgba64, bgrx64le, AV_PIX_FMT_BGRA64LE, 0)
1124
1125 /*
1126  * Write out 2 RGB pixels in the target pixel format. This function takes a
1127  * R/G/B LUT as generated by ff_yuv2rgb_c_init_tables(), which takes care of
1128  * things like endianness conversion and shifting. The caller takes care of
1129  * setting the correct offset in these tables from the chroma (U/V) values.
1130  * This function then uses the luminance (Y1/Y2) values to write out the
1131  * correct RGB values into the destination buffer.
1132  */
1133 static av_always_inline void
1134 yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2,
1135               unsigned A1, unsigned A2,
1136               const void *_r, const void *_g, const void *_b, int y,
1137               enum AVPixelFormat target, int hasAlpha)
1138 {
1139     if (target == AV_PIX_FMT_ARGB || target == AV_PIX_FMT_RGBA ||
1140         target == AV_PIX_FMT_ABGR || target == AV_PIX_FMT_BGRA) {
1141         uint32_t *dest = (uint32_t *) _dest;
1142         const uint32_t *r = (const uint32_t *) _r;
1143         const uint32_t *g = (const uint32_t *) _g;
1144         const uint32_t *b = (const uint32_t *) _b;
1145
1146 #if CONFIG_SMALL
1147         int sh = hasAlpha ? ((target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24) : 0;
1148
1149         dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0);
1150         dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0);
1151 #else
1152         if (hasAlpha) {
1153             int sh = (target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24;
1154
1155             av_assert2((((r[Y1] + g[Y1] + b[Y1]) >> sh) & 0xFF) == 0);
1156             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (A1 << sh);
1157             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (A2 << sh);
1158         } else {
1159 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
1160             int sh = (target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24;
1161
1162             av_assert2((((r[Y1] + g[Y1] + b[Y1]) >> sh) & 0xFF) == 0xFF);
1163 #endif
1164             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1];
1165             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2];
1166         }
1167 #endif
1168     } else if (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) {
1169         uint8_t *dest = (uint8_t *) _dest;
1170         const uint8_t *r = (const uint8_t *) _r;
1171         const uint8_t *g = (const uint8_t *) _g;
1172         const uint8_t *b = (const uint8_t *) _b;
1173
1174 #define r_b ((target == AV_PIX_FMT_RGB24) ? r : b)
1175 #define b_r ((target == AV_PIX_FMT_RGB24) ? b : r)
1176
1177         dest[i * 6 + 0] = r_b[Y1];
1178         dest[i * 6 + 1] =   g[Y1];
1179         dest[i * 6 + 2] = b_r[Y1];
1180         dest[i * 6 + 3] = r_b[Y2];
1181         dest[i * 6 + 4] =   g[Y2];
1182         dest[i * 6 + 5] = b_r[Y2];
1183 #undef r_b
1184 #undef b_r
1185     } else if (target == AV_PIX_FMT_RGB565 || target == AV_PIX_FMT_BGR565 ||
1186                target == AV_PIX_FMT_RGB555 || target == AV_PIX_FMT_BGR555 ||
1187                target == AV_PIX_FMT_RGB444 || target == AV_PIX_FMT_BGR444) {
1188         uint16_t *dest = (uint16_t *) _dest;
1189         const uint16_t *r = (const uint16_t *) _r;
1190         const uint16_t *g = (const uint16_t *) _g;
1191         const uint16_t *b = (const uint16_t *) _b;
1192         int dr1, dg1, db1, dr2, dg2, db2;
1193
1194         if (target == AV_PIX_FMT_RGB565 || target == AV_PIX_FMT_BGR565) {
1195             dr1 = ff_dither_2x2_8[ y & 1     ][0];
1196             dg1 = ff_dither_2x2_4[ y & 1     ][0];
1197             db1 = ff_dither_2x2_8[(y & 1) ^ 1][0];
1198             dr2 = ff_dither_2x2_8[ y & 1     ][1];
1199             dg2 = ff_dither_2x2_4[ y & 1     ][1];
1200             db2 = ff_dither_2x2_8[(y & 1) ^ 1][1];
1201         } else if (target == AV_PIX_FMT_RGB555 || target == AV_PIX_FMT_BGR555) {
1202             dr1 = ff_dither_2x2_8[ y & 1     ][0];
1203             dg1 = ff_dither_2x2_8[ y & 1     ][1];
1204             db1 = ff_dither_2x2_8[(y & 1) ^ 1][0];
1205             dr2 = ff_dither_2x2_8[ y & 1     ][1];
1206             dg2 = ff_dither_2x2_8[ y & 1     ][0];
1207             db2 = ff_dither_2x2_8[(y & 1) ^ 1][1];
1208         } else {
1209             dr1 = ff_dither_4x4_16[ y & 3     ][0];
1210             dg1 = ff_dither_4x4_16[ y & 3     ][1];
1211             db1 = ff_dither_4x4_16[(y & 3) ^ 3][0];
1212             dr2 = ff_dither_4x4_16[ y & 3     ][1];
1213             dg2 = ff_dither_4x4_16[ y & 3     ][0];
1214             db2 = ff_dither_4x4_16[(y & 3) ^ 3][1];
1215         }
1216
1217         dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
1218         dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
1219     } else /* 8/4-bit */ {
1220         uint8_t *dest = (uint8_t *) _dest;
1221         const uint8_t *r = (const uint8_t *) _r;
1222         const uint8_t *g = (const uint8_t *) _g;
1223         const uint8_t *b = (const uint8_t *) _b;
1224         int dr1, dg1, db1, dr2, dg2, db2;
1225
1226         if (target == AV_PIX_FMT_RGB8 || target == AV_PIX_FMT_BGR8) {
1227             const uint8_t * const d64 = ff_dither_8x8_73[y & 7];
1228             const uint8_t * const d32 = ff_dither_8x8_32[y & 7];
1229             dr1 = dg1 = d32[(i * 2 + 0) & 7];
1230             db1 =       d64[(i * 2 + 0) & 7];
1231             dr2 = dg2 = d32[(i * 2 + 1) & 7];
1232             db2 =       d64[(i * 2 + 1) & 7];
1233         } else {
1234             const uint8_t * const d64  = ff_dither_8x8_73 [y & 7];
1235             const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
1236             dr1 = db1 = d128[(i * 2 + 0) & 7];
1237             dg1 =        d64[(i * 2 + 0) & 7];
1238             dr2 = db2 = d128[(i * 2 + 1) & 7];
1239             dg2 =        d64[(i * 2 + 1) & 7];
1240         }
1241
1242         if (target == AV_PIX_FMT_RGB4 || target == AV_PIX_FMT_BGR4) {
1243             dest[i] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1] +
1244                     ((r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]) << 4);
1245         } else {
1246             dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
1247             dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
1248         }
1249     }
1250 }
1251
1252 static av_always_inline void
1253 yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter,
1254                      const int16_t **lumSrc, int lumFilterSize,
1255                      const int16_t *chrFilter, const int16_t **chrUSrc,
1256                      const int16_t **chrVSrc, int chrFilterSize,
1257                      const int16_t **alpSrc, uint8_t *dest, int dstW,
1258                      int y, enum AVPixelFormat target, int hasAlpha)
1259 {
1260     int i;
1261
1262     for (i = 0; i < ((dstW + 1) >> 1); i++) {
1263         int j, A1, A2;
1264         int Y1 = 1 << 18;
1265         int Y2 = 1 << 18;
1266         int U  = 1 << 18;
1267         int V  = 1 << 18;
1268         const void *r, *g, *b;
1269
1270         for (j = 0; j < lumFilterSize; j++) {
1271             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
1272             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
1273         }
1274         for (j = 0; j < chrFilterSize; j++) {
1275             U += chrUSrc[j][i] * chrFilter[j];
1276             V += chrVSrc[j][i] * chrFilter[j];
1277         }
1278         Y1 >>= 19;
1279         Y2 >>= 19;
1280         U  >>= 19;
1281         V  >>= 19;
1282         if (hasAlpha) {
1283             A1 = 1 << 18;
1284             A2 = 1 << 18;
1285             for (j = 0; j < lumFilterSize; j++) {
1286                 A1 += alpSrc[j][i * 2    ] * lumFilter[j];
1287                 A2 += alpSrc[j][i * 2 + 1] * lumFilter[j];
1288             }
1289             A1 >>= 19;
1290             A2 >>= 19;
1291             if ((A1 | A2) & 0x100) {
1292                 A1 = av_clip_uint8(A1);
1293                 A2 = av_clip_uint8(A2);
1294             }
1295         }
1296
1297         r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM];
1298         g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]);
1299         b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1300
1301         yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1302                       r, g, b, y, target, hasAlpha);
1303     }
1304 }
1305
1306 static av_always_inline void
1307 yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
1308                      const int16_t *ubuf[2], const int16_t *vbuf[2],
1309                      const int16_t *abuf[2], uint8_t *dest, int dstW,
1310                      int yalpha, int uvalpha, int y,
1311                      enum AVPixelFormat target, int hasAlpha)
1312 {
1313     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
1314                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1315                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
1316                   *abuf0 = hasAlpha ? abuf[0] : NULL,
1317                   *abuf1 = hasAlpha ? abuf[1] : NULL;
1318     int  yalpha1 = 4096 - yalpha;
1319     int uvalpha1 = 4096 - uvalpha;
1320     int i;
1321
1322     for (i = 0; i < ((dstW + 1) >> 1); i++) {
1323         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
1324         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
1325         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
1326         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
1327         int A1, A2;
1328         const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
1329                    *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
1330                    *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1331
1332         if (hasAlpha) {
1333             A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 19;
1334             A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
1335             A1 = av_clip_uint8(A1);
1336             A2 = av_clip_uint8(A2);
1337         }
1338
1339         yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1340                       r, g, b, y, target, hasAlpha);
1341     }
1342 }
1343
1344 static av_always_inline void
1345 yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
1346                      const int16_t *ubuf[2], const int16_t *vbuf[2],
1347                      const int16_t *abuf0, uint8_t *dest, int dstW,
1348                      int uvalpha, int y, enum AVPixelFormat target,
1349                      int hasAlpha)
1350 {
1351     const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
1352     int i;
1353
1354     if (uvalpha < 2048) {
1355         for (i = 0; i < ((dstW + 1) >> 1); i++) {
1356             int Y1 = (buf0[i * 2    ] + 64) >> 7;
1357             int Y2 = (buf0[i * 2 + 1] + 64) >> 7;
1358             int U  = (ubuf0[i]        + 64) >> 7;
1359             int V  = (vbuf0[i]        + 64) >> 7;
1360             int A1, A2;
1361             const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
1362                        *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
1363                        *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1364
1365             if (hasAlpha) {
1366                 A1 = abuf0[i * 2    ] * 255 + 16384 >> 15;
1367                 A2 = abuf0[i * 2 + 1] * 255 + 16384 >> 15;
1368                 A1 = av_clip_uint8(A1);
1369                 A2 = av_clip_uint8(A2);
1370             }
1371
1372             yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1373                           r, g, b, y, target, hasAlpha);
1374         }
1375     } else {
1376         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
1377         for (i = 0; i < ((dstW + 1) >> 1); i++) {
1378             int Y1 = (buf0[i * 2    ]     +  64) >> 7;
1379             int Y2 = (buf0[i * 2 + 1]     +  64) >> 7;
1380             int U  = (ubuf0[i] + ubuf1[i] + 128) >> 8;
1381             int V  = (vbuf0[i] + vbuf1[i] + 128) >> 8;
1382             int A1, A2;
1383             const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
1384                        *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
1385                        *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1386
1387             if (hasAlpha) {
1388                 A1 = (abuf0[i * 2    ] + 64) >> 7;
1389                 A2 = (abuf0[i * 2 + 1] + 64) >> 7;
1390                 A1 = av_clip_uint8(A1);
1391                 A2 = av_clip_uint8(A2);
1392             }
1393
1394             yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1395                           r, g, b, y, target, hasAlpha);
1396         }
1397     }
1398 }
1399
1400 #define YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1401 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
1402                                 const int16_t **lumSrc, int lumFilterSize, \
1403                                 const int16_t *chrFilter, const int16_t **chrUSrc, \
1404                                 const int16_t **chrVSrc, int chrFilterSize, \
1405                                 const int16_t **alpSrc, uint8_t *dest, int dstW, \
1406                                 int y) \
1407 { \
1408     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
1409                                   chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
1410                                   alpSrc, dest, dstW, y, fmt, hasAlpha); \
1411 }
1412
1413 #define YUV2RGBWRAPPERX2(name, base, ext, fmt, hasAlpha) \
1414 YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1415 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
1416                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
1417                                 const int16_t *abuf[2], uint8_t *dest, int dstW, \
1418                                 int yalpha, int uvalpha, int y) \
1419 { \
1420     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
1421                                   dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
1422 }
1423
1424 #define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha) \
1425 YUV2RGBWRAPPERX2(name, base, ext, fmt, hasAlpha) \
1426 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
1427                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
1428                                 const int16_t *abuf0, uint8_t *dest, int dstW, \
1429                                 int uvalpha, int y) \
1430 { \
1431     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
1432                                   dstW, uvalpha, y, fmt, hasAlpha); \
1433 }
1434
1435 #if CONFIG_SMALL
1436 YUV2RGBWRAPPER(yuv2rgb,,  32_1,  AV_PIX_FMT_RGB32_1,   CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1437 YUV2RGBWRAPPER(yuv2rgb,,  32,    AV_PIX_FMT_RGB32,     CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1438 #else
1439 #if CONFIG_SWSCALE_ALPHA
1440 YUV2RGBWRAPPER(yuv2rgb,, a32_1,  AV_PIX_FMT_RGB32_1,   1)
1441 YUV2RGBWRAPPER(yuv2rgb,, a32,    AV_PIX_FMT_RGB32,     1)
1442 #endif
1443 YUV2RGBWRAPPER(yuv2rgb,, x32_1,  AV_PIX_FMT_RGB32_1,   0)
1444 YUV2RGBWRAPPER(yuv2rgb,, x32,    AV_PIX_FMT_RGB32,     0)
1445 #endif
1446 YUV2RGBWRAPPER(yuv2, rgb, rgb24, AV_PIX_FMT_RGB24,   0)
1447 YUV2RGBWRAPPER(yuv2, rgb, bgr24, AV_PIX_FMT_BGR24,   0)
1448 YUV2RGBWRAPPER(yuv2rgb,,  16,    AV_PIX_FMT_RGB565,    0)
1449 YUV2RGBWRAPPER(yuv2rgb,,  15,    AV_PIX_FMT_RGB555,    0)
1450 YUV2RGBWRAPPER(yuv2rgb,,  12,    AV_PIX_FMT_RGB444,    0)
1451 YUV2RGBWRAPPER(yuv2rgb,,   8,    AV_PIX_FMT_RGB8,      0)
1452 YUV2RGBWRAPPER(yuv2rgb,,   4,    AV_PIX_FMT_RGB4,      0)
1453 YUV2RGBWRAPPER(yuv2rgb,,   4b,   AV_PIX_FMT_RGB4_BYTE, 0)
1454
1455 static av_always_inline void yuv2rgb_write_full(SwsContext *c,
1456     uint8_t *dest, int i, int Y, int A, int U, int V,
1457     int y, enum AVPixelFormat target, int hasAlpha, int err[4])
1458 {
1459     int R, G, B;
1460     int isrgb8 = target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8;
1461
1462     Y -= c->yuv2rgb_y_offset;
1463     Y *= c->yuv2rgb_y_coeff;
1464     Y += 1 << 21;
1465     R = Y + V*c->yuv2rgb_v2r_coeff;
1466     G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
1467     B = Y +                          U*c->yuv2rgb_u2b_coeff;
1468     if ((R | G | B) & 0xC0000000) {
1469         R = av_clip_uintp2(R, 30);
1470         G = av_clip_uintp2(G, 30);
1471         B = av_clip_uintp2(B, 30);
1472     }
1473
1474     switch(target) {
1475     case AV_PIX_FMT_ARGB:
1476         dest[0] = hasAlpha ? A : 255;
1477         dest[1] = R >> 22;
1478         dest[2] = G >> 22;
1479         dest[3] = B >> 22;
1480         break;
1481     case AV_PIX_FMT_RGB24:
1482         dest[0] = R >> 22;
1483         dest[1] = G >> 22;
1484         dest[2] = B >> 22;
1485         break;
1486     case AV_PIX_FMT_RGBA:
1487         dest[0] = R >> 22;
1488         dest[1] = G >> 22;
1489         dest[2] = B >> 22;
1490         dest[3] = hasAlpha ? A : 255;
1491         break;
1492     case AV_PIX_FMT_ABGR:
1493         dest[0] = hasAlpha ? A : 255;
1494         dest[1] = B >> 22;
1495         dest[2] = G >> 22;
1496         dest[3] = R >> 22;
1497         break;
1498     case AV_PIX_FMT_BGR24:
1499         dest[0] = B >> 22;
1500         dest[1] = G >> 22;
1501         dest[2] = R >> 22;
1502         break;
1503     case AV_PIX_FMT_BGRA:
1504         dest[0] = B >> 22;
1505         dest[1] = G >> 22;
1506         dest[2] = R >> 22;
1507         dest[3] = hasAlpha ? A : 255;
1508         break;
1509     case AV_PIX_FMT_BGR4_BYTE:
1510     case AV_PIX_FMT_RGB4_BYTE:
1511     case AV_PIX_FMT_BGR8:
1512     case AV_PIX_FMT_RGB8:
1513     {
1514         int r,g,b;
1515
1516         switch (c->dither) {
1517         default:
1518         case SWS_DITHER_AUTO:
1519         case SWS_DITHER_ED:
1520             R >>= 22;
1521             G >>= 22;
1522             B >>= 22;
1523             R += (7*err[0] + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2])>>4;
1524             G += (7*err[1] + 1*c->dither_error[1][i] + 5*c->dither_error[1][i+1] + 3*c->dither_error[1][i+2])>>4;
1525             B += (7*err[2] + 1*c->dither_error[2][i] + 5*c->dither_error[2][i+1] + 3*c->dither_error[2][i+2])>>4;
1526             c->dither_error[0][i] = err[0];
1527             c->dither_error[1][i] = err[1];
1528             c->dither_error[2][i] = err[2];
1529             r = R >> (isrgb8 ? 5 : 7);
1530             g = G >> (isrgb8 ? 5 : 6);
1531             b = B >> (isrgb8 ? 6 : 7);
1532             r = av_clip(r, 0, isrgb8 ? 7 : 1);
1533             g = av_clip(g, 0, isrgb8 ? 7 : 3);
1534             b = av_clip(b, 0, isrgb8 ? 3 : 1);
1535             err[0] = R - r*(isrgb8 ? 36 : 255);
1536             err[1] = G - g*(isrgb8 ? 36 : 85);
1537             err[2] = B - b*(isrgb8 ? 85 : 255);
1538             break;
1539         case SWS_DITHER_A_DITHER:
1540             if (isrgb8) {
1541   /* see http://pippin.gimp.org/a_dither/ for details/origin */
1542 #define A_DITHER(u,v)   (((((u)+((v)*236))*119)&0xff))
1543                 r = (((R >> 19) + A_DITHER(i,y)  -96)>>8);
1544                 g = (((G >> 19) + A_DITHER(i + 17,y) - 96)>>8);
1545                 b = (((B >> 20) + A_DITHER(i + 17*2,y) -96)>>8);
1546                 r = av_clip(r, 0, 7);
1547                 g = av_clip(g, 0, 7);
1548                 b = av_clip(b, 0, 3);
1549             } else {
1550                 r = (((R >> 21) + A_DITHER(i,y)-256)>>8);
1551                 g = (((G >> 19) + A_DITHER(i + 17,y)-256)>>8);
1552                 b = (((B >> 21) + A_DITHER(i + 17*2,y)-256)>>8);
1553                 r = av_clip(r, 0, 1);
1554                 g = av_clip(g, 0, 3);
1555                 b = av_clip(b, 0, 1);
1556             }
1557             break;
1558         case SWS_DITHER_X_DITHER:
1559             if (isrgb8) {
1560   /* see http://pippin.gimp.org/a_dither/ for details/origin */
1561 #define X_DITHER(u,v)   (((((u)^((v)*237))*181)&0x1ff)/2)
1562                 r = (((R >> 19) + X_DITHER(i,y) - 96)>>8);
1563                 g = (((G >> 19) + X_DITHER(i + 17,y) - 96)>>8);
1564                 b = (((B >> 20) + X_DITHER(i + 17*2,y) - 96)>>8);
1565                 r = av_clip(r, 0, 7);
1566                 g = av_clip(g, 0, 7);
1567                 b = av_clip(b, 0, 3);
1568             } else {
1569                 r = (((R >> 21) + X_DITHER(i,y)-256)>>8);
1570                 g = (((G >> 19) + X_DITHER(i + 17,y)-256)>>8);
1571                 b = (((B >> 21) + X_DITHER(i + 17*2,y)-256)>>8);
1572                 r = av_clip(r, 0, 1);
1573                 g = av_clip(g, 0, 3);
1574                 b = av_clip(b, 0, 1);
1575             }
1576
1577             break;
1578         }
1579
1580         if(target == AV_PIX_FMT_BGR4_BYTE) {
1581             dest[0] = r + 2*g + 8*b;
1582         } else if(target == AV_PIX_FMT_RGB4_BYTE) {
1583             dest[0] = b + 2*g + 8*r;
1584         } else if(target == AV_PIX_FMT_BGR8) {
1585             dest[0] = r + 8*g + 64*b;
1586         } else if(target == AV_PIX_FMT_RGB8) {
1587             dest[0] = b + 4*g + 32*r;
1588         } else
1589             av_assert2(0);
1590         break;}
1591     }
1592 }
1593
1594 static av_always_inline void
1595 yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
1596                           const int16_t **lumSrc, int lumFilterSize,
1597                           const int16_t *chrFilter, const int16_t **chrUSrc,
1598                           const int16_t **chrVSrc, int chrFilterSize,
1599                           const int16_t **alpSrc, uint8_t *dest,
1600                           int dstW, int y, enum AVPixelFormat target, int hasAlpha)
1601 {
1602     int i;
1603     int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
1604     int err[4] = {0};
1605     int A = 0; //init to silence warning
1606
1607     if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
1608        || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)
1609         step = 1;
1610
1611     for (i = 0; i < dstW; i++) {
1612         int j;
1613         int Y = 1<<9;
1614         int U = (1<<9)-(128 << 19);
1615         int V = (1<<9)-(128 << 19);
1616
1617         for (j = 0; j < lumFilterSize; j++) {
1618             Y += lumSrc[j][i] * lumFilter[j];
1619         }
1620         for (j = 0; j < chrFilterSize; j++) {
1621             U += chrUSrc[j][i] * chrFilter[j];
1622             V += chrVSrc[j][i] * chrFilter[j];
1623         }
1624         Y >>= 10;
1625         U >>= 10;
1626         V >>= 10;
1627         if (hasAlpha) {
1628             A = 1 << 18;
1629             for (j = 0; j < lumFilterSize; j++) {
1630                 A += alpSrc[j][i] * lumFilter[j];
1631             }
1632             A >>= 19;
1633             if (A & 0x100)
1634                 A = av_clip_uint8(A);
1635         }
1636         yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
1637         dest += step;
1638     }
1639     c->dither_error[0][i] = err[0];
1640     c->dither_error[1][i] = err[1];
1641     c->dither_error[2][i] = err[2];
1642 }
1643
1644 static av_always_inline void
1645 yuv2rgb_full_2_c_template(SwsContext *c, const int16_t *buf[2],
1646                      const int16_t *ubuf[2], const int16_t *vbuf[2],
1647                      const int16_t *abuf[2], uint8_t *dest, int dstW,
1648                      int yalpha, int uvalpha, int y,
1649                      enum AVPixelFormat target, int hasAlpha)
1650 {
1651     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
1652                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1653                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
1654                   *abuf0 = hasAlpha ? abuf[0] : NULL,
1655                   *abuf1 = hasAlpha ? abuf[1] : NULL;
1656     int  yalpha1 = 4096 - yalpha;
1657     int uvalpha1 = 4096 - uvalpha;
1658     int i;
1659     int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
1660     int err[4] = {0};
1661     int A = 0; // init to silcene warning
1662
1663     if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
1664        || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)
1665         step = 1;
1666
1667     for (i = 0; i < dstW; i++) {
1668         int Y = ( buf0[i] * yalpha1  +  buf1[i] * yalpha             ) >> 10; //FIXME rounding
1669         int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha-(128 << 19)) >> 10;
1670         int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha-(128 << 19)) >> 10;
1671
1672         if (hasAlpha) {
1673             A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha + (1<<18)) >> 19;
1674             if (A & 0x100)
1675                 A = av_clip_uint8(A);
1676         }
1677
1678         yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
1679         dest += step;
1680     }
1681     c->dither_error[0][i] = err[0];
1682     c->dither_error[1][i] = err[1];
1683     c->dither_error[2][i] = err[2];
1684 }
1685
1686 static av_always_inline void
1687 yuv2rgb_full_1_c_template(SwsContext *c, const int16_t *buf0,
1688                      const int16_t *ubuf[2], const int16_t *vbuf[2],
1689                      const int16_t *abuf0, uint8_t *dest, int dstW,
1690                      int uvalpha, int y, enum AVPixelFormat target,
1691                      int hasAlpha)
1692 {
1693     const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
1694     int i;
1695     int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
1696     int err[4] = {0};
1697
1698     if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
1699        || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)
1700         step = 1;
1701
1702     if (uvalpha < 2048) {
1703         int A = 0; //init to silence warning
1704         for (i = 0; i < dstW; i++) {
1705             int Y = buf0[i] << 2;
1706             int U = (ubuf0[i] - (128<<7)) << 2;
1707             int V = (vbuf0[i] - (128<<7)) << 2;
1708
1709             if (hasAlpha) {
1710                 A = (abuf0[i] + 64) >> 7;
1711                 if (A & 0x100)
1712                     A = av_clip_uint8(A);
1713             }
1714
1715             yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
1716             dest += step;
1717         }
1718     } else {
1719         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
1720         int A = 0; //init to silence warning
1721         for (i = 0; i < dstW; i++) {
1722             int Y = buf0[i] << 2;
1723             int U = (ubuf0[i] + ubuf1[i] - (128<<8)) << 1;
1724             int V = (vbuf0[i] + vbuf1[i] - (128<<8)) << 1;
1725
1726             if (hasAlpha) {
1727                 A = (abuf0[i] + 64) >> 7;
1728                 if (A & 0x100)
1729                     A = av_clip_uint8(A);
1730             }
1731
1732             yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
1733             dest += step;
1734         }
1735     }
1736
1737     c->dither_error[0][i] = err[0];
1738     c->dither_error[1][i] = err[1];
1739     c->dither_error[2][i] = err[2];
1740 }
1741
1742 #if CONFIG_SMALL
1743 YUV2RGBWRAPPER(yuv2, rgb_full, bgra32_full, AV_PIX_FMT_BGRA,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1744 YUV2RGBWRAPPER(yuv2, rgb_full, abgr32_full, AV_PIX_FMT_ABGR,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1745 YUV2RGBWRAPPER(yuv2, rgb_full, rgba32_full, AV_PIX_FMT_RGBA,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1746 YUV2RGBWRAPPER(yuv2, rgb_full, argb32_full, AV_PIX_FMT_ARGB,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1747 #else
1748 #if CONFIG_SWSCALE_ALPHA
1749 YUV2RGBWRAPPER(yuv2, rgb_full, bgra32_full, AV_PIX_FMT_BGRA,  1)
1750 YUV2RGBWRAPPER(yuv2, rgb_full, abgr32_full, AV_PIX_FMT_ABGR,  1)
1751 YUV2RGBWRAPPER(yuv2, rgb_full, rgba32_full, AV_PIX_FMT_RGBA,  1)
1752 YUV2RGBWRAPPER(yuv2, rgb_full, argb32_full, AV_PIX_FMT_ARGB,  1)
1753 #endif
1754 YUV2RGBWRAPPER(yuv2, rgb_full, bgrx32_full, AV_PIX_FMT_BGRA,  0)
1755 YUV2RGBWRAPPER(yuv2, rgb_full, xbgr32_full, AV_PIX_FMT_ABGR,  0)
1756 YUV2RGBWRAPPER(yuv2, rgb_full, rgbx32_full, AV_PIX_FMT_RGBA,  0)
1757 YUV2RGBWRAPPER(yuv2, rgb_full, xrgb32_full, AV_PIX_FMT_ARGB,  0)
1758 #endif
1759 YUV2RGBWRAPPER(yuv2, rgb_full, bgr24_full,  AV_PIX_FMT_BGR24, 0)
1760 YUV2RGBWRAPPER(yuv2, rgb_full, rgb24_full,  AV_PIX_FMT_RGB24, 0)
1761
1762 YUV2RGBWRAPPER(yuv2, rgb_full, bgr4_byte_full,  AV_PIX_FMT_BGR4_BYTE, 0)
1763 YUV2RGBWRAPPER(yuv2, rgb_full, rgb4_byte_full,  AV_PIX_FMT_RGB4_BYTE, 0)
1764 YUV2RGBWRAPPER(yuv2, rgb_full, bgr8_full,   AV_PIX_FMT_BGR8,  0)
1765 YUV2RGBWRAPPER(yuv2, rgb_full, rgb8_full,   AV_PIX_FMT_RGB8,  0)
1766
1767 static void
1768 yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter,
1769                   const int16_t **lumSrc, int lumFilterSize,
1770                   const int16_t *chrFilter, const int16_t **chrUSrc,
1771                   const int16_t **chrVSrc, int chrFilterSize,
1772                   const int16_t **alpSrc, uint8_t **dest,
1773                   int dstW, int y)
1774 {
1775     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
1776     int i;
1777     int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrc;
1778     uint16_t **dest16 = (uint16_t**)dest;
1779     int SH = 22 + 7 - desc->comp[0].depth_minus1;
1780     int A = 0; // init to silence warning
1781
1782     for (i = 0; i < dstW; i++) {
1783         int j;
1784         int Y = 1 << 9;
1785         int U = (1 << 9) - (128 << 19);
1786         int V = (1 << 9) - (128 << 19);
1787         int R, G, B;
1788
1789         for (j = 0; j < lumFilterSize; j++)
1790             Y += lumSrc[j][i] * lumFilter[j];
1791
1792         for (j = 0; j < chrFilterSize; j++) {
1793             U += chrUSrc[j][i] * chrFilter[j];
1794             V += chrVSrc[j][i] * chrFilter[j];
1795         }
1796
1797         Y >>= 10;
1798         U >>= 10;
1799         V >>= 10;
1800
1801         if (hasAlpha) {
1802             A = 1 << 18;
1803
1804             for (j = 0; j < lumFilterSize; j++)
1805                 A += alpSrc[j][i] * lumFilter[j];
1806
1807             A >>= 19;
1808
1809             if (A & 0x100)
1810                 A = av_clip_uint8(A);
1811         }
1812
1813         Y -= c->yuv2rgb_y_offset;
1814         Y *= c->yuv2rgb_y_coeff;
1815         Y += 1 << 21;
1816         R = Y + V * c->yuv2rgb_v2r_coeff;
1817         G = Y + V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
1818         B = Y +                            U * c->yuv2rgb_u2b_coeff;
1819
1820         if ((R | G | B) & 0xC0000000) {
1821             R = av_clip_uintp2(R, 30);
1822             G = av_clip_uintp2(G, 30);
1823             B = av_clip_uintp2(B, 30);
1824         }
1825
1826         if (SH != 22) {
1827             dest16[0][i] = G >> SH;
1828             dest16[1][i] = B >> SH;
1829             dest16[2][i] = R >> SH;
1830             if (hasAlpha)
1831                 dest16[3][i] = A;
1832         } else {
1833             dest[0][i] = G >> 22;
1834             dest[1][i] = B >> 22;
1835             dest[2][i] = R >> 22;
1836             if (hasAlpha)
1837                 dest[3][i] = A;
1838         }
1839     }
1840     if (SH != 22 && (!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
1841         for (i = 0; i < dstW; i++) {
1842             dest16[0][i] = av_bswap16(dest16[0][i]);
1843             dest16[1][i] = av_bswap16(dest16[1][i]);
1844             dest16[2][i] = av_bswap16(dest16[2][i]);
1845             if (hasAlpha)
1846                 dest16[3][i] = av_bswap16(dest16[3][i]);
1847         }
1848     }
1849 }
1850
1851 av_cold void ff_sws_init_output_funcs(SwsContext *c,
1852                                       yuv2planar1_fn *yuv2plane1,
1853                                       yuv2planarX_fn *yuv2planeX,
1854                                       yuv2interleavedX_fn *yuv2nv12cX,
1855                                       yuv2packed1_fn *yuv2packed1,
1856                                       yuv2packed2_fn *yuv2packed2,
1857                                       yuv2packedX_fn *yuv2packedX,
1858                                       yuv2anyX_fn *yuv2anyX)
1859 {
1860     enum AVPixelFormat dstFormat = c->dstFormat;
1861     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
1862
1863     if (is16BPS(dstFormat)) {
1864         *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c  : yuv2planeX_16LE_c;
1865         *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c  : yuv2plane1_16LE_c;
1866     } else if (is9_OR_10BPS(dstFormat)) {
1867         if (desc->comp[0].depth_minus1 == 8) {
1868             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c  : yuv2planeX_9LE_c;
1869             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_c  : yuv2plane1_9LE_c;
1870         } else if (desc->comp[0].depth_minus1 == 9) {
1871             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_10BE_c  : yuv2planeX_10LE_c;
1872             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_10BE_c  : yuv2plane1_10LE_c;
1873         } else if (desc->comp[0].depth_minus1 == 11) {
1874             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_12BE_c  : yuv2planeX_12LE_c;
1875             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_12BE_c  : yuv2plane1_12LE_c;
1876         } else if (desc->comp[0].depth_minus1 == 13) {
1877             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_14BE_c  : yuv2planeX_14LE_c;
1878             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_14BE_c  : yuv2plane1_14LE_c;
1879         } else
1880             av_assert0(0);
1881     } else {
1882         *yuv2plane1 = yuv2plane1_8_c;
1883         *yuv2planeX = yuv2planeX_8_c;
1884         if (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)
1885             *yuv2nv12cX = yuv2nv12cX_c;
1886     }
1887
1888     if(c->flags & SWS_FULL_CHR_H_INT) {
1889         switch (dstFormat) {
1890             case AV_PIX_FMT_RGBA:
1891 #if CONFIG_SMALL
1892                 *yuv2packedX = yuv2rgba32_full_X_c;
1893                 *yuv2packed2 = yuv2rgba32_full_2_c;
1894                 *yuv2packed1 = yuv2rgba32_full_1_c;
1895 #else
1896 #if CONFIG_SWSCALE_ALPHA
1897                 if (c->alpPixBuf) {
1898                     *yuv2packedX = yuv2rgba32_full_X_c;
1899                     *yuv2packed2 = yuv2rgba32_full_2_c;
1900                     *yuv2packed1 = yuv2rgba32_full_1_c;
1901                 } else
1902 #endif /* CONFIG_SWSCALE_ALPHA */
1903                 {
1904                     *yuv2packedX = yuv2rgbx32_full_X_c;
1905                     *yuv2packed2 = yuv2rgbx32_full_2_c;
1906                     *yuv2packed1 = yuv2rgbx32_full_1_c;
1907                 }
1908 #endif /* !CONFIG_SMALL */
1909                 break;
1910             case AV_PIX_FMT_ARGB:
1911 #if CONFIG_SMALL
1912                 *yuv2packedX = yuv2argb32_full_X_c;
1913                 *yuv2packed2 = yuv2argb32_full_2_c;
1914                 *yuv2packed1 = yuv2argb32_full_1_c;
1915 #else
1916 #if CONFIG_SWSCALE_ALPHA
1917                 if (c->alpPixBuf) {
1918                     *yuv2packedX = yuv2argb32_full_X_c;
1919                     *yuv2packed2 = yuv2argb32_full_2_c;
1920                     *yuv2packed1 = yuv2argb32_full_1_c;
1921                 } else
1922 #endif /* CONFIG_SWSCALE_ALPHA */
1923                 {
1924                     *yuv2packedX = yuv2xrgb32_full_X_c;
1925                     *yuv2packed2 = yuv2xrgb32_full_2_c;
1926                     *yuv2packed1 = yuv2xrgb32_full_1_c;
1927                 }
1928 #endif /* !CONFIG_SMALL */
1929                 break;
1930             case AV_PIX_FMT_BGRA:
1931 #if CONFIG_SMALL
1932                 *yuv2packedX = yuv2bgra32_full_X_c;
1933                 *yuv2packed2 = yuv2bgra32_full_2_c;
1934                 *yuv2packed1 = yuv2bgra32_full_1_c;
1935 #else
1936 #if CONFIG_SWSCALE_ALPHA
1937                 if (c->alpPixBuf) {
1938                     *yuv2packedX = yuv2bgra32_full_X_c;
1939                     *yuv2packed2 = yuv2bgra32_full_2_c;
1940                     *yuv2packed1 = yuv2bgra32_full_1_c;
1941                 } else
1942 #endif /* CONFIG_SWSCALE_ALPHA */
1943                 {
1944                     *yuv2packedX = yuv2bgrx32_full_X_c;
1945                     *yuv2packed2 = yuv2bgrx32_full_2_c;
1946                     *yuv2packed1 = yuv2bgrx32_full_1_c;
1947                 }
1948 #endif /* !CONFIG_SMALL */
1949                 break;
1950             case AV_PIX_FMT_ABGR:
1951 #if CONFIG_SMALL
1952                 *yuv2packedX = yuv2abgr32_full_X_c;
1953                 *yuv2packed2 = yuv2abgr32_full_2_c;
1954                 *yuv2packed1 = yuv2abgr32_full_1_c;
1955 #else
1956 #if CONFIG_SWSCALE_ALPHA
1957                 if (c->alpPixBuf) {
1958                     *yuv2packedX = yuv2abgr32_full_X_c;
1959                     *yuv2packed2 = yuv2abgr32_full_2_c;
1960                     *yuv2packed1 = yuv2abgr32_full_1_c;
1961                 } else
1962 #endif /* CONFIG_SWSCALE_ALPHA */
1963                 {
1964                     *yuv2packedX = yuv2xbgr32_full_X_c;
1965                     *yuv2packed2 = yuv2xbgr32_full_2_c;
1966                     *yuv2packed1 = yuv2xbgr32_full_1_c;
1967                 }
1968 #endif /* !CONFIG_SMALL */
1969                 break;
1970             case AV_PIX_FMT_RGB24:
1971             *yuv2packedX = yuv2rgb24_full_X_c;
1972             *yuv2packed2 = yuv2rgb24_full_2_c;
1973             *yuv2packed1 = yuv2rgb24_full_1_c;
1974             break;
1975         case AV_PIX_FMT_BGR24:
1976             *yuv2packedX = yuv2bgr24_full_X_c;
1977             *yuv2packed2 = yuv2bgr24_full_2_c;
1978             *yuv2packed1 = yuv2bgr24_full_1_c;
1979             break;
1980         case AV_PIX_FMT_BGR4_BYTE:
1981             *yuv2packedX = yuv2bgr4_byte_full_X_c;
1982             *yuv2packed2 = yuv2bgr4_byte_full_2_c;
1983             *yuv2packed1 = yuv2bgr4_byte_full_1_c;
1984             break;
1985         case AV_PIX_FMT_RGB4_BYTE:
1986             *yuv2packedX = yuv2rgb4_byte_full_X_c;
1987             *yuv2packed2 = yuv2rgb4_byte_full_2_c;
1988             *yuv2packed1 = yuv2rgb4_byte_full_1_c;
1989             break;
1990         case AV_PIX_FMT_BGR8:
1991             *yuv2packedX = yuv2bgr8_full_X_c;
1992             *yuv2packed2 = yuv2bgr8_full_2_c;
1993             *yuv2packed1 = yuv2bgr8_full_1_c;
1994             break;
1995         case AV_PIX_FMT_RGB8:
1996             *yuv2packedX = yuv2rgb8_full_X_c;
1997             *yuv2packed2 = yuv2rgb8_full_2_c;
1998             *yuv2packed1 = yuv2rgb8_full_1_c;
1999             break;
2000         case AV_PIX_FMT_GBRP:
2001         case AV_PIX_FMT_GBRP9BE:
2002         case AV_PIX_FMT_GBRP9LE:
2003         case AV_PIX_FMT_GBRP10BE:
2004         case AV_PIX_FMT_GBRP10LE:
2005         case AV_PIX_FMT_GBRP12BE:
2006         case AV_PIX_FMT_GBRP12LE:
2007         case AV_PIX_FMT_GBRP14BE:
2008         case AV_PIX_FMT_GBRP14LE:
2009         case AV_PIX_FMT_GBRP16BE:
2010         case AV_PIX_FMT_GBRP16LE:
2011         case AV_PIX_FMT_GBRAP:
2012             *yuv2anyX = yuv2gbrp_full_X_c;
2013             break;
2014         }
2015         if (!*yuv2packedX && !*yuv2anyX)
2016             goto YUV_PACKED;
2017     } else {
2018         YUV_PACKED:
2019         switch (dstFormat) {
2020         case AV_PIX_FMT_RGBA64LE:
2021 #if CONFIG_SWSCALE_ALPHA
2022             if (c->alpPixBuf) {
2023                 *yuv2packed1 = yuv2rgba64le_1_c;
2024                 *yuv2packed2 = yuv2rgba64le_2_c;
2025                 *yuv2packedX = yuv2rgba64le_X_c;
2026             } else
2027 #endif /* CONFIG_SWSCALE_ALPHA */
2028             {
2029                 *yuv2packed1 = yuv2rgbx64le_1_c;
2030                 *yuv2packed2 = yuv2rgbx64le_2_c;
2031                 *yuv2packedX = yuv2rgbx64le_X_c;
2032             }
2033             break;
2034         case AV_PIX_FMT_RGBA64BE:
2035 #if CONFIG_SWSCALE_ALPHA
2036             if (c->alpPixBuf) {
2037                 *yuv2packed1 = yuv2rgba64be_1_c;
2038                 *yuv2packed2 = yuv2rgba64be_2_c;
2039                 *yuv2packedX = yuv2rgba64be_X_c;
2040             } else
2041 #endif /* CONFIG_SWSCALE_ALPHA */
2042             {
2043                 *yuv2packed1 = yuv2rgbx64be_1_c;
2044                 *yuv2packed2 = yuv2rgbx64be_2_c;
2045                 *yuv2packedX = yuv2rgbx64be_X_c;
2046             }
2047             break;
2048         case AV_PIX_FMT_BGRA64LE:
2049 #if CONFIG_SWSCALE_ALPHA
2050             if (c->alpPixBuf) {
2051                 *yuv2packed1 = yuv2bgra64le_1_c;
2052                 *yuv2packed2 = yuv2bgra64le_2_c;
2053                 *yuv2packedX = yuv2bgra64le_X_c;
2054             } else
2055 #endif /* CONFIG_SWSCALE_ALPHA */
2056             {
2057                 *yuv2packed1 = yuv2bgrx64le_1_c;
2058                 *yuv2packed2 = yuv2bgrx64le_2_c;
2059                 *yuv2packedX = yuv2bgrx64le_X_c;
2060             }
2061             break;
2062         case AV_PIX_FMT_BGRA64BE:
2063 #if CONFIG_SWSCALE_ALPHA
2064             if (c->alpPixBuf) {
2065                 *yuv2packed1 = yuv2bgra64be_1_c;
2066                 *yuv2packed2 = yuv2bgra64be_2_c;
2067                 *yuv2packedX = yuv2bgra64be_X_c;
2068             } else
2069 #endif /* CONFIG_SWSCALE_ALPHA */
2070             {
2071                 *yuv2packed1 = yuv2bgrx64be_1_c;
2072                 *yuv2packed2 = yuv2bgrx64be_2_c;
2073                 *yuv2packedX = yuv2bgrx64be_X_c;
2074             }
2075             break;
2076         case AV_PIX_FMT_RGB48LE:
2077             *yuv2packed1 = yuv2rgb48le_1_c;
2078             *yuv2packed2 = yuv2rgb48le_2_c;
2079             *yuv2packedX = yuv2rgb48le_X_c;
2080             break;
2081         case AV_PIX_FMT_RGB48BE:
2082             *yuv2packed1 = yuv2rgb48be_1_c;
2083             *yuv2packed2 = yuv2rgb48be_2_c;
2084             *yuv2packedX = yuv2rgb48be_X_c;
2085             break;
2086         case AV_PIX_FMT_BGR48LE:
2087             *yuv2packed1 = yuv2bgr48le_1_c;
2088             *yuv2packed2 = yuv2bgr48le_2_c;
2089             *yuv2packedX = yuv2bgr48le_X_c;
2090             break;
2091         case AV_PIX_FMT_BGR48BE:
2092             *yuv2packed1 = yuv2bgr48be_1_c;
2093             *yuv2packed2 = yuv2bgr48be_2_c;
2094             *yuv2packedX = yuv2bgr48be_X_c;
2095             break;
2096         case AV_PIX_FMT_RGB32:
2097         case AV_PIX_FMT_BGR32:
2098 #if CONFIG_SMALL
2099             *yuv2packed1 = yuv2rgb32_1_c;
2100             *yuv2packed2 = yuv2rgb32_2_c;
2101             *yuv2packedX = yuv2rgb32_X_c;
2102 #else
2103 #if CONFIG_SWSCALE_ALPHA
2104                 if (c->alpPixBuf) {
2105                     *yuv2packed1 = yuv2rgba32_1_c;
2106                     *yuv2packed2 = yuv2rgba32_2_c;
2107                     *yuv2packedX = yuv2rgba32_X_c;
2108                 } else
2109 #endif /* CONFIG_SWSCALE_ALPHA */
2110                 {
2111                     *yuv2packed1 = yuv2rgbx32_1_c;
2112                     *yuv2packed2 = yuv2rgbx32_2_c;
2113                     *yuv2packedX = yuv2rgbx32_X_c;
2114                 }
2115 #endif /* !CONFIG_SMALL */
2116             break;
2117         case AV_PIX_FMT_RGB32_1:
2118         case AV_PIX_FMT_BGR32_1:
2119 #if CONFIG_SMALL
2120                 *yuv2packed1 = yuv2rgb32_1_1_c;
2121                 *yuv2packed2 = yuv2rgb32_1_2_c;
2122                 *yuv2packedX = yuv2rgb32_1_X_c;
2123 #else
2124 #if CONFIG_SWSCALE_ALPHA
2125                 if (c->alpPixBuf) {
2126                     *yuv2packed1 = yuv2rgba32_1_1_c;
2127                     *yuv2packed2 = yuv2rgba32_1_2_c;
2128                     *yuv2packedX = yuv2rgba32_1_X_c;
2129                 } else
2130 #endif /* CONFIG_SWSCALE_ALPHA */
2131                 {
2132                     *yuv2packed1 = yuv2rgbx32_1_1_c;
2133                     *yuv2packed2 = yuv2rgbx32_1_2_c;
2134                     *yuv2packedX = yuv2rgbx32_1_X_c;
2135                 }
2136 #endif /* !CONFIG_SMALL */
2137                 break;
2138         case AV_PIX_FMT_RGB24:
2139             *yuv2packed1 = yuv2rgb24_1_c;
2140             *yuv2packed2 = yuv2rgb24_2_c;
2141             *yuv2packedX = yuv2rgb24_X_c;
2142             break;
2143         case AV_PIX_FMT_BGR24:
2144             *yuv2packed1 = yuv2bgr24_1_c;
2145             *yuv2packed2 = yuv2bgr24_2_c;
2146             *yuv2packedX = yuv2bgr24_X_c;
2147             break;
2148         case AV_PIX_FMT_RGB565LE:
2149         case AV_PIX_FMT_RGB565BE:
2150         case AV_PIX_FMT_BGR565LE:
2151         case AV_PIX_FMT_BGR565BE:
2152             *yuv2packed1 = yuv2rgb16_1_c;
2153             *yuv2packed2 = yuv2rgb16_2_c;
2154             *yuv2packedX = yuv2rgb16_X_c;
2155             break;
2156         case AV_PIX_FMT_RGB555LE:
2157         case AV_PIX_FMT_RGB555BE:
2158         case AV_PIX_FMT_BGR555LE:
2159         case AV_PIX_FMT_BGR555BE:
2160             *yuv2packed1 = yuv2rgb15_1_c;
2161             *yuv2packed2 = yuv2rgb15_2_c;
2162             *yuv2packedX = yuv2rgb15_X_c;
2163             break;
2164         case AV_PIX_FMT_RGB444LE:
2165         case AV_PIX_FMT_RGB444BE:
2166         case AV_PIX_FMT_BGR444LE:
2167         case AV_PIX_FMT_BGR444BE:
2168             *yuv2packed1 = yuv2rgb12_1_c;
2169             *yuv2packed2 = yuv2rgb12_2_c;
2170             *yuv2packedX = yuv2rgb12_X_c;
2171             break;
2172         case AV_PIX_FMT_RGB8:
2173         case AV_PIX_FMT_BGR8:
2174             *yuv2packed1 = yuv2rgb8_1_c;
2175             *yuv2packed2 = yuv2rgb8_2_c;
2176             *yuv2packedX = yuv2rgb8_X_c;
2177             break;
2178         case AV_PIX_FMT_RGB4:
2179         case AV_PIX_FMT_BGR4:
2180             *yuv2packed1 = yuv2rgb4_1_c;
2181             *yuv2packed2 = yuv2rgb4_2_c;
2182             *yuv2packedX = yuv2rgb4_X_c;
2183             break;
2184         case AV_PIX_FMT_RGB4_BYTE:
2185         case AV_PIX_FMT_BGR4_BYTE:
2186             *yuv2packed1 = yuv2rgb4b_1_c;
2187             *yuv2packed2 = yuv2rgb4b_2_c;
2188             *yuv2packedX = yuv2rgb4b_X_c;
2189             break;
2190         }
2191     }
2192     switch (dstFormat) {
2193     case AV_PIX_FMT_MONOWHITE:
2194         *yuv2packed1 = yuv2monowhite_1_c;
2195         *yuv2packed2 = yuv2monowhite_2_c;
2196         *yuv2packedX = yuv2monowhite_X_c;
2197         break;
2198     case AV_PIX_FMT_MONOBLACK:
2199         *yuv2packed1 = yuv2monoblack_1_c;
2200         *yuv2packed2 = yuv2monoblack_2_c;
2201         *yuv2packedX = yuv2monoblack_X_c;
2202         break;
2203     case AV_PIX_FMT_YUYV422:
2204         *yuv2packed1 = yuv2yuyv422_1_c;
2205         *yuv2packed2 = yuv2yuyv422_2_c;
2206         *yuv2packedX = yuv2yuyv422_X_c;
2207         break;
2208     case AV_PIX_FMT_UYVY422:
2209         *yuv2packed1 = yuv2uyvy422_1_c;
2210         *yuv2packed2 = yuv2uyvy422_2_c;
2211         *yuv2packedX = yuv2uyvy422_X_c;
2212         break;
2213     }
2214 }