]> git.sesse.net Git - ffmpeg/blob - libswscale/input.c
40ed1224270649f3e3481d75335c958b6ff01c6b
[ffmpeg] / libswscale / input.c
1 /*
2  * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of Libav.
5  *
6  * Libav 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  * Libav 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 Libav; 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 rgb48ToY_c_template(uint16_t *dst,
55                                                  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 * 3 + 0]);
61         unsigned int g   = input_pixel(&src[i * 3 + 1]);
62         unsigned int b_r = input_pixel(&src[i * 3 + 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 rgb48ToUV_c_template(uint16_t *dstU,
69                                                   uint16_t *dstV,
70                                                   const uint16_t *src1,
71                                                   const uint16_t *src2,
72                                                   int width,
73                                                   enum PixelFormat origin)
74 {
75     int i;
76     assert(src1 == src2);
77     for (i = 0; i < width; i++) {
78         int r_b = input_pixel(&src1[i * 3 + 0]);
79         int g   = input_pixel(&src1[i * 3 + 1]);
80         int b_r = input_pixel(&src1[i * 3 + 2]);
81
82         dstU[i] = (RU * r + GU * g + BU * b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
83         dstV[i] = (RV * r + GV * g + BV * b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
84     }
85 }
86
87 static av_always_inline void rgb48ToUV_half_c_template(uint16_t *dstU,
88                                                        uint16_t *dstV,
89                                                        const uint16_t *src1,
90                                                        const uint16_t *src2,
91                                                        int width,
92                                                        enum PixelFormat origin)
93 {
94     int i;
95     assert(src1 == src2);
96     for (i = 0; i < width; i++) {
97         int r_b = (input_pixel(&src1[6 * i + 0]) +
98                    input_pixel(&src1[6 * i + 3]) + 1) >> 1;
99         int g   = (input_pixel(&src1[6 * i + 1]) +
100                    input_pixel(&src1[6 * i + 4]) + 1) >> 1;
101         int b_r = (input_pixel(&src1[6 * i + 2]) +
102                    input_pixel(&src1[6 * i + 5]) + 1) >> 1;
103
104         dstU[i] = (RU * r + GU * g + BU * b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
105         dstV[i] = (RV * r + GV * g + BV * b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
106     }
107 }
108
109 #undef r
110 #undef b
111 #undef input_pixel
112
113 #define rgb48funcs(pattern, BE_LE, origin)                              \
114 static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *_dst,              \
115                                             const uint8_t *_src,        \
116                                             int width,                  \
117                                             uint32_t *unused)           \
118 {                                                                       \
119     const uint16_t *src = (const uint16_t *)_src;                       \
120     uint16_t *dst       = (uint16_t *)_dst;                             \
121     rgb48ToY_c_template(dst, src, width, origin);                       \
122 }                                                                       \
123                                                                         \
124 static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *_dstU,            \
125                                              uint8_t *_dstV,            \
126                                              const uint8_t *_src1,      \
127                                              const uint8_t *_src2,      \
128                                              int width,                 \
129                                              uint32_t *unused)          \
130 {                                                                       \
131     const uint16_t *src1 = (const uint16_t *)_src1,                     \
132                    *src2 = (const uint16_t *)_src2;                     \
133     uint16_t *dstU = (uint16_t *)_dstU,                                 \
134              *dstV = (uint16_t *)_dstV;                                 \
135     rgb48ToUV_c_template(dstU, dstV, src1, src2, width, origin);        \
136 }                                                                       \
137                                                                         \
138 static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *_dstU,       \
139                                                   uint8_t *_dstV,       \
140                                                   const uint8_t *_src1, \
141                                                   const uint8_t *_src2, \
142                                                   int width,            \
143                                                   uint32_t *unused)     \
144 {                                                                       \
145     const uint16_t *src1 = (const uint16_t *)_src1,                     \
146                    *src2 = (const uint16_t *)_src2;                     \
147     uint16_t *dstU = (uint16_t *)_dstU,                                 \
148              *dstV = (uint16_t *)_dstV;                                 \
149     rgb48ToUV_half_c_template(dstU, dstV, src1, src2, width, origin);   \
150 }
151
152 rgb48funcs(rgb, LE, PIX_FMT_RGB48LE)
153 rgb48funcs(rgb, BE, PIX_FMT_RGB48BE)
154 rgb48funcs(bgr, LE, PIX_FMT_BGR48LE)
155 rgb48funcs(bgr, BE, PIX_FMT_BGR48BE)
156
157 #define input_pixel(i) ((origin == PIX_FMT_RGBA ||                      \
158                          origin == PIX_FMT_BGRA ||                      \
159                          origin == PIX_FMT_ARGB ||                      \
160                          origin == PIX_FMT_ABGR)                        \
161                         ? AV_RN32A(&src[(i) * 4])                       \
162                         : (isBE(origin) ? AV_RB16(&src[(i) * 2])        \
163                                         : AV_RL16(&src[(i) * 2])))
164
165 static av_always_inline void rgb16_32ToY_c_template(uint8_t *dst,
166                                                     const uint8_t *src,
167                                                     int width,
168                                                     enum PixelFormat origin,
169                                                     int shr, int shg,
170                                                     int shb, int shp,
171                                                     int maskr, int maskg,
172                                                     int maskb, int rsh,
173                                                     int gsh, int bsh, int S)
174 {
175     const int ry       = RY << rsh, gy = GY << gsh, by = BY << bsh;
176     const unsigned rnd = 33u << (S - 1);
177     int i;
178
179     for (i = 0; i < width; i++) {
180         int px = input_pixel(i) >> shp;
181         int b  = (px & maskb) >> shb;
182         int g  = (px & maskg) >> shg;
183         int r  = (px & maskr) >> shr;
184
185         dst[i] = (ry * r + gy * g + by * b + rnd) >> S;
186     }
187 }
188
189 static av_always_inline void rgb16_32ToUV_c_template(uint8_t *dstU,
190                                                      uint8_t *dstV,
191                                                      const uint8_t *src,
192                                                      int width,
193                                                      enum PixelFormat origin,
194                                                      int shr, int shg,
195                                                      int shb, int shp,
196                                                      int maskr, int maskg,
197                                                      int maskb, int rsh,
198                                                      int gsh, int bsh, int S)
199 {
200     const int ru       = RU << rsh, gu = GU << gsh, bu = BU << bsh,
201               rv       = RV << rsh, gv = GV << gsh, bv = BV << bsh;
202     const unsigned rnd = 257u << (S - 1);
203     int i;
204
205     for (i = 0; i < width; i++) {
206         int px = input_pixel(i) >> shp;
207         int b  = (px & maskb)   >> shb;
208         int g  = (px & maskg)   >> shg;
209         int r  = (px & maskr)   >> shr;
210
211         dstU[i] = (ru * r + gu * g + bu * b + rnd) >> S;
212         dstV[i] = (rv * r + gv * g + bv * b + rnd) >> S;
213     }
214 }
215
216 static av_always_inline void rgb16_32ToUV_half_c_template(uint8_t *dstU,
217                                                           uint8_t *dstV,
218                                                           const uint8_t *src,
219                                                           int width,
220                                                           enum PixelFormat origin,
221                                                           int shr, int shg,
222                                                           int shb, int shp,
223                                                           int maskr, int maskg,
224                                                           int maskb, int rsh,
225                                                           int gsh, int bsh, int S)
226 {
227     const int ru       = RU << rsh, gu = GU << gsh, bu = BU << bsh,
228               rv       = RV << rsh, gv = GV << gsh, bv = BV << bsh,
229               maskgx   = ~(maskr | maskb);
230     const unsigned rnd = 257u << S;
231     int i;
232
233     maskr |= maskr << 1;
234     maskb |= maskb << 1;
235     maskg |= maskg << 1;
236     for (i = 0; i < width; i++) {
237         int px0 = input_pixel(2 * i + 0) >> shp;
238         int px1 = input_pixel(2 * i + 1) >> shp;
239         int b, r, g = (px0 & maskgx) + (px1 & maskgx);
240         int rb = px0 + px1 - g;
241
242         b = (rb & maskb) >> shb;
243         if (shp ||
244             origin == PIX_FMT_BGR565LE || origin == PIX_FMT_BGR565BE ||
245             origin == PIX_FMT_RGB565LE || origin == PIX_FMT_RGB565BE) {
246             g >>= shg;
247         } else {
248             g = (g & maskg) >> shg;
249         }
250         r = (rb & maskr) >> shr;
251
252         dstU[i] = (ru * r + gu * g + bu * b + rnd) >> (S + 1);
253         dstV[i] = (rv * r + gv * g + bv * b + rnd) >> (S + 1);
254     }
255 }
256
257 #undef input_pixel
258
259 #define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr,          \
260                          maskg, maskb, rsh, gsh, bsh, S)                \
261 static void name ## ToY_c(uint8_t *dst, const uint8_t *src,             \
262                           int width, uint32_t *unused)                  \
263 {                                                                       \
264     rgb16_32ToY_c_template(dst, src, width, fmt, shr, shg, shb, shp,    \
265                            maskr, maskg, maskb, rsh, gsh, bsh, S);      \
266 }                                                                       \
267                                                                         \
268 static void name ## ToUV_c(uint8_t *dstU, uint8_t *dstV,                \
269                            const uint8_t *src, const uint8_t *dummy,    \
270                            int width, uint32_t *unused)                 \
271 {                                                                       \
272     rgb16_32ToUV_c_template(dstU, dstV, src, width, fmt,                \
273                             shr, shg, shb, shp,                         \
274                             maskr, maskg, maskb, rsh, gsh, bsh, S);     \
275 }                                                                       \
276                                                                         \
277 static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV,           \
278                                 const uint8_t *src,                     \
279                                 const uint8_t *dummy,                   \
280                                 int width, uint32_t *unused)            \
281 {                                                                       \
282     rgb16_32ToUV_half_c_template(dstU, dstV, src, width, fmt,           \
283                                  shr, shg, shb, shp,                    \
284                                  maskr, maskg, maskb,                   \
285                                  rsh, gsh, bsh, S);                     \
286 }
287
288 rgb16_32_wrapper(PIX_FMT_BGR32,    bgr32,  16, 0,  0, 0, 0xFF0000, 0xFF00,   0x00FF,  8, 0,  8, RGB2YUV_SHIFT + 8)
289 rgb16_32_wrapper(PIX_FMT_BGR32_1,  bgr321, 16, 0,  0, 8, 0xFF0000, 0xFF00,   0x00FF,  8, 0,  8, RGB2YUV_SHIFT + 8)
290 rgb16_32_wrapper(PIX_FMT_RGB32,    rgb32,   0, 0, 16, 0,   0x00FF, 0xFF00, 0xFF0000,  8, 0,  8, RGB2YUV_SHIFT + 8)
291 rgb16_32_wrapper(PIX_FMT_RGB32_1,  rgb321,  0, 0, 16, 8,   0x00FF, 0xFF00, 0xFF0000,  8, 0,  8, RGB2YUV_SHIFT + 8)
292 rgb16_32_wrapper(PIX_FMT_BGR565LE, bgr16le, 0, 0,  0, 0,   0x001F, 0x07E0,   0xF800, 11, 5,  0, RGB2YUV_SHIFT + 8)
293 rgb16_32_wrapper(PIX_FMT_BGR555LE, bgr15le, 0, 0,  0, 0,   0x001F, 0x03E0,   0x7C00, 10, 5,  0, RGB2YUV_SHIFT + 7)
294 rgb16_32_wrapper(PIX_FMT_BGR444LE, bgr12le, 0, 0,  0, 0,   0x000F, 0x00F0,   0x0F00,  8, 4,  0, RGB2YUV_SHIFT + 4)
295 rgb16_32_wrapper(PIX_FMT_RGB565LE, rgb16le, 0, 0,  0, 0,   0xF800, 0x07E0,   0x001F,  0, 5, 11, RGB2YUV_SHIFT + 8)
296 rgb16_32_wrapper(PIX_FMT_RGB555LE, rgb15le, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT + 7)
297 rgb16_32_wrapper(PIX_FMT_RGB444LE, rgb12le, 0, 0,  0, 0,   0x0F00, 0x00F0,   0x000F,  0, 4,  8, RGB2YUV_SHIFT + 4)
298 rgb16_32_wrapper(PIX_FMT_BGR565BE, bgr16be, 0, 0,  0, 0,   0x001F, 0x07E0,   0xF800, 11, 5,  0, RGB2YUV_SHIFT + 8)
299 rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr15be, 0, 0,  0, 0,   0x001F, 0x03E0,   0x7C00, 10, 5,  0, RGB2YUV_SHIFT + 7)
300 rgb16_32_wrapper(PIX_FMT_BGR444BE, bgr12be, 0, 0,  0, 0,   0x000F, 0x00F0,   0x0F00,  8, 4,  0, RGB2YUV_SHIFT + 4)
301 rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0,  0, 0,   0xF800, 0x07E0,   0x001F,  0, 5, 11, RGB2YUV_SHIFT + 8)
302 rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT + 7)
303 rgb16_32_wrapper(PIX_FMT_RGB444BE, rgb12be, 0, 0,  0, 0,   0x0F00, 0x00F0,   0x000F,  0, 4,  8, RGB2YUV_SHIFT + 4)
304
305 static void abgrToA_c(uint8_t *dst, const uint8_t *src, int width,
306                       uint32_t *unused)
307 {
308     int i;
309     for (i = 0; i < width; i++)
310         dst[i] = src[4 * i];
311 }
312
313 static void rgbaToA_c(uint8_t *dst, const uint8_t *src, int width,
314                       uint32_t *unused)
315 {
316     int i;
317     for (i = 0; i < width; i++)
318         dst[i] = src[4 * i + 3];
319 }
320
321 static void palToY_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *pal)
322 {
323     int i;
324     for (i = 0; i < width; i++) {
325         int d = src[i];
326
327         dst[i] = pal[d] & 0xFF;
328     }
329 }
330
331 static void palToUV_c(uint8_t *dstU, uint8_t *dstV,
332                       const uint8_t *src1, const uint8_t *src2,
333                       int width, uint32_t *pal)
334 {
335     int i;
336     assert(src1 == src2);
337     for (i = 0; i < width; i++) {
338         int p = pal[src1[i]];
339
340         dstU[i] = p >> 8;
341         dstV[i] = p >> 16;
342     }
343 }
344
345 static void monowhite2Y_c(uint8_t *dst, const uint8_t *src,
346                           int width, uint32_t *unused)
347 {
348     int i, j;
349     width = (width + 7) >> 3;
350     for (i = 0; i < width; i++) {
351         int d = ~src[i];
352         for (j = 0; j < 8; j++)
353             dst[8 * i + j] = ((d >> (7 - j)) & 1) * 255;
354     }
355 }
356
357 static void monoblack2Y_c(uint8_t *dst, const uint8_t *src,
358                           int width, uint32_t *unused)
359 {
360     int i, j;
361     width = (width + 7) >> 3;
362     for (i = 0; i < width; i++) {
363         int d = src[i];
364         for (j = 0; j < 8; j++)
365             dst[8 * i + j] = ((d >> (7 - j)) & 1) * 255;
366     }
367 }
368
369 static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, int width,
370                       uint32_t *unused)
371 {
372     int i;
373     for (i = 0; i < width; i++)
374         dst[i] = src[2 * i];
375 }
376
377 static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
378                        const uint8_t *src2, int width, uint32_t *unused)
379 {
380     int i;
381     for (i = 0; i < width; i++) {
382         dstU[i] = src1[4 * i + 1];
383         dstV[i] = src1[4 * i + 3];
384     }
385     assert(src1 == src2);
386 }
387
388 static void bswap16Y_c(uint8_t *_dst, const uint8_t *_src, int width,
389                        uint32_t *unused)
390 {
391     int i;
392     const uint16_t *src = (const uint16_t *)_src;
393     uint16_t *dst       = (uint16_t *)_dst;
394     for (i = 0; i < width; i++)
395         dst[i] = av_bswap16(src[i]);
396 }
397
398 static void bswap16UV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src1,
399                         const uint8_t *_src2, int width, uint32_t *unused)
400 {
401     int i;
402     const uint16_t *src1 = (const uint16_t *)_src1,
403     *src2                = (const uint16_t *)_src2;
404     uint16_t *dstU       = (uint16_t *)_dstU, *dstV = (uint16_t *)_dstV;
405     for (i = 0; i < width; i++) {
406         dstU[i] = av_bswap16(src1[i]);
407         dstV[i] = av_bswap16(src2[i]);
408     }
409 }
410
411 /* This is almost identical to the previous, end exists only because
412  * yuy2ToY/UV)(dst, src + 1, ...) would have 100% unaligned accesses. */
413 static void uyvyToY_c(uint8_t *dst, const uint8_t *src, int width,
414                       uint32_t *unused)
415 {
416     int i;
417     for (i = 0; i < width; i++)
418         dst[i] = src[2 * i + 1];
419 }
420
421 static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
422                        const uint8_t *src2, int width, uint32_t *unused)
423 {
424     int i;
425     for (i = 0; i < width; i++) {
426         dstU[i] = src1[4 * i + 0];
427         dstV[i] = src1[4 * i + 2];
428     }
429     assert(src1 == src2);
430 }
431
432 static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
433                                         const uint8_t *src, int width)
434 {
435     int i;
436     for (i = 0; i < width; i++) {
437         dst1[i] = src[2 * i + 0];
438         dst2[i] = src[2 * i + 1];
439     }
440 }
441
442 static void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
443                        const uint8_t *src1, const uint8_t *src2,
444                        int width, uint32_t *unused)
445 {
446     nvXXtoUV_c(dstU, dstV, src1, width);
447 }
448
449 static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
450                        const uint8_t *src1, const uint8_t *src2,
451                        int width, uint32_t *unused)
452 {
453     nvXXtoUV_c(dstV, dstU, src1, width);
454 }
455
456 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
457
458 static void bgr24ToY_c(uint8_t *dst, const uint8_t *src,
459                        int width, uint32_t *unused)
460 {
461     int i;
462     for (i = 0; i < width; i++) {
463         int b = src[i * 3 + 0];
464         int g = src[i * 3 + 1];
465         int r = src[i * 3 + 2];
466
467         dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
468     }
469 }
470
471 static void bgr24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
472                         const uint8_t *src2, int width, uint32_t *unused)
473 {
474     int i;
475     for (i = 0; i < width; i++) {
476         int b = src1[3 * i + 0];
477         int g = src1[3 * i + 1];
478         int r = src1[3 * i + 2];
479
480         dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
481         dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
482     }
483     assert(src1 == src2);
484 }
485
486 static void bgr24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
487                              const uint8_t *src2, int width, uint32_t *unused)
488 {
489     int i;
490     for (i = 0; i < width; i++) {
491         int b = src1[6 * i + 0] + src1[6 * i + 3];
492         int g = src1[6 * i + 1] + src1[6 * i + 4];
493         int r = src1[6 * i + 2] + src1[6 * i + 5];
494
495         dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
496         dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
497     }
498     assert(src1 == src2);
499 }
500
501 static void rgb24ToY_c(uint8_t *dst, const uint8_t *src, int width,
502                        uint32_t *unused)
503 {
504     int i;
505     for (i = 0; i < width; i++) {
506         int r = src[i * 3 + 0];
507         int g = src[i * 3 + 1];
508         int b = src[i * 3 + 2];
509
510         dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
511     }
512 }
513
514 static void rgb24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
515                         const uint8_t *src2, int width, uint32_t *unused)
516 {
517     int i;
518     assert(src1 == src2);
519     for (i = 0; i < width; i++) {
520         int r = src1[3 * i + 0];
521         int g = src1[3 * i + 1];
522         int b = src1[3 * i + 2];
523
524         dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
525         dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
526     }
527 }
528
529 static void rgb24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
530                              const uint8_t *src2, int width, uint32_t *unused)
531 {
532     int i;
533     assert(src1 == src2);
534     for (i = 0; i < width; i++) {
535         int r = src1[6 * i + 0] + src1[6 * i + 3];
536         int g = src1[6 * i + 1] + src1[6 * i + 4];
537         int b = src1[6 * i + 2] + src1[6 * i + 5];
538
539         dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
540         dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
541     }
542 }
543
544 static void planar_rgb_to_y(uint8_t *dst, const uint8_t *src[4], int width)
545 {
546     int i;
547     for (i = 0; i < width; i++) {
548         int g = src[0][i];
549         int b = src[1][i];
550         int r = src[2][i];
551
552         dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
553     }
554 }
555
556 static void planar_rgb_to_uv(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width)
557 {
558     int i;
559     for (i = 0; i < width; i++) {
560         int g = src[0][i];
561         int b = src[1][i];
562         int r = src[2][i];
563
564         dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
565         dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
566     }
567 }
568
569 #define rdpx(src) \
570     is_be ? AV_RB16(src) : AV_RL16(src)
571 static av_always_inline void planar_rgb16_to_y(uint8_t *_dst, const uint8_t *_src[4],
572                                                int width, int bpc, int is_be)
573 {
574     int i;
575     const uint16_t **src = (const uint16_t **)_src;
576     uint16_t *dst        = (uint16_t *)_dst;
577     for (i = 0; i < width; i++) {
578         int g = rdpx(src[0] + i);
579         int b = rdpx(src[1] + i);
580         int r = rdpx(src[2] + i);
581
582         dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT);
583     }
584 }
585
586 static void planar_rgb9le_to_y(uint8_t *dst, const uint8_t *src[4], int w)
587 {
588     planar_rgb16_to_y(dst, src, w, 9, 0);
589 }
590
591 static void planar_rgb9be_to_y(uint8_t *dst, const uint8_t *src[4], int w)
592 {
593     planar_rgb16_to_y(dst, src, w, 9, 1);
594 }
595
596 static void planar_rgb10le_to_y(uint8_t *dst, const uint8_t *src[4], int w)
597 {
598     planar_rgb16_to_y(dst, src, w, 10, 0);
599 }
600
601 static void planar_rgb10be_to_y(uint8_t *dst, const uint8_t *src[4], int w)
602 {
603     planar_rgb16_to_y(dst, src, w, 10, 1);
604 }
605
606 static void planar_rgb16le_to_y(uint8_t *dst, const uint8_t *src[4], int w)
607 {
608     planar_rgb16_to_y(dst, src, w, 16, 0);
609 }
610
611 static void planar_rgb16be_to_y(uint8_t *dst, const uint8_t *src[4], int w)
612 {
613     planar_rgb16_to_y(dst, src, w, 16, 1);
614 }
615
616 static av_always_inline void planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV,
617                                                 const uint8_t *_src[4], int width,
618                                                 int bpc, int is_be)
619 {
620     int i;
621     const uint16_t **src = (const uint16_t **)_src;
622     uint16_t *dstU       = (uint16_t *)_dstU;
623     uint16_t *dstV       = (uint16_t *)_dstV;
624     for (i = 0; i < width; i++) {
625         int g = rdpx(src[0] + i);
626         int b = rdpx(src[1] + i);
627         int r = rdpx(src[2] + i);
628
629         dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT;
630         dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT + bpc - 9))) >> RGB2YUV_SHIFT;
631     }
632 }
633 #undef rdpx
634
635 static void planar_rgb9le_to_uv(uint8_t *dstU, uint8_t *dstV,
636                                 const uint8_t *src[4], int w)
637 {
638     planar_rgb16_to_uv(dstU, dstV, src, w, 9, 0);
639 }
640
641 static void planar_rgb9be_to_uv(uint8_t *dstU, uint8_t *dstV,
642                                 const uint8_t *src[4], int w)
643 {
644     planar_rgb16_to_uv(dstU, dstV, src, w, 9, 1);
645 }
646
647 static void planar_rgb10le_to_uv(uint8_t *dstU, uint8_t *dstV,
648                                  const uint8_t *src[4], int w)
649 {
650     planar_rgb16_to_uv(dstU, dstV, src, w, 10, 0);
651 }
652
653 static void planar_rgb10be_to_uv(uint8_t *dstU, uint8_t *dstV,
654                                  const uint8_t *src[4], int w)
655 {
656     planar_rgb16_to_uv(dstU, dstV, src, w, 10, 1);
657 }
658
659 static void planar_rgb16le_to_uv(uint8_t *dstU, uint8_t *dstV,
660                                  const uint8_t *src[4], int w)
661 {
662     planar_rgb16_to_uv(dstU, dstV, src, w, 16, 0);
663 }
664
665 static void planar_rgb16be_to_uv(uint8_t *dstU, uint8_t *dstV,
666                                  const uint8_t *src[4], int w)
667 {
668     planar_rgb16_to_uv(dstU, dstV, src, w, 16, 1);
669 }
670
671 av_cold void ff_sws_init_input_funcs(SwsContext *c)
672 {
673     enum PixelFormat srcFormat = c->srcFormat;
674
675     c->chrToYV12 = NULL;
676     switch (srcFormat) {
677     case PIX_FMT_YUYV422:
678         c->chrToYV12 = yuy2ToUV_c;
679         break;
680     case PIX_FMT_UYVY422:
681         c->chrToYV12 = uyvyToUV_c;
682         break;
683     case PIX_FMT_NV12:
684         c->chrToYV12 = nv12ToUV_c;
685         break;
686     case PIX_FMT_NV21:
687         c->chrToYV12 = nv21ToUV_c;
688         break;
689     case PIX_FMT_RGB8:
690     case PIX_FMT_BGR8:
691     case PIX_FMT_PAL8:
692     case PIX_FMT_BGR4_BYTE:
693     case PIX_FMT_RGB4_BYTE:
694         c->chrToYV12 = palToUV_c;
695         break;
696     case PIX_FMT_GBRP9LE:
697         c->readChrPlanar = planar_rgb9le_to_uv;
698         break;
699     case PIX_FMT_GBRP10LE:
700         c->readChrPlanar = planar_rgb10le_to_uv;
701         break;
702     case PIX_FMT_GBRP16LE:
703         c->readChrPlanar = planar_rgb16le_to_uv;
704         break;
705     case PIX_FMT_GBRP9BE:
706         c->readChrPlanar = planar_rgb9be_to_uv;
707         break;
708     case PIX_FMT_GBRP10BE:
709         c->readChrPlanar = planar_rgb10be_to_uv;
710         break;
711     case PIX_FMT_GBRP16BE:
712         c->readChrPlanar = planar_rgb16be_to_uv;
713         break;
714     case PIX_FMT_GBRP:
715         c->readChrPlanar = planar_rgb_to_uv;
716         break;
717 #if HAVE_BIGENDIAN
718     case PIX_FMT_YUV444P9LE:
719     case PIX_FMT_YUV422P9LE:
720     case PIX_FMT_YUV420P9LE:
721     case PIX_FMT_YUV422P10LE:
722     case PIX_FMT_YUV444P10LE:
723     case PIX_FMT_YUV420P10LE:
724     case PIX_FMT_YUV420P16LE:
725     case PIX_FMT_YUV422P16LE:
726     case PIX_FMT_YUV444P16LE:
727         c->chrToYV12 = bswap16UV_c;
728         break;
729 #else
730     case PIX_FMT_YUV444P9BE:
731     case PIX_FMT_YUV422P9BE:
732     case PIX_FMT_YUV420P9BE:
733     case PIX_FMT_YUV444P10BE:
734     case PIX_FMT_YUV422P10BE:
735     case PIX_FMT_YUV420P10BE:
736     case PIX_FMT_YUV420P16BE:
737     case PIX_FMT_YUV422P16BE:
738     case PIX_FMT_YUV444P16BE:
739         c->chrToYV12 = bswap16UV_c;
740         break;
741 #endif
742     }
743     if (c->chrSrcHSubSample) {
744         switch (srcFormat) {
745         case PIX_FMT_RGB48BE:
746             c->chrToYV12 = rgb48BEToUV_half_c;
747             break;
748         case PIX_FMT_RGB48LE:
749             c->chrToYV12 = rgb48LEToUV_half_c;
750             break;
751         case PIX_FMT_BGR48BE:
752             c->chrToYV12 = bgr48BEToUV_half_c;
753             break;
754         case PIX_FMT_BGR48LE:
755             c->chrToYV12 = bgr48LEToUV_half_c;
756             break;
757         case PIX_FMT_RGB32:
758             c->chrToYV12 = bgr32ToUV_half_c;
759             break;
760         case PIX_FMT_RGB32_1:
761             c->chrToYV12 = bgr321ToUV_half_c;
762             break;
763         case PIX_FMT_BGR24:
764             c->chrToYV12 = bgr24ToUV_half_c;
765             break;
766         case PIX_FMT_BGR565LE:
767             c->chrToYV12 = bgr16leToUV_half_c;
768             break;
769         case PIX_FMT_BGR565BE:
770             c->chrToYV12 = bgr16beToUV_half_c;
771             break;
772         case PIX_FMT_BGR555LE:
773             c->chrToYV12 = bgr15leToUV_half_c;
774             break;
775         case PIX_FMT_BGR555BE:
776             c->chrToYV12 = bgr15beToUV_half_c;
777             break;
778         case PIX_FMT_BGR444LE:
779             c->chrToYV12 = bgr12leToUV_half_c;
780             break;
781         case PIX_FMT_BGR444BE:
782             c->chrToYV12 = bgr12beToUV_half_c;
783             break;
784         case PIX_FMT_BGR32:
785             c->chrToYV12 = rgb32ToUV_half_c;
786             break;
787         case PIX_FMT_BGR32_1:
788             c->chrToYV12 = rgb321ToUV_half_c;
789             break;
790         case PIX_FMT_RGB24:
791             c->chrToYV12 = rgb24ToUV_half_c;
792             break;
793         case PIX_FMT_RGB565LE:
794             c->chrToYV12 = rgb16leToUV_half_c;
795             break;
796         case PIX_FMT_RGB565BE:
797             c->chrToYV12 = rgb16beToUV_half_c;
798             break;
799         case PIX_FMT_RGB555LE:
800             c->chrToYV12 = rgb15leToUV_half_c;
801             break;
802         case PIX_FMT_RGB555BE:
803             c->chrToYV12 = rgb15beToUV_half_c;
804             break;
805         case PIX_FMT_RGB444LE:
806             c->chrToYV12 = rgb12leToUV_half_c;
807             break;
808         case PIX_FMT_RGB444BE:
809             c->chrToYV12 = rgb12beToUV_half_c;
810             break;
811         }
812     } else {
813         switch (srcFormat) {
814         case PIX_FMT_RGB48BE:
815             c->chrToYV12 = rgb48BEToUV_c;
816             break;
817         case PIX_FMT_RGB48LE:
818             c->chrToYV12 = rgb48LEToUV_c;
819             break;
820         case PIX_FMT_BGR48BE:
821             c->chrToYV12 = bgr48BEToUV_c;
822             break;
823         case PIX_FMT_BGR48LE:
824             c->chrToYV12 = bgr48LEToUV_c;
825             break;
826         case PIX_FMT_RGB32:
827             c->chrToYV12 = bgr32ToUV_c;
828             break;
829         case PIX_FMT_RGB32_1:
830             c->chrToYV12 = bgr321ToUV_c;
831             break;
832         case PIX_FMT_BGR24:
833             c->chrToYV12 = bgr24ToUV_c;
834             break;
835         case PIX_FMT_BGR565LE:
836             c->chrToYV12 = bgr16leToUV_c;
837             break;
838         case PIX_FMT_BGR565BE:
839             c->chrToYV12 = bgr16beToUV_c;
840             break;
841         case PIX_FMT_BGR555LE:
842             c->chrToYV12 = bgr15leToUV_c;
843             break;
844         case PIX_FMT_BGR555BE:
845             c->chrToYV12 = bgr15beToUV_c;
846             break;
847         case PIX_FMT_BGR444LE:
848             c->chrToYV12 = bgr12leToUV_c;
849             break;
850         case PIX_FMT_BGR444BE:
851             c->chrToYV12 = bgr12beToUV_c;
852             break;
853         case PIX_FMT_BGR32:
854             c->chrToYV12 = rgb32ToUV_c;
855             break;
856         case PIX_FMT_BGR32_1:
857             c->chrToYV12 = rgb321ToUV_c;
858             break;
859         case PIX_FMT_RGB24:
860             c->chrToYV12 = rgb24ToUV_c;
861             break;
862         case PIX_FMT_RGB565LE:
863             c->chrToYV12 = rgb16leToUV_c;
864             break;
865         case PIX_FMT_RGB565BE:
866             c->chrToYV12 = rgb16beToUV_c;
867             break;
868         case PIX_FMT_RGB555LE:
869             c->chrToYV12 = rgb15leToUV_c;
870             break;
871         case PIX_FMT_RGB555BE:
872             c->chrToYV12 = rgb15beToUV_c;
873             break;
874         case PIX_FMT_RGB444LE:
875             c->chrToYV12 = rgb12leToUV_c;
876             break;
877         case PIX_FMT_RGB444BE:
878             c->chrToYV12 = rgb12beToUV_c;
879             break;
880         }
881     }
882
883     c->lumToYV12 = NULL;
884     c->alpToYV12 = NULL;
885     switch (srcFormat) {
886     case PIX_FMT_GBRP9LE:
887         c->readLumPlanar = planar_rgb9le_to_y;
888         break;
889     case PIX_FMT_GBRP10LE:
890         c->readLumPlanar = planar_rgb10le_to_y;
891         break;
892     case PIX_FMT_GBRP16LE:
893         c->readLumPlanar = planar_rgb16le_to_y;
894         break;
895     case PIX_FMT_GBRP9BE:
896         c->readLumPlanar = planar_rgb9be_to_y;
897         break;
898     case PIX_FMT_GBRP10BE:
899         c->readLumPlanar = planar_rgb10be_to_y;
900         break;
901     case PIX_FMT_GBRP16BE:
902         c->readLumPlanar = planar_rgb16be_to_y;
903         break;
904     case PIX_FMT_GBRP:
905         c->readLumPlanar = planar_rgb_to_y;
906         break;
907 #if HAVE_BIGENDIAN
908     case PIX_FMT_YUV444P9LE:
909     case PIX_FMT_YUV422P9LE:
910     case PIX_FMT_YUV420P9LE:
911     case PIX_FMT_YUV444P10LE:
912     case PIX_FMT_YUV422P10LE:
913     case PIX_FMT_YUV420P10LE:
914     case PIX_FMT_YUV420P16LE:
915     case PIX_FMT_YUV422P16LE:
916     case PIX_FMT_YUV444P16LE:
917     case PIX_FMT_GRAY16LE:
918         c->lumToYV12 = bswap16Y_c;
919         break;
920 #else
921     case PIX_FMT_YUV444P9BE:
922     case PIX_FMT_YUV422P9BE:
923     case PIX_FMT_YUV420P9BE:
924     case PIX_FMT_YUV444P10BE:
925     case PIX_FMT_YUV422P10BE:
926     case PIX_FMT_YUV420P10BE:
927     case PIX_FMT_YUV420P16BE:
928     case PIX_FMT_YUV422P16BE:
929     case PIX_FMT_YUV444P16BE:
930     case PIX_FMT_GRAY16BE:
931         c->lumToYV12 = bswap16Y_c;
932         break;
933 #endif
934     case PIX_FMT_YUYV422:
935     case PIX_FMT_Y400A:
936         c->lumToYV12 = yuy2ToY_c;
937         break;
938     case PIX_FMT_UYVY422:
939         c->lumToYV12 = uyvyToY_c;
940         break;
941     case PIX_FMT_BGR24:
942         c->lumToYV12 = bgr24ToY_c;
943         break;
944     case PIX_FMT_BGR565LE:
945         c->lumToYV12 = bgr16leToY_c;
946         break;
947     case PIX_FMT_BGR565BE:
948         c->lumToYV12 = bgr16beToY_c;
949         break;
950     case PIX_FMT_BGR555LE:
951         c->lumToYV12 = bgr15leToY_c;
952         break;
953     case PIX_FMT_BGR555BE:
954         c->lumToYV12 = bgr15beToY_c;
955         break;
956     case PIX_FMT_BGR444LE:
957         c->lumToYV12 = bgr12leToY_c;
958         break;
959     case PIX_FMT_BGR444BE:
960         c->lumToYV12 = bgr12beToY_c;
961         break;
962     case PIX_FMT_RGB24:
963         c->lumToYV12 = rgb24ToY_c;
964         break;
965     case PIX_FMT_RGB565LE:
966         c->lumToYV12 = rgb16leToY_c;
967         break;
968     case PIX_FMT_RGB565BE:
969         c->lumToYV12 = rgb16beToY_c;
970         break;
971     case PIX_FMT_RGB555LE:
972         c->lumToYV12 = rgb15leToY_c;
973         break;
974     case PIX_FMT_RGB555BE:
975         c->lumToYV12 = rgb15beToY_c;
976         break;
977     case PIX_FMT_RGB444LE:
978         c->lumToYV12 = rgb12leToY_c;
979         break;
980     case PIX_FMT_RGB444BE:
981         c->lumToYV12 = rgb12beToY_c;
982         break;
983     case PIX_FMT_RGB8:
984     case PIX_FMT_BGR8:
985     case PIX_FMT_PAL8:
986     case PIX_FMT_BGR4_BYTE:
987     case PIX_FMT_RGB4_BYTE:
988         c->lumToYV12 = palToY_c;
989         break;
990     case PIX_FMT_MONOBLACK:
991         c->lumToYV12 = monoblack2Y_c;
992         break;
993     case PIX_FMT_MONOWHITE:
994         c->lumToYV12 = monowhite2Y_c;
995         break;
996     case PIX_FMT_RGB32:
997         c->lumToYV12 = bgr32ToY_c;
998         break;
999     case PIX_FMT_RGB32_1:
1000         c->lumToYV12 = bgr321ToY_c;
1001         break;
1002     case PIX_FMT_BGR32:
1003         c->lumToYV12 = rgb32ToY_c;
1004         break;
1005     case PIX_FMT_BGR32_1:
1006         c->lumToYV12 = rgb321ToY_c;
1007         break;
1008     case PIX_FMT_RGB48BE:
1009         c->lumToYV12 = rgb48BEToY_c;
1010         break;
1011     case PIX_FMT_RGB48LE:
1012         c->lumToYV12 = rgb48LEToY_c;
1013         break;
1014     case PIX_FMT_BGR48BE:
1015         c->lumToYV12 = bgr48BEToY_c;
1016         break;
1017     case PIX_FMT_BGR48LE:
1018         c->lumToYV12 = bgr48LEToY_c;
1019         break;
1020     }
1021     if (c->alpPixBuf) {
1022         switch (srcFormat) {
1023         case PIX_FMT_BGRA:
1024         case PIX_FMT_RGBA:
1025             c->alpToYV12 = rgbaToA_c;
1026             break;
1027         case PIX_FMT_ABGR:
1028         case PIX_FMT_ARGB:
1029             c->alpToYV12 = abgrToA_c;
1030             break;
1031         case PIX_FMT_Y400A:
1032             c->alpToYV12 = uyvyToY_c;
1033             break;
1034         }
1035     }
1036 }