sws/input: replace hardcoded rgb2yuv coefficients by table
[ffmpeg.git] / libswscale / input.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/bswap.h"
29 #include "libavutil/cpu.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/mathematics.h"
32 #include "libavutil/pixdesc.h"
33 #include "libavutil/avassert.h"
34 #include "config.h"
35 #include "rgb2rgb.h"
36 #include "swscale.h"
37 #include "swscale_internal.h"
38
39 #define RGB2YUV_SHIFT 15
40
41 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
42
43 #define r ((origin == AV_PIX_FMT_BGR48BE || origin == AV_PIX_FMT_BGR48LE) ? b_r : r_b)
44 #define b ((origin == AV_PIX_FMT_BGR48BE || origin == AV_PIX_FMT_BGR48LE) ? r_b : b_r)
45
46 static av_always_inline void
47 rgb64ToY_c_template(uint16_t *dst, const uint16_t *src, int width,
48                     enum AVPixelFormat origin, int32_t *rgb2yuv)
49 {
50     int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX];
51     int i;
52     for (i = 0; i < width; i++) {
53         unsigned int r_b = input_pixel(&src[i*4+0]);
54         unsigned int   g = input_pixel(&src[i*4+1]);
55         unsigned int b_r = input_pixel(&src[i*4+2]);
56
57         dst[i] = (ry*r + gy*g + by*b + (0x2001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
58     }
59 }
60
61 static av_always_inline void
62 rgb64ToUV_c_template(uint16_t *dstU, uint16_t *dstV,
63                     const uint16_t *src1, const uint16_t *src2,
64                     int width, enum AVPixelFormat origin, int32_t *rgb2yuv)
65 {
66     int i;
67     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
68     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
69     av_assert1(src1==src2);
70     for (i = 0; i < width; i++) {
71         int r_b = input_pixel(&src1[i*4+0]);
72         int   g = input_pixel(&src1[i*4+1]);
73         int b_r = input_pixel(&src1[i*4+2]);
74
75         dstU[i] = (ru*r + gu*g + bu*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
76         dstV[i] = (rv*r + gv*g + bv*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
77     }
78 }
79
80 static av_always_inline void
81 rgb64ToUV_half_c_template(uint16_t *dstU, uint16_t *dstV,
82                           const uint16_t *src1, const uint16_t *src2,
83                           int width, enum AVPixelFormat origin, int32_t *rgb2yuv)
84 {
85     int i;
86     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
87     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
88     av_assert1(src1==src2);
89     for (i = 0; i < width; i++) {
90         int r_b = (input_pixel(&src1[8 * i + 0]) + input_pixel(&src1[8 * i + 4]) + 1) >> 1;
91         int   g = (input_pixel(&src1[8 * i + 1]) + input_pixel(&src1[8 * i + 5]) + 1) >> 1;
92         int b_r = (input_pixel(&src1[8 * i + 2]) + input_pixel(&src1[8 * i + 6]) + 1) >> 1;
93
94         dstU[i]= (ru*r + gu*g + bu*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
95         dstV[i]= (rv*r + gv*g + bv*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
96     }
97 }
98
99 #define rgb64funcs(pattern, BE_LE, origin) \
100 static void pattern ## 64 ## BE_LE ## ToY_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused0, const uint8_t *unused1,\
101                                     int width, uint32_t *rgb2yuv) \
102 { \
103     const uint16_t *src = (const uint16_t *) _src; \
104     uint16_t *dst = (uint16_t *) _dst; \
105     rgb64ToY_c_template(dst, src, width, origin, rgb2yuv); \
106 } \
107  \
108 static void pattern ## 64 ## BE_LE ## ToUV_c(uint8_t *_dstU, uint8_t *_dstV, \
109                                     const uint8_t *unused0, const uint8_t *_src1, const uint8_t *_src2, \
110                                     int width, uint32_t *rgb2yuv) \
111 { \
112     const uint16_t *src1 = (const uint16_t *) _src1, \
113                    *src2 = (const uint16_t *) _src2; \
114     uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
115     rgb64ToUV_c_template(dstU, dstV, src1, src2, width, origin, rgb2yuv); \
116 } \
117  \
118 static void pattern ## 64 ## BE_LE ## ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, \
119                                     const uint8_t *unused0, const uint8_t *_src1, const uint8_t *_src2, \
120                                     int width, uint32_t *rgb2yuv) \
121 { \
122     const uint16_t *src1 = (const uint16_t *) _src1, \
123                    *src2 = (const uint16_t *) _src2; \
124     uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
125     rgb64ToUV_half_c_template(dstU, dstV, src1, src2, width, origin, rgb2yuv); \
126 }
127
128 rgb64funcs(rgb, LE, AV_PIX_FMT_RGBA64LE)
129 rgb64funcs(rgb, BE, AV_PIX_FMT_RGBA64BE)
130
131 static av_always_inline void rgb48ToY_c_template(uint16_t *dst,
132                                                  const uint16_t *src, int width,
133                                                  enum AVPixelFormat origin,
134                                                  int32_t *rgb2yuv)
135 {
136     int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX];
137     int i;
138     for (i = 0; i < width; i++) {
139         unsigned int r_b = input_pixel(&src[i * 3 + 0]);
140         unsigned int g   = input_pixel(&src[i * 3 + 1]);
141         unsigned int b_r = input_pixel(&src[i * 3 + 2]);
142
143         dst[i] = (ry*r + gy*g + by*b + (0x2001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
144     }
145 }
146
147 static av_always_inline void rgb48ToUV_c_template(uint16_t *dstU,
148                                                   uint16_t *dstV,
149                                                   const uint16_t *src1,
150                                                   const uint16_t *src2,
151                                                   int width,
152                                                   enum AVPixelFormat origin,
153                                                   int32_t *rgb2yuv)
154 {
155     int i;
156     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
157     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
158     av_assert1(src1 == src2);
159     for (i = 0; i < width; i++) {
160         int r_b = input_pixel(&src1[i * 3 + 0]);
161         int g   = input_pixel(&src1[i * 3 + 1]);
162         int b_r = input_pixel(&src1[i * 3 + 2]);
163
164         dstU[i] = (ru*r + gu*g + bu*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
165         dstV[i] = (rv*r + gv*g + bv*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
166     }
167 }
168
169 static av_always_inline void rgb48ToUV_half_c_template(uint16_t *dstU,
170                                                        uint16_t *dstV,
171                                                        const uint16_t *src1,
172                                                        const uint16_t *src2,
173                                                        int width,
174                                                        enum AVPixelFormat origin,
175                                                        int32_t *rgb2yuv)
176 {
177     int i;
178     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
179     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
180     av_assert1(src1 == src2);
181     for (i = 0; i < width; i++) {
182         int r_b = (input_pixel(&src1[6 * i + 0]) +
183                    input_pixel(&src1[6 * i + 3]) + 1) >> 1;
184         int g   = (input_pixel(&src1[6 * i + 1]) +
185                    input_pixel(&src1[6 * i + 4]) + 1) >> 1;
186         int b_r = (input_pixel(&src1[6 * i + 2]) +
187                    input_pixel(&src1[6 * i + 5]) + 1) >> 1;
188
189         dstU[i] = (ru*r + gu*g + bu*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
190         dstV[i] = (rv*r + gv*g + bv*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
191     }
192 }
193
194 #undef r
195 #undef b
196 #undef input_pixel
197
198 #define rgb48funcs(pattern, BE_LE, origin)                              \
199 static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *_dst,              \
200                                             const uint8_t *_src,        \
201                                             const uint8_t *unused0, const uint8_t *unused1,\
202                                             int width,                  \
203                                             uint32_t *rgb2yuv)          \
204 {                                                                       \
205     const uint16_t *src = (const uint16_t *)_src;                       \
206     uint16_t *dst       = (uint16_t *)_dst;                             \
207     rgb48ToY_c_template(dst, src, width, origin, rgb2yuv);              \
208 }                                                                       \
209                                                                         \
210 static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *_dstU,            \
211                                              uint8_t *_dstV,            \
212                                              const uint8_t *unused0,    \
213                                              const uint8_t *_src1,      \
214                                              const uint8_t *_src2,      \
215                                              int width,                 \
216                                              uint32_t *rgb2yuv)         \
217 {                                                                       \
218     const uint16_t *src1 = (const uint16_t *)_src1,                     \
219                    *src2 = (const uint16_t *)_src2;                     \
220     uint16_t *dstU = (uint16_t *)_dstU,                                 \
221              *dstV = (uint16_t *)_dstV;                                 \
222     rgb48ToUV_c_template(dstU, dstV, src1, src2, width, origin, rgb2yuv);        \
223 }                                                                       \
224                                                                         \
225 static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *_dstU,       \
226                                                   uint8_t *_dstV,       \
227                                                   const uint8_t *unused0,    \
228                                                   const uint8_t *_src1, \
229                                                   const uint8_t *_src2, \
230                                                   int width,            \
231                                                   uint32_t *rgb2yuv)    \
232 {                                                                       \
233     const uint16_t *src1 = (const uint16_t *)_src1,                     \
234                    *src2 = (const uint16_t *)_src2;                     \
235     uint16_t *dstU = (uint16_t *)_dstU,                                 \
236              *dstV = (uint16_t *)_dstV;                                 \
237     rgb48ToUV_half_c_template(dstU, dstV, src1, src2, width, origin, rgb2yuv);   \
238 }
239
240 rgb48funcs(rgb, LE, AV_PIX_FMT_RGB48LE)
241 rgb48funcs(rgb, BE, AV_PIX_FMT_RGB48BE)
242 rgb48funcs(bgr, LE, AV_PIX_FMT_BGR48LE)
243 rgb48funcs(bgr, BE, AV_PIX_FMT_BGR48BE)
244
245 #define input_pixel(i) ((origin == AV_PIX_FMT_RGBA ||                      \
246                          origin == AV_PIX_FMT_BGRA ||                      \
247                          origin == AV_PIX_FMT_ARGB ||                      \
248                          origin == AV_PIX_FMT_ABGR)                        \
249                         ? AV_RN32A(&src[(i) * 4])                       \
250                         : (isBE(origin) ? AV_RB16(&src[(i) * 2])        \
251                                         : AV_RL16(&src[(i) * 2])))
252
253 static av_always_inline void rgb16_32ToY_c_template(int16_t *dst,
254                                                     const uint8_t *src,
255                                                     int width,
256                                                     enum AVPixelFormat origin,
257                                                     int shr, int shg,
258                                                     int shb, int shp,
259                                                     int maskr, int maskg,
260                                                     int maskb, int rsh,
261                                                     int gsh, int bsh, int S,
262                                                     int32_t *rgb2yuv)
263 {
264     const int ry       = rgb2yuv[RY_IDX]<<rsh, gy = rgb2yuv[GY_IDX]<<gsh, by = rgb2yuv[BY_IDX]<<bsh;
265     const unsigned rnd = (32<<((S)-1)) + (1<<(S-7));
266     int i;
267
268     for (i = 0; i < width; i++) {
269         int px = input_pixel(i) >> shp;
270         int b  = (px & maskb) >> shb;
271         int g  = (px & maskg) >> shg;
272         int r  = (px & maskr) >> shr;
273
274         dst[i] = (ry * r + gy * g + by * b + rnd) >> ((S)-6);
275     }
276 }
277
278 static av_always_inline void rgb16_32ToUV_c_template(int16_t *dstU,
279                                                      int16_t *dstV,
280                                                      const uint8_t *src,
281                                                      int width,
282                                                      enum AVPixelFormat origin,
283                                                      int shr, int shg,
284                                                      int shb, int shp,
285                                                      int maskr, int maskg,
286                                                      int maskb, int rsh,
287                                                      int gsh, int bsh, int S,
288                                                      int32_t *rgb2yuv)
289 {
290     const int ru       = rgb2yuv[RU_IDX] << rsh, gu = rgb2yuv[GU_IDX] << gsh, bu = rgb2yuv[BU_IDX] << bsh,
291               rv       = rgb2yuv[RV_IDX] << rsh, gv = rgb2yuv[GV_IDX] << gsh, bv = rgb2yuv[BV_IDX] << bsh;
292     const unsigned rnd = (256u<<((S)-1)) + (1<<(S-7));
293     int i;
294
295     for (i = 0; i < width; i++) {
296         int px = input_pixel(i) >> shp;
297         int b  = (px & maskb)   >> shb;
298         int g  = (px & maskg)   >> shg;
299         int r  = (px & maskr)   >> shr;
300
301         dstU[i] = (ru * r + gu * g + bu * b + rnd) >> ((S)-6);
302         dstV[i] = (rv * r + gv * g + bv * b + rnd) >> ((S)-6);
303     }
304 }
305
306 static av_always_inline void rgb16_32ToUV_half_c_template(int16_t *dstU,
307                                                           int16_t *dstV,
308                                                           const uint8_t *src,
309                                                           int width,
310                                                           enum AVPixelFormat origin,
311                                                           int shr, int shg,
312                                                           int shb, int shp,
313                                                           int maskr, int maskg,
314                                                           int maskb, int rsh,
315                                                           int gsh, int bsh, int S,
316                                                           int32_t *rgb2yuv)
317 {
318     const int ru       = rgb2yuv[RU_IDX] << rsh, gu = rgb2yuv[GU_IDX] << gsh, bu = rgb2yuv[BU_IDX] << bsh,
319               rv       = rgb2yuv[RV_IDX] << rsh, gv = rgb2yuv[GV_IDX] << gsh, bv = rgb2yuv[BV_IDX] << bsh,
320               maskgx   = ~(maskr | maskb);
321     const unsigned rnd = (256U<<(S)) + (1<<(S-6));
322     int i;
323
324     maskr |= maskr << 1;
325     maskb |= maskb << 1;
326     maskg |= maskg << 1;
327     for (i = 0; i < width; i++) {
328         int px0 = input_pixel(2 * i + 0) >> shp;
329         int px1 = input_pixel(2 * i + 1) >> shp;
330         int b, r, g = (px0 & maskgx) + (px1 & maskgx);
331         int rb = px0 + px1 - g;
332
333         b = (rb & maskb) >> shb;
334         if (shp ||
335             origin == AV_PIX_FMT_BGR565LE || origin == AV_PIX_FMT_BGR565BE ||
336             origin == AV_PIX_FMT_RGB565LE || origin == AV_PIX_FMT_RGB565BE) {
337             g >>= shg;
338         } else {
339             g = (g & maskg) >> shg;
340         }
341         r = (rb & maskr) >> shr;
342
343         dstU[i] = (ru * r + gu * g + bu * b + (unsigned)rnd) >> ((S)-6+1);
344         dstV[i] = (rv * r + gv * g + bv * b + (unsigned)rnd) >> ((S)-6+1);
345     }
346 }
347
348 #undef input_pixel
349
350 #define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr,          \
351                          maskg, maskb, rsh, gsh, bsh, S)                \
352 static void name ## ToY_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,            \
353                           int width, uint32_t *tab)                     \
354 {                                                                       \
355     rgb16_32ToY_c_template((int16_t*)dst, src, width, fmt, shr, shg, shb, shp,    \
356                            maskr, maskg, maskb, rsh, gsh, bsh, S, tab); \
357 }                                                                       \
358                                                                         \
359 static void name ## ToUV_c(uint8_t *dstU, uint8_t *dstV,                \
360                            const uint8_t *unused0, const uint8_t *src, const uint8_t *dummy,    \
361                            int width, uint32_t *tab)                    \
362 {                                                                       \
363     rgb16_32ToUV_c_template((int16_t*)dstU, (int16_t*)dstV, src, width, fmt,                \
364                             shr, shg, shb, shp,                         \
365                             maskr, maskg, maskb, rsh, gsh, bsh, S, tab);\
366 }                                                                       \
367                                                                         \
368 static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV,           \
369                                 const uint8_t *unused0, const uint8_t *src,                     \
370                                 const uint8_t *dummy,                   \
371                                 int width, uint32_t *tab)               \
372 {                                                                       \
373     rgb16_32ToUV_half_c_template((int16_t*)dstU, (int16_t*)dstV, src, width, fmt,           \
374                                  shr, shg, shb, shp,                    \
375                                  maskr, maskg, maskb,                   \
376                                  rsh, gsh, bsh, S, tab);                \
377 }
378
379 rgb16_32_wrapper(AV_PIX_FMT_BGR32,    bgr32,  16, 0,  0, 0, 0xFF0000, 0xFF00,   0x00FF,  8, 0,  8, RGB2YUV_SHIFT + 8)
380 rgb16_32_wrapper(AV_PIX_FMT_BGR32_1,  bgr321, 16, 0,  0, 8, 0xFF0000, 0xFF00,   0x00FF,  8, 0,  8, RGB2YUV_SHIFT + 8)
381 rgb16_32_wrapper(AV_PIX_FMT_RGB32,    rgb32,   0, 0, 16, 0,   0x00FF, 0xFF00, 0xFF0000,  8, 0,  8, RGB2YUV_SHIFT + 8)
382 rgb16_32_wrapper(AV_PIX_FMT_RGB32_1,  rgb321,  0, 0, 16, 8,   0x00FF, 0xFF00, 0xFF0000,  8, 0,  8, RGB2YUV_SHIFT + 8)
383 rgb16_32_wrapper(AV_PIX_FMT_BGR565LE, bgr16le, 0, 0,  0, 0,   0x001F, 0x07E0,   0xF800, 11, 5,  0, RGB2YUV_SHIFT + 8)
384 rgb16_32_wrapper(AV_PIX_FMT_BGR555LE, bgr15le, 0, 0,  0, 0,   0x001F, 0x03E0,   0x7C00, 10, 5,  0, RGB2YUV_SHIFT + 7)
385 rgb16_32_wrapper(AV_PIX_FMT_BGR444LE, bgr12le, 0, 0,  0, 0,   0x000F, 0x00F0,   0x0F00,  8, 4,  0, RGB2YUV_SHIFT + 4)
386 rgb16_32_wrapper(AV_PIX_FMT_RGB565LE, rgb16le, 0, 0,  0, 0,   0xF800, 0x07E0,   0x001F,  0, 5, 11, RGB2YUV_SHIFT + 8)
387 rgb16_32_wrapper(AV_PIX_FMT_RGB555LE, rgb15le, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT + 7)
388 rgb16_32_wrapper(AV_PIX_FMT_RGB444LE, rgb12le, 0, 0,  0, 0,   0x0F00, 0x00F0,   0x000F,  0, 4,  8, RGB2YUV_SHIFT + 4)
389 rgb16_32_wrapper(AV_PIX_FMT_BGR565BE, bgr16be, 0, 0,  0, 0,   0x001F, 0x07E0,   0xF800, 11, 5,  0, RGB2YUV_SHIFT + 8)
390 rgb16_32_wrapper(AV_PIX_FMT_BGR555BE, bgr15be, 0, 0,  0, 0,   0x001F, 0x03E0,   0x7C00, 10, 5,  0, RGB2YUV_SHIFT + 7)
391 rgb16_32_wrapper(AV_PIX_FMT_BGR444BE, bgr12be, 0, 0,  0, 0,   0x000F, 0x00F0,   0x0F00,  8, 4,  0, RGB2YUV_SHIFT + 4)
392 rgb16_32_wrapper(AV_PIX_FMT_RGB565BE, rgb16be, 0, 0,  0, 0,   0xF800, 0x07E0,   0x001F,  0, 5, 11, RGB2YUV_SHIFT + 8)
393 rgb16_32_wrapper(AV_PIX_FMT_RGB555BE, rgb15be, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT + 7)
394 rgb16_32_wrapper(AV_PIX_FMT_RGB444BE, rgb12be, 0, 0,  0, 0,   0x0F00, 0x00F0,   0x000F,  0, 4,  8, RGB2YUV_SHIFT + 4)
395
396 static void gbr24pToUV_half_c(uint8_t *_dstU, uint8_t *_dstV,
397                          const uint8_t *gsrc, const uint8_t *bsrc, const uint8_t *rsrc,
398                          int width, uint32_t *rgb2yuv)
399 {
400     uint16_t *dstU = (uint16_t *)_dstU;
401     uint16_t *dstV = (uint16_t *)_dstV;
402     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
403     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
404
405     int i;
406     for (i = 0; i < width; i++) {
407         unsigned int g   = gsrc[2*i] + gsrc[2*i+1];
408         unsigned int b   = bsrc[2*i] + bsrc[2*i+1];
409         unsigned int r   = rsrc[2*i] + rsrc[2*i+1];
410
411         dstU[i] = (ru*r + gu*g + bu*b + (0x4001<<(RGB2YUV_SHIFT-6))) >> (RGB2YUV_SHIFT-6+1);
412         dstV[i] = (rv*r + gv*g + bv*b + (0x4001<<(RGB2YUV_SHIFT-6))) >> (RGB2YUV_SHIFT-6+1);
413     }
414 }
415
416 static void rgba64ToA_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1,
417                         const uint8_t *unused2, int width, uint32_t *unused)
418 {
419     int16_t *dst = (int16_t *)_dst;
420     const uint16_t *src = (const uint16_t *)_src;
421     int i;
422     for (i = 0; i < width; i++)
423         dst[i] = src[4 * i + 3];
424 }
425
426 static void abgrToA_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *unused)
427 {
428     int16_t *dst = (int16_t *)_dst;
429     int i;
430     for (i=0; i<width; i++) {
431         dst[i]= src[4*i]<<6;
432     }
433 }
434
435 static void rgbaToA_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *unused)
436 {
437     int16_t *dst = (int16_t *)_dst;
438     int i;
439     for (i=0; i<width; i++) {
440         dst[i]= src[4*i+3]<<6;
441     }
442 }
443
444 static void palToA_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *pal)
445 {
446     int16_t *dst = (int16_t *)_dst;
447     int i;
448     for (i=0; i<width; i++) {
449         int d= src[i];
450
451         dst[i]= (pal[d] >> 24)<<6;
452     }
453 }
454
455 static void palToY_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *pal)
456 {
457     int16_t *dst = (int16_t *)_dst;
458     int i;
459     for (i = 0; i < width; i++) {
460         int d = src[i];
461
462         dst[i] = (pal[d] & 0xFF)<<6;
463     }
464 }
465
466 static void palToUV_c(uint8_t *_dstU, uint8_t *_dstV,
467                            const uint8_t *unused0, const uint8_t *src1, const uint8_t *src2,
468                       int width, uint32_t *pal)
469 {
470     uint16_t *dstU = (uint16_t *)_dstU;
471     int16_t *dstV = (int16_t *)_dstV;
472     int i;
473     av_assert1(src1 == src2);
474     for (i = 0; i < width; i++) {
475         int p = pal[src1[i]];
476
477         dstU[i] = (uint8_t)(p>> 8)<<6;
478         dstV[i] = (uint8_t)(p>>16)<<6;
479     }
480 }
481
482 static void monowhite2Y_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width, uint32_t *unused)
483 {
484     int16_t *dst = (int16_t *)_dst;
485     int i, j;
486     width = (width + 7) >> 3;
487     for (i = 0; i < width; i++) {
488         int d = ~src[i];
489         for (j = 0; j < 8; j++)
490             dst[8*i+j]= ((d>>(7-j))&1) * 16383;
491     }
492     if(width&7){
493         int d= ~src[i];
494         for (j = 0; j < (width&7); j++)
495             dst[8*i+j]= ((d>>(7-j))&1) * 16383;
496     }
497 }
498
499 static void monoblack2Y_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width, uint32_t *unused)
500 {
501     int16_t *dst = (int16_t *)_dst;
502     int i, j;
503     width = (width + 7) >> 3;
504     for (i = 0; i < width; i++) {
505         int d = src[i];
506         for (j = 0; j < 8; j++)
507             dst[8*i+j]= ((d>>(7-j))&1) * 16383;
508     }
509     if(width&7){
510         int d = src[i];
511         for (j = 0; j < (width&7); j++)
512             dst[8*i+j] = ((d>>(7-j))&1) * 16383;
513     }
514 }
515
516 static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width,
517                       uint32_t *unused)
518 {
519     int i;
520     for (i = 0; i < width; i++)
521         dst[i] = src[2 * i];
522 }
523
524 static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, const uint8_t *src1,
525                        const uint8_t *src2, int width, uint32_t *unused)
526 {
527     int i;
528     for (i = 0; i < width; i++) {
529         dstU[i] = src1[4 * i + 1];
530         dstV[i] = src1[4 * i + 3];
531     }
532     av_assert1(src1 == src2);
533 }
534
535 static void bswap16Y_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1, const uint8_t *unused2,  int width,
536                        uint32_t *unused)
537 {
538     int i;
539     const uint16_t *src = (const uint16_t *)_src;
540     uint16_t *dst       = (uint16_t *)_dst;
541     for (i = 0; i < width; i++)
542         dst[i] = av_bswap16(src[i]);
543 }
544
545 static void bswap16UV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *_src1,
546                         const uint8_t *_src2, int width, uint32_t *unused)
547 {
548     int i;
549     const uint16_t *src1 = (const uint16_t *)_src1,
550     *src2                = (const uint16_t *)_src2;
551     uint16_t *dstU       = (uint16_t *)_dstU, *dstV = (uint16_t *)_dstV;
552     for (i = 0; i < width; i++) {
553         dstU[i] = av_bswap16(src1[i]);
554         dstV[i] = av_bswap16(src2[i]);
555     }
556 }
557
558 /* This is almost identical to the previous, end exists only because
559  * yuy2ToY/UV)(dst, src + 1, ...) would have 100% unaligned accesses. */
560 static void uyvyToY_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width,
561                       uint32_t *unused)
562 {
563     int i;
564     for (i = 0; i < width; i++)
565         dst[i] = src[2 * i + 1];
566 }
567
568 static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, const uint8_t *src1,
569                        const uint8_t *src2, int width, uint32_t *unused)
570 {
571     int i;
572     for (i = 0; i < width; i++) {
573         dstU[i] = src1[4 * i + 0];
574         dstV[i] = src1[4 * i + 2];
575     }
576     av_assert1(src1 == src2);
577 }
578
579 static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
580                                         const uint8_t *src, int width)
581 {
582     int i;
583     for (i = 0; i < width; i++) {
584         dst1[i] = src[2 * i + 0];
585         dst2[i] = src[2 * i + 1];
586     }
587 }
588
589 static void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
590                        const uint8_t *unused0, const uint8_t *src1, const uint8_t *src2,
591                        int width, uint32_t *unused)
592 {
593     nvXXtoUV_c(dstU, dstV, src1, width);
594 }
595
596 static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
597                        const uint8_t *unused0, const uint8_t *src1, const uint8_t *src2,
598                        int width, uint32_t *unused)
599 {
600     nvXXtoUV_c(dstV, dstU, src1, width);
601 }
602
603 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
604
605 static void bgr24ToY_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,
606                        int width, uint32_t *rgb2yuv)
607 {
608     int16_t *dst = (int16_t *)_dst;
609     int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX];
610     int i;
611     for (i = 0; i < width; i++) {
612         int b = src[i * 3 + 0];
613         int g = src[i * 3 + 1];
614         int r = src[i * 3 + 2];
615
616         dst[i] = ((ry*r + gy*g + by*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
617     }
618 }
619
620 static void bgr24ToUV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
621                         const uint8_t *src2, int width, uint32_t *rgb2yuv)
622 {
623     int16_t *dstU = (int16_t *)_dstU;
624     int16_t *dstV = (int16_t *)_dstV;
625     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
626     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
627     int i;
628     for (i = 0; i < width; i++) {
629         int b = src1[3 * i + 0];
630         int g = src1[3 * i + 1];
631         int r = src1[3 * i + 2];
632
633         dstU[i] = (ru*r + gu*g + bu*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
634         dstV[i] = (rv*r + gv*g + bv*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
635     }
636     av_assert1(src1 == src2);
637 }
638
639 static void bgr24ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
640                              const uint8_t *src2, int width, uint32_t *rgb2yuv)
641 {
642     int16_t *dstU = (int16_t *)_dstU;
643     int16_t *dstV = (int16_t *)_dstV;
644     int i;
645     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
646     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
647     for (i = 0; i < width; i++) {
648         int b = src1[6 * i + 0] + src1[6 * i + 3];
649         int g = src1[6 * i + 1] + src1[6 * i + 4];
650         int r = src1[6 * i + 2] + src1[6 * i + 5];
651
652         dstU[i] = (ru*r + gu*g + bu*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
653         dstV[i] = (rv*r + gv*g + bv*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
654     }
655     av_assert1(src1 == src2);
656 }
657
658 static void rgb24ToY_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width,
659                        uint32_t *rgb2yuv)
660 {
661     int16_t *dst = (int16_t *)_dst;
662     int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX];
663     int i;
664     for (i = 0; i < width; i++) {
665         int r = src[i * 3 + 0];
666         int g = src[i * 3 + 1];
667         int b = src[i * 3 + 2];
668
669         dst[i] = ((ry*r + gy*g + by*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
670     }
671 }
672
673 static void rgb24ToUV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
674                         const uint8_t *src2, int width, uint32_t *rgb2yuv)
675 {
676     int16_t *dstU = (int16_t *)_dstU;
677     int16_t *dstV = (int16_t *)_dstV;
678     int i;
679     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
680     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
681     av_assert1(src1 == src2);
682     for (i = 0; i < width; i++) {
683         int r = src1[3 * i + 0];
684         int g = src1[3 * i + 1];
685         int b = src1[3 * i + 2];
686
687         dstU[i] = (ru*r + gu*g + bu*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
688         dstV[i] = (rv*r + gv*g + bv*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
689     }
690 }
691
692 static void rgb24ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
693                              const uint8_t *src2, int width, uint32_t *rgb2yuv)
694 {
695     int16_t *dstU = (int16_t *)_dstU;
696     int16_t *dstV = (int16_t *)_dstV;
697     int i;
698     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
699     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
700     av_assert1(src1 == src2);
701     for (i = 0; i < width; i++) {
702         int r = src1[6 * i + 0] + src1[6 * i + 3];
703         int g = src1[6 * i + 1] + src1[6 * i + 4];
704         int b = src1[6 * i + 2] + src1[6 * i + 5];
705
706         dstU[i] = (ru*r + gu*g + bu*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
707         dstV[i] = (rv*r + gv*g + bv*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
708     }
709 }
710
711 static void planar_rgb_to_y(uint8_t *_dst, const uint8_t *src[4], int width, int32_t *rgb2yuv)
712 {
713     uint16_t *dst = (uint16_t *)_dst;
714     int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX];
715     int i;
716     for (i = 0; i < width; i++) {
717         int g = src[0][i];
718         int b = src[1][i];
719         int r = src[2][i];
720
721         dst[i] = (ry*r + gy*g + by*b + (0x801<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6);
722     }
723 }
724
725 static void planar_rgb_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *src[4], int width, int32_t *rgb2yuv)
726 {
727     uint16_t *dstU = (uint16_t *)_dstU;
728     uint16_t *dstV = (uint16_t *)_dstV;
729     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
730     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
731     int i;
732     for (i = 0; i < width; i++) {
733         int g = src[0][i];
734         int b = src[1][i];
735         int r = src[2][i];
736
737         dstU[i] = (ru*r + gu*g + bu*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6);
738         dstV[i] = (rv*r + gv*g + bv*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6);
739     }
740 }
741
742 #define rdpx(src) \
743     is_be ? AV_RB16(src) : AV_RL16(src)
744 static av_always_inline void planar_rgb16_to_y(uint8_t *_dst, const uint8_t *_src[4],
745                                                int width, int bpc, int is_be, int32_t *rgb2yuv)
746 {
747     int i;
748     const uint16_t **src = (const uint16_t **)_src;
749     uint16_t *dst        = (uint16_t *)_dst;
750     int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX];
751     for (i = 0; i < width; i++) {
752         int g = rdpx(src[0] + i);
753         int b = rdpx(src[1] + i);
754         int r = rdpx(src[2] + i);
755
756         dst[i] = ((ry*r + gy*g + by*b + (33 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + bpc - 14));
757     }
758 }
759
760 static void planar_rgb9le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
761 {
762     planar_rgb16_to_y(dst, src, w, 9, 0, rgb2yuv);
763 }
764
765 static void planar_rgb9be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
766 {
767     planar_rgb16_to_y(dst, src, w, 9, 1, rgb2yuv);
768 }
769
770 static void planar_rgb10le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
771 {
772     planar_rgb16_to_y(dst, src, w, 10, 0, rgb2yuv);
773 }
774
775 static void planar_rgb10be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
776 {
777     planar_rgb16_to_y(dst, src, w, 10, 1, rgb2yuv);
778 }
779
780 static void planar_rgb12le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
781 {
782     planar_rgb16_to_y(dst, src, w, 12, 0, rgb2yuv);
783 }
784
785 static void planar_rgb12be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
786 {
787     planar_rgb16_to_y(dst, src, w, 12, 1, rgb2yuv);
788 }
789
790 static void planar_rgb14le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
791 {
792     planar_rgb16_to_y(dst, src, w, 14, 0, rgb2yuv);
793 }
794
795 static void planar_rgb14be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
796 {
797     planar_rgb16_to_y(dst, src, w, 14, 1, rgb2yuv);
798 }
799
800 static void planar_rgb16le_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
801 {
802     planar_rgb16_to_y(dst, src, w, 16, 0, rgb2yuv);
803 }
804
805 static void planar_rgb16be_to_y(uint8_t *dst, const uint8_t *src[4], int w, int32_t *rgb2yuv)
806 {
807     planar_rgb16_to_y(dst, src, w, 16, 1, rgb2yuv);
808 }
809
810 static av_always_inline void planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV,
811                                                 const uint8_t *_src[4], int width,
812                                                 int bpc, int is_be, int32_t *rgb2yuv)
813 {
814     int i;
815     const uint16_t **src = (const uint16_t **)_src;
816     uint16_t *dstU       = (uint16_t *)_dstU;
817     uint16_t *dstV       = (uint16_t *)_dstV;
818     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
819     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
820     for (i = 0; i < width; i++) {
821         int g = rdpx(src[0] + i);
822         int b = rdpx(src[1] + i);
823         int r = rdpx(src[2] + i);
824
825         dstU[i] = (ru*r + gu*g + bu*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + bpc - 14);
826         dstV[i] = (rv*r + gv*g + bv*b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> (RGB2YUV_SHIFT + bpc - 14);
827     }
828 }
829 #undef rdpx
830
831 static void planar_rgb9le_to_uv(uint8_t *dstU, uint8_t *dstV,
832                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
833 {
834     planar_rgb16_to_uv(dstU, dstV, src, w, 9, 0, rgb2yuv);
835 }
836
837 static void planar_rgb9be_to_uv(uint8_t *dstU, uint8_t *dstV,
838                                 const uint8_t *src[4], int w, int32_t *rgb2yuv)
839 {
840     planar_rgb16_to_uv(dstU, dstV, src, w, 9, 1, rgb2yuv);
841 }
842
843 static void planar_rgb10le_to_uv(uint8_t *dstU, uint8_t *dstV,
844                                  const uint8_t *src[4], int w, int32_t *rgb2yuv)
845 {
846     planar_rgb16_to_uv(dstU, dstV, src, w, 10, 0, rgb2yuv);
847 }
848
849 static void planar_rgb10be_to_uv(uint8_t *dstU, uint8_t *dstV,
850                                  const uint8_t *src[4], int w, int32_t *rgb2yuv)
851 {
852     planar_rgb16_to_uv(dstU, dstV, src, w, 10, 1, rgb2yuv);
853 }
854
855 static void planar_rgb12le_to_uv(uint8_t *dstU, uint8_t *dstV,
856                                  const uint8_t *src[4], int w, int32_t *rgb2yuv)
857 {
858     planar_rgb16_to_uv(dstU, dstV, src, w, 12, 0, rgb2yuv);
859 }
860
861 static void planar_rgb12be_to_uv(uint8_t *dstU, uint8_t *dstV,
862                                  const uint8_t *src[4], int w, int32_t *rgb2yuv)
863 {
864     planar_rgb16_to_uv(dstU, dstV, src, w, 12, 1, rgb2yuv);
865 }
866
867 static void planar_rgb14le_to_uv(uint8_t *dstU, uint8_t *dstV,
868                                  const uint8_t *src[4], int w, int32_t *rgb2yuv)
869 {
870     planar_rgb16_to_uv(dstU, dstV, src, w, 14, 0, rgb2yuv);
871 }
872
873 static void planar_rgb14be_to_uv(uint8_t *dstU, uint8_t *dstV,
874                                  const uint8_t *src[4], int w, int32_t *rgb2yuv)
875 {
876     planar_rgb16_to_uv(dstU, dstV, src, w, 14, 1, rgb2yuv);
877 }
878
879 static void planar_rgb16le_to_uv(uint8_t *dstU, uint8_t *dstV,
880                                  const uint8_t *src[4], int w, int32_t *rgb2yuv)
881 {
882     planar_rgb16_to_uv(dstU, dstV, src, w, 16, 0, rgb2yuv);
883 }
884
885 static void planar_rgb16be_to_uv(uint8_t *dstU, uint8_t *dstV,
886                                  const uint8_t *src[4], int w, int32_t *rgb2yuv)
887 {
888     planar_rgb16_to_uv(dstU, dstV, src, w, 16, 1, rgb2yuv);
889 }
890
891 av_cold void ff_sws_init_input_funcs(SwsContext *c)
892 {
893     enum AVPixelFormat srcFormat = c->srcFormat;
894
895     c->chrToYV12 = NULL;
896     switch (srcFormat) {
897     case AV_PIX_FMT_YUYV422:
898         c->chrToYV12 = yuy2ToUV_c;
899         break;
900     case AV_PIX_FMT_UYVY422:
901         c->chrToYV12 = uyvyToUV_c;
902         break;
903     case AV_PIX_FMT_NV12:
904         c->chrToYV12 = nv12ToUV_c;
905         break;
906     case AV_PIX_FMT_NV21:
907         c->chrToYV12 = nv21ToUV_c;
908         break;
909     case AV_PIX_FMT_RGB8:
910     case AV_PIX_FMT_BGR8:
911     case AV_PIX_FMT_PAL8:
912     case AV_PIX_FMT_BGR4_BYTE:
913     case AV_PIX_FMT_RGB4_BYTE:
914         c->chrToYV12 = palToUV_c;
915         break;
916     case AV_PIX_FMT_GBRP9LE:
917         c->readChrPlanar = planar_rgb9le_to_uv;
918         break;
919     case AV_PIX_FMT_GBRP10LE:
920         c->readChrPlanar = planar_rgb10le_to_uv;
921         break;
922     case AV_PIX_FMT_GBRP12LE:
923         c->readChrPlanar = planar_rgb12le_to_uv;
924         break;
925     case AV_PIX_FMT_GBRP14LE:
926         c->readChrPlanar = planar_rgb14le_to_uv;
927         break;
928     case AV_PIX_FMT_GBRP16LE:
929         c->readChrPlanar = planar_rgb16le_to_uv;
930         break;
931     case AV_PIX_FMT_GBRP9BE:
932         c->readChrPlanar = planar_rgb9be_to_uv;
933         break;
934     case AV_PIX_FMT_GBRP10BE:
935         c->readChrPlanar = planar_rgb10be_to_uv;
936         break;
937     case AV_PIX_FMT_GBRP12BE:
938         c->readChrPlanar = planar_rgb12be_to_uv;
939         break;
940     case AV_PIX_FMT_GBRP14BE:
941         c->readChrPlanar = planar_rgb14be_to_uv;
942         break;
943     case AV_PIX_FMT_GBRP16BE:
944         c->readChrPlanar = planar_rgb16be_to_uv;
945         break;
946     case AV_PIX_FMT_GBRP:
947         c->readChrPlanar = planar_rgb_to_uv;
948         break;
949 #if HAVE_BIGENDIAN
950     case AV_PIX_FMT_YUV444P9LE:
951     case AV_PIX_FMT_YUV422P9LE:
952     case AV_PIX_FMT_YUV420P9LE:
953     case AV_PIX_FMT_YUV422P10LE:
954     case AV_PIX_FMT_YUV444P10LE:
955     case AV_PIX_FMT_YUV420P10LE:
956     case AV_PIX_FMT_YUV422P12LE:
957     case AV_PIX_FMT_YUV444P12LE:
958     case AV_PIX_FMT_YUV420P12LE:
959     case AV_PIX_FMT_YUV422P14LE:
960     case AV_PIX_FMT_YUV444P14LE:
961     case AV_PIX_FMT_YUV420P14LE:
962     case AV_PIX_FMT_YUV420P16LE:
963     case AV_PIX_FMT_YUV422P16LE:
964     case AV_PIX_FMT_YUV444P16LE:
965
966     case AV_PIX_FMT_YUVA444P9LE:
967     case AV_PIX_FMT_YUVA422P9LE:
968     case AV_PIX_FMT_YUVA420P9LE:
969     case AV_PIX_FMT_YUVA444P10LE:
970     case AV_PIX_FMT_YUVA422P10LE:
971     case AV_PIX_FMT_YUVA420P10LE:
972     case AV_PIX_FMT_YUVA420P16LE:
973     case AV_PIX_FMT_YUVA422P16LE:
974     case AV_PIX_FMT_YUVA444P16LE:
975         c->chrToYV12 = bswap16UV_c;
976         break;
977 #else
978     case AV_PIX_FMT_YUV444P9BE:
979     case AV_PIX_FMT_YUV422P9BE:
980     case AV_PIX_FMT_YUV420P9BE:
981     case AV_PIX_FMT_YUV444P10BE:
982     case AV_PIX_FMT_YUV422P10BE:
983     case AV_PIX_FMT_YUV420P10BE:
984     case AV_PIX_FMT_YUV444P12BE:
985     case AV_PIX_FMT_YUV422P12BE:
986     case AV_PIX_FMT_YUV420P12BE:
987     case AV_PIX_FMT_YUV444P14BE:
988     case AV_PIX_FMT_YUV422P14BE:
989     case AV_PIX_FMT_YUV420P14BE:
990     case AV_PIX_FMT_YUV420P16BE:
991     case AV_PIX_FMT_YUV422P16BE:
992     case AV_PIX_FMT_YUV444P16BE:
993
994     case AV_PIX_FMT_YUVA444P9BE:
995     case AV_PIX_FMT_YUVA422P9BE:
996     case AV_PIX_FMT_YUVA420P9BE:
997     case AV_PIX_FMT_YUVA444P10BE:
998     case AV_PIX_FMT_YUVA422P10BE:
999     case AV_PIX_FMT_YUVA420P10BE:
1000     case AV_PIX_FMT_YUVA420P16BE:
1001     case AV_PIX_FMT_YUVA422P16BE:
1002     case AV_PIX_FMT_YUVA444P16BE:
1003         c->chrToYV12 = bswap16UV_c;
1004         break;
1005 #endif
1006     }
1007     if (c->chrSrcHSubSample) {
1008         switch (srcFormat) {
1009         case AV_PIX_FMT_RGBA64BE:
1010             c->chrToYV12 = rgb64BEToUV_half_c;
1011             break;
1012         case AV_PIX_FMT_RGBA64LE:
1013             c->chrToYV12 = rgb64LEToUV_half_c;
1014             break;
1015         case AV_PIX_FMT_RGB48BE:
1016             c->chrToYV12 = rgb48BEToUV_half_c;
1017             break;
1018         case AV_PIX_FMT_RGB48LE:
1019             c->chrToYV12 = rgb48LEToUV_half_c;
1020             break;
1021         case AV_PIX_FMT_BGR48BE:
1022             c->chrToYV12 = bgr48BEToUV_half_c;
1023             break;
1024         case AV_PIX_FMT_BGR48LE:
1025             c->chrToYV12 = bgr48LEToUV_half_c;
1026             break;
1027         case AV_PIX_FMT_RGB32:
1028             c->chrToYV12 = bgr32ToUV_half_c;
1029             break;
1030         case AV_PIX_FMT_RGB32_1:
1031             c->chrToYV12 = bgr321ToUV_half_c;
1032             break;
1033         case AV_PIX_FMT_BGR24:
1034             c->chrToYV12 = bgr24ToUV_half_c;
1035             break;
1036         case AV_PIX_FMT_BGR565LE:
1037             c->chrToYV12 = bgr16leToUV_half_c;
1038             break;
1039         case AV_PIX_FMT_BGR565BE:
1040             c->chrToYV12 = bgr16beToUV_half_c;
1041             break;
1042         case AV_PIX_FMT_BGR555LE:
1043             c->chrToYV12 = bgr15leToUV_half_c;
1044             break;
1045         case AV_PIX_FMT_BGR555BE:
1046             c->chrToYV12 = bgr15beToUV_half_c;
1047             break;
1048         case AV_PIX_FMT_GBR24P  :
1049             c->chrToYV12 = gbr24pToUV_half_c;
1050             break;
1051         case AV_PIX_FMT_BGR444LE:
1052             c->chrToYV12 = bgr12leToUV_half_c;
1053             break;
1054         case AV_PIX_FMT_BGR444BE:
1055             c->chrToYV12 = bgr12beToUV_half_c;
1056             break;
1057         case AV_PIX_FMT_BGR32:
1058             c->chrToYV12 = rgb32ToUV_half_c;
1059             break;
1060         case AV_PIX_FMT_BGR32_1:
1061             c->chrToYV12 = rgb321ToUV_half_c;
1062             break;
1063         case AV_PIX_FMT_RGB24:
1064             c->chrToYV12 = rgb24ToUV_half_c;
1065             break;
1066         case AV_PIX_FMT_RGB565LE:
1067             c->chrToYV12 = rgb16leToUV_half_c;
1068             break;
1069         case AV_PIX_FMT_RGB565BE:
1070             c->chrToYV12 = rgb16beToUV_half_c;
1071             break;
1072         case AV_PIX_FMT_RGB555LE:
1073             c->chrToYV12 = rgb15leToUV_half_c;
1074             break;
1075         case AV_PIX_FMT_RGB555BE:
1076             c->chrToYV12 = rgb15beToUV_half_c;
1077             break;
1078         case AV_PIX_FMT_RGB444LE:
1079             c->chrToYV12 = rgb12leToUV_half_c;
1080             break;
1081         case AV_PIX_FMT_RGB444BE:
1082             c->chrToYV12 = rgb12beToUV_half_c;
1083             break;
1084         }
1085     } else {
1086         switch (srcFormat) {
1087         case AV_PIX_FMT_RGBA64BE:
1088             c->chrToYV12 = rgb64BEToUV_c;
1089             break;
1090         case AV_PIX_FMT_RGBA64LE:
1091             c->chrToYV12 = rgb64LEToUV_c;
1092             break;
1093         case AV_PIX_FMT_RGB48BE:
1094             c->chrToYV12 = rgb48BEToUV_c;
1095             break;
1096         case AV_PIX_FMT_RGB48LE:
1097             c->chrToYV12 = rgb48LEToUV_c;
1098             break;
1099         case AV_PIX_FMT_BGR48BE:
1100             c->chrToYV12 = bgr48BEToUV_c;
1101             break;
1102         case AV_PIX_FMT_BGR48LE:
1103             c->chrToYV12 = bgr48LEToUV_c;
1104             break;
1105         case AV_PIX_FMT_RGB32:
1106             c->chrToYV12 = bgr32ToUV_c;
1107             break;
1108         case AV_PIX_FMT_RGB32_1:
1109             c->chrToYV12 = bgr321ToUV_c;
1110             break;
1111         case AV_PIX_FMT_BGR24:
1112             c->chrToYV12 = bgr24ToUV_c;
1113             break;
1114         case AV_PIX_FMT_BGR565LE:
1115             c->chrToYV12 = bgr16leToUV_c;
1116             break;
1117         case AV_PIX_FMT_BGR565BE:
1118             c->chrToYV12 = bgr16beToUV_c;
1119             break;
1120         case AV_PIX_FMT_BGR555LE:
1121             c->chrToYV12 = bgr15leToUV_c;
1122             break;
1123         case AV_PIX_FMT_BGR555BE:
1124             c->chrToYV12 = bgr15beToUV_c;
1125             break;
1126         case AV_PIX_FMT_BGR444LE:
1127             c->chrToYV12 = bgr12leToUV_c;
1128             break;
1129         case AV_PIX_FMT_BGR444BE:
1130             c->chrToYV12 = bgr12beToUV_c;
1131             break;
1132         case AV_PIX_FMT_BGR32:
1133             c->chrToYV12 = rgb32ToUV_c;
1134             break;
1135         case AV_PIX_FMT_BGR32_1:
1136             c->chrToYV12 = rgb321ToUV_c;
1137             break;
1138         case AV_PIX_FMT_RGB24:
1139             c->chrToYV12 = rgb24ToUV_c;
1140             break;
1141         case AV_PIX_FMT_RGB565LE:
1142             c->chrToYV12 = rgb16leToUV_c;
1143             break;
1144         case AV_PIX_FMT_RGB565BE:
1145             c->chrToYV12 = rgb16beToUV_c;
1146             break;
1147         case AV_PIX_FMT_RGB555LE:
1148             c->chrToYV12 = rgb15leToUV_c;
1149             break;
1150         case AV_PIX_FMT_RGB555BE:
1151             c->chrToYV12 = rgb15beToUV_c;
1152             break;
1153         case AV_PIX_FMT_RGB444LE:
1154             c->chrToYV12 = rgb12leToUV_c;
1155             break;
1156         case AV_PIX_FMT_RGB444BE:
1157             c->chrToYV12 = rgb12beToUV_c;
1158             break;
1159         }
1160     }
1161
1162     c->lumToYV12 = NULL;
1163     c->alpToYV12 = NULL;
1164     switch (srcFormat) {
1165     case AV_PIX_FMT_GBRP9LE:
1166         c->readLumPlanar = planar_rgb9le_to_y;
1167         break;
1168     case AV_PIX_FMT_GBRP10LE:
1169         c->readLumPlanar = planar_rgb10le_to_y;
1170         break;
1171     case AV_PIX_FMT_GBRP12LE:
1172         c->readLumPlanar = planar_rgb12le_to_y;
1173         break;
1174     case AV_PIX_FMT_GBRP14LE:
1175         c->readLumPlanar = planar_rgb14le_to_y;
1176         break;
1177     case AV_PIX_FMT_GBRP16LE:
1178         c->readLumPlanar = planar_rgb16le_to_y;
1179         break;
1180     case AV_PIX_FMT_GBRP9BE:
1181         c->readLumPlanar = planar_rgb9be_to_y;
1182         break;
1183     case AV_PIX_FMT_GBRP10BE:
1184         c->readLumPlanar = planar_rgb10be_to_y;
1185         break;
1186     case AV_PIX_FMT_GBRP12BE:
1187         c->readLumPlanar = planar_rgb12be_to_y;
1188         break;
1189     case AV_PIX_FMT_GBRP14BE:
1190         c->readLumPlanar = planar_rgb14be_to_y;
1191         break;
1192     case AV_PIX_FMT_GBRP16BE:
1193         c->readLumPlanar = planar_rgb16be_to_y;
1194         break;
1195     case AV_PIX_FMT_GBRP:
1196         c->readLumPlanar = planar_rgb_to_y;
1197         break;
1198 #if HAVE_BIGENDIAN
1199     case AV_PIX_FMT_YUV444P9LE:
1200     case AV_PIX_FMT_YUV422P9LE:
1201     case AV_PIX_FMT_YUV420P9LE:
1202     case AV_PIX_FMT_YUV444P10LE:
1203     case AV_PIX_FMT_YUV422P10LE:
1204     case AV_PIX_FMT_YUV420P10LE:
1205     case AV_PIX_FMT_YUV444P12LE:
1206     case AV_PIX_FMT_YUV422P12LE:
1207     case AV_PIX_FMT_YUV420P12LE:
1208     case AV_PIX_FMT_YUV444P14LE:
1209     case AV_PIX_FMT_YUV422P14LE:
1210     case AV_PIX_FMT_YUV420P14LE:
1211     case AV_PIX_FMT_YUV420P16LE:
1212     case AV_PIX_FMT_YUV422P16LE:
1213     case AV_PIX_FMT_YUV444P16LE:
1214
1215     case AV_PIX_FMT_GRAY16LE:
1216         c->lumToYV12 = bswap16Y_c;
1217         break;
1218     case AV_PIX_FMT_YUVA444P9LE:
1219     case AV_PIX_FMT_YUVA422P9LE:
1220     case AV_PIX_FMT_YUVA420P9LE:
1221     case AV_PIX_FMT_YUVA444P10LE:
1222     case AV_PIX_FMT_YUVA422P10LE:
1223     case AV_PIX_FMT_YUVA420P10LE:
1224     case AV_PIX_FMT_YUVA420P16LE:
1225     case AV_PIX_FMT_YUVA422P16LE:
1226     case AV_PIX_FMT_YUVA444P16LE:
1227         c->lumToYV12 = bswap16Y_c;
1228         c->alpToYV12 = bswap16Y_c;
1229         break;
1230 #else
1231     case AV_PIX_FMT_YUV444P9BE:
1232     case AV_PIX_FMT_YUV422P9BE:
1233     case AV_PIX_FMT_YUV420P9BE:
1234     case AV_PIX_FMT_YUV444P10BE:
1235     case AV_PIX_FMT_YUV422P10BE:
1236     case AV_PIX_FMT_YUV420P10BE:
1237     case AV_PIX_FMT_YUV444P12BE:
1238     case AV_PIX_FMT_YUV422P12BE:
1239     case AV_PIX_FMT_YUV420P12BE:
1240     case AV_PIX_FMT_YUV444P14BE:
1241     case AV_PIX_FMT_YUV422P14BE:
1242     case AV_PIX_FMT_YUV420P14BE:
1243     case AV_PIX_FMT_YUV420P16BE:
1244     case AV_PIX_FMT_YUV422P16BE:
1245     case AV_PIX_FMT_YUV444P16BE:
1246
1247     case AV_PIX_FMT_GRAY16BE:
1248         c->lumToYV12 = bswap16Y_c;
1249         break;
1250     case AV_PIX_FMT_YUVA444P9BE:
1251     case AV_PIX_FMT_YUVA422P9BE:
1252     case AV_PIX_FMT_YUVA420P9BE:
1253     case AV_PIX_FMT_YUVA444P10BE:
1254     case AV_PIX_FMT_YUVA422P10BE:
1255     case AV_PIX_FMT_YUVA420P10BE:
1256     case AV_PIX_FMT_YUVA420P16BE:
1257     case AV_PIX_FMT_YUVA422P16BE:
1258     case AV_PIX_FMT_YUVA444P16BE:
1259         c->lumToYV12 = bswap16Y_c;
1260         c->alpToYV12 = bswap16Y_c;
1261         break;
1262 #endif
1263     case AV_PIX_FMT_YUYV422:
1264     case AV_PIX_FMT_Y400A:
1265         c->lumToYV12 = yuy2ToY_c;
1266         break;
1267     case AV_PIX_FMT_UYVY422:
1268         c->lumToYV12 = uyvyToY_c;
1269         break;
1270     case AV_PIX_FMT_BGR24:
1271         c->lumToYV12 = bgr24ToY_c;
1272         break;
1273     case AV_PIX_FMT_BGR565LE:
1274         c->lumToYV12 = bgr16leToY_c;
1275         break;
1276     case AV_PIX_FMT_BGR565BE:
1277         c->lumToYV12 = bgr16beToY_c;
1278         break;
1279     case AV_PIX_FMT_BGR555LE:
1280         c->lumToYV12 = bgr15leToY_c;
1281         break;
1282     case AV_PIX_FMT_BGR555BE:
1283         c->lumToYV12 = bgr15beToY_c;
1284         break;
1285     case AV_PIX_FMT_BGR444LE:
1286         c->lumToYV12 = bgr12leToY_c;
1287         break;
1288     case AV_PIX_FMT_BGR444BE:
1289         c->lumToYV12 = bgr12beToY_c;
1290         break;
1291     case AV_PIX_FMT_RGB24:
1292         c->lumToYV12 = rgb24ToY_c;
1293         break;
1294     case AV_PIX_FMT_RGB565LE:
1295         c->lumToYV12 = rgb16leToY_c;
1296         break;
1297     case AV_PIX_FMT_RGB565BE:
1298         c->lumToYV12 = rgb16beToY_c;
1299         break;
1300     case AV_PIX_FMT_RGB555LE:
1301         c->lumToYV12 = rgb15leToY_c;
1302         break;
1303     case AV_PIX_FMT_RGB555BE:
1304         c->lumToYV12 = rgb15beToY_c;
1305         break;
1306     case AV_PIX_FMT_RGB444LE:
1307         c->lumToYV12 = rgb12leToY_c;
1308         break;
1309     case AV_PIX_FMT_RGB444BE:
1310         c->lumToYV12 = rgb12beToY_c;
1311         break;
1312     case AV_PIX_FMT_RGB8:
1313     case AV_PIX_FMT_BGR8:
1314     case AV_PIX_FMT_PAL8:
1315     case AV_PIX_FMT_BGR4_BYTE:
1316     case AV_PIX_FMT_RGB4_BYTE:
1317         c->lumToYV12 = palToY_c;
1318         break;
1319     case AV_PIX_FMT_MONOBLACK:
1320         c->lumToYV12 = monoblack2Y_c;
1321         break;
1322     case AV_PIX_FMT_MONOWHITE:
1323         c->lumToYV12 = monowhite2Y_c;
1324         break;
1325     case AV_PIX_FMT_RGB32:
1326         c->lumToYV12 = bgr32ToY_c;
1327         break;
1328     case AV_PIX_FMT_RGB32_1:
1329         c->lumToYV12 = bgr321ToY_c;
1330         break;
1331     case AV_PIX_FMT_BGR32:
1332         c->lumToYV12 = rgb32ToY_c;
1333         break;
1334     case AV_PIX_FMT_BGR32_1:
1335         c->lumToYV12 = rgb321ToY_c;
1336         break;
1337     case AV_PIX_FMT_RGB48BE:
1338         c->lumToYV12 = rgb48BEToY_c;
1339         break;
1340     case AV_PIX_FMT_RGB48LE:
1341         c->lumToYV12 = rgb48LEToY_c;
1342         break;
1343     case AV_PIX_FMT_BGR48BE:
1344         c->lumToYV12 = bgr48BEToY_c;
1345         break;
1346     case AV_PIX_FMT_BGR48LE:
1347         c->lumToYV12 = bgr48LEToY_c;
1348         break;
1349     case AV_PIX_FMT_RGBA64BE:
1350         c->lumToYV12 = rgb64BEToY_c;
1351         break;
1352     case AV_PIX_FMT_RGBA64LE:
1353         c->lumToYV12 = rgb64LEToY_c;
1354         break;
1355     }
1356     if (c->alpPixBuf) {
1357         if (is16BPS(srcFormat) || isNBPS(srcFormat)) {
1358             if (HAVE_BIGENDIAN == !isBE(srcFormat))
1359                 c->alpToYV12 = bswap16Y_c;
1360         }
1361         switch (srcFormat) {
1362         case AV_PIX_FMT_RGBA64LE:
1363         case AV_PIX_FMT_RGBA64BE:  c->alpToYV12 = rgba64ToA_c; break;
1364         case AV_PIX_FMT_BGRA:
1365         case AV_PIX_FMT_RGBA:
1366             c->alpToYV12 = rgbaToA_c;
1367             break;
1368         case AV_PIX_FMT_ABGR:
1369         case AV_PIX_FMT_ARGB:
1370             c->alpToYV12 = abgrToA_c;
1371             break;
1372         case AV_PIX_FMT_Y400A:
1373             c->alpToYV12 = uyvyToY_c;
1374             break;
1375         case AV_PIX_FMT_PAL8 :
1376             c->alpToYV12 = palToA_c;
1377             break;
1378         }
1379     }
1380 }