ARM: allow runtime masking of CPU features
[libav.git] / libswscale / input.c
CommitLineData
2dd7a1c0
RB
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
54static av_always_inline void
55rgb48ToY_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*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
68static av_always_inline void
69rgb48ToUV_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*3+0]);
77 int g = input_pixel(&src1[i*3+1]);
78 int b_r = input_pixel(&src1[i*3+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
85static av_always_inline void
86rgb48ToUV_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[6 * i + 0]) + input_pixel(&src1[6 * i + 3]) + 1) >> 1;
94 int g = (input_pixel(&src1[6 * i + 1]) + input_pixel(&src1[6 * i + 4]) + 1) >> 1;
95 int b_r = (input_pixel(&src1[6 * i + 2]) + input_pixel(&src1[6 * i + 5]) + 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#undef r
103#undef b
104#undef input_pixel
105
106#define rgb48funcs(pattern, BE_LE, origin) \
107static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *_dst, const uint8_t *_src, \
108 int width, uint32_t *unused) \
109{ \
110 const uint16_t *src = (const uint16_t *) _src; \
111 uint16_t *dst = (uint16_t *) _dst; \
112 rgb48ToY_c_template(dst, src, width, origin); \
113} \
114 \
115static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *_dstU, uint8_t *_dstV, \
116 const uint8_t *_src1, const uint8_t *_src2, \
117 int width, uint32_t *unused) \
118{ \
119 const uint16_t *src1 = (const uint16_t *) _src1, \
120 *src2 = (const uint16_t *) _src2; \
121 uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
122 rgb48ToUV_c_template(dstU, dstV, src1, src2, width, origin); \
123} \
124 \
125static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, \
126 const uint8_t *_src1, const uint8_t *_src2, \
127 int width, uint32_t *unused) \
128{ \
129 const uint16_t *src1 = (const uint16_t *) _src1, \
130 *src2 = (const uint16_t *) _src2; \
131 uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
132 rgb48ToUV_half_c_template(dstU, dstV, src1, src2, width, origin); \
133}
134
135rgb48funcs(rgb, LE, PIX_FMT_RGB48LE)
136rgb48funcs(rgb, BE, PIX_FMT_RGB48BE)
137rgb48funcs(bgr, LE, PIX_FMT_BGR48LE)
138rgb48funcs(bgr, BE, PIX_FMT_BGR48BE)
139
140#define input_pixel(i) ((origin == PIX_FMT_RGBA || origin == PIX_FMT_BGRA || \
141 origin == PIX_FMT_ARGB || origin == PIX_FMT_ABGR) ? AV_RN32A(&src[(i)*4]) : \
142 (isBE(origin) ? AV_RB16(&src[(i)*2]) : AV_RL16(&src[(i)*2])))
143
144static av_always_inline void
145rgb16_32ToY_c_template(uint8_t *dst, const uint8_t *src,
146 int width, enum PixelFormat origin,
147 int shr, int shg, int shb, int shp,
148 int maskr, int maskg, int maskb,
149 int rsh, int gsh, int bsh, int S)
150{
151 const int ry = RY << rsh, gy = GY << gsh, by = BY << bsh;
152 const unsigned rnd = 33u << (S - 1);
153 int i;
154
155 for (i = 0; i < width; i++) {
156 int px = input_pixel(i) >> shp;
157 int b = (px & maskb) >> shb;
158 int g = (px & maskg) >> shg;
159 int r = (px & maskr) >> shr;
160
161 dst[i] = (ry * r + gy * g + by * b + rnd) >> S;
162 }
163}
164
165static av_always_inline void
166rgb16_32ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
167 const uint8_t *src, int width,
168 enum PixelFormat origin,
169 int shr, int shg, int shb, int shp,
170 int maskr, int maskg, int maskb,
171 int rsh, int gsh, int bsh, int S)
172{
173 const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
174 rv = RV << rsh, gv = GV << gsh, bv = BV << bsh;
175 const unsigned rnd = 257u << (S - 1);
176 int i;
177
178 for (i = 0; i < width; i++) {
179 int px = input_pixel(i) >> shp;
180 int b = (px & maskb) >> shb;
181 int g = (px & maskg) >> shg;
182 int r = (px & maskr) >> shr;
183
184 dstU[i] = (ru * r + gu * g + bu * b + rnd) >> S;
185 dstV[i] = (rv * r + gv * g + bv * b + rnd) >> S;
186 }
187}
188
189static av_always_inline void
190rgb16_32ToUV_half_c_template(uint8_t *dstU, uint8_t *dstV,
191 const uint8_t *src, int width,
192 enum PixelFormat origin,
193 int shr, int shg, int shb, int shp,
194 int maskr, int maskg, int maskb,
195 int rsh, int gsh, int bsh, int S)
196{
197 const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
198 rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
199 maskgx = ~(maskr | maskb);
200 const unsigned rnd = 257u << S;
201 int i;
202
203 maskr |= maskr << 1; maskb |= maskb << 1; maskg |= maskg << 1;
204 for (i = 0; i < width; i++) {
205 int px0 = input_pixel(2 * i + 0) >> shp;
206 int px1 = input_pixel(2 * i + 1) >> shp;
207 int b, r, g = (px0 & maskgx) + (px1 & maskgx);
208 int rb = px0 + px1 - g;
209
210 b = (rb & maskb) >> shb;
211 if (shp || origin == PIX_FMT_BGR565LE || origin == PIX_FMT_BGR565BE ||
212 origin == PIX_FMT_RGB565LE || origin == PIX_FMT_RGB565BE) {
213 g >>= shg;
214 } else {
215 g = (g & maskg) >> shg;
216 }
217 r = (rb & maskr) >> shr;
218
219 dstU[i] = (ru * r + gu * g + bu * b + rnd) >> (S + 1);
220 dstV[i] = (rv * r + gv * g + bv * b + rnd) >> (S + 1);
221 }
222}
223
224#undef input_pixel
225
226#define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr, \
227 maskg, maskb, rsh, gsh, bsh, S) \
228static void name ## ToY_c(uint8_t *dst, const uint8_t *src, \
229 int width, uint32_t *unused) \
230{ \
231 rgb16_32ToY_c_template(dst, src, width, fmt, shr, shg, shb, shp, \
232 maskr, maskg, maskb, rsh, gsh, bsh, S); \
233} \
234 \
235static void name ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
236 const uint8_t *src, const uint8_t *dummy, \
237 int width, uint32_t *unused) \
238{ \
239 rgb16_32ToUV_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
240 maskr, maskg, maskb, rsh, gsh, bsh, S); \
241} \
242 \
243static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
244 const uint8_t *src, const uint8_t *dummy, \
245 int width, uint32_t *unused) \
246{ \
247 rgb16_32ToUV_half_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
248 maskr, maskg, maskb, rsh, gsh, bsh, S); \
249}
250
251rgb16_32_wrapper(PIX_FMT_BGR32, bgr32, 16, 0, 0, 0, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8)
252rgb16_32_wrapper(PIX_FMT_BGR32_1, bgr321, 16, 0, 0, 8, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8)
253rgb16_32_wrapper(PIX_FMT_RGB32, rgb32, 0, 0, 16, 0, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8)
254rgb16_32_wrapper(PIX_FMT_RGB32_1, rgb321, 0, 0, 16, 8, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8)
255rgb16_32_wrapper(PIX_FMT_BGR565LE, bgr16le, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8)
256rgb16_32_wrapper(PIX_FMT_BGR555LE, bgr15le, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7)
257rgb16_32_wrapper(PIX_FMT_BGR444LE, bgr12le, 0, 0, 0, 0, 0x000F, 0x00F0, 0x0F00, 8, 4, 0, RGB2YUV_SHIFT+4)
258rgb16_32_wrapper(PIX_FMT_RGB565LE, rgb16le, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8)
259rgb16_32_wrapper(PIX_FMT_RGB555LE, rgb15le, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7)
260rgb16_32_wrapper(PIX_FMT_RGB444LE, rgb12le, 0, 0, 0, 0, 0x0F00, 0x00F0, 0x000F, 0, 4, 8, RGB2YUV_SHIFT+4)
261rgb16_32_wrapper(PIX_FMT_BGR565BE, bgr16be, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8)
262rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr15be, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7)
263rgb16_32_wrapper(PIX_FMT_BGR444BE, bgr12be, 0, 0, 0, 0, 0x000F, 0x00F0, 0x0F00, 8, 4, 0, RGB2YUV_SHIFT+4)
264rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8)
265rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7)
266rgb16_32_wrapper(PIX_FMT_RGB444BE, rgb12be, 0, 0, 0, 0, 0x0F00, 0x00F0, 0x000F, 0, 4, 8, RGB2YUV_SHIFT+4)
267
268static void abgrToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
269{
270 int i;
271 for (i=0; i<width; i++) {
272 dst[i]= src[4*i];
273 }
274}
275
276static void rgbaToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
277{
278 int i;
279 for (i=0; i<width; i++) {
280 dst[i]= src[4*i+3];
281 }
282}
283
284static void palToY_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *pal)
285{
286 int i;
287 for (i=0; i<width; i++) {
288 int d= src[i];
289
290 dst[i]= pal[d] & 0xFF;
291 }
292}
293
294static void palToUV_c(uint8_t *dstU, uint8_t *dstV,
295 const uint8_t *src1, const uint8_t *src2,
296 int width, uint32_t *pal)
297{
298 int i;
299 assert(src1 == src2);
300 for (i=0; i<width; i++) {
301 int p= pal[src1[i]];
302
303 dstU[i]= p>>8;
304 dstV[i]= p>>16;
305 }
306}
307
308static void monowhite2Y_c(uint8_t *dst, const uint8_t *src,
309 int width, uint32_t *unused)
310{
311 int i, j;
bc0bdda7
RB
312 width = (width + 7) >> 3;
313 for (i = 0; i < width; i++) {
2dd7a1c0
RB
314 int d= ~src[i];
315 for(j=0; j<8; j++)
316 dst[8*i+j]= ((d>>(7-j))&1)*255;
317 }
318}
319
320static void monoblack2Y_c(uint8_t *dst, const uint8_t *src,
321 int width, uint32_t *unused)
322{
323 int i, j;
bc0bdda7
RB
324 width = (width + 7) >> 3;
325 for (i = 0; i < width; i++) {
2dd7a1c0
RB
326 int d= src[i];
327 for(j=0; j<8; j++)
328 dst[8*i+j]= ((d>>(7-j))&1)*255;
329 }
330}
331
332static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, int width,
333 uint32_t *unused)
334{
335 int i;
336 for (i=0; i<width; i++)
337 dst[i]= src[2*i];
338}
339
340static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
341 const uint8_t *src2, int width, uint32_t *unused)
342{
343 int i;
344 for (i=0; i<width; i++) {
345 dstU[i]= src1[4*i + 1];
346 dstV[i]= src1[4*i + 3];
347 }
348 assert(src1 == src2);
349}
350
351static void bswap16Y_c(uint8_t *_dst, const uint8_t *_src, int width, uint32_t *unused)
352{
353 int i;
354 const uint16_t *src = (const uint16_t *) _src;
355 uint16_t *dst = (uint16_t *) _dst;
356 for (i=0; i<width; i++) {
357 dst[i] = av_bswap16(src[i]);
358 }
359}
360
361static void bswap16UV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src1,
362 const uint8_t *_src2, int width, uint32_t *unused)
363{
364 int i;
365 const uint16_t *src1 = (const uint16_t *) _src1,
366 *src2 = (const uint16_t *) _src2;
367 uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV;
368 for (i=0; i<width; i++) {
369 dstU[i] = av_bswap16(src1[i]);
370 dstV[i] = av_bswap16(src2[i]);
371 }
372}
373
374/* This is almost identical to the previous, end exists only because
375 * yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
376static void uyvyToY_c(uint8_t *dst, const uint8_t *src, int width,
377 uint32_t *unused)
378{
379 int i;
380 for (i=0; i<width; i++)
381 dst[i]= src[2*i+1];
382}
383
384static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
385 const uint8_t *src2, int width, uint32_t *unused)
386{
387 int i;
388 for (i=0; i<width; i++) {
389 dstU[i]= src1[4*i + 0];
390 dstV[i]= src1[4*i + 2];
391 }
392 assert(src1 == src2);
393}
394
395static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
396 const uint8_t *src, int width)
397{
398 int i;
399 for (i = 0; i < width; i++) {
400 dst1[i] = src[2*i+0];
401 dst2[i] = src[2*i+1];
402 }
403}
404
405static void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
406 const uint8_t *src1, const uint8_t *src2,
407 int width, uint32_t *unused)
408{
409 nvXXtoUV_c(dstU, dstV, src1, width);
410}
411
412static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
413 const uint8_t *src1, const uint8_t *src2,
414 int width, uint32_t *unused)
415{
416 nvXXtoUV_c(dstV, dstU, src1, width);
417}
418
419#define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
420
421static void bgr24ToY_c(uint8_t *dst, const uint8_t *src,
422 int width, uint32_t *unused)
423{
424 int i;
425 for (i=0; i<width; i++) {
426 int b= src[i*3+0];
427 int g= src[i*3+1];
428 int r= src[i*3+2];
429
430 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
431 }
432}
433
434static void bgr24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
435 const uint8_t *src2, int width, uint32_t *unused)
436{
437 int i;
438 for (i=0; i<width; i++) {
439 int b= src1[3*i + 0];
440 int g= src1[3*i + 1];
441 int r= src1[3*i + 2];
442
443 dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
444 dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
445 }
446 assert(src1 == src2);
447}
448
449static void bgr24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
450 const uint8_t *src2, int width, uint32_t *unused)
451{
452 int i;
453 for (i=0; i<width; i++) {
454 int b= src1[6*i + 0] + src1[6*i + 3];
455 int g= src1[6*i + 1] + src1[6*i + 4];
456 int r= src1[6*i + 2] + src1[6*i + 5];
457
458 dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
459 dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
460 }
461 assert(src1 == src2);
462}
463
464static void rgb24ToY_c(uint8_t *dst, const uint8_t *src, int width,
465 uint32_t *unused)
466{
467 int i;
468 for (i=0; i<width; i++) {
469 int r= src[i*3+0];
470 int g= src[i*3+1];
471 int b= src[i*3+2];
472
473 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
474 }
475}
476
477static void rgb24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
478 const uint8_t *src2, int width, uint32_t *unused)
479{
480 int i;
481 assert(src1==src2);
482 for (i=0; i<width; i++) {
483 int r= src1[3*i + 0];
484 int g= src1[3*i + 1];
485 int b= src1[3*i + 2];
486
487 dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
488 dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
489 }
490}
491
492static void rgb24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
493 const uint8_t *src2, int width, uint32_t *unused)
494{
495 int i;
496 assert(src1==src2);
497 for (i=0; i<width; i++) {
498 int r= src1[6*i + 0] + src1[6*i + 3];
499 int g= src1[6*i + 1] + src1[6*i + 4];
500 int b= src1[6*i + 2] + src1[6*i + 5];
501
502 dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
503 dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
504 }
505}
506
507static void planar_rgb_to_y(uint8_t *dst, const uint8_t *src[4], int width)
508{
509 int i;
510 for (i = 0; i < width; i++) {
511 int g = src[0][i];
512 int b = src[1][i];
513 int r = src[2][i];
514
515 dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
516 }
517}
518
519static void planar_rgb16le_to_y(uint8_t *_dst, const uint8_t *_src[4], int width)
520{
521 int i;
522 const uint16_t **src = (const uint16_t **) _src;
523 uint16_t *dst = (uint16_t *) _dst;
524 for (i = 0; i < width; i++) {
525 int g = AV_RL16(src[0] + i);
526 int b = AV_RL16(src[1] + i);
527 int r = AV_RL16(src[2] + i);
528
529 dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
530 }
531}
532
533static void planar_rgb16be_to_y(uint8_t *_dst, const uint8_t *_src[4], int width)
534{
535 int i;
536 const uint16_t **src = (const uint16_t **) _src;
537 uint16_t *dst = (uint16_t *) _dst;
538 for (i = 0; i < width; i++) {
539 int g = AV_RB16(src[0] + i);
540 int b = AV_RB16(src[1] + i);
541 int r = AV_RB16(src[2] + i);
542
543 dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
544 }
545}
546
547static void planar_rgb_to_uv(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width)
548{
549 int i;
550 for (i = 0; i < width; i++) {
551 int g = src[0][i];
552 int b = src[1][i];
553 int r = src[2][i];
554
555 dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
556 dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
557 }
558}
559
560static void planar_rgb16le_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src[4], int width)
561{
562 int i;
563 const uint16_t **src = (const uint16_t **) _src;
564 uint16_t *dstU = (uint16_t *) _dstU;
565 uint16_t *dstV = (uint16_t *) _dstV;
566 for (i = 0; i < width; i++) {
567 int g = AV_RL16(src[0] + i);
568 int b = AV_RL16(src[1] + i);
569 int r = AV_RL16(src[2] + i);
570
571 dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
572 dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
573 }
574}
575
576static void planar_rgb16be_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src[4], int width)
577{
578 int i;
579 const uint16_t **src = (const uint16_t **) _src;
580 uint16_t *dstU = (uint16_t *) _dstU;
581 uint16_t *dstV = (uint16_t *) _dstV;
582 for (i = 0; i < width; i++) {
583 int g = AV_RB16(src[0] + i);
584 int b = AV_RB16(src[1] + i);
585 int r = AV_RB16(src[2] + i);
586
587 dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
588 dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
589 }
590}
591
592av_cold void ff_sws_init_input_funcs(SwsContext *c)
593{
594 enum PixelFormat srcFormat = c->srcFormat;
595
596 c->chrToYV12 = NULL;
597 switch(srcFormat) {
598 case PIX_FMT_YUYV422 : c->chrToYV12 = yuy2ToUV_c; break;
599 case PIX_FMT_UYVY422 : c->chrToYV12 = uyvyToUV_c; break;
600 case PIX_FMT_NV12 : c->chrToYV12 = nv12ToUV_c; break;
601 case PIX_FMT_NV21 : c->chrToYV12 = nv21ToUV_c; break;
602 case PIX_FMT_RGB8 :
603 case PIX_FMT_BGR8 :
604 case PIX_FMT_PAL8 :
605 case PIX_FMT_BGR4_BYTE:
606 case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
607 case PIX_FMT_GBRP9LE:
608 case PIX_FMT_GBRP10LE:
609 case PIX_FMT_GBRP16LE: c->readChrPlanar = planar_rgb16le_to_uv; break;
610 case PIX_FMT_GBRP9BE:
611 case PIX_FMT_GBRP10BE:
612 case PIX_FMT_GBRP16BE: c->readChrPlanar = planar_rgb16be_to_uv; break;
613 case PIX_FMT_GBRP: c->readChrPlanar = planar_rgb_to_uv; break;
614#if HAVE_BIGENDIAN
615 case PIX_FMT_YUV444P9LE:
616 case PIX_FMT_YUV422P9LE:
617 case PIX_FMT_YUV420P9LE:
618 case PIX_FMT_YUV422P10LE:
619 case PIX_FMT_YUV444P10LE:
620 case PIX_FMT_YUV420P10LE:
621 case PIX_FMT_YUV420P16LE:
622 case PIX_FMT_YUV422P16LE:
623 case PIX_FMT_YUV444P16LE: c->chrToYV12 = bswap16UV_c; break;
624#else
625 case PIX_FMT_YUV444P9BE:
626 case PIX_FMT_YUV422P9BE:
627 case PIX_FMT_YUV420P9BE:
628 case PIX_FMT_YUV444P10BE:
629 case PIX_FMT_YUV422P10BE:
630 case PIX_FMT_YUV420P10BE:
631 case PIX_FMT_YUV420P16BE:
632 case PIX_FMT_YUV422P16BE:
633 case PIX_FMT_YUV444P16BE: c->chrToYV12 = bswap16UV_c; break;
634#endif
635 }
636 if (c->chrSrcHSubSample) {
637 switch(srcFormat) {
638 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_half_c; break;
639 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_half_c; break;
640 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_half_c; break;
641 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_half_c; break;
642 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_half_c; break;
643 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_half_c; break;
644 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_half_c; break;
645 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_half_c; break;
646 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_half_c; break;
647 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_half_c; break;
648 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_half_c; break;
649 case PIX_FMT_BGR444LE: c->chrToYV12 = bgr12leToUV_half_c; break;
650 case PIX_FMT_BGR444BE: c->chrToYV12 = bgr12beToUV_half_c; break;
651 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_half_c; break;
652 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_half_c; break;
653 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_half_c; break;
654 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_half_c; break;
655 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_half_c; break;
656 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_half_c; break;
657 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_half_c; break;
658 case PIX_FMT_RGB444LE: c->chrToYV12 = rgb12leToUV_half_c; break;
659 case PIX_FMT_RGB444BE: c->chrToYV12 = rgb12beToUV_half_c; break;
660 }
661 } else {
662 switch(srcFormat) {
663 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_c; break;
664 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_c; break;
665 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_c; break;
666 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_c; break;
667 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_c; break;
668 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_c; break;
669 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_c; break;
670 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_c; break;
671 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_c; break;
672 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_c; break;
673 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_c; break;
674 case PIX_FMT_BGR444LE: c->chrToYV12 = bgr12leToUV_c; break;
675 case PIX_FMT_BGR444BE: c->chrToYV12 = bgr12beToUV_c; break;
676 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_c; break;
677 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_c; break;
678 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_c; break;
679 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_c; break;
680 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_c; break;
681 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_c; break;
682 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_c; break;
683 case PIX_FMT_RGB444LE: c->chrToYV12 = rgb12leToUV_c; break;
684 case PIX_FMT_RGB444BE: c->chrToYV12 = rgb12beToUV_c; break;
685 }
686 }
687
688 c->lumToYV12 = NULL;
689 c->alpToYV12 = NULL;
690 switch (srcFormat) {
691 case PIX_FMT_GBRP9LE:
692 case PIX_FMT_GBRP10LE:
693 case PIX_FMT_GBRP16LE: c->readLumPlanar = planar_rgb16le_to_y; break;
694 case PIX_FMT_GBRP9BE:
695 case PIX_FMT_GBRP10BE:
696 case PIX_FMT_GBRP16BE: c->readLumPlanar = planar_rgb16be_to_y; break;
697 case PIX_FMT_GBRP: c->readLumPlanar = planar_rgb_to_y; break;
698#if HAVE_BIGENDIAN
699 case PIX_FMT_YUV444P9LE:
700 case PIX_FMT_YUV422P9LE:
701 case PIX_FMT_YUV420P9LE:
702 case PIX_FMT_YUV444P10LE:
703 case PIX_FMT_YUV422P10LE:
704 case PIX_FMT_YUV420P10LE:
705 case PIX_FMT_YUV420P16LE:
706 case PIX_FMT_YUV422P16LE:
707 case PIX_FMT_YUV444P16LE:
708 case PIX_FMT_GRAY16LE: c->lumToYV12 = bswap16Y_c; break;
709#else
710 case PIX_FMT_YUV444P9BE:
711 case PIX_FMT_YUV422P9BE:
712 case PIX_FMT_YUV420P9BE:
713 case PIX_FMT_YUV444P10BE:
714 case PIX_FMT_YUV422P10BE:
715 case PIX_FMT_YUV420P10BE:
716 case PIX_FMT_YUV420P16BE:
717 case PIX_FMT_YUV422P16BE:
718 case PIX_FMT_YUV444P16BE:
719 case PIX_FMT_GRAY16BE: c->lumToYV12 = bswap16Y_c; break;
720#endif
721 case PIX_FMT_YUYV422 :
722 case PIX_FMT_Y400A : c->lumToYV12 = yuy2ToY_c; break;
723 case PIX_FMT_UYVY422 : c->lumToYV12 = uyvyToY_c; break;
724 case PIX_FMT_BGR24 : c->lumToYV12 = bgr24ToY_c; break;
725 case PIX_FMT_BGR565LE : c->lumToYV12 = bgr16leToY_c; break;
726 case PIX_FMT_BGR565BE : c->lumToYV12 = bgr16beToY_c; break;
727 case PIX_FMT_BGR555LE : c->lumToYV12 = bgr15leToY_c; break;
728 case PIX_FMT_BGR555BE : c->lumToYV12 = bgr15beToY_c; break;
729 case PIX_FMT_BGR444LE : c->lumToYV12 = bgr12leToY_c; break;
730 case PIX_FMT_BGR444BE : c->lumToYV12 = bgr12beToY_c; break;
731 case PIX_FMT_RGB24 : c->lumToYV12 = rgb24ToY_c; break;
732 case PIX_FMT_RGB565LE : c->lumToYV12 = rgb16leToY_c; break;
733 case PIX_FMT_RGB565BE : c->lumToYV12 = rgb16beToY_c; break;
734 case PIX_FMT_RGB555LE : c->lumToYV12 = rgb15leToY_c; break;
735 case PIX_FMT_RGB555BE : c->lumToYV12 = rgb15beToY_c; break;
736 case PIX_FMT_RGB444LE : c->lumToYV12 = rgb12leToY_c; break;
737 case PIX_FMT_RGB444BE : c->lumToYV12 = rgb12beToY_c; break;
738 case PIX_FMT_RGB8 :
739 case PIX_FMT_BGR8 :
740 case PIX_FMT_PAL8 :
741 case PIX_FMT_BGR4_BYTE:
742 case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY_c; break;
743 case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y_c; break;
744 case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y_c; break;
745 case PIX_FMT_RGB32 : c->lumToYV12 = bgr32ToY_c; break;
746 case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY_c; break;
747 case PIX_FMT_BGR32 : c->lumToYV12 = rgb32ToY_c; break;
748 case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY_c; break;
749 case PIX_FMT_RGB48BE: c->lumToYV12 = rgb48BEToY_c; break;
750 case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break;
751 case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break;
752 case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break;
753 }
754 if (c->alpPixBuf) {
755 switch (srcFormat) {
756 case PIX_FMT_BGRA:
757 case PIX_FMT_RGBA: c->alpToYV12 = rgbaToA_c; break;
758 case PIX_FMT_ABGR:
759 case PIX_FMT_ARGB: c->alpToYV12 = abgrToA_c; break;
760 case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
761 }
762 }
763}