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