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