swscale: yuv2422_2_c_template() add cliping.
[ffmpeg.git] / 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 <assert.h>
22 #include <math.h>
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <string.h>
26
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, static const uint8_t, dither_2x2_4)[2][8]={
40 {  1,   3,   1,   3,   1,   3,   1,   3, },
41 {  2,   0,   2,   0,   2,   0,   2,   0, },
42 };
43
44 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
45 {  6,   2,   6,   2,   6,   2,   6,   2, },
46 {  0,   4,   0,   4,   0,   4,   0,   4, },
47 };
48
49 DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
50 {  8,   4,  11,   7,   8,   4,  11,   7, },
51 {  2,  14,   1,  13,   2,  14,   1,  13, },
52 { 10,   6,   9,   5,  10,   6,   9,   5, },
53 {  0,  12,   3,  15,   0,  12,   3,  15, },
54 };
55
56 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
57 { 17,   9,  23,  15,  16,   8,  22,  14, },
58 {  5,  29,   3,  27,   4,  28,   2,  26, },
59 { 21,  13,  19,  11,  20,  12,  18,  10, },
60 {  0,  24,   6,  30,   1,  25,   7,  31, },
61 { 16,   8,  22,  14,  17,   9,  23,  15, },
62 {  4,  28,   2,  26,   5,  29,   3,  27, },
63 { 20,  12,  18,  10,  21,  13,  19,  11, },
64 {  1,  25,   7,  31,   0,  24,   6,  30, },
65 };
66
67 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
68 {  0,  55,  14,  68,   3,  58,  17,  72, },
69 { 37,  18,  50,  32,  40,  22,  54,  35, },
70 {  9,  64,   5,  59,  13,  67,   8,  63, },
71 { 46,  27,  41,  23,  49,  31,  44,  26, },
72 {  2,  57,  16,  71,   1,  56,  15,  70, },
73 { 39,  21,  52,  34,  38,  19,  51,  33, },
74 { 11,  66,   7,  62,  10,  65,   6,  60, },
75 { 48,  30,  43,  25,  47,  29,  42,  24, },
76 };
77
78 #if 1
79 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
80 {117,  62, 158, 103, 113,  58, 155, 100, },
81 { 34, 199,  21, 186,  31, 196,  17, 182, },
82 {144,  89, 131,  76, 141,  86, 127,  72, },
83 {  0, 165,  41, 206,  10, 175,  52, 217, },
84 {110,  55, 151,  96, 120,  65, 162, 107, },
85 { 28, 193,  14, 179,  38, 203,  24, 189, },
86 {138,  83, 124,  69, 148,  93, 134,  79, },
87 {  7, 172,  48, 213,   3, 168,  45, 210, },
88 };
89 #elif 1
90 // tries to correct a gamma of 1.5
91 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
92 {  0, 143,  18, 200,   2, 156,  25, 215, },
93 { 78,  28, 125,  64,  89,  36, 138,  74, },
94 { 10, 180,   3, 161,  16, 195,   8, 175, },
95 {109,  51,  93,  38, 121,  60, 105,  47, },
96 {  1, 152,  23, 210,   0, 147,  20, 205, },
97 { 85,  33, 134,  71,  81,  30, 130,  67, },
98 { 14, 190,   6, 171,  12, 185,   5, 166, },
99 {117,  57, 101,  44, 113,  54,  97,  41, },
100 };
101 #elif 1
102 // tries to correct a gamma of 2.0
103 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
104 {  0, 124,   8, 193,   0, 140,  12, 213, },
105 { 55,  14, 104,  42,  66,  19, 119,  52, },
106 {  3, 168,   1, 145,   6, 187,   3, 162, },
107 { 86,  31,  70,  21,  99,  39,  82,  28, },
108 {  0, 134,  11, 206,   0, 129,   9, 200, },
109 { 62,  17, 114,  48,  58,  16, 109,  45, },
110 {  5, 181,   2, 157,   4, 175,   1, 151, },
111 { 95,  36,  78,  26,  90,  34,  74,  24, },
112 };
113 #else
114 // tries to correct a gamma of 2.5
115 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
116 {  0, 107,   3, 187,   0, 125,   6, 212, },
117 { 39,   7,  86,  28,  49,  11, 102,  36, },
118 {  1, 158,   0, 131,   3, 180,   1, 151, },
119 { 68,  19,  52,  12,  81,  25,  64,  17, },
120 {  0, 119,   5, 203,   0, 113,   4, 195, },
121 { 45,   9,  96,  33,  42,   8,  91,  30, },
122 {  2, 172,   1, 144,   2, 165,   0, 137, },
123 { 77,  23,  60,  15,  72,  21,  56,  14, },
124 };
125 #endif
126
127 #define output_pixel(pos, val, bias, signedness) \
128     if (big_endian) { \
129         AV_WB16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
130     } else { \
131         AV_WL16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
132     }
133
134 static av_always_inline void
135 yuv2plane1_16_c_template(const int32_t *src, uint16_t *dest, int dstW,
136                          int big_endian, int output_bits)
137 {
138     int i;
139     int shift = 3;
140     av_assert0(output_bits == 16);
141
142     for (i = 0; i < dstW; i++) {
143         int val = src[i] + (1 << (shift - 1));
144         output_pixel(&dest[i], val, 0, uint);
145     }
146 }
147
148 static av_always_inline void
149 yuv2planeX_16_c_template(const int16_t *filter, int filterSize,
150                          const int32_t **src, uint16_t *dest, int dstW,
151                          int big_endian, int output_bits)
152 {
153     int i;
154     int shift = 15;
155     av_assert0(output_bits == 16);
156
157     for (i = 0; i < dstW; i++) {
158         int val = 1 << (shift - 1);
159         int j;
160
161         /* range of val is [0,0x7FFFFFFF], so 31 bits, but with lanczos/spline
162          * filters (or anything with negative coeffs, the range can be slightly
163          * wider in both directions. To account for this overflow, we subtract
164          * a constant so it always fits in the signed range (assuming a
165          * reasonable filterSize), and re-add that at the end. */
166         val -= 0x40000000;
167         for (j = 0; j < filterSize; j++)
168             val += src[j][i] * filter[j];
169
170         output_pixel(&dest[i], val, 0x8000, int);
171     }
172 }
173
174 #undef output_pixel
175
176 #define output_pixel(pos, val) \
177     if (big_endian) { \
178         AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
179     } else { \
180         AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
181     }
182
183 static av_always_inline void
184 yuv2plane1_10_c_template(const int16_t *src, uint16_t *dest, int dstW,
185                          int big_endian, int output_bits)
186 {
187     int i;
188     int shift = 15 - output_bits;
189
190     for (i = 0; i < dstW; i++) {
191         int val = src[i] + (1 << (shift - 1));
192         output_pixel(&dest[i], val);
193     }
194 }
195
196 static av_always_inline void
197 yuv2planeX_10_c_template(const int16_t *filter, int filterSize,
198                          const int16_t **src, uint16_t *dest, int dstW,
199                          int big_endian, int output_bits)
200 {
201     int i;
202     int shift = 11 + 16 - output_bits;
203
204     for (i = 0; i < dstW; i++) {
205         int val = 1 << (shift - 1);
206         int j;
207
208         for (j = 0; j < filterSize; j++)
209             val += src[j][i] * filter[j];
210
211         output_pixel(&dest[i], val);
212     }
213 }
214
215 #undef output_pixel
216
217 #define yuv2NBPS(bits, BE_LE, is_be, template_size, typeX_t) \
218 static void yuv2plane1_ ## bits ## BE_LE ## _c(const int16_t *src, \
219                               uint8_t *dest, int dstW, \
220                               const uint8_t *dither, int offset)\
221 { \
222     yuv2plane1_ ## template_size ## _c_template((const typeX_t *) src, \
223                          (uint16_t *) dest, dstW, is_be, bits); \
224 }\
225 static void yuv2planeX_ ## bits ## BE_LE ## _c(const int16_t *filter, int filterSize, \
226                               const int16_t **src, uint8_t *dest, int dstW, \
227                               const uint8_t *dither, int offset)\
228 { \
229     yuv2planeX_## template_size ## _c_template(filter, \
230                          filterSize, (const typeX_t **) src, \
231                          (uint16_t *) dest, dstW, is_be, bits); \
232 }
233 yuv2NBPS( 9, BE, 1, 10, int16_t)
234 yuv2NBPS( 9, LE, 0, 10, int16_t)
235 yuv2NBPS(10, BE, 1, 10, int16_t)
236 yuv2NBPS(10, LE, 0, 10, int16_t)
237 yuv2NBPS(16, BE, 1, 16, int32_t)
238 yuv2NBPS(16, LE, 0, 16, int32_t)
239
240 static void yuv2planeX_8_c(const int16_t *filter, int filterSize,
241                            const int16_t **src, uint8_t *dest, int dstW,
242                            const uint8_t *dither, int offset)
243 {
244     int i;
245     for (i=0; i<dstW; i++) {
246         int val = dither[(i + offset) & 7] << 12;
247         int j;
248         for (j=0; j<filterSize; j++)
249             val += src[j][i] * filter[j];
250
251         dest[i]= av_clip_uint8(val>>19);
252     }
253 }
254
255 static void yuv2plane1_8_c(const int16_t *src, uint8_t *dest, int dstW,
256                            const uint8_t *dither, int offset)
257 {
258     int i;
259     for (i=0; i<dstW; i++) {
260         int val = (src[i] + dither[(i + offset) & 7]) >> 7;
261         dest[i]= av_clip_uint8(val);
262     }
263 }
264
265 static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize,
266                         const int16_t **chrUSrc, const int16_t **chrVSrc,
267                         uint8_t *dest, int chrDstW)
268 {
269     enum PixelFormat dstFormat = c->dstFormat;
270     const uint8_t *chrDither = c->chrDither8;
271     int i;
272
273     if (dstFormat == PIX_FMT_NV12)
274         for (i=0; i<chrDstW; i++) {
275             int u = chrDither[i & 7] << 12;
276             int v = chrDither[(i + 3) & 7] << 12;
277             int j;
278             for (j=0; j<chrFilterSize; j++) {
279                 u += chrUSrc[j][i] * chrFilter[j];
280                 v += chrVSrc[j][i] * chrFilter[j];
281             }
282
283             dest[2*i]= av_clip_uint8(u>>19);
284             dest[2*i+1]= av_clip_uint8(v>>19);
285         }
286     else
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(v>>19);
297             dest[2*i+1]= av_clip_uint8(u>>19);
298         }
299 }
300
301 #define output_pixel(pos, acc) \
302     if (target == PIX_FMT_MONOBLACK) { \
303         pos = acc; \
304     } else { \
305         pos = ~acc; \
306     }
307
308 static av_always_inline void
309 yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
310                       const int16_t **lumSrc, int lumFilterSize,
311                       const int16_t *chrFilter, const int16_t **chrUSrc,
312                       const int16_t **chrVSrc, int chrFilterSize,
313                       const int16_t **alpSrc, uint8_t *dest, int dstW,
314                       int y, enum PixelFormat target)
315 {
316     const uint8_t * const d128=dither_8x8_220[y&7];
317     uint8_t *g = c->table_gU[128 + YUVRGB_TABLE_HEADROOM] + c->table_gV[128 + YUVRGB_TABLE_HEADROOM];
318     int i;
319     unsigned acc = 0;
320
321     for (i = 0; i < dstW - 1; i += 2) {
322         int j;
323         int Y1 = 1 << 18;
324         int Y2 = 1 << 18;
325
326         for (j = 0; j < lumFilterSize; j++) {
327             Y1 += lumSrc[j][i]   * lumFilter[j];
328             Y2 += lumSrc[j][i+1] * lumFilter[j];
329         }
330         Y1 >>= 19;
331         Y2 >>= 19;
332         if ((Y1 | Y2) & 0x100) {
333             Y1 = av_clip_uint8(Y1);
334             Y2 = av_clip_uint8(Y2);
335         }
336         acc += acc + g[Y1 + d128[(i + 0) & 7]];
337         acc += acc + g[Y2 + d128[(i + 1) & 7]];
338         if ((i & 7) == 6) {
339             output_pixel(*dest++, acc);
340         }
341     }
342 }
343
344 static av_always_inline void
345 yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2],
346                       const int16_t *ubuf[2], const int16_t *vbuf[2],
347                       const int16_t *abuf[2], uint8_t *dest, int dstW,
348                       int yalpha, int uvalpha, int y,
349                       enum PixelFormat target)
350 {
351     const int16_t *buf0  = buf[0],  *buf1  = buf[1];
352     const uint8_t * const d128 = dither_8x8_220[y & 7];
353     uint8_t *g = c->table_gU[128 + YUVRGB_TABLE_HEADROOM] + c->table_gV[128 + YUVRGB_TABLE_HEADROOM];
354     int  yalpha1 = 4095 - yalpha;
355     int i;
356
357     for (i = 0; i < dstW - 7; i += 8) {
358         int acc =    g[((buf0[i    ] * yalpha1 + buf1[i    ] * yalpha) >> 19) + d128[0]];
359         acc += acc + g[((buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19) + d128[1]];
360         acc += acc + g[((buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19) + d128[2]];
361         acc += acc + g[((buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19) + d128[3]];
362         acc += acc + g[((buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19) + d128[4]];
363         acc += acc + g[((buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19) + d128[5]];
364         acc += acc + g[((buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19) + d128[6]];
365         acc += acc + g[((buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19) + d128[7]];
366         output_pixel(*dest++, acc);
367     }
368 }
369
370 static av_always_inline void
371 yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0,
372                       const int16_t *ubuf[2], const int16_t *vbuf[2],
373                       const int16_t *abuf0, uint8_t *dest, int dstW,
374                       int uvalpha, int y, enum PixelFormat target)
375 {
376     const uint8_t * const d128 = dither_8x8_220[y & 7];
377     uint8_t *g = c->table_gU[128 + YUVRGB_TABLE_HEADROOM] + c->table_gV[128 + YUVRGB_TABLE_HEADROOM];
378     int i;
379
380     for (i = 0; i < dstW - 7; i += 8) {
381         int acc =    g[((buf0[i    ] + 64) >> 7) + d128[0]];
382         acc += acc + g[((buf0[i + 1] + 64) >> 7) + d128[1]];
383         acc += acc + g[((buf0[i + 2] + 64) >> 7) + d128[2]];
384         acc += acc + g[((buf0[i + 3] + 64) >> 7) + d128[3]];
385         acc += acc + g[((buf0[i + 4] + 64) >> 7) + d128[4]];
386         acc += acc + g[((buf0[i + 5] + 64) >> 7) + d128[5]];
387         acc += acc + g[((buf0[i + 6] + 64) >> 7) + d128[6]];
388         acc += acc + g[((buf0[i + 7] + 64) >> 7) + d128[7]];
389         output_pixel(*dest++, acc);
390     }
391 }
392
393 #undef output_pixel
394
395 #define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
396 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
397                                 const int16_t **lumSrc, int lumFilterSize, \
398                                 const int16_t *chrFilter, const int16_t **chrUSrc, \
399                                 const int16_t **chrVSrc, int chrFilterSize, \
400                                 const int16_t **alpSrc, uint8_t *dest, int dstW, \
401                                 int y) \
402 { \
403     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
404                                   chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
405                                   alpSrc, dest, dstW, y, fmt); \
406 } \
407  \
408 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
409                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
410                                 const int16_t *abuf[2], uint8_t *dest, int dstW, \
411                                 int yalpha, int uvalpha, int y) \
412 { \
413     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
414                                   dest, dstW, yalpha, uvalpha, y, fmt); \
415 } \
416  \
417 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
418                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
419                                 const int16_t *abuf0, uint8_t *dest, int dstW, \
420                                 int uvalpha, int y) \
421 { \
422     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, \
423                                   abuf0, dest, dstW, uvalpha, \
424                                   y, fmt); \
425 }
426
427 YUV2PACKEDWRAPPER(yuv2mono,, white, PIX_FMT_MONOWHITE)
428 YUV2PACKEDWRAPPER(yuv2mono,, black, PIX_FMT_MONOBLACK)
429
430 #define output_pixels(pos, Y1, U, Y2, V) \
431     if (target == PIX_FMT_YUYV422) { \
432         dest[pos + 0] = Y1; \
433         dest[pos + 1] = U;  \
434         dest[pos + 2] = Y2; \
435         dest[pos + 3] = V;  \
436     } else { \
437         dest[pos + 0] = U;  \
438         dest[pos + 1] = Y1; \
439         dest[pos + 2] = V;  \
440         dest[pos + 3] = Y2; \
441     }
442
443 static av_always_inline void
444 yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
445                      const int16_t **lumSrc, int lumFilterSize,
446                      const int16_t *chrFilter, const int16_t **chrUSrc,
447                      const int16_t **chrVSrc, int chrFilterSize,
448                      const int16_t **alpSrc, uint8_t *dest, int dstW,
449                      int y, enum PixelFormat target)
450 {
451     int i;
452
453     for (i = 0; i < (dstW >> 1); i++) {
454         int j;
455         int Y1 = 1 << 18;
456         int Y2 = 1 << 18;
457         int U  = 1 << 18;
458         int V  = 1 << 18;
459
460         for (j = 0; j < lumFilterSize; j++) {
461             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
462             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
463         }
464         for (j = 0; j < chrFilterSize; j++) {
465             U += chrUSrc[j][i] * chrFilter[j];
466             V += chrVSrc[j][i] * chrFilter[j];
467         }
468         Y1 >>= 19;
469         Y2 >>= 19;
470         U  >>= 19;
471         V  >>= 19;
472         if ((Y1 | Y2 | U | V) & 0x100) {
473             Y1 = av_clip_uint8(Y1);
474             Y2 = av_clip_uint8(Y2);
475             U  = av_clip_uint8(U);
476             V  = av_clip_uint8(V);
477         }
478         output_pixels(4*i, Y1, U, Y2, V);
479     }
480 }
481
482 static av_always_inline void
483 yuv2422_2_c_template(SwsContext *c, const int16_t *buf[2],
484                      const int16_t *ubuf[2], const int16_t *vbuf[2],
485                      const int16_t *abuf[2], uint8_t *dest, int dstW,
486                      int yalpha, int uvalpha, int y,
487                      enum PixelFormat target)
488 {
489     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
490                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
491                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
492     int  yalpha1 = 4095 - yalpha;
493     int uvalpha1 = 4095 - uvalpha;
494     int i;
495
496     for (i = 0; i < (dstW >> 1); i++) {
497         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
498         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
499         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
500         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
501
502         if ((Y1 | Y2 | U | V) & 0x100) {
503             Y1 = av_clip_uint8(Y1);
504             Y2 = av_clip_uint8(Y2);
505             U  = av_clip_uint8(U);
506             V  = av_clip_uint8(V);
507         }
508
509         output_pixels(i * 4, Y1, U, Y2, V);
510     }
511 }
512
513 static av_always_inline void
514 yuv2422_1_c_template(SwsContext *c, const int16_t *buf0,
515                      const int16_t *ubuf[2], const int16_t *vbuf[2],
516                      const int16_t *abuf0, uint8_t *dest, int dstW,
517                      int uvalpha, int y, enum PixelFormat target)
518 {
519     const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
520     int i;
521
522     if (uvalpha < 2048) {
523         for (i = 0; i < (dstW >> 1); i++) {
524             int Y1 = (buf0[i * 2    ]+64) >> 7;
525             int Y2 = (buf0[i * 2 + 1]+64) >> 7;
526             int U  = (ubuf0[i]       +64) >> 7;
527             int V  = (vbuf0[i]       +64) >> 7;
528
529             if ((Y1 | Y2 | U | V) & 0x100) {
530                 Y1 = av_clip_uint8(Y1);
531                 Y2 = av_clip_uint8(Y2);
532                 U  = av_clip_uint8(U);
533                 V  = av_clip_uint8(V);
534             }
535
536             output_pixels(i * 4, Y1, U, Y2, V);
537         }
538     } else {
539         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
540         for (i = 0; i < (dstW >> 1); i++) {
541             int Y1 = (buf0[i * 2    ]    + 64) >> 7;
542             int Y2 = (buf0[i * 2 + 1]    + 64) >> 7;
543             int U  = (ubuf0[i] + ubuf1[i]+128) >> 8;
544             int V  = (vbuf0[i] + vbuf1[i]+128) >> 8;
545
546             if ((Y1 | Y2 | U | V) & 0x100) {
547                 Y1 = av_clip_uint8(Y1);
548                 Y2 = av_clip_uint8(Y2);
549                 U  = av_clip_uint8(U);
550                 V  = av_clip_uint8(V);
551             }
552
553             output_pixels(i * 4, Y1, U, Y2, V);
554         }
555     }
556 }
557
558 #undef output_pixels
559
560 YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, PIX_FMT_YUYV422)
561 YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, PIX_FMT_UYVY422)
562
563 #define R_B ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? R : B)
564 #define B_R ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? B : R)
565 #define output_pixel(pos, val) \
566     if (isBE(target)) { \
567         AV_WB16(pos, val); \
568     } else { \
569         AV_WL16(pos, val); \
570     }
571
572 static av_always_inline void
573 yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
574                        const int32_t **lumSrc, int lumFilterSize,
575                        const int16_t *chrFilter, const int32_t **chrUSrc,
576                        const int32_t **chrVSrc, int chrFilterSize,
577                        const int32_t **alpSrc, uint16_t *dest, int dstW,
578                        int y, enum PixelFormat target)
579 {
580     int i;
581
582     for (i = 0; i < (dstW >> 1); i++) {
583         int j;
584         int Y1 = -0x40000000;
585         int Y2 = -0x40000000;
586         int U  = -128 << 23; // 19
587         int V  = -128 << 23;
588         int R, G, B;
589
590         for (j = 0; j < lumFilterSize; j++) {
591             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
592             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
593         }
594         for (j = 0; j < chrFilterSize; j++) {
595             U += chrUSrc[j][i] * chrFilter[j];
596             V += chrVSrc[j][i] * chrFilter[j];
597         }
598
599         // 8bit: 12+15=27; 16-bit: 12+19=31
600         Y1 >>= 14; // 10
601         Y1 += 0x10000;
602         Y2 >>= 14;
603         Y2 += 0x10000;
604         U  >>= 14;
605         V  >>= 14;
606
607         // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
608         Y1 -= c->yuv2rgb_y_offset;
609         Y2 -= c->yuv2rgb_y_offset;
610         Y1 *= c->yuv2rgb_y_coeff;
611         Y2 *= c->yuv2rgb_y_coeff;
612         Y1 += 1 << 13; // 21
613         Y2 += 1 << 13;
614         // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
615
616         R = V * c->yuv2rgb_v2r_coeff;
617         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
618         B =                            U * c->yuv2rgb_u2b_coeff;
619
620         // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
621         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
622         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
623         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
624         output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
625         output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
626         output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
627         dest += 6;
628     }
629 }
630
631 static av_always_inline void
632 yuv2rgb48_2_c_template(SwsContext *c, const int32_t *buf[2],
633                        const int32_t *ubuf[2], const int32_t *vbuf[2],
634                        const int32_t *abuf[2], uint16_t *dest, int dstW,
635                        int yalpha, int uvalpha, int y,
636                        enum PixelFormat target)
637 {
638     const int32_t *buf0  = buf[0],  *buf1  = buf[1],
639                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
640                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
641     int  yalpha1 = 4095 - yalpha;
642     int uvalpha1 = 4095 - uvalpha;
643     int i;
644
645     for (i = 0; i < (dstW >> 1); i++) {
646         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha) >> 14;
647         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha) >> 14;
648         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha + (-128 << 23)) >> 14;
649         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha + (-128 << 23)) >> 14;
650         int R, G, B;
651
652         Y1 -= c->yuv2rgb_y_offset;
653         Y2 -= c->yuv2rgb_y_offset;
654         Y1 *= c->yuv2rgb_y_coeff;
655         Y2 *= c->yuv2rgb_y_coeff;
656         Y1 += 1 << 13;
657         Y2 += 1 << 13;
658
659         R = V * c->yuv2rgb_v2r_coeff;
660         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
661         B =                            U * c->yuv2rgb_u2b_coeff;
662
663         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
664         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
665         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
666         output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
667         output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
668         output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
669         dest += 6;
670     }
671 }
672
673 static av_always_inline void
674 yuv2rgb48_1_c_template(SwsContext *c, const int32_t *buf0,
675                        const int32_t *ubuf[2], const int32_t *vbuf[2],
676                        const int32_t *abuf0, uint16_t *dest, int dstW,
677                        int uvalpha, int y, enum PixelFormat target)
678 {
679     const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
680     int i;
681
682     if (uvalpha < 2048) {
683         for (i = 0; i < (dstW >> 1); i++) {
684             int Y1 = (buf0[i * 2]    ) >> 2;
685             int Y2 = (buf0[i * 2 + 1]) >> 2;
686             int U  = (ubuf0[i] + (-128 << 11)) >> 2;
687             int V  = (vbuf0[i] + (-128 << 11)) >> 2;
688             int R, G, B;
689
690             Y1 -= c->yuv2rgb_y_offset;
691             Y2 -= c->yuv2rgb_y_offset;
692             Y1 *= c->yuv2rgb_y_coeff;
693             Y2 *= c->yuv2rgb_y_coeff;
694             Y1 += 1 << 13;
695             Y2 += 1 << 13;
696
697             R = V * c->yuv2rgb_v2r_coeff;
698             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
699             B =                            U * c->yuv2rgb_u2b_coeff;
700
701             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
702             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
703             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
704             output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
705             output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
706             output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
707             dest += 6;
708         }
709     } else {
710         const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
711         for (i = 0; i < (dstW >> 1); i++) {
712             int Y1 = (buf0[i * 2]    ) >> 2;
713             int Y2 = (buf0[i * 2 + 1]) >> 2;
714             int U  = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
715             int V  = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
716             int R, G, B;
717
718             Y1 -= c->yuv2rgb_y_offset;
719             Y2 -= c->yuv2rgb_y_offset;
720             Y1 *= c->yuv2rgb_y_coeff;
721             Y2 *= c->yuv2rgb_y_coeff;
722             Y1 += 1 << 13;
723             Y2 += 1 << 13;
724
725             R = V * c->yuv2rgb_v2r_coeff;
726             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
727             B =                            U * c->yuv2rgb_u2b_coeff;
728
729             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
730             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
731             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
732             output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
733             output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
734             output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
735             dest += 6;
736         }
737     }
738 }
739
740 #undef output_pixel
741 #undef r_b
742 #undef b_r
743
744 #define YUV2PACKED16WRAPPER(name, base, ext, fmt) \
745 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
746                         const int16_t **_lumSrc, int lumFilterSize, \
747                         const int16_t *chrFilter, const int16_t **_chrUSrc, \
748                         const int16_t **_chrVSrc, int chrFilterSize, \
749                         const int16_t **_alpSrc, uint8_t *_dest, int dstW, \
750                         int y) \
751 { \
752     const int32_t **lumSrc  = (const int32_t **) _lumSrc, \
753                   **chrUSrc = (const int32_t **) _chrUSrc, \
754                   **chrVSrc = (const int32_t **) _chrVSrc, \
755                   **alpSrc  = (const int32_t **) _alpSrc; \
756     uint16_t *dest = (uint16_t *) _dest; \
757     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
758                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
759                           alpSrc, dest, dstW, y, fmt); \
760 } \
761  \
762 static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \
763                         const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
764                         const int16_t *_abuf[2], uint8_t *_dest, int dstW, \
765                         int yalpha, int uvalpha, int y) \
766 { \
767     const int32_t **buf  = (const int32_t **) _buf, \
768                   **ubuf = (const int32_t **) _ubuf, \
769                   **vbuf = (const int32_t **) _vbuf, \
770                   **abuf = (const int32_t **) _abuf; \
771     uint16_t *dest = (uint16_t *) _dest; \
772     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
773                           dest, dstW, yalpha, uvalpha, y, fmt); \
774 } \
775  \
776 static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \
777                         const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
778                         const int16_t *_abuf0, uint8_t *_dest, int dstW, \
779                         int uvalpha, int y) \
780 { \
781     const int32_t *buf0  = (const int32_t *)  _buf0, \
782                  **ubuf  = (const int32_t **) _ubuf, \
783                  **vbuf  = (const int32_t **) _vbuf, \
784                   *abuf0 = (const int32_t *)  _abuf0; \
785     uint16_t *dest = (uint16_t *) _dest; \
786     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
787                                   dstW, uvalpha, y, fmt); \
788 }
789
790 YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48be, PIX_FMT_RGB48BE)
791 YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, PIX_FMT_RGB48LE)
792 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, PIX_FMT_BGR48BE)
793 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, PIX_FMT_BGR48LE)
794
795 /*
796  * Write out 2 RGB pixels in the target pixel format. This function takes a
797  * R/G/B LUT as generated by ff_yuv2rgb_c_init_tables(), which takes care of
798  * things like endianness conversion and shifting. The caller takes care of
799  * setting the correct offset in these tables from the chroma (U/V) values.
800  * This function then uses the luminance (Y1/Y2) values to write out the
801  * correct RGB values into the destination buffer.
802  */
803 static av_always_inline void
804 yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2,
805               unsigned A1, unsigned A2,
806               const void *_r, const void *_g, const void *_b, int y,
807               enum PixelFormat target, int hasAlpha)
808 {
809     if (target == PIX_FMT_ARGB || target == PIX_FMT_RGBA ||
810         target == PIX_FMT_ABGR || target == PIX_FMT_BGRA) {
811         uint32_t *dest = (uint32_t *) _dest;
812         const uint32_t *r = (const uint32_t *) _r;
813         const uint32_t *g = (const uint32_t *) _g;
814         const uint32_t *b = (const uint32_t *) _b;
815
816 #if CONFIG_SMALL
817         int sh = hasAlpha ? ((target == PIX_FMT_RGB32_1 || target == PIX_FMT_BGR32_1) ? 0 : 24) : 0;
818
819         dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0);
820         dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0);
821 #else
822         if (hasAlpha) {
823             int sh = (target == PIX_FMT_RGB32_1 || target == PIX_FMT_BGR32_1) ? 0 : 24;
824
825             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (A1 << sh);
826             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (A2 << sh);
827         } else {
828             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1];
829             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2];
830         }
831 #endif
832     } else if (target == PIX_FMT_RGB24 || target == PIX_FMT_BGR24) {
833         uint8_t *dest = (uint8_t *) _dest;
834         const uint8_t *r = (const uint8_t *) _r;
835         const uint8_t *g = (const uint8_t *) _g;
836         const uint8_t *b = (const uint8_t *) _b;
837
838 #define r_b ((target == PIX_FMT_RGB24) ? r : b)
839 #define b_r ((target == PIX_FMT_RGB24) ? b : r)
840
841         dest[i * 6 + 0] = r_b[Y1];
842         dest[i * 6 + 1] =   g[Y1];
843         dest[i * 6 + 2] = b_r[Y1];
844         dest[i * 6 + 3] = r_b[Y2];
845         dest[i * 6 + 4] =   g[Y2];
846         dest[i * 6 + 5] = b_r[Y2];
847 #undef r_b
848 #undef b_r
849     } else if (target == PIX_FMT_RGB565 || target == PIX_FMT_BGR565 ||
850                target == PIX_FMT_RGB555 || target == PIX_FMT_BGR555 ||
851                target == PIX_FMT_RGB444 || target == PIX_FMT_BGR444) {
852         uint16_t *dest = (uint16_t *) _dest;
853         const uint16_t *r = (const uint16_t *) _r;
854         const uint16_t *g = (const uint16_t *) _g;
855         const uint16_t *b = (const uint16_t *) _b;
856         int dr1, dg1, db1, dr2, dg2, db2;
857
858         if (target == PIX_FMT_RGB565 || target == PIX_FMT_BGR565) {
859             dr1 = dither_2x2_8[ y & 1     ][0];
860             dg1 = dither_2x2_4[ y & 1     ][0];
861             db1 = dither_2x2_8[(y & 1) ^ 1][0];
862             dr2 = dither_2x2_8[ y & 1     ][1];
863             dg2 = dither_2x2_4[ y & 1     ][1];
864             db2 = dither_2x2_8[(y & 1) ^ 1][1];
865         } else if (target == PIX_FMT_RGB555 || target == PIX_FMT_BGR555) {
866             dr1 = dither_2x2_8[ y & 1     ][0];
867             dg1 = dither_2x2_8[ y & 1     ][1];
868             db1 = dither_2x2_8[(y & 1) ^ 1][0];
869             dr2 = dither_2x2_8[ y & 1     ][1];
870             dg2 = dither_2x2_8[ y & 1     ][0];
871             db2 = dither_2x2_8[(y & 1) ^ 1][1];
872         } else {
873             dr1 = dither_4x4_16[ y & 3     ][0];
874             dg1 = dither_4x4_16[ y & 3     ][1];
875             db1 = dither_4x4_16[(y & 3) ^ 3][0];
876             dr2 = dither_4x4_16[ y & 3     ][1];
877             dg2 = dither_4x4_16[ y & 3     ][0];
878             db2 = dither_4x4_16[(y & 3) ^ 3][1];
879         }
880
881         dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
882         dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
883     } else /* 8/4-bit */ {
884         uint8_t *dest = (uint8_t *) _dest;
885         const uint8_t *r = (const uint8_t *) _r;
886         const uint8_t *g = (const uint8_t *) _g;
887         const uint8_t *b = (const uint8_t *) _b;
888         int dr1, dg1, db1, dr2, dg2, db2;
889
890         if (target == PIX_FMT_RGB8 || target == PIX_FMT_BGR8) {
891             const uint8_t * const d64 = dither_8x8_73[y & 7];
892             const uint8_t * const d32 = dither_8x8_32[y & 7];
893             dr1 = dg1 = d32[(i * 2 + 0) & 7];
894             db1 =       d64[(i * 2 + 0) & 7];
895             dr2 = dg2 = d32[(i * 2 + 1) & 7];
896             db2 =       d64[(i * 2 + 1) & 7];
897         } else {
898             const uint8_t * const d64  = dither_8x8_73 [y & 7];
899             const uint8_t * const d128 = dither_8x8_220[y & 7];
900             dr1 = db1 = d128[(i * 2 + 0) & 7];
901             dg1 =        d64[(i * 2 + 0) & 7];
902             dr2 = db2 = d128[(i * 2 + 1) & 7];
903             dg2 =        d64[(i * 2 + 1) & 7];
904         }
905
906         if (target == PIX_FMT_RGB4 || target == PIX_FMT_BGR4) {
907             dest[i] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1] +
908                     ((r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]) << 4);
909         } else {
910             dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
911             dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
912         }
913     }
914 }
915
916 static av_always_inline void
917 yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter,
918                      const int16_t **lumSrc, int lumFilterSize,
919                      const int16_t *chrFilter, const int16_t **chrUSrc,
920                      const int16_t **chrVSrc, int chrFilterSize,
921                      const int16_t **alpSrc, uint8_t *dest, int dstW,
922                      int y, enum PixelFormat target, int hasAlpha)
923 {
924     int i;
925
926     for (i = 0; i < (dstW >> 1); i++) {
927         int j, A1, A2;
928         int Y1 = 1 << 18;
929         int Y2 = 1 << 18;
930         int U  = 1 << 18;
931         int V  = 1 << 18;
932         const void *r, *g, *b;
933
934         for (j = 0; j < lumFilterSize; j++) {
935             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
936             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
937         }
938         for (j = 0; j < chrFilterSize; j++) {
939             U += chrUSrc[j][i] * chrFilter[j];
940             V += chrVSrc[j][i] * chrFilter[j];
941         }
942         Y1 >>= 19;
943         Y2 >>= 19;
944         U  >>= 19;
945         V  >>= 19;
946         if (hasAlpha) {
947             A1 = 1 << 18;
948             A2 = 1 << 18;
949             for (j = 0; j < lumFilterSize; j++) {
950                 A1 += alpSrc[j][i * 2    ] * lumFilter[j];
951                 A2 += alpSrc[j][i * 2 + 1] * lumFilter[j];
952             }
953             A1 >>= 19;
954             A2 >>= 19;
955             if ((A1 | A2) & 0x100) {
956                 A1 = av_clip_uint8(A1);
957                 A2 = av_clip_uint8(A2);
958             }
959         }
960
961         r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM];
962         g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]);
963         b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
964
965         yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
966                       r, g, b, y, target, hasAlpha);
967     }
968 }
969
970 static av_always_inline void
971 yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
972                      const int16_t *ubuf[2], const int16_t *vbuf[2],
973                      const int16_t *abuf[2], uint8_t *dest, int dstW,
974                      int yalpha, int uvalpha, int y,
975                      enum PixelFormat target, int hasAlpha)
976 {
977     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
978                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
979                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
980                   *abuf0 = hasAlpha ? abuf[0] : NULL,
981                   *abuf1 = hasAlpha ? abuf[1] : NULL;
982     int  yalpha1 = 4095 - yalpha;
983     int uvalpha1 = 4095 - uvalpha;
984     int i;
985
986     for (i = 0; i < (dstW >> 1); i++) {
987         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
988         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
989         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
990         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
991         int A1, A2;
992         const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
993                    *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
994                    *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
995
996         if (hasAlpha) {
997             A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 19;
998             A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
999         }
1000
1001         yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1002                       r, g, b, y, target, hasAlpha);
1003     }
1004 }
1005
1006 static av_always_inline void
1007 yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
1008                      const int16_t *ubuf[2], const int16_t *vbuf[2],
1009                      const int16_t *abuf0, uint8_t *dest, int dstW,
1010                      int uvalpha, int y, enum PixelFormat target,
1011                      int hasAlpha)
1012 {
1013     const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
1014     int i;
1015
1016     if (uvalpha < 2048) {
1017         for (i = 0; i < (dstW >> 1); i++) {
1018             int Y1 = (buf0[i * 2    ] + 64) >> 7;
1019             int Y2 = (buf0[i * 2 + 1] + 64) >> 7;
1020             int U  = (ubuf0[i]        + 64) >> 7;
1021             int V  = (vbuf0[i]        + 64) >> 7;
1022             int A1, A2;
1023             const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
1024                        *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
1025                        *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1026
1027             if (hasAlpha) {
1028                 A1 = (abuf0[i * 2    ] + 64) >> 7;
1029                 A2 = (abuf0[i * 2 + 1] + 64) >> 7;
1030             }
1031
1032             yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1033                           r, g, b, y, target, hasAlpha);
1034         }
1035     } else {
1036         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
1037         for (i = 0; i < (dstW >> 1); i++) {
1038             int Y1 = (buf0[i * 2    ]     +  64) >> 7;
1039             int Y2 = (buf0[i * 2 + 1]     +  64) >> 7;
1040             int U  = (ubuf0[i] + ubuf1[i] + 128) >> 8;
1041             int V  = (vbuf0[i] + vbuf1[i] + 128) >> 8;
1042             int A1, A2;
1043             const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
1044                        *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
1045                        *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1046
1047             if (hasAlpha) {
1048                 A1 = (abuf0[i * 2    ] + 64) >> 7;
1049                 A2 = (abuf0[i * 2 + 1] + 64) >> 7;
1050             }
1051
1052             yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1053                           r, g, b, y, target, hasAlpha);
1054         }
1055     }
1056 }
1057
1058 #define YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1059 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
1060                                 const int16_t **lumSrc, int lumFilterSize, \
1061                                 const int16_t *chrFilter, const int16_t **chrUSrc, \
1062                                 const int16_t **chrVSrc, int chrFilterSize, \
1063                                 const int16_t **alpSrc, uint8_t *dest, int dstW, \
1064                                 int y) \
1065 { \
1066     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
1067                                   chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
1068                                   alpSrc, dest, dstW, y, fmt, hasAlpha); \
1069 }
1070 #define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha) \
1071 YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1072 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
1073                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
1074                                 const int16_t *abuf[2], uint8_t *dest, int dstW, \
1075                                 int yalpha, int uvalpha, int y) \
1076 { \
1077     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
1078                                   dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
1079 } \
1080  \
1081 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
1082                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
1083                                 const int16_t *abuf0, uint8_t *dest, int dstW, \
1084                                 int uvalpha, int y) \
1085 { \
1086     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
1087                                   dstW, uvalpha, y, fmt, hasAlpha); \
1088 }
1089
1090 #if CONFIG_SMALL
1091 YUV2RGBWRAPPER(yuv2rgb,,  32_1,  PIX_FMT_RGB32_1,   CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1092 YUV2RGBWRAPPER(yuv2rgb,,  32,    PIX_FMT_RGB32,     CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1093 #else
1094 #if CONFIG_SWSCALE_ALPHA
1095 YUV2RGBWRAPPER(yuv2rgb,, a32_1,  PIX_FMT_RGB32_1,   1)
1096 YUV2RGBWRAPPER(yuv2rgb,, a32,    PIX_FMT_RGB32,     1)
1097 #endif
1098 YUV2RGBWRAPPER(yuv2rgb,, x32_1,  PIX_FMT_RGB32_1,   0)
1099 YUV2RGBWRAPPER(yuv2rgb,, x32,    PIX_FMT_RGB32,     0)
1100 #endif
1101 YUV2RGBWRAPPER(yuv2, rgb, rgb24, PIX_FMT_RGB24,   0)
1102 YUV2RGBWRAPPER(yuv2, rgb, bgr24, PIX_FMT_BGR24,   0)
1103 YUV2RGBWRAPPER(yuv2rgb,,  16,    PIX_FMT_RGB565,    0)
1104 YUV2RGBWRAPPER(yuv2rgb,,  15,    PIX_FMT_RGB555,    0)
1105 YUV2RGBWRAPPER(yuv2rgb,,  12,    PIX_FMT_RGB444,    0)
1106 YUV2RGBWRAPPER(yuv2rgb,,   8,    PIX_FMT_RGB8,      0)
1107 YUV2RGBWRAPPER(yuv2rgb,,   4,    PIX_FMT_RGB4,      0)
1108 YUV2RGBWRAPPER(yuv2rgb,,   4b,   PIX_FMT_RGB4_BYTE, 0)
1109
1110 static av_always_inline void
1111 yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
1112                           const int16_t **lumSrc, int lumFilterSize,
1113                           const int16_t *chrFilter, const int16_t **chrUSrc,
1114                           const int16_t **chrVSrc, int chrFilterSize,
1115                           const int16_t **alpSrc, uint8_t *dest,
1116                           int dstW, int y, enum PixelFormat target, int hasAlpha)
1117 {
1118     int i;
1119     int step = (target == PIX_FMT_RGB24 || target == PIX_FMT_BGR24) ? 3 : 4;
1120
1121     for (i = 0; i < dstW; i++) {
1122         int j;
1123         int Y = 1<<9;
1124         int U = (1<<9)-(128 << 19);
1125         int V = (1<<9)-(128 << 19);
1126         int R, G, B, A;
1127
1128         for (j = 0; j < lumFilterSize; j++) {
1129             Y += lumSrc[j][i] * lumFilter[j];
1130         }
1131         for (j = 0; j < chrFilterSize; j++) {
1132             U += chrUSrc[j][i] * chrFilter[j];
1133             V += chrVSrc[j][i] * chrFilter[j];
1134         }
1135         Y >>= 10;
1136         U >>= 10;
1137         V >>= 10;
1138         if (hasAlpha) {
1139             A = 1 << 18;
1140             for (j = 0; j < lumFilterSize; j++) {
1141                 A += alpSrc[j][i] * lumFilter[j];
1142             }
1143             A >>= 19;
1144             if (A & 0x100)
1145                 A = av_clip_uint8(A);
1146         }
1147         Y -= c->yuv2rgb_y_offset;
1148         Y *= c->yuv2rgb_y_coeff;
1149         Y += 1 << 21;
1150         R = Y + V*c->yuv2rgb_v2r_coeff;
1151         G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
1152         B = Y +                          U*c->yuv2rgb_u2b_coeff;
1153         if ((R | G | B) & 0xC0000000) {
1154             R = av_clip_uintp2(R, 30);
1155             G = av_clip_uintp2(G, 30);
1156             B = av_clip_uintp2(B, 30);
1157         }
1158
1159         switch(target) {
1160         case PIX_FMT_ARGB:
1161             dest[0] = hasAlpha ? A : 255;
1162             dest[1] = R >> 22;
1163             dest[2] = G >> 22;
1164             dest[3] = B >> 22;
1165             break;
1166         case PIX_FMT_RGB24:
1167             dest[0] = R >> 22;
1168             dest[1] = G >> 22;
1169             dest[2] = B >> 22;
1170             break;
1171         case PIX_FMT_RGBA:
1172             dest[0] = R >> 22;
1173             dest[1] = G >> 22;
1174             dest[2] = B >> 22;
1175             dest[3] = hasAlpha ? A : 255;
1176             break;
1177         case PIX_FMT_ABGR:
1178             dest[0] = hasAlpha ? A : 255;
1179             dest[1] = B >> 22;
1180             dest[2] = G >> 22;
1181             dest[3] = R >> 22;
1182             break;
1183         case PIX_FMT_BGR24:
1184             dest[0] = B >> 22;
1185             dest[1] = G >> 22;
1186             dest[2] = R >> 22;
1187             break;
1188         case PIX_FMT_BGRA:
1189             dest[0] = B >> 22;
1190             dest[1] = G >> 22;
1191             dest[2] = R >> 22;
1192             dest[3] = hasAlpha ? A : 255;
1193             break;
1194         }
1195         dest += step;
1196     }
1197 }
1198
1199 #if CONFIG_SMALL
1200 YUV2RGBWRAPPERX(yuv2, rgb_full, bgra32_full, PIX_FMT_BGRA,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1201 YUV2RGBWRAPPERX(yuv2, rgb_full, abgr32_full, PIX_FMT_ABGR,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1202 YUV2RGBWRAPPERX(yuv2, rgb_full, rgba32_full, PIX_FMT_RGBA,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1203 YUV2RGBWRAPPERX(yuv2, rgb_full, argb32_full, PIX_FMT_ARGB,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1204 #else
1205 #if CONFIG_SWSCALE_ALPHA
1206 YUV2RGBWRAPPERX(yuv2, rgb_full, bgra32_full, PIX_FMT_BGRA,  1)
1207 YUV2RGBWRAPPERX(yuv2, rgb_full, abgr32_full, PIX_FMT_ABGR,  1)
1208 YUV2RGBWRAPPERX(yuv2, rgb_full, rgba32_full, PIX_FMT_RGBA,  1)
1209 YUV2RGBWRAPPERX(yuv2, rgb_full, argb32_full, PIX_FMT_ARGB,  1)
1210 #endif
1211 YUV2RGBWRAPPERX(yuv2, rgb_full, bgrx32_full, PIX_FMT_BGRA,  0)
1212 YUV2RGBWRAPPERX(yuv2, rgb_full, xbgr32_full, PIX_FMT_ABGR,  0)
1213 YUV2RGBWRAPPERX(yuv2, rgb_full, rgbx32_full, PIX_FMT_RGBA,  0)
1214 YUV2RGBWRAPPERX(yuv2, rgb_full, xrgb32_full, PIX_FMT_ARGB,  0)
1215 #endif
1216 YUV2RGBWRAPPERX(yuv2, rgb_full, bgr24_full,  PIX_FMT_BGR24, 0)
1217 YUV2RGBWRAPPERX(yuv2, rgb_full, rgb24_full,  PIX_FMT_RGB24, 0)
1218
1219 void ff_sws_init_output_funcs(SwsContext *c,
1220                               yuv2planar1_fn *yuv2plane1,
1221                               yuv2planarX_fn *yuv2planeX,
1222                               yuv2interleavedX_fn *yuv2nv12cX,
1223                               yuv2packed1_fn *yuv2packed1,
1224                               yuv2packed2_fn *yuv2packed2,
1225                               yuv2packedX_fn *yuv2packedX)
1226 {
1227     enum PixelFormat dstFormat = c->dstFormat;
1228
1229     if (is16BPS(dstFormat)) {
1230         *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c  : yuv2planeX_16LE_c;
1231         *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c  : yuv2plane1_16LE_c;
1232     } else if (is9_OR_10BPS(dstFormat)) {
1233         if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
1234             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c  : yuv2planeX_9LE_c;
1235             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_c  : yuv2plane1_9LE_c;
1236         } else {
1237             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_10BE_c  : yuv2planeX_10LE_c;
1238             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_10BE_c  : yuv2plane1_10LE_c;
1239         }
1240     } else {
1241         *yuv2plane1 = yuv2plane1_8_c;
1242         *yuv2planeX = yuv2planeX_8_c;
1243         if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21)
1244             *yuv2nv12cX = yuv2nv12cX_c;
1245     }
1246
1247     if(c->flags & SWS_FULL_CHR_H_INT) {
1248         switch (dstFormat) {
1249             case PIX_FMT_RGBA:
1250 #if CONFIG_SMALL
1251                 *yuv2packedX = yuv2rgba32_full_X_c;
1252 #else
1253 #if CONFIG_SWSCALE_ALPHA
1254                 if (c->alpPixBuf) {
1255                     *yuv2packedX = yuv2rgba32_full_X_c;
1256                 } else
1257 #endif /* CONFIG_SWSCALE_ALPHA */
1258                 {
1259                     *yuv2packedX = yuv2rgbx32_full_X_c;
1260                 }
1261 #endif /* !CONFIG_SMALL */
1262                 break;
1263             case PIX_FMT_ARGB:
1264 #if CONFIG_SMALL
1265                 *yuv2packedX = yuv2argb32_full_X_c;
1266 #else
1267 #if CONFIG_SWSCALE_ALPHA
1268                 if (c->alpPixBuf) {
1269                     *yuv2packedX = yuv2argb32_full_X_c;
1270                 } else
1271 #endif /* CONFIG_SWSCALE_ALPHA */
1272                 {
1273                     *yuv2packedX = yuv2xrgb32_full_X_c;
1274                 }
1275 #endif /* !CONFIG_SMALL */
1276                 break;
1277             case PIX_FMT_BGRA:
1278 #if CONFIG_SMALL
1279                 *yuv2packedX = yuv2bgra32_full_X_c;
1280 #else
1281 #if CONFIG_SWSCALE_ALPHA
1282                 if (c->alpPixBuf) {
1283                     *yuv2packedX = yuv2bgra32_full_X_c;
1284                 } else
1285 #endif /* CONFIG_SWSCALE_ALPHA */
1286                 {
1287                     *yuv2packedX = yuv2bgrx32_full_X_c;
1288                 }
1289 #endif /* !CONFIG_SMALL */
1290                 break;
1291             case PIX_FMT_ABGR:
1292 #if CONFIG_SMALL
1293                 *yuv2packedX = yuv2abgr32_full_X_c;
1294 #else
1295 #if CONFIG_SWSCALE_ALPHA
1296                 if (c->alpPixBuf) {
1297                     *yuv2packedX = yuv2abgr32_full_X_c;
1298                 } else
1299 #endif /* CONFIG_SWSCALE_ALPHA */
1300                 {
1301                     *yuv2packedX = yuv2xbgr32_full_X_c;
1302                 }
1303 #endif /* !CONFIG_SMALL */
1304                 break;
1305             case PIX_FMT_RGB24:
1306             *yuv2packedX = yuv2rgb24_full_X_c;
1307             break;
1308         case PIX_FMT_BGR24:
1309             *yuv2packedX = yuv2bgr24_full_X_c;
1310             break;
1311         }
1312         if(!*yuv2packedX)
1313             goto YUV_PACKED;
1314     } else {
1315         YUV_PACKED:
1316         switch (dstFormat) {
1317         case PIX_FMT_RGB48LE:
1318             *yuv2packed1 = yuv2rgb48le_1_c;
1319             *yuv2packed2 = yuv2rgb48le_2_c;
1320             *yuv2packedX = yuv2rgb48le_X_c;
1321             break;
1322         case PIX_FMT_RGB48BE:
1323             *yuv2packed1 = yuv2rgb48be_1_c;
1324             *yuv2packed2 = yuv2rgb48be_2_c;
1325             *yuv2packedX = yuv2rgb48be_X_c;
1326             break;
1327         case PIX_FMT_BGR48LE:
1328             *yuv2packed1 = yuv2bgr48le_1_c;
1329             *yuv2packed2 = yuv2bgr48le_2_c;
1330             *yuv2packedX = yuv2bgr48le_X_c;
1331             break;
1332         case PIX_FMT_BGR48BE:
1333             *yuv2packed1 = yuv2bgr48be_1_c;
1334             *yuv2packed2 = yuv2bgr48be_2_c;
1335             *yuv2packedX = yuv2bgr48be_X_c;
1336             break;
1337         case PIX_FMT_RGB32:
1338         case PIX_FMT_BGR32:
1339 #if CONFIG_SMALL
1340             *yuv2packed1 = yuv2rgb32_1_c;
1341             *yuv2packed2 = yuv2rgb32_2_c;
1342             *yuv2packedX = yuv2rgb32_X_c;
1343 #else
1344 #if CONFIG_SWSCALE_ALPHA
1345                 if (c->alpPixBuf) {
1346                     *yuv2packed1 = yuv2rgba32_1_c;
1347                     *yuv2packed2 = yuv2rgba32_2_c;
1348                     *yuv2packedX = yuv2rgba32_X_c;
1349                 } else
1350 #endif /* CONFIG_SWSCALE_ALPHA */
1351                 {
1352                     *yuv2packed1 = yuv2rgbx32_1_c;
1353                     *yuv2packed2 = yuv2rgbx32_2_c;
1354                     *yuv2packedX = yuv2rgbx32_X_c;
1355                 }
1356 #endif /* !CONFIG_SMALL */
1357             break;
1358         case PIX_FMT_RGB32_1:
1359         case PIX_FMT_BGR32_1:
1360 #if CONFIG_SMALL
1361                 *yuv2packed1 = yuv2rgb32_1_1_c;
1362                 *yuv2packed2 = yuv2rgb32_1_2_c;
1363                 *yuv2packedX = yuv2rgb32_1_X_c;
1364 #else
1365 #if CONFIG_SWSCALE_ALPHA
1366                 if (c->alpPixBuf) {
1367                     *yuv2packed1 = yuv2rgba32_1_1_c;
1368                     *yuv2packed2 = yuv2rgba32_1_2_c;
1369                     *yuv2packedX = yuv2rgba32_1_X_c;
1370                 } else
1371 #endif /* CONFIG_SWSCALE_ALPHA */
1372                 {
1373                     *yuv2packed1 = yuv2rgbx32_1_1_c;
1374                     *yuv2packed2 = yuv2rgbx32_1_2_c;
1375                     *yuv2packedX = yuv2rgbx32_1_X_c;
1376                 }
1377 #endif /* !CONFIG_SMALL */
1378                 break;
1379         case PIX_FMT_RGB24:
1380             *yuv2packed1 = yuv2rgb24_1_c;
1381             *yuv2packed2 = yuv2rgb24_2_c;
1382             *yuv2packedX = yuv2rgb24_X_c;
1383             break;
1384         case PIX_FMT_BGR24:
1385             *yuv2packed1 = yuv2bgr24_1_c;
1386             *yuv2packed2 = yuv2bgr24_2_c;
1387             *yuv2packedX = yuv2bgr24_X_c;
1388             break;
1389         case PIX_FMT_RGB565LE:
1390         case PIX_FMT_RGB565BE:
1391         case PIX_FMT_BGR565LE:
1392         case PIX_FMT_BGR565BE:
1393             *yuv2packed1 = yuv2rgb16_1_c;
1394             *yuv2packed2 = yuv2rgb16_2_c;
1395             *yuv2packedX = yuv2rgb16_X_c;
1396             break;
1397         case PIX_FMT_RGB555LE:
1398         case PIX_FMT_RGB555BE:
1399         case PIX_FMT_BGR555LE:
1400         case PIX_FMT_BGR555BE:
1401             *yuv2packed1 = yuv2rgb15_1_c;
1402             *yuv2packed2 = yuv2rgb15_2_c;
1403             *yuv2packedX = yuv2rgb15_X_c;
1404             break;
1405         case PIX_FMT_RGB444LE:
1406         case PIX_FMT_RGB444BE:
1407         case PIX_FMT_BGR444LE:
1408         case PIX_FMT_BGR444BE:
1409             *yuv2packed1 = yuv2rgb12_1_c;
1410             *yuv2packed2 = yuv2rgb12_2_c;
1411             *yuv2packedX = yuv2rgb12_X_c;
1412             break;
1413         case PIX_FMT_RGB8:
1414         case PIX_FMT_BGR8:
1415             *yuv2packed1 = yuv2rgb8_1_c;
1416             *yuv2packed2 = yuv2rgb8_2_c;
1417             *yuv2packedX = yuv2rgb8_X_c;
1418             break;
1419         case PIX_FMT_RGB4:
1420         case PIX_FMT_BGR4:
1421             *yuv2packed1 = yuv2rgb4_1_c;
1422             *yuv2packed2 = yuv2rgb4_2_c;
1423             *yuv2packedX = yuv2rgb4_X_c;
1424             break;
1425         case PIX_FMT_RGB4_BYTE:
1426         case PIX_FMT_BGR4_BYTE:
1427             *yuv2packed1 = yuv2rgb4b_1_c;
1428             *yuv2packed2 = yuv2rgb4b_2_c;
1429             *yuv2packedX = yuv2rgb4b_X_c;
1430             break;
1431         }
1432     }
1433     switch (dstFormat) {
1434     case PIX_FMT_MONOWHITE:
1435         *yuv2packed1 = yuv2monowhite_1_c;
1436         *yuv2packed2 = yuv2monowhite_2_c;
1437         *yuv2packedX = yuv2monowhite_X_c;
1438         break;
1439     case PIX_FMT_MONOBLACK:
1440         *yuv2packed1 = yuv2monoblack_1_c;
1441         *yuv2packed2 = yuv2monoblack_2_c;
1442         *yuv2packedX = yuv2monoblack_X_c;
1443         break;
1444     case PIX_FMT_YUYV422:
1445         *yuv2packed1 = yuv2yuyv422_1_c;
1446         *yuv2packed2 = yuv2yuyv422_2_c;
1447         *yuv2packedX = yuv2yuyv422_X_c;
1448         break;
1449     case PIX_FMT_UYVY422:
1450         *yuv2packed1 = yuv2uyvy422_1_c;
1451         *yuv2packed2 = yuv2uyvy422_2_c;
1452         *yuv2packedX = yuv2uyvy422_X_c;
1453         break;
1454     }
1455 }