2 * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of Libav.
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.
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.
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
22 supported Input formats: YV12, I420/IYUV, YUY2, UYVY, BGR32, BGR32_1, BGR24, BGR16, BGR15, RGB32, RGB32_1, RGB24, Y8/Y800, YVU9/IF09, PAL8
23 supported output formats: YV12, I420/IYUV, YUY2, UYVY, {BGR,RGB}{1,4,8,15,16,24,32}, Y8/Y800, YVU9/IF09
24 {BGR,RGB}{1,4,8,15,16} support dithering
26 unscaled special converters (YV12=I420=IYUV, Y800=Y8)
27 YV12 -> {BGR,RGB}{1,4,8,12,15,16,24,32}
32 BGR24 -> BGR32 & RGB24 -> RGB32
33 BGR32 -> BGR24 & RGB32 -> RGB24
38 tested special converters (most are tested actually, but I did not write it down ...)
45 untested special converters
46 YV12/I420 -> BGR15/BGR24/BGR32 (it is the yuv2rgb stuff, so it should be OK)
47 YV12/I420 -> YV12/I420
48 YUY2/BGR15/BGR24/BGR32/RGB24/RGB32 -> same format
49 BGR24 -> BGR32 & RGB24 -> RGB32
50 BGR32 -> BGR24 & RGB32 -> RGB24
61 #include "swscale_internal.h"
63 #include "libavutil/intreadwrite.h"
64 #include "libavutil/cpu.h"
65 #include "libavutil/avutil.h"
66 #include "libavutil/mathematics.h"
67 #include "libavutil/bswap.h"
68 #include "libavutil/pixdesc.h"
72 #define RGB2YUV_SHIFT 15
73 #define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
74 #define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5))
75 #define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
76 #define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5))
77 #define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5))
78 #define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5))
79 #define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5))
80 #define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
81 #define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5))
83 static const double rgb2yuv_table[8][9]={
84 {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
85 {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
86 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
87 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
88 {0.59 , 0.11 , 0.30 , -0.331, 0.5, -0.169, -0.421, -0.079, 0.5}, //FCC
89 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
90 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
91 {0.701 , 0.087 , 0.212 , -0.384, 0.5, -0.116, -0.445, -0.055, 0.5}, //SMPTE 240M
96 Special versions: fast Y 1:1 scaling (no interpolation in y direction)
99 more intelligent misalignment avoidance for the horizontal scaler
100 write special vertical cubic upscale version
101 optimize C code (YV12 / minmax)
102 add support for packed pixel YUV input & output
103 add support for Y8 output
104 optimize BGR24 & BGR32
105 add BGR4 output support
106 write special BGR->BGR scaler
109 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_4)[2][8]={
110 { 1, 3, 1, 3, 1, 3, 1, 3, },
111 { 2, 0, 2, 0, 2, 0, 2, 0, },
114 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
115 { 6, 2, 6, 2, 6, 2, 6, 2, },
116 { 0, 4, 0, 4, 0, 4, 0, 4, },
119 DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
120 { 8, 4, 11, 7, 8, 4, 11, 7, },
121 { 2, 14, 1, 13, 2, 14, 1, 13, },
122 { 10, 6, 9, 5, 10, 6, 9, 5, },
123 { 0, 12, 3, 15, 0, 12, 3, 15, },
126 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
127 { 17, 9, 23, 15, 16, 8, 22, 14, },
128 { 5, 29, 3, 27, 4, 28, 2, 26, },
129 { 21, 13, 19, 11, 20, 12, 18, 10, },
130 { 0, 24, 6, 30, 1, 25, 7, 31, },
131 { 16, 8, 22, 14, 17, 9, 23, 15, },
132 { 4, 28, 2, 26, 5, 29, 3, 27, },
133 { 20, 12, 18, 10, 21, 13, 19, 11, },
134 { 1, 25, 7, 31, 0, 24, 6, 30, },
137 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
138 { 0, 55, 14, 68, 3, 58, 17, 72, },
139 { 37, 18, 50, 32, 40, 22, 54, 35, },
140 { 9, 64, 5, 59, 13, 67, 8, 63, },
141 { 46, 27, 41, 23, 49, 31, 44, 26, },
142 { 2, 57, 16, 71, 1, 56, 15, 70, },
143 { 39, 21, 52, 34, 38, 19, 51, 33, },
144 { 11, 66, 7, 62, 10, 65, 6, 60, },
145 { 48, 30, 43, 25, 47, 29, 42, 24, },
149 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
150 {117, 62, 158, 103, 113, 58, 155, 100, },
151 { 34, 199, 21, 186, 31, 196, 17, 182, },
152 {144, 89, 131, 76, 141, 86, 127, 72, },
153 { 0, 165, 41, 206, 10, 175, 52, 217, },
154 {110, 55, 151, 96, 120, 65, 162, 107, },
155 { 28, 193, 14, 179, 38, 203, 24, 189, },
156 {138, 83, 124, 69, 148, 93, 134, 79, },
157 { 7, 172, 48, 213, 3, 168, 45, 210, },
160 // tries to correct a gamma of 1.5
161 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
162 { 0, 143, 18, 200, 2, 156, 25, 215, },
163 { 78, 28, 125, 64, 89, 36, 138, 74, },
164 { 10, 180, 3, 161, 16, 195, 8, 175, },
165 {109, 51, 93, 38, 121, 60, 105, 47, },
166 { 1, 152, 23, 210, 0, 147, 20, 205, },
167 { 85, 33, 134, 71, 81, 30, 130, 67, },
168 { 14, 190, 6, 171, 12, 185, 5, 166, },
169 {117, 57, 101, 44, 113, 54, 97, 41, },
172 // tries to correct a gamma of 2.0
173 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
174 { 0, 124, 8, 193, 0, 140, 12, 213, },
175 { 55, 14, 104, 42, 66, 19, 119, 52, },
176 { 3, 168, 1, 145, 6, 187, 3, 162, },
177 { 86, 31, 70, 21, 99, 39, 82, 28, },
178 { 0, 134, 11, 206, 0, 129, 9, 200, },
179 { 62, 17, 114, 48, 58, 16, 109, 45, },
180 { 5, 181, 2, 157, 4, 175, 1, 151, },
181 { 95, 36, 78, 26, 90, 34, 74, 24, },
184 // tries to correct a gamma of 2.5
185 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
186 { 0, 107, 3, 187, 0, 125, 6, 212, },
187 { 39, 7, 86, 28, 49, 11, 102, 36, },
188 { 1, 158, 0, 131, 3, 180, 1, 151, },
189 { 68, 19, 52, 12, 81, 25, 64, 17, },
190 { 0, 119, 5, 203, 0, 113, 4, 195, },
191 { 45, 9, 96, 33, 42, 8, 91, 30, },
192 { 2, 172, 1, 144, 2, 165, 0, 137, },
193 { 77, 23, 60, 15, 72, 21, 56, 14, },
197 static av_always_inline void
198 yuv2yuvX16_c_template(const int16_t *lumFilter, const int16_t **lumSrc,
199 int lumFilterSize, const int16_t *chrFilter,
200 const int16_t **chrUSrc, const int16_t **chrVSrc,
201 int chrFilterSize, const int16_t **alpSrc,
202 uint16_t *dest, uint16_t *uDest, uint16_t *vDest,
203 uint16_t *aDest, int dstW, int chrDstW,
204 int big_endian, int output_bits)
206 //FIXME Optimize (just quickly written not optimized..)
208 int shift = 11 + 16 - output_bits;
210 #define output_pixel(pos, val) \
212 if (output_bits == 16) { \
213 AV_WB16(pos, av_clip_uint16(val >> shift)); \
215 AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
218 if (output_bits == 16) { \
219 AV_WL16(pos, av_clip_uint16(val >> shift)); \
221 AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
224 for (i = 0; i < dstW; i++) {
225 int val = 1 << (26-output_bits);
228 for (j = 0; j < lumFilterSize; j++)
229 val += lumSrc[j][i] * lumFilter[j];
231 output_pixel(&dest[i], val);
235 for (i = 0; i < chrDstW; i++) {
236 int u = 1 << (26-output_bits);
237 int v = 1 << (26-output_bits);
240 for (j = 0; j < chrFilterSize; j++) {
241 u += chrUSrc[j][i] * chrFilter[j];
242 v += chrVSrc[j][i] * chrFilter[j];
245 output_pixel(&uDest[i], u);
246 output_pixel(&vDest[i], v);
250 if (CONFIG_SWSCALE_ALPHA && aDest) {
251 for (i = 0; i < dstW; i++) {
252 int val = 1 << (26-output_bits);
255 for (j = 0; j < lumFilterSize; j++)
256 val += alpSrc[j][i] * lumFilter[j];
258 output_pixel(&aDest[i], val);
264 #define yuv2NBPS(bits, BE_LE, is_be) \
265 static void yuv2yuvX ## bits ## BE_LE ## _c(SwsContext *c, const int16_t *lumFilter, \
266 const int16_t **lumSrc, int lumFilterSize, \
267 const int16_t *chrFilter, const int16_t **chrUSrc, \
268 const int16_t **chrVSrc, \
269 int chrFilterSize, const int16_t **alpSrc, \
270 uint8_t *_dest, uint8_t *_uDest, uint8_t *_vDest, \
271 uint8_t *_aDest, int dstW, int chrDstW) \
273 uint16_t *dest = (uint16_t *) _dest, *uDest = (uint16_t *) _uDest, \
274 *vDest = (uint16_t *) _vDest, *aDest = (uint16_t *) _aDest; \
275 yuv2yuvX16_c_template(lumFilter, lumSrc, lumFilterSize, \
276 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
278 dest, uDest, vDest, aDest, \
279 dstW, chrDstW, is_be, bits); \
288 static void yuv2yuvX_c(SwsContext *c, const int16_t *lumFilter,
289 const int16_t **lumSrc, int lumFilterSize,
290 const int16_t *chrFilter, const int16_t **chrUSrc,
291 const int16_t **chrVSrc,
292 int chrFilterSize, const int16_t **alpSrc,
293 uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
294 uint8_t *aDest, int dstW, int chrDstW)
296 //FIXME Optimize (just quickly written not optimized..)
298 for (i=0; i<dstW; i++) {
301 for (j=0; j<lumFilterSize; j++)
302 val += lumSrc[j][i] * lumFilter[j];
304 dest[i]= av_clip_uint8(val>>19);
308 for (i=0; i<chrDstW; i++) {
312 for (j=0; j<chrFilterSize; j++) {
313 u += chrUSrc[j][i] * chrFilter[j];
314 v += chrVSrc[j][i] * chrFilter[j];
317 uDest[i]= av_clip_uint8(u>>19);
318 vDest[i]= av_clip_uint8(v>>19);
321 if (CONFIG_SWSCALE_ALPHA && aDest)
322 for (i=0; i<dstW; i++) {
325 for (j=0; j<lumFilterSize; j++)
326 val += alpSrc[j][i] * lumFilter[j];
328 aDest[i]= av_clip_uint8(val>>19);
332 static void yuv2yuv1_c(SwsContext *c, const int16_t *lumSrc,
333 const int16_t *chrUSrc, const int16_t *chrVSrc,
334 const int16_t *alpSrc,
335 uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
336 uint8_t *aDest, int dstW, int chrDstW)
339 for (i=0; i<dstW; i++) {
340 int val= (lumSrc[i]+64)>>7;
341 dest[i]= av_clip_uint8(val);
345 for (i=0; i<chrDstW; i++) {
346 int u=(chrUSrc[i]+64)>>7;
347 int v=(chrVSrc[i]+64)>>7;
348 uDest[i]= av_clip_uint8(u);
349 vDest[i]= av_clip_uint8(v);
352 if (CONFIG_SWSCALE_ALPHA && aDest)
353 for (i=0; i<dstW; i++) {
354 int val= (alpSrc[i]+64)>>7;
355 aDest[i]= av_clip_uint8(val);
359 static void yuv2nv12X_c(SwsContext *c, const int16_t *lumFilter,
360 const int16_t **lumSrc, int lumFilterSize,
361 const int16_t *chrFilter, const int16_t **chrUSrc,
362 const int16_t **chrVSrc, int chrFilterSize,
363 const int16_t **alpSrc, uint8_t *dest, uint8_t *uDest,
364 uint8_t *vDest, uint8_t *aDest,
365 int dstW, int chrDstW)
367 enum PixelFormat dstFormat = c->dstFormat;
369 //FIXME Optimize (just quickly written not optimized..)
371 for (i=0; i<dstW; i++) {
374 for (j=0; j<lumFilterSize; j++)
375 val += lumSrc[j][i] * lumFilter[j];
377 dest[i]= av_clip_uint8(val>>19);
383 if (dstFormat == PIX_FMT_NV12)
384 for (i=0; i<chrDstW; i++) {
388 for (j=0; j<chrFilterSize; j++) {
389 u += chrUSrc[j][i] * chrFilter[j];
390 v += chrVSrc[j][i] * chrFilter[j];
393 uDest[2*i]= av_clip_uint8(u>>19);
394 uDest[2*i+1]= av_clip_uint8(v>>19);
397 for (i=0; i<chrDstW; i++) {
401 for (j=0; j<chrFilterSize; j++) {
402 u += chrUSrc[j][i] * chrFilter[j];
403 v += chrVSrc[j][i] * chrFilter[j];
406 uDest[2*i]= av_clip_uint8(v>>19);
407 uDest[2*i+1]= av_clip_uint8(u>>19);
411 static av_always_inline void
412 yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter,
413 const int16_t **lumSrc, int lumFilterSize,
414 const int16_t *chrFilter, const int16_t **chrUSrc,
415 const int16_t **chrVSrc, int chrFilterSize,
416 const int16_t **alpSrc, uint8_t *dest, int dstW,
417 int y, enum PixelFormat target)
421 #define output_pixel(pos, val) \
422 if (target == PIX_FMT_GRAY16BE) { \
427 for (i = 0; i < (dstW >> 1); i++) {
431 const int i2 = 2 * i;
433 for (j = 0; j < lumFilterSize; j++) {
434 Y1 += lumSrc[j][i2] * lumFilter[j];
435 Y2 += lumSrc[j][i2+1] * lumFilter[j];
439 if ((Y1 | Y2) & 0x10000) {
440 Y1 = av_clip_uint16(Y1);
441 Y2 = av_clip_uint16(Y2);
443 output_pixel(&dest[2 * i2 + 0], Y1);
444 output_pixel(&dest[2 * i2 + 2], Y2);
448 static av_always_inline void
449 yuv2gray16_2_c_template(SwsContext *c, const uint16_t *buf0,
450 const uint16_t *buf1, const uint16_t *ubuf0,
451 const uint16_t *ubuf1, const uint16_t *vbuf0,
452 const uint16_t *vbuf1, const uint16_t *abuf0,
453 const uint16_t *abuf1, uint8_t *dest, int dstW,
454 int yalpha, int uvalpha, int y,
455 enum PixelFormat target)
457 int yalpha1 = 4095 - yalpha; \
460 for (i = 0; i < (dstW >> 1); i++) {
461 const int i2 = 2 * i;
462 int Y1 = (buf0[i2 ] * yalpha1 + buf1[i2 ] * yalpha) >> 11;
463 int Y2 = (buf0[i2+1] * yalpha1 + buf1[i2+1] * yalpha) >> 11;
465 output_pixel(&dest[2 * i2 + 0], Y1);
466 output_pixel(&dest[2 * i2 + 2], Y2);
470 static av_always_inline void
471 yuv2gray16_1_c_template(SwsContext *c, const uint16_t *buf0,
472 const uint16_t *ubuf0, const uint16_t *ubuf1,
473 const uint16_t *vbuf0, const uint16_t *vbuf1,
474 const uint16_t *abuf0, uint8_t *dest, int dstW,
475 int uvalpha, enum PixelFormat dstFormat,
476 int flags, int y, enum PixelFormat target)
480 for (i = 0; i < (dstW >> 1); i++) {
481 const int i2 = 2 * i;
482 int Y1 = buf0[i2 ] << 1;
483 int Y2 = buf0[i2+1] << 1;
485 output_pixel(&dest[2 * i2 + 0], Y1);
486 output_pixel(&dest[2 * i2 + 2], Y2);
491 #define YUV2PACKEDWRAPPER(name, ext, fmt) \
492 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
493 const int16_t **lumSrc, int lumFilterSize, \
494 const int16_t *chrFilter, const int16_t **chrUSrc, \
495 const int16_t **chrVSrc, int chrFilterSize, \
496 const int16_t **alpSrc, uint8_t *dest, int dstW, \
499 name ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
500 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
501 alpSrc, dest, dstW, y, fmt); \
504 static void name ## ext ## _2_c(SwsContext *c, const uint16_t *buf0, \
505 const uint16_t *buf1, const uint16_t *ubuf0, \
506 const uint16_t *ubuf1, const uint16_t *vbuf0, \
507 const uint16_t *vbuf1, const uint16_t *abuf0, \
508 const uint16_t *abuf1, uint8_t *dest, int dstW, \
509 int yalpha, int uvalpha, int y) \
511 name ## _2_c_template(c, buf0, buf1, ubuf0, ubuf1, \
512 vbuf0, vbuf1, abuf0, abuf1, \
513 dest, dstW, yalpha, uvalpha, y, fmt); \
516 static void name ## ext ## _1_c(SwsContext *c, const uint16_t *buf0, \
517 const uint16_t *ubuf0, const uint16_t *ubuf1, \
518 const uint16_t *vbuf0, const uint16_t *vbuf1, \
519 const uint16_t *abuf0, uint8_t *dest, int dstW, \
520 int uvalpha, enum PixelFormat dstFormat, \
523 name ## _1_c_template(c, buf0, ubuf0, ubuf1, vbuf0, \
524 vbuf1, abuf0, dest, dstW, uvalpha, \
525 dstFormat, flags, y, fmt); \
528 YUV2PACKEDWRAPPER(yuv2gray16, LE, PIX_FMT_GRAY16LE);
529 YUV2PACKEDWRAPPER(yuv2gray16, BE, PIX_FMT_GRAY16BE);
531 static av_always_inline void
532 yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
533 const int16_t **lumSrc, int lumFilterSize,
534 const int16_t *chrFilter, const int16_t **chrUSrc,
535 const int16_t **chrVSrc, int chrFilterSize,
536 const int16_t **alpSrc, uint8_t *dest, int dstW,
537 int y, enum PixelFormat target)
539 const uint8_t * const d128=dither_8x8_220[y&7];
540 uint8_t *g = c->table_gU[128] + c->table_gV[128];
544 #define output_pixel(pos, acc) \
545 if (target == PIX_FMT_MONOBLACK) { \
550 for (i = 0; i < dstW - 1; i += 2) {
555 for (j = 0; j < lumFilterSize; j++) {
556 Y1 += lumSrc[j][i] * lumFilter[j];
557 Y2 += lumSrc[j][i+1] * lumFilter[j];
561 if ((Y1 | Y2) & 0x100) {
562 Y1 = av_clip_uint8(Y1);
563 Y2 = av_clip_uint8(Y2);
565 acc += acc + g[Y1 + d128[(i + 0) & 7]];
566 acc += acc + g[Y2 + d128[(i + 1) & 7]];
568 output_pixel(*dest++, acc);
573 static av_always_inline void
574 yuv2mono_2_c_template(SwsContext *c, const uint16_t *buf0,
575 const uint16_t *buf1, const uint16_t *ubuf0,
576 const uint16_t *ubuf1, const uint16_t *vbuf0,
577 const uint16_t *vbuf1, const uint16_t *abuf0,
578 const uint16_t *abuf1, uint8_t *dest, int dstW,
579 int yalpha, int uvalpha, int y,
580 enum PixelFormat target)
582 const uint8_t * const d128 = dither_8x8_220[y & 7];
583 uint8_t *g = c->table_gU[128] + c->table_gV[128];
584 int yalpha1 = 4095 - yalpha;
587 for (i = 0; i < dstW - 7; i += 8) {
588 int acc = g[((buf0[i ] * yalpha1 + buf1[i ] * yalpha) >> 19) + d128[0]];
589 acc += acc + g[((buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19) + d128[1]];
590 acc += acc + g[((buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19) + d128[2]];
591 acc += acc + g[((buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19) + d128[3]];
592 acc += acc + g[((buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19) + d128[4]];
593 acc += acc + g[((buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19) + d128[5]];
594 acc += acc + g[((buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19) + d128[6]];
595 acc += acc + g[((buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19) + d128[7]];
596 output_pixel(*dest++, acc);
600 static av_always_inline void
601 yuv2mono_1_c_template(SwsContext *c, const uint16_t *buf0,
602 const uint16_t *ubuf0, const uint16_t *ubuf1,
603 const uint16_t *vbuf0, const uint16_t *vbuf1,
604 const uint16_t *abuf0, uint8_t *dest, int dstW,
605 int uvalpha, enum PixelFormat dstFormat,
606 int flags, int y, enum PixelFormat target)
608 const uint8_t * const d128 = dither_8x8_220[y & 7];
609 uint8_t *g = c->table_gU[128] + c->table_gV[128];
612 for (i = 0; i < dstW - 7; i += 8) {
613 int acc = g[(buf0[i ] >> 7) + d128[0]];
614 acc += acc + g[(buf0[i + 1] >> 7) + d128[1]];
615 acc += acc + g[(buf0[i + 2] >> 7) + d128[2]];
616 acc += acc + g[(buf0[i + 3] >> 7) + d128[3]];
617 acc += acc + g[(buf0[i + 4] >> 7) + d128[4]];
618 acc += acc + g[(buf0[i + 5] >> 7) + d128[5]];
619 acc += acc + g[(buf0[i + 6] >> 7) + d128[6]];
620 acc += acc + g[(buf0[i + 7] >> 7) + d128[7]];
621 output_pixel(*dest++, acc);
626 YUV2PACKEDWRAPPER(yuv2mono, white, PIX_FMT_MONOWHITE);
627 YUV2PACKEDWRAPPER(yuv2mono, black, PIX_FMT_MONOBLACK);
629 static av_always_inline void
630 yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
631 const int16_t **lumSrc, int lumFilterSize,
632 const int16_t *chrFilter, const int16_t **chrUSrc,
633 const int16_t **chrVSrc, int chrFilterSize,
634 const int16_t **alpSrc, uint8_t *dest, int dstW,
635 int y, enum PixelFormat target)
639 #define output_pixels(pos, Y1, U, Y2, V) \
640 if (target == PIX_FMT_YUYV422) { \
641 dest[pos + 0] = Y1; \
643 dest[pos + 2] = Y2; \
647 dest[pos + 1] = Y1; \
649 dest[pos + 3] = Y2; \
652 for (i = 0; i < (dstW >> 1); i++) {
659 for (j = 0; j < lumFilterSize; j++) {
660 Y1 += lumSrc[j][i * 2] * lumFilter[j];
661 Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
663 for (j = 0; j < chrFilterSize; j++) {
664 U += chrUSrc[j][i] * chrFilter[j];
665 V += chrVSrc[j][i] * chrFilter[j];
671 if ((Y1 | Y2 | U | V) & 0x100) {
672 Y1 = av_clip_uint8(Y1);
673 Y2 = av_clip_uint8(Y2);
674 U = av_clip_uint8(U);
675 V = av_clip_uint8(V);
677 output_pixels(4*i, Y1, U, Y2, V);
681 static av_always_inline void
682 yuv2422_2_c_template(SwsContext *c, const uint16_t *buf0,
683 const uint16_t *buf1, const uint16_t *ubuf0,
684 const uint16_t *ubuf1, const uint16_t *vbuf0,
685 const uint16_t *vbuf1, const uint16_t *abuf0,
686 const uint16_t *abuf1, uint8_t *dest, int dstW,
687 int yalpha, int uvalpha, int y,
688 enum PixelFormat target)
690 int yalpha1 = 4095 - yalpha;
691 int uvalpha1 = 4095 - uvalpha;
694 for (i = 0; i < (dstW >> 1); i++) {
695 int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19;
696 int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
697 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
698 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
700 output_pixels(i * 4, Y1, U, Y2, V);
704 static av_always_inline void
705 yuv2422_1_c_template(SwsContext *c, const uint16_t *buf0,
706 const uint16_t *ubuf0, const uint16_t *ubuf1,
707 const uint16_t *vbuf0, const uint16_t *vbuf1,
708 const uint16_t *abuf0, uint8_t *dest, int dstW,
709 int uvalpha, enum PixelFormat dstFormat,
710 int flags, int y, enum PixelFormat target)
714 if (uvalpha < 2048) {
715 for (i = 0; i < (dstW >> 1); i++) {
716 int Y1 = buf0[i * 2] >> 7;
717 int Y2 = buf0[i * 2 + 1] >> 7;
718 int U = ubuf1[i] >> 7;
719 int V = vbuf1[i] >> 7;
721 output_pixels(i * 4, Y1, U, Y2, V);
724 for (i = 0; i < (dstW >> 1); i++) {
725 int Y1 = buf0[i * 2] >> 7;
726 int Y2 = buf0[i * 2 + 1] >> 7;
727 int U = (ubuf0[i] + ubuf1[i]) >> 8;
728 int V = (vbuf0[i] + vbuf1[i]) >> 8;
730 output_pixels(i * 4, Y1, U, Y2, V);
736 YUV2PACKEDWRAPPER(yuv2422, yuyv, PIX_FMT_YUYV422);
737 YUV2PACKEDWRAPPER(yuv2422, uyvy, PIX_FMT_UYVY422);
739 #define YSCALE_YUV_2_RGBX_C(type,alpha) \
740 for (i=0; i<(dstW>>1); i++) {\
746 int av_unused A1, A2;\
747 type av_unused *r, *b, *g;\
750 for (j=0; j<lumFilterSize; j++) {\
751 Y1 += lumSrc[j][i2] * lumFilter[j];\
752 Y2 += lumSrc[j][i2+1] * lumFilter[j];\
754 for (j=0; j<chrFilterSize; j++) {\
755 U += chrUSrc[j][i] * chrFilter[j];\
756 V += chrVSrc[j][i] * chrFilter[j];\
762 if ((Y1|Y2|U|V)&0x100) {\
763 Y1 = av_clip_uint8(Y1); \
764 Y2 = av_clip_uint8(Y2); \
765 U = av_clip_uint8(U); \
766 V = av_clip_uint8(V); \
771 for (j=0; j<lumFilterSize; j++) {\
772 A1 += alpSrc[j][i2 ] * lumFilter[j];\
773 A2 += alpSrc[j][i2+1] * lumFilter[j];\
777 if ((A1|A2)&0x100) {\
778 A1 = av_clip_uint8(A1); \
779 A2 = av_clip_uint8(A2); \
782 /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/\
783 r = (type *)c->table_rV[V]; \
784 g = (type *)(c->table_gU[U] + c->table_gV[V]); \
785 b = (type *)c->table_bU[U];
787 #define YSCALE_YUV_2_RGBX_FULL_C(rnd,alpha) \
788 for (i=0; i<dstW; i++) {\
796 for (j=0; j<lumFilterSize; j++) {\
797 Y += lumSrc[j][i ] * lumFilter[j];\
799 for (j=0; j<chrFilterSize; j++) {\
800 U += chrUSrc[j][i] * chrFilter[j];\
801 V += chrVSrc[j][i] * chrFilter[j];\
808 for (j=0; j<lumFilterSize; j++)\
809 A += alpSrc[j][i ] * lumFilter[j];\
812 A = av_clip_uint8(A);\
814 Y-= c->yuv2rgb_y_offset;\
815 Y*= c->yuv2rgb_y_coeff;\
817 R= Y + V*c->yuv2rgb_v2r_coeff;\
818 G= Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;\
819 B= Y + U*c->yuv2rgb_u2b_coeff;\
820 if ((R|G|B)&(0xC0000000)) {\
821 R = av_clip_uintp2(R, 30); \
822 G = av_clip_uintp2(G, 30); \
823 B = av_clip_uintp2(B, 30); \
826 #define YSCALE_YUV_2_RGB2_C(type,alpha) \
827 for (i=0; i<(dstW>>1); i++) { \
829 int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>19; \
830 int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19; \
831 int U= (ubuf0[i]*uvalpha1+ubuf1[i]*uvalpha)>>19; \
832 int V= (vbuf0[i]*uvalpha1+vbuf1[i]*uvalpha)>>19; \
833 type av_unused *r, *b, *g; \
834 int av_unused A1, A2; \
836 A1= (abuf0[i2 ]*yalpha1+abuf1[i2 ]*yalpha)>>19; \
837 A2= (abuf0[i2+1]*yalpha1+abuf1[i2+1]*yalpha)>>19; \
839 r = (type *)c->table_rV[V];\
840 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
841 b = (type *)c->table_bU[U];
843 #define YSCALE_YUV_2_RGB1_C(type,alpha) \
844 for (i=0; i<(dstW>>1); i++) {\
846 int Y1= buf0[i2 ]>>7;\
847 int Y2= buf0[i2+1]>>7;\
848 int U= (ubuf1[i])>>7;\
849 int V= (vbuf1[i])>>7;\
850 type av_unused *r, *b, *g;\
851 int av_unused A1, A2;\
856 r = (type *)c->table_rV[V];\
857 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
858 b = (type *)c->table_bU[U];
860 #define YSCALE_YUV_2_RGB1B_C(type,alpha) \
861 for (i=0; i<(dstW>>1); i++) {\
863 int Y1= buf0[i2 ]>>7;\
864 int Y2= buf0[i2+1]>>7;\
865 int U= (ubuf0[i] + ubuf1[i])>>8;\
866 int V= (vbuf0[i] + vbuf1[i])>>8;\
867 type av_unused *r, *b, *g;\
868 int av_unused A1, A2;\
873 r = (type *)c->table_rV[V];\
874 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
875 b = (type *)c->table_bU[U];
877 #define YSCALE_YUV_2_ANYRGB_C(func)\
878 switch(c->dstFormat) {\
879 case PIX_FMT_RGB48BE:\
880 case PIX_FMT_RGB48LE:\
882 ((uint8_t*)dest)[ 0]= r[Y1];\
883 ((uint8_t*)dest)[ 1]= r[Y1];\
884 ((uint8_t*)dest)[ 2]= g[Y1];\
885 ((uint8_t*)dest)[ 3]= g[Y1];\
886 ((uint8_t*)dest)[ 4]= b[Y1];\
887 ((uint8_t*)dest)[ 5]= b[Y1];\
888 ((uint8_t*)dest)[ 6]= r[Y2];\
889 ((uint8_t*)dest)[ 7]= r[Y2];\
890 ((uint8_t*)dest)[ 8]= g[Y2];\
891 ((uint8_t*)dest)[ 9]= g[Y2];\
892 ((uint8_t*)dest)[10]= b[Y2];\
893 ((uint8_t*)dest)[11]= b[Y2];\
897 case PIX_FMT_BGR48BE:\
898 case PIX_FMT_BGR48LE:\
900 ((uint8_t*)dest)[ 0] = ((uint8_t*)dest)[ 1] = b[Y1];\
901 ((uint8_t*)dest)[ 2] = ((uint8_t*)dest)[ 3] = g[Y1];\
902 ((uint8_t*)dest)[ 4] = ((uint8_t*)dest)[ 5] = r[Y1];\
903 ((uint8_t*)dest)[ 6] = ((uint8_t*)dest)[ 7] = b[Y2];\
904 ((uint8_t*)dest)[ 8] = ((uint8_t*)dest)[ 9] = g[Y2];\
905 ((uint8_t*)dest)[10] = ((uint8_t*)dest)[11] = r[Y2];\
912 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
913 func(uint32_t,needAlpha)\
914 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? (A1<<24) : 0);\
915 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? (A2<<24) : 0);\
918 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
920 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (A1<<24);\
921 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (A2<<24);\
925 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
926 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
934 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
935 func(uint32_t,needAlpha)\
936 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? A1 : 0);\
937 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? A2 : 0);\
940 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
942 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + A1;\
943 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + A2;\
947 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
948 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
955 ((uint8_t*)dest)[0]= r[Y1];\
956 ((uint8_t*)dest)[1]= g[Y1];\
957 ((uint8_t*)dest)[2]= b[Y1];\
958 ((uint8_t*)dest)[3]= r[Y2];\
959 ((uint8_t*)dest)[4]= g[Y2];\
960 ((uint8_t*)dest)[5]= b[Y2];\
966 ((uint8_t*)dest)[0]= b[Y1];\
967 ((uint8_t*)dest)[1]= g[Y1];\
968 ((uint8_t*)dest)[2]= r[Y1];\
969 ((uint8_t*)dest)[3]= b[Y2];\
970 ((uint8_t*)dest)[4]= g[Y2];\
971 ((uint8_t*)dest)[5]= r[Y2];\
975 case PIX_FMT_RGB565:\
976 case PIX_FMT_BGR565:\
978 const int dr1= dither_2x2_8[y&1 ][0];\
979 const int dg1= dither_2x2_4[y&1 ][0];\
980 const int db1= dither_2x2_8[(y&1)^1][0];\
981 const int dr2= dither_2x2_8[y&1 ][1];\
982 const int dg2= dither_2x2_4[y&1 ][1];\
983 const int db2= dither_2x2_8[(y&1)^1][1];\
985 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
986 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
990 case PIX_FMT_RGB555:\
991 case PIX_FMT_BGR555:\
993 const int dr1= dither_2x2_8[y&1 ][0];\
994 const int dg1= dither_2x2_8[y&1 ][1];\
995 const int db1= dither_2x2_8[(y&1)^1][0];\
996 const int dr2= dither_2x2_8[y&1 ][1];\
997 const int dg2= dither_2x2_8[y&1 ][0];\
998 const int db2= dither_2x2_8[(y&1)^1][1];\
1000 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
1001 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
1005 case PIX_FMT_RGB444:\
1006 case PIX_FMT_BGR444:\
1008 const int dr1= dither_4x4_16[y&3 ][0];\
1009 const int dg1= dither_4x4_16[y&3 ][1];\
1010 const int db1= dither_4x4_16[(y&3)^3][0];\
1011 const int dr2= dither_4x4_16[y&3 ][1];\
1012 const int dg2= dither_4x4_16[y&3 ][0];\
1013 const int db2= dither_4x4_16[(y&3)^3][1];\
1015 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
1016 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
1023 const uint8_t * const d64= dither_8x8_73[y&7];\
1024 const uint8_t * const d32= dither_8x8_32[y&7];\
1026 ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];\
1027 ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];\
1034 const uint8_t * const d64= dither_8x8_73 [y&7];\
1035 const uint8_t * const d128=dither_8x8_220[y&7];\
1037 ((uint8_t*)dest)[i]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]]\
1038 + ((r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]])<<4);\
1042 case PIX_FMT_RGB4_BYTE:\
1043 case PIX_FMT_BGR4_BYTE:\
1045 const uint8_t * const d64= dither_8x8_73 [y&7];\
1046 const uint8_t * const d128=dither_8x8_220[y&7];\
1048 ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];\
1049 ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];\
1055 static void yuv2packedX_c(SwsContext *c, const int16_t *lumFilter,
1056 const int16_t **lumSrc, int lumFilterSize,
1057 const int16_t *chrFilter, const int16_t **chrUSrc,
1058 const int16_t **chrVSrc, int chrFilterSize,
1059 const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
1062 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C)
1065 static void yuv2rgbX_c_full(SwsContext *c, const int16_t *lumFilter,
1066 const int16_t **lumSrc, int lumFilterSize,
1067 const int16_t *chrFilter, const int16_t **chrUSrc,
1068 const int16_t **chrVSrc, int chrFilterSize,
1069 const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
1072 int step= c->dstFormatBpp/8;
1075 switch(c->dstFormat) {
1083 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
1084 YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
1085 dest[aidx]= needAlpha ? A : 255;
1092 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
1093 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
1101 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
1118 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
1119 YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
1120 dest[aidx]= needAlpha ? A : 255;
1127 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
1128 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
1136 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
1152 * vertical bilinear scale YV12 to RGB
1154 static void yuv2packed2_c(SwsContext *c, const uint16_t *buf0,
1155 const uint16_t *buf1, const uint16_t *ubuf0,
1156 const uint16_t *ubuf1, const uint16_t *vbuf0,
1157 const uint16_t *vbuf1, const uint16_t *abuf0,
1158 const uint16_t *abuf1, uint8_t *dest, int dstW,
1159 int yalpha, int uvalpha, int y)
1161 int yalpha1=4095- yalpha;
1162 int uvalpha1=4095-uvalpha;
1165 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C)
1169 * YV12 to RGB without scaling or interpolating
1171 static void yuv2packed1_c(SwsContext *c, const uint16_t *buf0,
1172 const uint16_t *ubuf0, const uint16_t *ubuf1,
1173 const uint16_t *vbuf0, const uint16_t *vbuf1,
1174 const uint16_t *abuf0, uint8_t *dest, int dstW,
1175 int uvalpha, enum PixelFormat dstFormat,
1180 if (uvalpha < 2048) {
1181 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C)
1183 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C)
1187 static av_always_inline void fillPlane(uint8_t* plane, int stride,
1188 int width, int height,
1192 uint8_t *ptr = plane + stride*y;
1193 for (i=0; i<height; i++) {
1194 memset(ptr, val, width);
1199 static av_always_inline void
1200 rgb48ToY_c_template(uint8_t *dst, const uint8_t *src, int width,
1201 enum PixelFormat origin)
1204 for (i = 0; i < width; i++) {
1205 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1206 int a = input_pixel(&src[i*6+0]) >> 8;
1207 int g = input_pixel(&src[i*6+2]) >> 8;
1208 int c = input_pixel(&src[i*6+4]) >> 8;
1210 #define r ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? c : a)
1211 #define b ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? a : c)
1212 dst[i] = (RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1216 static av_always_inline void
1217 rgb48ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
1218 const uint8_t *src1, const uint8_t *src2,
1219 int width, enum PixelFormat origin)
1223 for (i = 0; i < width; i++) {
1224 int a = input_pixel(&src1[6*i + 0]) >> 8;
1225 int g = input_pixel(&src1[6*i + 2]) >> 8;
1226 int c = input_pixel(&src1[6*i + 4]) >> 8;
1228 dstU[i] = (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1229 dstV[i] = (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1233 static av_always_inline void
1234 rgb48ToUV_half_c_template(uint8_t *dstU, uint8_t *dstV,
1235 const uint8_t *src1, const uint8_t *src2,
1236 int width, enum PixelFormat origin)
1240 for (i = 0; i < width; i++) {
1241 int a = (input_pixel(&src1[12*i + 0]) >> 8) + (input_pixel(&src1[12*i + 6]) >> 8);
1242 int g = (input_pixel(&src1[12*i + 2]) >> 8) + (input_pixel(&src1[12*i + 8]) >> 8);
1243 int c = (input_pixel(&src1[12*i + 4]) >> 8) + (input_pixel(&src1[12*i + 10]) >> 8);
1245 dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
1246 dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
1253 #define rgb48funcs(pattern, BE_LE, origin) \
1254 static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *dst, const uint8_t *src, \
1255 int width, uint32_t *unused) \
1257 rgb48ToY_c_template(dst, src, width, origin); \
1260 static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1261 const uint8_t *src1, const uint8_t *src2, \
1262 int width, uint32_t *unused) \
1264 rgb48ToUV_c_template(dstU, dstV, src1, src2, width, origin); \
1267 static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
1268 const uint8_t *src1, const uint8_t *src2, \
1269 int width, uint32_t *unused) \
1271 rgb48ToUV_half_c_template(dstU, dstV, src1, src2, width, origin); \
1274 rgb48funcs(rgb, LE, PIX_FMT_RGB48LE);
1275 rgb48funcs(rgb, BE, PIX_FMT_RGB48BE);
1276 rgb48funcs(bgr, LE, PIX_FMT_BGR48LE);
1277 rgb48funcs(bgr, BE, PIX_FMT_BGR48BE);
1279 static av_always_inline void
1280 rgb16_32ToY_c_template(uint8_t *dst, const uint8_t *src,
1281 int width, enum PixelFormat origin,
1282 int shr, int shg, int shb, int shp,
1283 int maskr, int maskg, int maskb,
1284 int rsh, int gsh, int bsh, int S)
1286 const int ry = RY << rsh, gy = GY << gsh, by = BY << bsh,
1287 rnd = 33 << (S - 1);
1290 for (i = 0; i < width; i++) {
1291 #define input_pixel(i) ((origin == PIX_FMT_RGBA || origin == PIX_FMT_BGRA || \
1292 origin == PIX_FMT_ARGB || origin == PIX_FMT_ABGR) ? AV_RN32A(&src[(i)*4]) : \
1293 (isBE(origin) ? AV_RB16(&src[(i)*2]) : AV_RL16(&src[(i)*2])))
1294 int px = input_pixel(i) >> shp;
1295 int b = (px & maskb) >> shb;
1296 int g = (px & maskg) >> shg;
1297 int r = (px & maskr) >> shr;
1299 dst[i] = (ry * r + gy * g + by * b + rnd) >> S;
1303 static av_always_inline void
1304 rgb16_32ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
1305 const uint8_t *src, int width,
1306 enum PixelFormat origin,
1307 int shr, int shg, int shb, int shp,
1308 int maskr, int maskg, int maskb,
1309 int rsh, int gsh, int bsh, int S)
1311 const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1312 rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1313 rnd = 257 << (S - 1);
1316 for (i = 0; i < width; i++) {
1317 int px = input_pixel(i) >> shp;
1318 int b = (px & maskb) >> shb;
1319 int g = (px & maskg) >> shg;
1320 int r = (px & maskr) >> shr;
1322 dstU[i] = (ru * r + gu * g + bu * b + rnd) >> S;
1323 dstV[i] = (rv * r + gv * g + bv * b + rnd) >> S;
1327 static av_always_inline void
1328 rgb16_32ToUV_half_c_template(uint8_t *dstU, uint8_t *dstV,
1329 const uint8_t *src, int width,
1330 enum PixelFormat origin,
1331 int shr, int shg, int shb, int shp,
1332 int maskr, int maskg, int maskb,
1333 int rsh, int gsh, int bsh, int S)
1335 const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1336 rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1337 rnd = 257 << S, maskgx = ~(maskr | maskb);
1340 maskr |= maskr << 1; maskb |= maskb << 1; maskg |= maskg << 1;
1341 for (i = 0; i < width; i++) {
1342 int px0 = input_pixel(2 * i + 0) >> shp;
1343 int px1 = input_pixel(2 * i + 1) >> shp;
1344 int b, r, g = (px0 & maskgx) + (px1 & maskgx);
1345 int rb = px0 + px1 - g;
1347 b = (rb & maskb) >> shb;
1348 if (shp || origin == PIX_FMT_BGR565LE || origin == PIX_FMT_BGR565BE ||
1349 origin == PIX_FMT_RGB565LE || origin == PIX_FMT_RGB565BE) {
1352 g = (g & maskg) >> shg;
1354 r = (rb & maskr) >> shr;
1356 dstU[i] = (ru * r + gu * g + bu * b + rnd) >> (S + 1);
1357 dstV[i] = (rv * r + gv * g + bv * b + rnd) >> (S + 1);
1362 #define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr, \
1363 maskg, maskb, rsh, gsh, bsh, S) \
1364 static void name ## ToY_c(uint8_t *dst, const uint8_t *src, \
1365 int width, uint32_t *unused) \
1367 rgb16_32ToY_c_template(dst, src, width, fmt, shr, shg, shb, shp, \
1368 maskr, maskg, maskb, rsh, gsh, bsh, S); \
1371 static void name ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1372 const uint8_t *src, const uint8_t *dummy, \
1373 int width, uint32_t *unused) \
1375 rgb16_32ToUV_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1376 maskr, maskg, maskb, rsh, gsh, bsh, S); \
1379 static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
1380 const uint8_t *src, const uint8_t *dummy, \
1381 int width, uint32_t *unused) \
1383 rgb16_32ToUV_half_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1384 maskr, maskg, maskb, rsh, gsh, bsh, S); \
1387 rgb16_32_wrapper(PIX_FMT_BGR32, bgr32, 16, 0, 0, 0, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8);
1388 rgb16_32_wrapper(PIX_FMT_BGR32_1, bgr321, 16, 0, 0, 8, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8);
1389 rgb16_32_wrapper(PIX_FMT_RGB32, rgb32, 0, 0, 16, 0, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8);
1390 rgb16_32_wrapper(PIX_FMT_RGB32_1, rgb321, 0, 0, 16, 8, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8);
1391 rgb16_32_wrapper(PIX_FMT_BGR565LE, bgr16le, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8);
1392 rgb16_32_wrapper(PIX_FMT_BGR555LE, bgr15le, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7);
1393 rgb16_32_wrapper(PIX_FMT_RGB565LE, rgb16le, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8);
1394 rgb16_32_wrapper(PIX_FMT_RGB555LE, rgb15le, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7);
1395 rgb16_32_wrapper(PIX_FMT_BGR565BE, bgr16be, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8);
1396 rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr15be, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7);
1397 rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8);
1398 rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7);
1400 static void abgrToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
1403 for (i=0; i<width; i++) {
1408 static void rgbaToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
1411 for (i=0; i<width; i++) {
1416 static void palToY_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *pal)
1419 for (i=0; i<width; i++) {
1422 dst[i]= pal[d] & 0xFF;
1426 static void palToUV_c(uint8_t *dstU, uint8_t *dstV,
1427 const uint8_t *src1, const uint8_t *src2,
1428 int width, uint32_t *pal)
1431 assert(src1 == src2);
1432 for (i=0; i<width; i++) {
1433 int p= pal[src1[i]];
1440 static void monowhite2Y_c(uint8_t *dst, const uint8_t *src,
1441 int width, uint32_t *unused)
1444 for (i=0; i<width/8; i++) {
1447 dst[8*i+j]= ((d>>(7-j))&1)*255;
1451 static void monoblack2Y_c(uint8_t *dst, const uint8_t *src,
1452 int width, uint32_t *unused)
1455 for (i=0; i<width/8; i++) {
1458 dst[8*i+j]= ((d>>(7-j))&1)*255;
1462 //FIXME yuy2* can read up to 7 samples too much
1464 static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, int width,
1468 for (i=0; i<width; i++)
1472 static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1473 const uint8_t *src2, int width, uint32_t *unused)
1476 for (i=0; i<width; i++) {
1477 dstU[i]= src1[4*i + 1];
1478 dstV[i]= src1[4*i + 3];
1480 assert(src1 == src2);
1483 static void LEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1484 const uint8_t *src2, int width, uint32_t *unused)
1487 for (i=0; i<width; i++) {
1488 dstU[i]= src1[2*i + 1];
1489 dstV[i]= src2[2*i + 1];
1493 /* This is almost identical to the previous, end exists only because
1494 * yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
1495 static void uyvyToY_c(uint8_t *dst, const uint8_t *src, int width,
1499 for (i=0; i<width; i++)
1503 static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1504 const uint8_t *src2, int width, uint32_t *unused)
1507 for (i=0; i<width; i++) {
1508 dstU[i]= src1[4*i + 0];
1509 dstV[i]= src1[4*i + 2];
1511 assert(src1 == src2);
1514 static void BEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1515 const uint8_t *src2, int width, uint32_t *unused)
1518 for (i=0; i<width; i++) {
1524 static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
1525 const uint8_t *src, int width)
1528 for (i = 0; i < width; i++) {
1529 dst1[i] = src[2*i+0];
1530 dst2[i] = src[2*i+1];
1534 static void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
1535 const uint8_t *src1, const uint8_t *src2,
1536 int width, uint32_t *unused)
1538 nvXXtoUV_c(dstU, dstV, src1, width);
1541 static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
1542 const uint8_t *src1, const uint8_t *src2,
1543 int width, uint32_t *unused)
1545 nvXXtoUV_c(dstV, dstU, src1, width);
1548 // FIXME Maybe dither instead.
1549 static av_always_inline void
1550 yuv9_OR_10ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
1551 const uint8_t *_srcU, const uint8_t *_srcV,
1552 int width, enum PixelFormat origin, int depth)
1555 const uint16_t *srcU = (const uint16_t *) _srcU;
1556 const uint16_t *srcV = (const uint16_t *) _srcV;
1558 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1559 for (i = 0; i < width; i++) {
1560 dstU[i] = input_pixel(&srcU[i]) >> (depth - 8);
1561 dstV[i] = input_pixel(&srcV[i]) >> (depth - 8);
1565 static av_always_inline void
1566 yuv9_or_10ToY_c_template(uint8_t *dstY, const uint8_t *_srcY,
1567 int width, enum PixelFormat origin, int depth)
1570 const uint16_t *srcY = (const uint16_t*)_srcY;
1572 for (i = 0; i < width; i++)
1573 dstY[i] = input_pixel(&srcY[i]) >> (depth - 8);
1577 #define YUV_NBPS(depth, BE_LE, origin) \
1578 static void BE_LE ## depth ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1579 const uint8_t *srcU, const uint8_t *srcV, \
1580 int width, uint32_t *unused) \
1582 yuv9_OR_10ToUV_c_template(dstU, dstV, srcU, srcV, width, origin, depth); \
1584 static void BE_LE ## depth ## ToY_c(uint8_t *dstY, const uint8_t *srcY, \
1585 int width, uint32_t *unused) \
1587 yuv9_or_10ToY_c_template(dstY, srcY, width, origin, depth); \
1590 YUV_NBPS( 9, LE, PIX_FMT_YUV420P9LE);
1591 YUV_NBPS( 9, BE, PIX_FMT_YUV420P9BE);
1592 YUV_NBPS(10, LE, PIX_FMT_YUV420P10LE);
1593 YUV_NBPS(10, BE, PIX_FMT_YUV420P10BE);
1595 static void bgr24ToY_c(uint8_t *dst, const uint8_t *src,
1596 int width, uint32_t *unused)
1599 for (i=0; i<width; i++) {
1604 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
1608 static void bgr24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1609 const uint8_t *src2, int width, uint32_t *unused)
1612 for (i=0; i<width; i++) {
1613 int b= src1[3*i + 0];
1614 int g= src1[3*i + 1];
1615 int r= src1[3*i + 2];
1617 dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
1618 dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
1620 assert(src1 == src2);
1623 static void bgr24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1624 const uint8_t *src2, int width, uint32_t *unused)
1627 for (i=0; i<width; i++) {
1628 int b= src1[6*i + 0] + src1[6*i + 3];
1629 int g= src1[6*i + 1] + src1[6*i + 4];
1630 int r= src1[6*i + 2] + src1[6*i + 5];
1632 dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1633 dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1635 assert(src1 == src2);
1638 static void rgb24ToY_c(uint8_t *dst, const uint8_t *src, int width,
1642 for (i=0; i<width; i++) {
1647 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
1651 static void rgb24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1652 const uint8_t *src2, int width, uint32_t *unused)
1656 for (i=0; i<width; i++) {
1657 int r= src1[3*i + 0];
1658 int g= src1[3*i + 1];
1659 int b= src1[3*i + 2];
1661 dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
1662 dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
1666 static void rgb24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1667 const uint8_t *src2, int width, uint32_t *unused)
1671 for (i=0; i<width; i++) {
1672 int r= src1[6*i + 0] + src1[6*i + 3];
1673 int g= src1[6*i + 1] + src1[6*i + 4];
1674 int b= src1[6*i + 2] + src1[6*i + 5];
1676 dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1677 dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1682 // bilinear / bicubic scaling
1683 static void hScale_c(int16_t *dst, int dstW, const uint8_t *src,
1685 const int16_t *filter, const int16_t *filterPos,
1689 for (i=0; i<dstW; i++) {
1691 int srcPos= filterPos[i];
1693 for (j=0; j<filterSize; j++) {
1694 val += ((int)src[srcPos + j])*filter[filterSize*i + j];
1696 //filter += hFilterSize;
1697 dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
1702 //FIXME all pal and rgb srcFormats could do this convertion as well
1703 //FIXME all scalers more complex than bilinear could do half of this transform
1704 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1707 for (i = 0; i < width; i++) {
1708 dstU[i] = (FFMIN(dstU[i],30775)*4663 - 9289992)>>12; //-264
1709 dstV[i] = (FFMIN(dstV[i],30775)*4663 - 9289992)>>12; //-264
1712 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1715 for (i = 0; i < width; i++) {
1716 dstU[i] = (dstU[i]*1799 + 4081085)>>11; //1469
1717 dstV[i] = (dstV[i]*1799 + 4081085)>>11; //1469
1720 static void lumRangeToJpeg_c(int16_t *dst, int width)
1723 for (i = 0; i < width; i++)
1724 dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
1726 static void lumRangeFromJpeg_c(int16_t *dst, int width)
1729 for (i = 0; i < width; i++)
1730 dst[i] = (dst[i]*14071 + 33561947)>>14;
1733 static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
1734 const uint8_t *src, int srcW, int xInc)
1737 unsigned int xpos=0;
1738 for (i=0;i<dstWidth;i++) {
1739 register unsigned int xx=xpos>>16;
1740 register unsigned int xalpha=(xpos&0xFFFF)>>9;
1741 dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
1746 // *** horizontal scale Y line to temp buffer
1747 static av_always_inline void hyscale(SwsContext *c, uint16_t *dst, int dstWidth,
1748 const uint8_t *src, int srcW, int xInc,
1749 const int16_t *hLumFilter,
1750 const int16_t *hLumFilterPos, int hLumFilterSize,
1751 uint8_t *formatConvBuffer,
1752 uint32_t *pal, int isAlpha)
1754 void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
1755 void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
1758 toYV12(formatConvBuffer, src, srcW, pal);
1759 src= formatConvBuffer;
1762 if (!c->hyscale_fast) {
1763 c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
1764 } else { // fast bilinear upscale / crap downscale
1765 c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
1769 convertRange(dst, dstWidth);
1772 static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
1773 int dstWidth, const uint8_t *src1,
1774 const uint8_t *src2, int srcW, int xInc)
1777 unsigned int xpos=0;
1778 for (i=0;i<dstWidth;i++) {
1779 register unsigned int xx=xpos>>16;
1780 register unsigned int xalpha=(xpos&0xFFFF)>>9;
1781 dst1[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
1782 dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
1787 static av_always_inline void hcscale(SwsContext *c, uint16_t *dst1, uint16_t *dst2, int dstWidth,
1788 const uint8_t *src1, const uint8_t *src2,
1789 int srcW, int xInc, const int16_t *hChrFilter,
1790 const int16_t *hChrFilterPos, int hChrFilterSize,
1791 uint8_t *formatConvBuffer, uint32_t *pal)
1794 uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW, 16);
1795 c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
1796 src1= formatConvBuffer;
1800 if (!c->hcscale_fast) {
1801 c->hScale(dst1, dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
1802 c->hScale(dst2, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
1803 } else { // fast bilinear upscale / crap downscale
1804 c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc);
1807 if (c->chrConvertRange)
1808 c->chrConvertRange(dst1, dst2, dstWidth);
1811 static av_always_inline void
1812 find_c_packed_planar_out_funcs(SwsContext *c,
1813 yuv2planar1_fn *yuv2yuv1, yuv2planarX_fn *yuv2yuvX,
1814 yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2,
1815 yuv2packedX_fn *yuv2packedX)
1817 enum PixelFormat dstFormat = c->dstFormat;
1819 if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
1820 *yuv2yuvX = yuv2nv12X_c;
1821 } else if (is16BPS(dstFormat)) {
1822 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX16BE_c : yuv2yuvX16LE_c;
1823 } else if (is9_OR_10BPS(dstFormat)) {
1824 if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
1825 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c : yuv2yuvX9LE_c;
1827 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c;
1830 *yuv2yuv1 = yuv2yuv1_c;
1831 *yuv2yuvX = yuv2yuvX_c;
1833 if(c->flags & SWS_FULL_CHR_H_INT) {
1834 *yuv2packedX = yuv2rgbX_c_full;
1836 switch (dstFormat) {
1837 case PIX_FMT_GRAY16BE:
1838 *yuv2packed1 = yuv2gray16BE_1_c;
1839 *yuv2packed2 = yuv2gray16BE_2_c;
1840 *yuv2packedX = yuv2gray16BE_X_c;
1842 case PIX_FMT_GRAY16LE:
1843 *yuv2packed1 = yuv2gray16LE_1_c;
1844 *yuv2packed2 = yuv2gray16LE_2_c;
1845 *yuv2packedX = yuv2gray16LE_X_c;
1847 case PIX_FMT_MONOWHITE:
1848 *yuv2packed1 = yuv2monowhite_1_c;
1849 *yuv2packed2 = yuv2monowhite_2_c;
1850 *yuv2packedX = yuv2monowhite_X_c;
1852 case PIX_FMT_MONOBLACK:
1853 *yuv2packed1 = yuv2monoblack_1_c;
1854 *yuv2packed2 = yuv2monoblack_2_c;
1855 *yuv2packedX = yuv2monoblack_X_c;
1857 case PIX_FMT_YUYV422:
1858 *yuv2packed1 = yuv2422yuyv_1_c;
1859 *yuv2packed2 = yuv2422yuyv_2_c;
1860 *yuv2packedX = yuv2422yuyv_X_c;
1862 case PIX_FMT_UYVY422:
1863 *yuv2packed1 = yuv2422uyvy_1_c;
1864 *yuv2packed2 = yuv2422uyvy_2_c;
1865 *yuv2packedX = yuv2422uyvy_X_c;
1868 *yuv2packed1 = yuv2packed1_c;
1869 *yuv2packed2 = yuv2packed2_c;
1870 *yuv2packedX = yuv2packedX_c;
1876 #define DEBUG_SWSCALE_BUFFERS 0
1877 #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
1879 static int swScale(SwsContext *c, const uint8_t* src[],
1880 int srcStride[], int srcSliceY,
1881 int srcSliceH, uint8_t* dst[], int dstStride[])
1883 /* load a few things into local vars to make the code more readable? and faster */
1884 const int srcW= c->srcW;
1885 const int dstW= c->dstW;
1886 const int dstH= c->dstH;
1887 const int chrDstW= c->chrDstW;
1888 const int chrSrcW= c->chrSrcW;
1889 const int lumXInc= c->lumXInc;
1890 const int chrXInc= c->chrXInc;
1891 const enum PixelFormat dstFormat= c->dstFormat;
1892 const int flags= c->flags;
1893 int16_t *vLumFilterPos= c->vLumFilterPos;
1894 int16_t *vChrFilterPos= c->vChrFilterPos;
1895 int16_t *hLumFilterPos= c->hLumFilterPos;
1896 int16_t *hChrFilterPos= c->hChrFilterPos;
1897 int16_t *vLumFilter= c->vLumFilter;
1898 int16_t *vChrFilter= c->vChrFilter;
1899 int16_t *hLumFilter= c->hLumFilter;
1900 int16_t *hChrFilter= c->hChrFilter;
1901 int32_t *lumMmxFilter= c->lumMmxFilter;
1902 int32_t *chrMmxFilter= c->chrMmxFilter;
1903 int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
1904 const int vLumFilterSize= c->vLumFilterSize;
1905 const int vChrFilterSize= c->vChrFilterSize;
1906 const int hLumFilterSize= c->hLumFilterSize;
1907 const int hChrFilterSize= c->hChrFilterSize;
1908 int16_t **lumPixBuf= c->lumPixBuf;
1909 int16_t **chrUPixBuf= c->chrUPixBuf;
1910 int16_t **chrVPixBuf= c->chrVPixBuf;
1911 int16_t **alpPixBuf= c->alpPixBuf;
1912 const int vLumBufSize= c->vLumBufSize;
1913 const int vChrBufSize= c->vChrBufSize;
1914 uint8_t *formatConvBuffer= c->formatConvBuffer;
1915 const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
1916 const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
1918 uint32_t *pal=c->pal_yuv;
1919 yuv2planar1_fn yuv2yuv1 = c->yuv2yuv1;
1920 yuv2planarX_fn yuv2yuvX = c->yuv2yuvX;
1921 yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
1922 yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
1923 yuv2packedX_fn yuv2packedX = c->yuv2packedX;
1925 /* vars which will change and which we need to store back in the context */
1927 int lumBufIndex= c->lumBufIndex;
1928 int chrBufIndex= c->chrBufIndex;
1929 int lastInLumBuf= c->lastInLumBuf;
1930 int lastInChrBuf= c->lastInChrBuf;
1932 if (isPacked(c->srcFormat)) {
1940 srcStride[3]= srcStride[0];
1942 srcStride[1]<<= c->vChrDrop;
1943 srcStride[2]<<= c->vChrDrop;
1945 DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
1946 src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
1947 dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
1948 DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
1949 srcSliceY, srcSliceH, dstY, dstH);
1950 DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
1951 vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize);
1953 if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
1954 static int warnedAlready=0; //FIXME move this into the context perhaps
1955 if (flags & SWS_PRINT_INFO && !warnedAlready) {
1956 av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
1957 " ->cannot do aligned memory accesses anymore\n");
1962 /* Note the user might start scaling the picture in the middle so this
1963 will not get executed. This is not really intended but works
1964 currently, so people might do it. */
1965 if (srcSliceY ==0) {
1975 for (;dstY < dstH; dstY++) {
1976 unsigned char *dest =dst[0]+dstStride[0]*dstY;
1977 const int chrDstY= dstY>>c->chrDstVSubSample;
1978 unsigned char *uDest=dst[1]+dstStride[1]*chrDstY;
1979 unsigned char *vDest=dst[2]+dstStride[2]*chrDstY;
1980 unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL;
1982 const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
1983 const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
1984 const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
1985 int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
1986 int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
1987 int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
1990 //handle holes (FAST_BILINEAR & weird filters)
1991 if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
1992 if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
1993 assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
1994 assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
1996 DEBUG_BUFFERS("dstY: %d\n", dstY);
1997 DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
1998 firstLumSrcY, lastLumSrcY, lastInLumBuf);
1999 DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
2000 firstChrSrcY, lastChrSrcY, lastInChrBuf);
2002 // Do we have enough lines in this slice to output the dstY line
2003 enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
2005 if (!enough_lines) {
2006 lastLumSrcY = srcSliceY + srcSliceH - 1;
2007 lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
2008 DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
2009 lastLumSrcY, lastChrSrcY);
2012 //Do horizontal scaling
2013 while(lastInLumBuf < lastLumSrcY) {
2014 const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
2015 const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
2017 assert(lumBufIndex < 2*vLumBufSize);
2018 assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
2019 assert(lastInLumBuf + 1 - srcSliceY >= 0);
2020 hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
2021 hLumFilter, hLumFilterPos, hLumFilterSize,
2024 if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
2025 hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW,
2026 lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
2030 DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
2031 lumBufIndex, lastInLumBuf);
2033 while(lastInChrBuf < lastChrSrcY) {
2034 const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
2035 const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
2037 assert(chrBufIndex < 2*vChrBufSize);
2038 assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
2039 assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
2040 //FIXME replace parameters through context struct (some at least)
2042 if (c->needs_hcscale)
2043 hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
2044 chrDstW, src1, src2, chrSrcW, chrXInc,
2045 hChrFilter, hChrFilterPos, hChrFilterSize,
2046 formatConvBuffer, pal);
2048 DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
2049 chrBufIndex, lastInChrBuf);
2051 //wrap buf index around to stay inside the ring buffer
2052 if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
2053 if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
2055 break; //we can't output a dstY line so let's try with the next slice
2058 updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf);
2060 if (dstY >= dstH-2) {
2061 // hmm looks like we can't use MMX here without overwriting this array's tail
2062 find_c_packed_planar_out_funcs(c, &yuv2yuv1, &yuv2yuvX,
2063 &yuv2packed1, &yuv2packed2,
2068 const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
2069 const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2070 const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2071 const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
2072 if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
2073 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2074 if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
2075 if (c->yuv2yuv1 && vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
2076 const int16_t *lumBuf = lumSrcPtr[0];
2077 const int16_t *chrUBuf= chrUSrcPtr[0];
2078 const int16_t *chrVBuf= chrVSrcPtr[0];
2079 const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
2080 yuv2yuv1(c, lumBuf, chrUBuf, chrVBuf, alpBuf, dest,
2081 uDest, vDest, aDest, dstW, chrDstW);
2082 } else { //General YV12
2084 vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
2085 vChrFilter+chrDstY*vChrFilterSize, chrUSrcPtr,
2086 chrVSrcPtr, vChrFilterSize,
2087 alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW);
2090 assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
2091 assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize*2);
2092 if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
2093 int chrAlpha= vChrFilter[2*dstY+1];
2094 yuv2packed1(c, *lumSrcPtr, *chrUSrcPtr, *(chrUSrcPtr+1),
2095 *chrVSrcPtr, *(chrVSrcPtr+1),
2096 alpPixBuf ? *alpSrcPtr : NULL,
2097 dest, dstW, chrAlpha, dstFormat, flags, dstY);
2098 } else if (c->yuv2packed2 && vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
2099 int lumAlpha= vLumFilter[2*dstY+1];
2100 int chrAlpha= vChrFilter[2*dstY+1];
2102 lumMmxFilter[3]= vLumFilter[2*dstY ]*0x10001;
2104 chrMmxFilter[3]= vChrFilter[2*chrDstY]*0x10001;
2105 yuv2packed2(c, *lumSrcPtr, *(lumSrcPtr+1), *chrUSrcPtr, *(chrUSrcPtr+1),
2106 *chrVSrcPtr, *(chrVSrcPtr+1),
2107 alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *(alpSrcPtr+1) : NULL,
2108 dest, dstW, lumAlpha, chrAlpha, dstY);
2109 } else { //general RGB
2111 vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
2112 vChrFilter+dstY*vChrFilterSize, chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2113 alpSrcPtr, dest, dstW, dstY);
2119 if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
2120 fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
2123 if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2)
2124 __asm__ volatile("sfence":::"memory");
2128 /* store changed local vars back in the context */
2130 c->lumBufIndex= lumBufIndex;
2131 c->chrBufIndex= chrBufIndex;
2132 c->lastInLumBuf= lastInLumBuf;
2133 c->lastInChrBuf= lastInChrBuf;
2135 return dstY - lastDstY;
2138 static av_cold void sws_init_swScale_c(SwsContext *c)
2140 enum PixelFormat srcFormat = c->srcFormat;
2142 find_c_packed_planar_out_funcs(c, &c->yuv2yuv1, &c->yuv2yuvX,
2143 &c->yuv2packed1, &c->yuv2packed2,
2146 c->hScale = hScale_c;
2148 if (c->flags & SWS_FAST_BILINEAR) {
2149 c->hyscale_fast = hyscale_fast_c;
2150 c->hcscale_fast = hcscale_fast_c;
2153 c->chrToYV12 = NULL;
2155 case PIX_FMT_YUYV422 : c->chrToYV12 = yuy2ToUV_c; break;
2156 case PIX_FMT_UYVY422 : c->chrToYV12 = uyvyToUV_c; break;
2157 case PIX_FMT_NV12 : c->chrToYV12 = nv12ToUV_c; break;
2158 case PIX_FMT_NV21 : c->chrToYV12 = nv21ToUV_c; break;
2162 case PIX_FMT_BGR4_BYTE:
2163 case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
2164 case PIX_FMT_YUV444P9BE:
2165 case PIX_FMT_YUV420P9BE: c->chrToYV12 = BE9ToUV_c; break;
2166 case PIX_FMT_YUV444P9LE:
2167 case PIX_FMT_YUV420P9LE: c->chrToYV12 = LE9ToUV_c; break;
2168 case PIX_FMT_YUV444P10BE:
2169 case PIX_FMT_YUV422P10BE:
2170 case PIX_FMT_YUV420P10BE: c->chrToYV12 = BE10ToUV_c; break;
2171 case PIX_FMT_YUV422P10LE:
2172 case PIX_FMT_YUV444P10LE:
2173 case PIX_FMT_YUV420P10LE: c->chrToYV12 = LE10ToUV_c; break;
2174 case PIX_FMT_YUV420P16BE:
2175 case PIX_FMT_YUV422P16BE:
2176 case PIX_FMT_YUV444P16BE: c->chrToYV12 = BEToUV_c; break;
2177 case PIX_FMT_YUV420P16LE:
2178 case PIX_FMT_YUV422P16LE:
2179 case PIX_FMT_YUV444P16LE: c->chrToYV12 = LEToUV_c; break;
2181 if (c->chrSrcHSubSample) {
2183 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_half_c; break;
2184 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_half_c; break;
2185 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_half_c; break;
2186 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_half_c; break;
2187 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_half_c; break;
2188 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_half_c; break;
2189 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_half_c; break;
2190 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_half_c; break;
2191 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_half_c; break;
2192 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_half_c; break;
2193 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_half_c; break;
2194 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_half_c; break;
2195 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_half_c; break;
2196 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_half_c; break;
2197 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_half_c; break;
2198 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_half_c; break;
2199 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_half_c; break;
2200 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_half_c; break;
2204 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_c; break;
2205 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_c; break;
2206 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_c; break;
2207 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_c; break;
2208 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_c; break;
2209 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_c; break;
2210 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_c; break;
2211 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_c; break;
2212 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_c; break;
2213 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_c; break;
2214 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_c; break;
2215 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_c; break;
2216 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_c; break;
2217 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_c; break;
2218 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_c; break;
2219 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_c; break;
2220 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_c; break;
2221 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_c; break;
2225 c->lumToYV12 = NULL;
2226 c->alpToYV12 = NULL;
2227 switch (srcFormat) {
2228 case PIX_FMT_YUV444P9BE:
2229 case PIX_FMT_YUV420P9BE: c->lumToYV12 = BE9ToY_c; break;
2230 case PIX_FMT_YUV444P9LE:
2231 case PIX_FMT_YUV420P9LE: c->lumToYV12 = LE9ToY_c; break;
2232 case PIX_FMT_YUV444P10BE:
2233 case PIX_FMT_YUV422P10BE:
2234 case PIX_FMT_YUV420P10BE: c->lumToYV12 = BE10ToY_c; break;
2235 case PIX_FMT_YUV444P10LE:
2236 case PIX_FMT_YUV422P10LE:
2237 case PIX_FMT_YUV420P10LE: c->lumToYV12 = LE10ToY_c; break;
2238 case PIX_FMT_YUYV422 :
2239 case PIX_FMT_YUV420P16BE:
2240 case PIX_FMT_YUV422P16BE:
2241 case PIX_FMT_YUV444P16BE:
2242 case PIX_FMT_Y400A :
2243 case PIX_FMT_GRAY16BE : c->lumToYV12 = yuy2ToY_c; break;
2244 case PIX_FMT_UYVY422 :
2245 case PIX_FMT_YUV420P16LE:
2246 case PIX_FMT_YUV422P16LE:
2247 case PIX_FMT_YUV444P16LE:
2248 case PIX_FMT_GRAY16LE : c->lumToYV12 = uyvyToY_c; break;
2249 case PIX_FMT_BGR24 : c->lumToYV12 = bgr24ToY_c; break;
2250 case PIX_FMT_BGR565LE : c->lumToYV12 = bgr16leToY_c; break;
2251 case PIX_FMT_BGR565BE : c->lumToYV12 = bgr16beToY_c; break;
2252 case PIX_FMT_BGR555LE : c->lumToYV12 = bgr15leToY_c; break;
2253 case PIX_FMT_BGR555BE : c->lumToYV12 = bgr15beToY_c; break;
2254 case PIX_FMT_RGB24 : c->lumToYV12 = rgb24ToY_c; break;
2255 case PIX_FMT_RGB565LE : c->lumToYV12 = rgb16leToY_c; break;
2256 case PIX_FMT_RGB565BE : c->lumToYV12 = rgb16beToY_c; break;
2257 case PIX_FMT_RGB555LE : c->lumToYV12 = rgb15leToY_c; break;
2258 case PIX_FMT_RGB555BE : c->lumToYV12 = rgb15beToY_c; break;
2262 case PIX_FMT_BGR4_BYTE:
2263 case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY_c; break;
2264 case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y_c; break;
2265 case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y_c; break;
2266 case PIX_FMT_RGB32 : c->lumToYV12 = bgr32ToY_c; break;
2267 case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY_c; break;
2268 case PIX_FMT_BGR32 : c->lumToYV12 = rgb32ToY_c; break;
2269 case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY_c; break;
2270 case PIX_FMT_RGB48BE: c->lumToYV12 = rgb48BEToY_c; break;
2271 case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break;
2272 case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break;
2273 case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break;
2276 switch (srcFormat) {
2278 case PIX_FMT_RGBA: c->alpToYV12 = rgbaToA_c; break;
2280 case PIX_FMT_ARGB: c->alpToYV12 = abgrToA_c; break;
2281 case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
2285 if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
2287 c->lumConvertRange = lumRangeFromJpeg_c;
2288 c->chrConvertRange = chrRangeFromJpeg_c;
2290 c->lumConvertRange = lumRangeToJpeg_c;
2291 c->chrConvertRange = chrRangeToJpeg_c;
2295 if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
2296 srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE))
2297 c->needs_hcscale = 1;
2300 SwsFunc ff_getSwsFunc(SwsContext *c)
2302 sws_init_swScale_c(c);
2305 ff_sws_init_swScale_mmx(c);
2307 ff_sws_init_swScale_altivec(c);