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 #define output_pixel(pos, val) \
412 if (target == PIX_FMT_GRAY16BE) { \
418 static av_always_inline void
419 yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter,
420 const int16_t **lumSrc, int lumFilterSize,
421 const int16_t *chrFilter, const int16_t **chrUSrc,
422 const int16_t **chrVSrc, int chrFilterSize,
423 const int16_t **alpSrc, uint8_t *dest, int dstW,
424 int y, enum PixelFormat target)
428 for (i = 0; i < (dstW >> 1); i++) {
432 const int i2 = 2 * i;
434 for (j = 0; j < lumFilterSize; j++) {
435 Y1 += lumSrc[j][i2] * lumFilter[j];
436 Y2 += lumSrc[j][i2+1] * lumFilter[j];
440 if ((Y1 | Y2) & 0x10000) {
441 Y1 = av_clip_uint16(Y1);
442 Y2 = av_clip_uint16(Y2);
444 output_pixel(&dest[2 * i2 + 0], Y1);
445 output_pixel(&dest[2 * i2 + 2], Y2);
449 static av_always_inline void
450 yuv2gray16_2_c_template(SwsContext *c, const uint16_t *buf0,
451 const uint16_t *buf1, const uint16_t *ubuf0,
452 const uint16_t *ubuf1, const uint16_t *vbuf0,
453 const uint16_t *vbuf1, const uint16_t *abuf0,
454 const uint16_t *abuf1, uint8_t *dest, int dstW,
455 int yalpha, int uvalpha, int y,
456 enum PixelFormat target)
458 int yalpha1 = 4095 - yalpha; \
461 for (i = 0; i < (dstW >> 1); i++) {
462 const int i2 = 2 * i;
463 int Y1 = (buf0[i2 ] * yalpha1 + buf1[i2 ] * yalpha) >> 11;
464 int Y2 = (buf0[i2+1] * yalpha1 + buf1[i2+1] * yalpha) >> 11;
466 output_pixel(&dest[2 * i2 + 0], Y1);
467 output_pixel(&dest[2 * i2 + 2], Y2);
471 static av_always_inline void
472 yuv2gray16_1_c_template(SwsContext *c, const uint16_t *buf0,
473 const uint16_t *ubuf0, const uint16_t *ubuf1,
474 const uint16_t *vbuf0, const uint16_t *vbuf1,
475 const uint16_t *abuf0, uint8_t *dest, int dstW,
476 int uvalpha, enum PixelFormat dstFormat,
477 int flags, int y, enum PixelFormat target)
481 for (i = 0; i < (dstW >> 1); i++) {
482 const int i2 = 2 * i;
483 int Y1 = buf0[i2 ] << 1;
484 int Y2 = buf0[i2+1] << 1;
486 output_pixel(&dest[2 * i2 + 0], Y1);
487 output_pixel(&dest[2 * i2 + 2], Y2);
493 #define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
494 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
495 const int16_t **lumSrc, int lumFilterSize, \
496 const int16_t *chrFilter, const int16_t **chrUSrc, \
497 const int16_t **chrVSrc, int chrFilterSize, \
498 const int16_t **alpSrc, uint8_t *dest, int dstW, \
501 name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
502 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
503 alpSrc, dest, dstW, y, fmt); \
506 static void name ## ext ## _2_c(SwsContext *c, const uint16_t *buf0, \
507 const uint16_t *buf1, const uint16_t *ubuf0, \
508 const uint16_t *ubuf1, const uint16_t *vbuf0, \
509 const uint16_t *vbuf1, const uint16_t *abuf0, \
510 const uint16_t *abuf1, uint8_t *dest, int dstW, \
511 int yalpha, int uvalpha, int y) \
513 name ## base ## _2_c_template(c, buf0, buf1, ubuf0, ubuf1, \
514 vbuf0, vbuf1, abuf0, abuf1, \
515 dest, dstW, yalpha, uvalpha, y, fmt); \
518 static void name ## ext ## _1_c(SwsContext *c, const uint16_t *buf0, \
519 const uint16_t *ubuf0, const uint16_t *ubuf1, \
520 const uint16_t *vbuf0, const uint16_t *vbuf1, \
521 const uint16_t *abuf0, uint8_t *dest, int dstW, \
522 int uvalpha, enum PixelFormat dstFormat, \
525 name ## base ## _1_c_template(c, buf0, ubuf0, ubuf1, vbuf0, \
526 vbuf1, abuf0, dest, dstW, uvalpha, \
527 dstFormat, flags, y, fmt); \
530 YUV2PACKEDWRAPPER(yuv2gray16,, LE, PIX_FMT_GRAY16LE);
531 YUV2PACKEDWRAPPER(yuv2gray16,, BE, PIX_FMT_GRAY16BE);
533 #define output_pixel(pos, acc) \
534 if (target == PIX_FMT_MONOBLACK) { \
540 static av_always_inline void
541 yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
542 const int16_t **lumSrc, int lumFilterSize,
543 const int16_t *chrFilter, const int16_t **chrUSrc,
544 const int16_t **chrVSrc, int chrFilterSize,
545 const int16_t **alpSrc, uint8_t *dest, int dstW,
546 int y, enum PixelFormat target)
548 const uint8_t * const d128=dither_8x8_220[y&7];
549 uint8_t *g = c->table_gU[128] + c->table_gV[128];
553 for (i = 0; i < dstW - 1; i += 2) {
558 for (j = 0; j < lumFilterSize; j++) {
559 Y1 += lumSrc[j][i] * lumFilter[j];
560 Y2 += lumSrc[j][i+1] * lumFilter[j];
564 if ((Y1 | Y2) & 0x100) {
565 Y1 = av_clip_uint8(Y1);
566 Y2 = av_clip_uint8(Y2);
568 acc += acc + g[Y1 + d128[(i + 0) & 7]];
569 acc += acc + g[Y2 + d128[(i + 1) & 7]];
571 output_pixel(*dest++, acc);
576 static av_always_inline void
577 yuv2mono_2_c_template(SwsContext *c, const uint16_t *buf0,
578 const uint16_t *buf1, const uint16_t *ubuf0,
579 const uint16_t *ubuf1, const uint16_t *vbuf0,
580 const uint16_t *vbuf1, const uint16_t *abuf0,
581 const uint16_t *abuf1, uint8_t *dest, int dstW,
582 int yalpha, int uvalpha, int y,
583 enum PixelFormat target)
585 const uint8_t * const d128 = dither_8x8_220[y & 7];
586 uint8_t *g = c->table_gU[128] + c->table_gV[128];
587 int yalpha1 = 4095 - yalpha;
590 for (i = 0; i < dstW - 7; i += 8) {
591 int acc = g[((buf0[i ] * yalpha1 + buf1[i ] * yalpha) >> 19) + d128[0]];
592 acc += acc + g[((buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19) + d128[1]];
593 acc += acc + g[((buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19) + d128[2]];
594 acc += acc + g[((buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19) + d128[3]];
595 acc += acc + g[((buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19) + d128[4]];
596 acc += acc + g[((buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19) + d128[5]];
597 acc += acc + g[((buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19) + d128[6]];
598 acc += acc + g[((buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19) + d128[7]];
599 output_pixel(*dest++, acc);
603 static av_always_inline void
604 yuv2mono_1_c_template(SwsContext *c, const uint16_t *buf0,
605 const uint16_t *ubuf0, const uint16_t *ubuf1,
606 const uint16_t *vbuf0, const uint16_t *vbuf1,
607 const uint16_t *abuf0, uint8_t *dest, int dstW,
608 int uvalpha, enum PixelFormat dstFormat,
609 int flags, int y, enum PixelFormat target)
611 const uint8_t * const d128 = dither_8x8_220[y & 7];
612 uint8_t *g = c->table_gU[128] + c->table_gV[128];
615 for (i = 0; i < dstW - 7; i += 8) {
616 int acc = g[(buf0[i ] >> 7) + d128[0]];
617 acc += acc + g[(buf0[i + 1] >> 7) + d128[1]];
618 acc += acc + g[(buf0[i + 2] >> 7) + d128[2]];
619 acc += acc + g[(buf0[i + 3] >> 7) + d128[3]];
620 acc += acc + g[(buf0[i + 4] >> 7) + d128[4]];
621 acc += acc + g[(buf0[i + 5] >> 7) + d128[5]];
622 acc += acc + g[(buf0[i + 6] >> 7) + d128[6]];
623 acc += acc + g[(buf0[i + 7] >> 7) + d128[7]];
624 output_pixel(*dest++, acc);
630 YUV2PACKEDWRAPPER(yuv2mono,, white, PIX_FMT_MONOWHITE);
631 YUV2PACKEDWRAPPER(yuv2mono,, black, PIX_FMT_MONOBLACK);
633 #define output_pixels(pos, Y1, U, Y2, V) \
634 if (target == PIX_FMT_YUYV422) { \
635 dest[pos + 0] = Y1; \
637 dest[pos + 2] = Y2; \
641 dest[pos + 1] = Y1; \
643 dest[pos + 3] = Y2; \
646 static av_always_inline void
647 yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
648 const int16_t **lumSrc, int lumFilterSize,
649 const int16_t *chrFilter, const int16_t **chrUSrc,
650 const int16_t **chrVSrc, int chrFilterSize,
651 const int16_t **alpSrc, uint8_t *dest, int dstW,
652 int y, enum PixelFormat target)
656 for (i = 0; i < (dstW >> 1); i++) {
663 for (j = 0; j < lumFilterSize; j++) {
664 Y1 += lumSrc[j][i * 2] * lumFilter[j];
665 Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
667 for (j = 0; j < chrFilterSize; j++) {
668 U += chrUSrc[j][i] * chrFilter[j];
669 V += chrVSrc[j][i] * chrFilter[j];
675 if ((Y1 | Y2 | U | V) & 0x100) {
676 Y1 = av_clip_uint8(Y1);
677 Y2 = av_clip_uint8(Y2);
678 U = av_clip_uint8(U);
679 V = av_clip_uint8(V);
681 output_pixels(4*i, Y1, U, Y2, V);
685 static av_always_inline void
686 yuv2422_2_c_template(SwsContext *c, const uint16_t *buf0,
687 const uint16_t *buf1, const uint16_t *ubuf0,
688 const uint16_t *ubuf1, const uint16_t *vbuf0,
689 const uint16_t *vbuf1, const uint16_t *abuf0,
690 const uint16_t *abuf1, uint8_t *dest, int dstW,
691 int yalpha, int uvalpha, int y,
692 enum PixelFormat target)
694 int yalpha1 = 4095 - yalpha;
695 int uvalpha1 = 4095 - uvalpha;
698 for (i = 0; i < (dstW >> 1); i++) {
699 int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19;
700 int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
701 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
702 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
704 output_pixels(i * 4, Y1, U, Y2, V);
708 static av_always_inline void
709 yuv2422_1_c_template(SwsContext *c, const uint16_t *buf0,
710 const uint16_t *ubuf0, const uint16_t *ubuf1,
711 const uint16_t *vbuf0, const uint16_t *vbuf1,
712 const uint16_t *abuf0, uint8_t *dest, int dstW,
713 int uvalpha, enum PixelFormat dstFormat,
714 int flags, int y, enum PixelFormat target)
718 if (uvalpha < 2048) {
719 for (i = 0; i < (dstW >> 1); i++) {
720 int Y1 = buf0[i * 2] >> 7;
721 int Y2 = buf0[i * 2 + 1] >> 7;
722 int U = ubuf1[i] >> 7;
723 int V = vbuf1[i] >> 7;
725 output_pixels(i * 4, Y1, U, Y2, V);
728 for (i = 0; i < (dstW >> 1); i++) {
729 int Y1 = buf0[i * 2] >> 7;
730 int Y2 = buf0[i * 2 + 1] >> 7;
731 int U = (ubuf0[i] + ubuf1[i]) >> 8;
732 int V = (vbuf0[i] + vbuf1[i]) >> 8;
734 output_pixels(i * 4, Y1, U, Y2, V);
741 YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, PIX_FMT_YUYV422);
742 YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, PIX_FMT_UYVY422);
744 #define r_b ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? r : b)
745 #define b_r ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? b : r)
747 static av_always_inline void
748 yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
749 const int16_t **lumSrc, int lumFilterSize,
750 const int16_t *chrFilter, const int16_t **chrUSrc,
751 const int16_t **chrVSrc, int chrFilterSize,
752 const int16_t **alpSrc, uint8_t *dest, int dstW,
753 int y, enum PixelFormat target)
757 for (i = 0; i < (dstW >> 1); i++) {
763 const uint8_t *r, *g, *b;
765 for (j = 0; j < lumFilterSize; j++) {
766 Y1 += lumSrc[j][i * 2] * lumFilter[j];
767 Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
769 for (j = 0; j < chrFilterSize; j++) {
770 U += chrUSrc[j][i] * chrFilter[j];
771 V += chrVSrc[j][i] * chrFilter[j];
777 if ((Y1 | Y2 | U | V) & 0x100) {
778 Y1 = av_clip_uint8(Y1);
779 Y2 = av_clip_uint8(Y2);
780 U = av_clip_uint8(U);
781 V = av_clip_uint8(V);
784 /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/
785 r = (const uint8_t *) c->table_rV[V];
786 g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]);
787 b = (const uint8_t *) c->table_bU[U];
789 dest[ 0] = dest[ 1] = r_b[Y1];
790 dest[ 2] = dest[ 3] = g[Y1];
791 dest[ 4] = dest[ 5] = b_r[Y1];
792 dest[ 6] = dest[ 7] = r_b[Y2];
793 dest[ 8] = dest[ 9] = g[Y2];
794 dest[10] = dest[11] = b_r[Y2];
799 static av_always_inline void
800 yuv2rgb48_2_c_template(SwsContext *c, const uint16_t *buf0,
801 const uint16_t *buf1, const uint16_t *ubuf0,
802 const uint16_t *ubuf1, const uint16_t *vbuf0,
803 const uint16_t *vbuf1, const uint16_t *abuf0,
804 const uint16_t *abuf1, uint8_t *dest, int dstW,
805 int yalpha, int uvalpha, int y,
806 enum PixelFormat target)
808 int yalpha1 = 4095 - yalpha;
809 int uvalpha1 = 4095 - uvalpha;
812 for (i = 0; i < (dstW >> 1); i++) {
813 int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19;
814 int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
815 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
816 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
817 const uint8_t *r = (const uint8_t *) c->table_rV[V],
818 *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
819 *b = (const uint8_t *) c->table_bU[U];
821 dest[ 0] = dest[ 1] = r_b[Y1];
822 dest[ 2] = dest[ 3] = g[Y1];
823 dest[ 4] = dest[ 5] = b_r[Y1];
824 dest[ 6] = dest[ 7] = r_b[Y2];
825 dest[ 8] = dest[ 9] = g[Y2];
826 dest[10] = dest[11] = b_r[Y2];
831 static av_always_inline void
832 yuv2rgb48_1_c_template(SwsContext *c, const uint16_t *buf0,
833 const uint16_t *ubuf0, const uint16_t *ubuf1,
834 const uint16_t *vbuf0, const uint16_t *vbuf1,
835 const uint16_t *abuf0, uint8_t *dest, int dstW,
836 int uvalpha, enum PixelFormat dstFormat,
837 int flags, int y, enum PixelFormat target)
841 if (uvalpha < 2048) {
842 for (i = 0; i < (dstW >> 1); i++) {
843 int Y1 = buf0[i * 2] >> 7;
844 int Y2 = buf0[i * 2 + 1] >> 7;
845 int U = ubuf1[i] >> 7;
846 int V = vbuf1[i] >> 7;
847 const uint8_t *r = (const uint8_t *) c->table_rV[V],
848 *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
849 *b = (const uint8_t *) c->table_bU[U];
851 dest[ 0] = dest[ 1] = r_b[Y1];
852 dest[ 2] = dest[ 3] = g[Y1];
853 dest[ 4] = dest[ 5] = b_r[Y1];
854 dest[ 6] = dest[ 7] = r_b[Y2];
855 dest[ 8] = dest[ 9] = g[Y2];
856 dest[10] = dest[11] = b_r[Y2];
860 for (i = 0; i < (dstW >> 1); i++) {
861 int Y1 = buf0[i * 2] >> 7;
862 int Y2 = buf0[i * 2 + 1] >> 7;
863 int U = (ubuf0[i] + ubuf1[i]) >> 8;
864 int V = (vbuf0[i] + vbuf1[i]) >> 8;
865 const uint8_t *r = (const uint8_t *) c->table_rV[V],
866 *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
867 *b = (const uint8_t *) c->table_bU[U];
869 dest[ 0] = dest[ 1] = r_b[Y1];
870 dest[ 2] = dest[ 3] = g[Y1];
871 dest[ 4] = dest[ 5] = b_r[Y1];
872 dest[ 6] = dest[ 7] = r_b[Y2];
873 dest[ 8] = dest[ 9] = g[Y2];
874 dest[10] = dest[11] = b_r[Y2];
883 YUV2PACKEDWRAPPER(yuv2, rgb48, rgb48be, PIX_FMT_RGB48BE);
884 //YUV2PACKEDWRAPPER(yuv2, rgb48, rgb48le, PIX_FMT_RGB48LE);
885 YUV2PACKEDWRAPPER(yuv2, rgb48, bgr48be, PIX_FMT_BGR48BE);
886 //YUV2PACKEDWRAPPER(yuv2, rgb48, bgr48le, PIX_FMT_BGR48LE);
888 #define YSCALE_YUV_2_RGBX_C(type,alpha) \
889 for (i=0; i<(dstW>>1); i++) {\
895 int av_unused A1, A2;\
896 type av_unused *r, *b, *g;\
899 for (j=0; j<lumFilterSize; j++) {\
900 Y1 += lumSrc[j][i2] * lumFilter[j];\
901 Y2 += lumSrc[j][i2+1] * lumFilter[j];\
903 for (j=0; j<chrFilterSize; j++) {\
904 U += chrUSrc[j][i] * chrFilter[j];\
905 V += chrVSrc[j][i] * chrFilter[j];\
911 if ((Y1|Y2|U|V)&0x100) {\
912 Y1 = av_clip_uint8(Y1); \
913 Y2 = av_clip_uint8(Y2); \
914 U = av_clip_uint8(U); \
915 V = av_clip_uint8(V); \
920 for (j=0; j<lumFilterSize; j++) {\
921 A1 += alpSrc[j][i2 ] * lumFilter[j];\
922 A2 += alpSrc[j][i2+1] * lumFilter[j];\
926 if ((A1|A2)&0x100) {\
927 A1 = av_clip_uint8(A1); \
928 A2 = av_clip_uint8(A2); \
931 /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/\
932 r = (type *)c->table_rV[V]; \
933 g = (type *)(c->table_gU[U] + c->table_gV[V]); \
934 b = (type *)c->table_bU[U];
936 #define YSCALE_YUV_2_RGBX_FULL_C(rnd,alpha) \
937 for (i=0; i<dstW; i++) {\
945 for (j=0; j<lumFilterSize; j++) {\
946 Y += lumSrc[j][i ] * lumFilter[j];\
948 for (j=0; j<chrFilterSize; j++) {\
949 U += chrUSrc[j][i] * chrFilter[j];\
950 V += chrVSrc[j][i] * chrFilter[j];\
957 for (j=0; j<lumFilterSize; j++)\
958 A += alpSrc[j][i ] * lumFilter[j];\
961 A = av_clip_uint8(A);\
963 Y-= c->yuv2rgb_y_offset;\
964 Y*= c->yuv2rgb_y_coeff;\
966 R= Y + V*c->yuv2rgb_v2r_coeff;\
967 G= Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;\
968 B= Y + U*c->yuv2rgb_u2b_coeff;\
969 if ((R|G|B)&(0xC0000000)) {\
970 R = av_clip_uintp2(R, 30); \
971 G = av_clip_uintp2(G, 30); \
972 B = av_clip_uintp2(B, 30); \
975 #define YSCALE_YUV_2_RGB2_C(type,alpha) \
976 for (i=0; i<(dstW>>1); i++) { \
978 int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>19; \
979 int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19; \
980 int U= (ubuf0[i]*uvalpha1+ubuf1[i]*uvalpha)>>19; \
981 int V= (vbuf0[i]*uvalpha1+vbuf1[i]*uvalpha)>>19; \
982 type av_unused *r, *b, *g; \
983 int av_unused A1, A2; \
985 A1= (abuf0[i2 ]*yalpha1+abuf1[i2 ]*yalpha)>>19; \
986 A2= (abuf0[i2+1]*yalpha1+abuf1[i2+1]*yalpha)>>19; \
988 r = (type *)c->table_rV[V];\
989 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
990 b = (type *)c->table_bU[U];
992 #define YSCALE_YUV_2_RGB1_C(type,alpha) \
993 for (i=0; i<(dstW>>1); i++) {\
995 int Y1= buf0[i2 ]>>7;\
996 int Y2= buf0[i2+1]>>7;\
997 int U= (ubuf1[i])>>7;\
998 int V= (vbuf1[i])>>7;\
999 type av_unused *r, *b, *g;\
1000 int av_unused A1, A2;\
1003 A2= abuf0[i2+1]>>7;\
1005 r = (type *)c->table_rV[V];\
1006 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
1007 b = (type *)c->table_bU[U];
1009 #define YSCALE_YUV_2_RGB1B_C(type,alpha) \
1010 for (i=0; i<(dstW>>1); i++) {\
1012 int Y1= buf0[i2 ]>>7;\
1013 int Y2= buf0[i2+1]>>7;\
1014 int U= (ubuf0[i] + ubuf1[i])>>8;\
1015 int V= (vbuf0[i] + vbuf1[i])>>8;\
1016 type av_unused *r, *b, *g;\
1017 int av_unused A1, A2;\
1020 A2= abuf0[i2+1]>>7;\
1022 r = (type *)c->table_rV[V];\
1023 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
1024 b = (type *)c->table_bU[U];
1026 #define YSCALE_YUV_2_ANYRGB_C(func)\
1027 switch(c->dstFormat) {\
1030 if (CONFIG_SMALL) {\
1031 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
1032 func(uint32_t,needAlpha)\
1033 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? (A1<<24) : 0);\
1034 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? (A2<<24) : 0);\
1037 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
1039 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (A1<<24);\
1040 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (A2<<24);\
1044 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
1045 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
1052 if (CONFIG_SMALL) {\
1053 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
1054 func(uint32_t,needAlpha)\
1055 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? A1 : 0);\
1056 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? A2 : 0);\
1059 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
1061 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + A1;\
1062 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + A2;\
1066 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
1067 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
1072 case PIX_FMT_RGB24:\
1074 ((uint8_t*)dest)[0]= r[Y1];\
1075 ((uint8_t*)dest)[1]= g[Y1];\
1076 ((uint8_t*)dest)[2]= b[Y1];\
1077 ((uint8_t*)dest)[3]= r[Y2];\
1078 ((uint8_t*)dest)[4]= g[Y2];\
1079 ((uint8_t*)dest)[5]= b[Y2];\
1083 case PIX_FMT_BGR24:\
1085 ((uint8_t*)dest)[0]= b[Y1];\
1086 ((uint8_t*)dest)[1]= g[Y1];\
1087 ((uint8_t*)dest)[2]= r[Y1];\
1088 ((uint8_t*)dest)[3]= b[Y2];\
1089 ((uint8_t*)dest)[4]= g[Y2];\
1090 ((uint8_t*)dest)[5]= r[Y2];\
1094 case PIX_FMT_RGB565:\
1095 case PIX_FMT_BGR565:\
1097 const int dr1= dither_2x2_8[y&1 ][0];\
1098 const int dg1= dither_2x2_4[y&1 ][0];\
1099 const int db1= dither_2x2_8[(y&1)^1][0];\
1100 const int dr2= dither_2x2_8[y&1 ][1];\
1101 const int dg2= dither_2x2_4[y&1 ][1];\
1102 const int db2= dither_2x2_8[(y&1)^1][1];\
1104 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
1105 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
1109 case PIX_FMT_RGB555:\
1110 case PIX_FMT_BGR555:\
1112 const int dr1= dither_2x2_8[y&1 ][0];\
1113 const int dg1= dither_2x2_8[y&1 ][1];\
1114 const int db1= dither_2x2_8[(y&1)^1][0];\
1115 const int dr2= dither_2x2_8[y&1 ][1];\
1116 const int dg2= dither_2x2_8[y&1 ][0];\
1117 const int db2= dither_2x2_8[(y&1)^1][1];\
1119 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
1120 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
1124 case PIX_FMT_RGB444:\
1125 case PIX_FMT_BGR444:\
1127 const int dr1= dither_4x4_16[y&3 ][0];\
1128 const int dg1= dither_4x4_16[y&3 ][1];\
1129 const int db1= dither_4x4_16[(y&3)^3][0];\
1130 const int dr2= dither_4x4_16[y&3 ][1];\
1131 const int dg2= dither_4x4_16[y&3 ][0];\
1132 const int db2= dither_4x4_16[(y&3)^3][1];\
1134 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
1135 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
1142 const uint8_t * const d64= dither_8x8_73[y&7];\
1143 const uint8_t * const d32= dither_8x8_32[y&7];\
1145 ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];\
1146 ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];\
1153 const uint8_t * const d64= dither_8x8_73 [y&7];\
1154 const uint8_t * const d128=dither_8x8_220[y&7];\
1156 ((uint8_t*)dest)[i]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]]\
1157 + ((r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]])<<4);\
1161 case PIX_FMT_RGB4_BYTE:\
1162 case PIX_FMT_BGR4_BYTE:\
1164 const uint8_t * const d64= dither_8x8_73 [y&7];\
1165 const uint8_t * const d128=dither_8x8_220[y&7];\
1167 ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];\
1168 ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];\
1174 static void yuv2packedX_c(SwsContext *c, const int16_t *lumFilter,
1175 const int16_t **lumSrc, int lumFilterSize,
1176 const int16_t *chrFilter, const int16_t **chrUSrc,
1177 const int16_t **chrVSrc, int chrFilterSize,
1178 const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
1181 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C)
1184 static void yuv2rgbX_c_full(SwsContext *c, const int16_t *lumFilter,
1185 const int16_t **lumSrc, int lumFilterSize,
1186 const int16_t *chrFilter, const int16_t **chrUSrc,
1187 const int16_t **chrVSrc, int chrFilterSize,
1188 const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
1191 int step= c->dstFormatBpp/8;
1194 switch(c->dstFormat) {
1202 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
1203 YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
1204 dest[aidx]= needAlpha ? A : 255;
1211 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
1212 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
1220 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
1237 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
1238 YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
1239 dest[aidx]= needAlpha ? A : 255;
1246 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
1247 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
1255 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
1271 * vertical bilinear scale YV12 to RGB
1273 static void yuv2packed2_c(SwsContext *c, const uint16_t *buf0,
1274 const uint16_t *buf1, const uint16_t *ubuf0,
1275 const uint16_t *ubuf1, const uint16_t *vbuf0,
1276 const uint16_t *vbuf1, const uint16_t *abuf0,
1277 const uint16_t *abuf1, uint8_t *dest, int dstW,
1278 int yalpha, int uvalpha, int y)
1280 int yalpha1=4095- yalpha;
1281 int uvalpha1=4095-uvalpha;
1284 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C)
1288 * YV12 to RGB without scaling or interpolating
1290 static void yuv2packed1_c(SwsContext *c, const uint16_t *buf0,
1291 const uint16_t *ubuf0, const uint16_t *ubuf1,
1292 const uint16_t *vbuf0, const uint16_t *vbuf1,
1293 const uint16_t *abuf0, uint8_t *dest, int dstW,
1294 int uvalpha, enum PixelFormat dstFormat,
1299 if (uvalpha < 2048) {
1300 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C)
1302 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C)
1306 static av_always_inline void fillPlane(uint8_t* plane, int stride,
1307 int width, int height,
1311 uint8_t *ptr = plane + stride*y;
1312 for (i=0; i<height; i++) {
1313 memset(ptr, val, width);
1318 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1320 #define r ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? b_r : r_b)
1321 #define b ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? r_b : b_r)
1323 static av_always_inline void
1324 rgb48ToY_c_template(uint8_t *dst, const uint8_t *src, int width,
1325 enum PixelFormat origin)
1328 for (i = 0; i < width; i++) {
1329 int r_b = input_pixel(&src[i*6+0]) >> 8;
1330 int g = input_pixel(&src[i*6+2]) >> 8;
1331 int b_r = input_pixel(&src[i*6+4]) >> 8;
1333 dst[i] = (RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1337 static av_always_inline void
1338 rgb48ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
1339 const uint8_t *src1, const uint8_t *src2,
1340 int width, enum PixelFormat origin)
1344 for (i = 0; i < width; i++) {
1345 int r_b = input_pixel(&src1[i*6+0]) >> 8;
1346 int g = input_pixel(&src1[i*6+2]) >> 8;
1347 int b_r = input_pixel(&src1[i*6+4]) >> 8;
1349 dstU[i] = (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1350 dstV[i] = (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
1354 static av_always_inline void
1355 rgb48ToUV_half_c_template(uint8_t *dstU, uint8_t *dstV,
1356 const uint8_t *src1, const uint8_t *src2,
1357 int width, enum PixelFormat origin)
1361 for (i = 0; i < width; i++) {
1362 int r_b = (input_pixel(&src1[12*i + 0]) >> 8) + (input_pixel(&src1[12*i + 6]) >> 8);
1363 int g = (input_pixel(&src1[12*i + 2]) >> 8) + (input_pixel(&src1[12*i + 8]) >> 8);
1364 int b_r = (input_pixel(&src1[12*i + 4]) >> 8) + (input_pixel(&src1[12*i + 10]) >> 8);
1366 dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
1367 dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
1375 #define rgb48funcs(pattern, BE_LE, origin) \
1376 static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *dst, const uint8_t *src, \
1377 int width, uint32_t *unused) \
1379 rgb48ToY_c_template(dst, src, width, origin); \
1382 static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1383 const uint8_t *src1, const uint8_t *src2, \
1384 int width, uint32_t *unused) \
1386 rgb48ToUV_c_template(dstU, dstV, src1, src2, width, origin); \
1389 static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
1390 const uint8_t *src1, const uint8_t *src2, \
1391 int width, uint32_t *unused) \
1393 rgb48ToUV_half_c_template(dstU, dstV, src1, src2, width, origin); \
1396 rgb48funcs(rgb, LE, PIX_FMT_RGB48LE);
1397 rgb48funcs(rgb, BE, PIX_FMT_RGB48BE);
1398 rgb48funcs(bgr, LE, PIX_FMT_BGR48LE);
1399 rgb48funcs(bgr, BE, PIX_FMT_BGR48BE);
1401 #define input_pixel(i) ((origin == PIX_FMT_RGBA || origin == PIX_FMT_BGRA || \
1402 origin == PIX_FMT_ARGB || origin == PIX_FMT_ABGR) ? AV_RN32A(&src[(i)*4]) : \
1403 (isBE(origin) ? AV_RB16(&src[(i)*2]) : AV_RL16(&src[(i)*2])))
1405 static av_always_inline void
1406 rgb16_32ToY_c_template(uint8_t *dst, const uint8_t *src,
1407 int width, enum PixelFormat origin,
1408 int shr, int shg, int shb, int shp,
1409 int maskr, int maskg, int maskb,
1410 int rsh, int gsh, int bsh, int S)
1412 const int ry = RY << rsh, gy = GY << gsh, by = BY << bsh,
1413 rnd = 33 << (S - 1);
1416 for (i = 0; i < width; i++) {
1417 int px = input_pixel(i) >> shp;
1418 int b = (px & maskb) >> shb;
1419 int g = (px & maskg) >> shg;
1420 int r = (px & maskr) >> shr;
1422 dst[i] = (ry * r + gy * g + by * b + rnd) >> S;
1426 static av_always_inline void
1427 rgb16_32ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
1428 const uint8_t *src, int width,
1429 enum PixelFormat origin,
1430 int shr, int shg, int shb, int shp,
1431 int maskr, int maskg, int maskb,
1432 int rsh, int gsh, int bsh, int S)
1434 const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1435 rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1436 rnd = 257 << (S - 1);
1439 for (i = 0; i < width; i++) {
1440 int px = input_pixel(i) >> shp;
1441 int b = (px & maskb) >> shb;
1442 int g = (px & maskg) >> shg;
1443 int r = (px & maskr) >> shr;
1445 dstU[i] = (ru * r + gu * g + bu * b + rnd) >> S;
1446 dstV[i] = (rv * r + gv * g + bv * b + rnd) >> S;
1450 static av_always_inline void
1451 rgb16_32ToUV_half_c_template(uint8_t *dstU, uint8_t *dstV,
1452 const uint8_t *src, int width,
1453 enum PixelFormat origin,
1454 int shr, int shg, int shb, int shp,
1455 int maskr, int maskg, int maskb,
1456 int rsh, int gsh, int bsh, int S)
1458 const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1459 rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1460 rnd = 257 << S, maskgx = ~(maskr | maskb);
1463 maskr |= maskr << 1; maskb |= maskb << 1; maskg |= maskg << 1;
1464 for (i = 0; i < width; i++) {
1465 int px0 = input_pixel(2 * i + 0) >> shp;
1466 int px1 = input_pixel(2 * i + 1) >> shp;
1467 int b, r, g = (px0 & maskgx) + (px1 & maskgx);
1468 int rb = px0 + px1 - g;
1470 b = (rb & maskb) >> shb;
1471 if (shp || origin == PIX_FMT_BGR565LE || origin == PIX_FMT_BGR565BE ||
1472 origin == PIX_FMT_RGB565LE || origin == PIX_FMT_RGB565BE) {
1475 g = (g & maskg) >> shg;
1477 r = (rb & maskr) >> shr;
1479 dstU[i] = (ru * r + gu * g + bu * b + rnd) >> (S + 1);
1480 dstV[i] = (rv * r + gv * g + bv * b + rnd) >> (S + 1);
1486 #define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr, \
1487 maskg, maskb, rsh, gsh, bsh, S) \
1488 static void name ## ToY_c(uint8_t *dst, const uint8_t *src, \
1489 int width, uint32_t *unused) \
1491 rgb16_32ToY_c_template(dst, src, width, fmt, shr, shg, shb, shp, \
1492 maskr, maskg, maskb, rsh, gsh, bsh, S); \
1495 static void name ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1496 const uint8_t *src, const uint8_t *dummy, \
1497 int width, uint32_t *unused) \
1499 rgb16_32ToUV_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1500 maskr, maskg, maskb, rsh, gsh, bsh, S); \
1503 static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
1504 const uint8_t *src, const uint8_t *dummy, \
1505 int width, uint32_t *unused) \
1507 rgb16_32ToUV_half_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1508 maskr, maskg, maskb, rsh, gsh, bsh, S); \
1511 rgb16_32_wrapper(PIX_FMT_BGR32, bgr32, 16, 0, 0, 0, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8);
1512 rgb16_32_wrapper(PIX_FMT_BGR32_1, bgr321, 16, 0, 0, 8, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8);
1513 rgb16_32_wrapper(PIX_FMT_RGB32, rgb32, 0, 0, 16, 0, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8);
1514 rgb16_32_wrapper(PIX_FMT_RGB32_1, rgb321, 0, 0, 16, 8, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8);
1515 rgb16_32_wrapper(PIX_FMT_BGR565LE, bgr16le, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8);
1516 rgb16_32_wrapper(PIX_FMT_BGR555LE, bgr15le, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7);
1517 rgb16_32_wrapper(PIX_FMT_RGB565LE, rgb16le, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8);
1518 rgb16_32_wrapper(PIX_FMT_RGB555LE, rgb15le, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7);
1519 rgb16_32_wrapper(PIX_FMT_BGR565BE, bgr16be, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8);
1520 rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr15be, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7);
1521 rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8);
1522 rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7);
1524 static void abgrToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
1527 for (i=0; i<width; i++) {
1532 static void rgbaToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
1535 for (i=0; i<width; i++) {
1540 static void palToY_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *pal)
1543 for (i=0; i<width; i++) {
1546 dst[i]= pal[d] & 0xFF;
1550 static void palToUV_c(uint8_t *dstU, uint8_t *dstV,
1551 const uint8_t *src1, const uint8_t *src2,
1552 int width, uint32_t *pal)
1555 assert(src1 == src2);
1556 for (i=0; i<width; i++) {
1557 int p= pal[src1[i]];
1564 static void monowhite2Y_c(uint8_t *dst, const uint8_t *src,
1565 int width, uint32_t *unused)
1568 for (i=0; i<width/8; i++) {
1571 dst[8*i+j]= ((d>>(7-j))&1)*255;
1575 static void monoblack2Y_c(uint8_t *dst, const uint8_t *src,
1576 int width, uint32_t *unused)
1579 for (i=0; i<width/8; i++) {
1582 dst[8*i+j]= ((d>>(7-j))&1)*255;
1586 //FIXME yuy2* can read up to 7 samples too much
1588 static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, int width,
1592 for (i=0; i<width; i++)
1596 static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1597 const uint8_t *src2, int width, uint32_t *unused)
1600 for (i=0; i<width; i++) {
1601 dstU[i]= src1[4*i + 1];
1602 dstV[i]= src1[4*i + 3];
1604 assert(src1 == src2);
1607 static void LEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1608 const uint8_t *src2, int width, uint32_t *unused)
1611 for (i=0; i<width; i++) {
1612 dstU[i]= src1[2*i + 1];
1613 dstV[i]= src2[2*i + 1];
1617 /* This is almost identical to the previous, end exists only because
1618 * yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
1619 static void uyvyToY_c(uint8_t *dst, const uint8_t *src, int width,
1623 for (i=0; i<width; i++)
1627 static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1628 const uint8_t *src2, int width, uint32_t *unused)
1631 for (i=0; i<width; i++) {
1632 dstU[i]= src1[4*i + 0];
1633 dstV[i]= src1[4*i + 2];
1635 assert(src1 == src2);
1638 static void BEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1639 const uint8_t *src2, int width, uint32_t *unused)
1642 for (i=0; i<width; i++) {
1648 static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
1649 const uint8_t *src, int width)
1652 for (i = 0; i < width; i++) {
1653 dst1[i] = src[2*i+0];
1654 dst2[i] = src[2*i+1];
1658 static void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
1659 const uint8_t *src1, const uint8_t *src2,
1660 int width, uint32_t *unused)
1662 nvXXtoUV_c(dstU, dstV, src1, width);
1665 static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
1666 const uint8_t *src1, const uint8_t *src2,
1667 int width, uint32_t *unused)
1669 nvXXtoUV_c(dstV, dstU, src1, width);
1672 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1674 // FIXME Maybe dither instead.
1675 static av_always_inline void
1676 yuv9_OR_10ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
1677 const uint8_t *_srcU, const uint8_t *_srcV,
1678 int width, enum PixelFormat origin, int depth)
1681 const uint16_t *srcU = (const uint16_t *) _srcU;
1682 const uint16_t *srcV = (const uint16_t *) _srcV;
1684 for (i = 0; i < width; i++) {
1685 dstU[i] = input_pixel(&srcU[i]) >> (depth - 8);
1686 dstV[i] = input_pixel(&srcV[i]) >> (depth - 8);
1690 static av_always_inline void
1691 yuv9_or_10ToY_c_template(uint8_t *dstY, const uint8_t *_srcY,
1692 int width, enum PixelFormat origin, int depth)
1695 const uint16_t *srcY = (const uint16_t*)_srcY;
1697 for (i = 0; i < width; i++)
1698 dstY[i] = input_pixel(&srcY[i]) >> (depth - 8);
1703 #define YUV_NBPS(depth, BE_LE, origin) \
1704 static void BE_LE ## depth ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1705 const uint8_t *srcU, const uint8_t *srcV, \
1706 int width, uint32_t *unused) \
1708 yuv9_OR_10ToUV_c_template(dstU, dstV, srcU, srcV, width, origin, depth); \
1710 static void BE_LE ## depth ## ToY_c(uint8_t *dstY, const uint8_t *srcY, \
1711 int width, uint32_t *unused) \
1713 yuv9_or_10ToY_c_template(dstY, srcY, width, origin, depth); \
1716 YUV_NBPS( 9, LE, PIX_FMT_YUV420P9LE);
1717 YUV_NBPS( 9, BE, PIX_FMT_YUV420P9BE);
1718 YUV_NBPS(10, LE, PIX_FMT_YUV420P10LE);
1719 YUV_NBPS(10, BE, PIX_FMT_YUV420P10BE);
1721 static void bgr24ToY_c(uint8_t *dst, const uint8_t *src,
1722 int width, uint32_t *unused)
1725 for (i=0; i<width; i++) {
1730 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
1734 static void bgr24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1735 const uint8_t *src2, int width, uint32_t *unused)
1738 for (i=0; i<width; i++) {
1739 int b= src1[3*i + 0];
1740 int g= src1[3*i + 1];
1741 int r= src1[3*i + 2];
1743 dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
1744 dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
1746 assert(src1 == src2);
1749 static void bgr24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1750 const uint8_t *src2, int width, uint32_t *unused)
1753 for (i=0; i<width; i++) {
1754 int b= src1[6*i + 0] + src1[6*i + 3];
1755 int g= src1[6*i + 1] + src1[6*i + 4];
1756 int r= src1[6*i + 2] + src1[6*i + 5];
1758 dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1759 dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1761 assert(src1 == src2);
1764 static void rgb24ToY_c(uint8_t *dst, const uint8_t *src, int width,
1768 for (i=0; i<width; i++) {
1773 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
1777 static void rgb24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1778 const uint8_t *src2, int width, uint32_t *unused)
1782 for (i=0; i<width; i++) {
1783 int r= src1[3*i + 0];
1784 int g= src1[3*i + 1];
1785 int b= src1[3*i + 2];
1787 dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
1788 dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
1792 static void rgb24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1793 const uint8_t *src2, int width, uint32_t *unused)
1797 for (i=0; i<width; i++) {
1798 int r= src1[6*i + 0] + src1[6*i + 3];
1799 int g= src1[6*i + 1] + src1[6*i + 4];
1800 int b= src1[6*i + 2] + src1[6*i + 5];
1802 dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1803 dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1808 // bilinear / bicubic scaling
1809 static void hScale_c(int16_t *dst, int dstW, const uint8_t *src,
1811 const int16_t *filter, const int16_t *filterPos,
1815 for (i=0; i<dstW; i++) {
1817 int srcPos= filterPos[i];
1819 for (j=0; j<filterSize; j++) {
1820 val += ((int)src[srcPos + j])*filter[filterSize*i + j];
1822 //filter += hFilterSize;
1823 dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
1828 //FIXME all pal and rgb srcFormats could do this convertion as well
1829 //FIXME all scalers more complex than bilinear could do half of this transform
1830 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1833 for (i = 0; i < width; i++) {
1834 dstU[i] = (FFMIN(dstU[i],30775)*4663 - 9289992)>>12; //-264
1835 dstV[i] = (FFMIN(dstV[i],30775)*4663 - 9289992)>>12; //-264
1838 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1841 for (i = 0; i < width; i++) {
1842 dstU[i] = (dstU[i]*1799 + 4081085)>>11; //1469
1843 dstV[i] = (dstV[i]*1799 + 4081085)>>11; //1469
1846 static void lumRangeToJpeg_c(int16_t *dst, int width)
1849 for (i = 0; i < width; i++)
1850 dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
1852 static void lumRangeFromJpeg_c(int16_t *dst, int width)
1855 for (i = 0; i < width; i++)
1856 dst[i] = (dst[i]*14071 + 33561947)>>14;
1859 static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
1860 const uint8_t *src, int srcW, int xInc)
1863 unsigned int xpos=0;
1864 for (i=0;i<dstWidth;i++) {
1865 register unsigned int xx=xpos>>16;
1866 register unsigned int xalpha=(xpos&0xFFFF)>>9;
1867 dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
1872 // *** horizontal scale Y line to temp buffer
1873 static av_always_inline void hyscale(SwsContext *c, uint16_t *dst, int dstWidth,
1874 const uint8_t *src, int srcW, int xInc,
1875 const int16_t *hLumFilter,
1876 const int16_t *hLumFilterPos, int hLumFilterSize,
1877 uint8_t *formatConvBuffer,
1878 uint32_t *pal, int isAlpha)
1880 void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
1881 void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
1884 toYV12(formatConvBuffer, src, srcW, pal);
1885 src= formatConvBuffer;
1888 if (!c->hyscale_fast) {
1889 c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
1890 } else { // fast bilinear upscale / crap downscale
1891 c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
1895 convertRange(dst, dstWidth);
1898 static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
1899 int dstWidth, const uint8_t *src1,
1900 const uint8_t *src2, int srcW, int xInc)
1903 unsigned int xpos=0;
1904 for (i=0;i<dstWidth;i++) {
1905 register unsigned int xx=xpos>>16;
1906 register unsigned int xalpha=(xpos&0xFFFF)>>9;
1907 dst1[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
1908 dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
1913 static av_always_inline void hcscale(SwsContext *c, uint16_t *dst1, uint16_t *dst2, int dstWidth,
1914 const uint8_t *src1, const uint8_t *src2,
1915 int srcW, int xInc, const int16_t *hChrFilter,
1916 const int16_t *hChrFilterPos, int hChrFilterSize,
1917 uint8_t *formatConvBuffer, uint32_t *pal)
1920 uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW, 16);
1921 c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
1922 src1= formatConvBuffer;
1926 if (!c->hcscale_fast) {
1927 c->hScale(dst1, dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
1928 c->hScale(dst2, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
1929 } else { // fast bilinear upscale / crap downscale
1930 c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc);
1933 if (c->chrConvertRange)
1934 c->chrConvertRange(dst1, dst2, dstWidth);
1937 static av_always_inline void
1938 find_c_packed_planar_out_funcs(SwsContext *c,
1939 yuv2planar1_fn *yuv2yuv1, yuv2planarX_fn *yuv2yuvX,
1940 yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2,
1941 yuv2packedX_fn *yuv2packedX)
1943 enum PixelFormat dstFormat = c->dstFormat;
1945 if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
1946 *yuv2yuvX = yuv2nv12X_c;
1947 } else if (is16BPS(dstFormat)) {
1948 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX16BE_c : yuv2yuvX16LE_c;
1949 } else if (is9_OR_10BPS(dstFormat)) {
1950 if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
1951 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c : yuv2yuvX9LE_c;
1953 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c;
1956 *yuv2yuv1 = yuv2yuv1_c;
1957 *yuv2yuvX = yuv2yuvX_c;
1959 if(c->flags & SWS_FULL_CHR_H_INT) {
1960 *yuv2packedX = yuv2rgbX_c_full;
1962 switch (dstFormat) {
1963 case PIX_FMT_GRAY16BE:
1964 *yuv2packed1 = yuv2gray16BE_1_c;
1965 *yuv2packed2 = yuv2gray16BE_2_c;
1966 *yuv2packedX = yuv2gray16BE_X_c;
1968 case PIX_FMT_GRAY16LE:
1969 *yuv2packed1 = yuv2gray16LE_1_c;
1970 *yuv2packed2 = yuv2gray16LE_2_c;
1971 *yuv2packedX = yuv2gray16LE_X_c;
1973 case PIX_FMT_MONOWHITE:
1974 *yuv2packed1 = yuv2monowhite_1_c;
1975 *yuv2packed2 = yuv2monowhite_2_c;
1976 *yuv2packedX = yuv2monowhite_X_c;
1978 case PIX_FMT_MONOBLACK:
1979 *yuv2packed1 = yuv2monoblack_1_c;
1980 *yuv2packed2 = yuv2monoblack_2_c;
1981 *yuv2packedX = yuv2monoblack_X_c;
1983 case PIX_FMT_YUYV422:
1984 *yuv2packed1 = yuv2yuyv422_1_c;
1985 *yuv2packed2 = yuv2yuyv422_2_c;
1986 *yuv2packedX = yuv2yuyv422_X_c;
1988 case PIX_FMT_UYVY422:
1989 *yuv2packed1 = yuv2uyvy422_1_c;
1990 *yuv2packed2 = yuv2uyvy422_2_c;
1991 *yuv2packedX = yuv2uyvy422_X_c;
1993 case PIX_FMT_RGB48LE:
1994 //*yuv2packed1 = yuv2rgb48le_1_c;
1995 //*yuv2packed2 = yuv2rgb48le_2_c;
1996 //*yuv2packedX = yuv2rgb48le_X_c;
1998 case PIX_FMT_RGB48BE:
1999 *yuv2packed1 = yuv2rgb48be_1_c;
2000 *yuv2packed2 = yuv2rgb48be_2_c;
2001 *yuv2packedX = yuv2rgb48be_X_c;
2003 case PIX_FMT_BGR48LE:
2004 //*yuv2packed1 = yuv2bgr48le_1_c;
2005 //*yuv2packed2 = yuv2bgr48le_2_c;
2006 //*yuv2packedX = yuv2bgr48le_X_c;
2008 case PIX_FMT_BGR48BE:
2009 *yuv2packed1 = yuv2bgr48be_1_c;
2010 *yuv2packed2 = yuv2bgr48be_2_c;
2011 *yuv2packedX = yuv2bgr48be_X_c;
2014 *yuv2packed1 = yuv2packed1_c;
2015 *yuv2packed2 = yuv2packed2_c;
2016 *yuv2packedX = yuv2packedX_c;
2022 #define DEBUG_SWSCALE_BUFFERS 0
2023 #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
2025 static int swScale(SwsContext *c, const uint8_t* src[],
2026 int srcStride[], int srcSliceY,
2027 int srcSliceH, uint8_t* dst[], int dstStride[])
2029 /* load a few things into local vars to make the code more readable? and faster */
2030 const int srcW= c->srcW;
2031 const int dstW= c->dstW;
2032 const int dstH= c->dstH;
2033 const int chrDstW= c->chrDstW;
2034 const int chrSrcW= c->chrSrcW;
2035 const int lumXInc= c->lumXInc;
2036 const int chrXInc= c->chrXInc;
2037 const enum PixelFormat dstFormat= c->dstFormat;
2038 const int flags= c->flags;
2039 int16_t *vLumFilterPos= c->vLumFilterPos;
2040 int16_t *vChrFilterPos= c->vChrFilterPos;
2041 int16_t *hLumFilterPos= c->hLumFilterPos;
2042 int16_t *hChrFilterPos= c->hChrFilterPos;
2043 int16_t *vLumFilter= c->vLumFilter;
2044 int16_t *vChrFilter= c->vChrFilter;
2045 int16_t *hLumFilter= c->hLumFilter;
2046 int16_t *hChrFilter= c->hChrFilter;
2047 int32_t *lumMmxFilter= c->lumMmxFilter;
2048 int32_t *chrMmxFilter= c->chrMmxFilter;
2049 int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
2050 const int vLumFilterSize= c->vLumFilterSize;
2051 const int vChrFilterSize= c->vChrFilterSize;
2052 const int hLumFilterSize= c->hLumFilterSize;
2053 const int hChrFilterSize= c->hChrFilterSize;
2054 int16_t **lumPixBuf= c->lumPixBuf;
2055 int16_t **chrUPixBuf= c->chrUPixBuf;
2056 int16_t **chrVPixBuf= c->chrVPixBuf;
2057 int16_t **alpPixBuf= c->alpPixBuf;
2058 const int vLumBufSize= c->vLumBufSize;
2059 const int vChrBufSize= c->vChrBufSize;
2060 uint8_t *formatConvBuffer= c->formatConvBuffer;
2061 const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
2062 const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
2064 uint32_t *pal=c->pal_yuv;
2065 yuv2planar1_fn yuv2yuv1 = c->yuv2yuv1;
2066 yuv2planarX_fn yuv2yuvX = c->yuv2yuvX;
2067 yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
2068 yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
2069 yuv2packedX_fn yuv2packedX = c->yuv2packedX;
2071 /* vars which will change and which we need to store back in the context */
2073 int lumBufIndex= c->lumBufIndex;
2074 int chrBufIndex= c->chrBufIndex;
2075 int lastInLumBuf= c->lastInLumBuf;
2076 int lastInChrBuf= c->lastInChrBuf;
2078 if (isPacked(c->srcFormat)) {
2086 srcStride[3]= srcStride[0];
2088 srcStride[1]<<= c->vChrDrop;
2089 srcStride[2]<<= c->vChrDrop;
2091 DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
2092 src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
2093 dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
2094 DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
2095 srcSliceY, srcSliceH, dstY, dstH);
2096 DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
2097 vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize);
2099 if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
2100 static int warnedAlready=0; //FIXME move this into the context perhaps
2101 if (flags & SWS_PRINT_INFO && !warnedAlready) {
2102 av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
2103 " ->cannot do aligned memory accesses anymore\n");
2108 /* Note the user might start scaling the picture in the middle so this
2109 will not get executed. This is not really intended but works
2110 currently, so people might do it. */
2111 if (srcSliceY ==0) {
2121 for (;dstY < dstH; dstY++) {
2122 unsigned char *dest =dst[0]+dstStride[0]*dstY;
2123 const int chrDstY= dstY>>c->chrDstVSubSample;
2124 unsigned char *uDest=dst[1]+dstStride[1]*chrDstY;
2125 unsigned char *vDest=dst[2]+dstStride[2]*chrDstY;
2126 unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL;
2128 const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
2129 const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
2130 const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
2131 int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
2132 int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
2133 int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
2136 //handle holes (FAST_BILINEAR & weird filters)
2137 if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
2138 if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
2139 assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
2140 assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
2142 DEBUG_BUFFERS("dstY: %d\n", dstY);
2143 DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
2144 firstLumSrcY, lastLumSrcY, lastInLumBuf);
2145 DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
2146 firstChrSrcY, lastChrSrcY, lastInChrBuf);
2148 // Do we have enough lines in this slice to output the dstY line
2149 enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
2151 if (!enough_lines) {
2152 lastLumSrcY = srcSliceY + srcSliceH - 1;
2153 lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
2154 DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
2155 lastLumSrcY, lastChrSrcY);
2158 //Do horizontal scaling
2159 while(lastInLumBuf < lastLumSrcY) {
2160 const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
2161 const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
2163 assert(lumBufIndex < 2*vLumBufSize);
2164 assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
2165 assert(lastInLumBuf + 1 - srcSliceY >= 0);
2166 hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
2167 hLumFilter, hLumFilterPos, hLumFilterSize,
2170 if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
2171 hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW,
2172 lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
2176 DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
2177 lumBufIndex, lastInLumBuf);
2179 while(lastInChrBuf < lastChrSrcY) {
2180 const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
2181 const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
2183 assert(chrBufIndex < 2*vChrBufSize);
2184 assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
2185 assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
2186 //FIXME replace parameters through context struct (some at least)
2188 if (c->needs_hcscale)
2189 hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
2190 chrDstW, src1, src2, chrSrcW, chrXInc,
2191 hChrFilter, hChrFilterPos, hChrFilterSize,
2192 formatConvBuffer, pal);
2194 DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
2195 chrBufIndex, lastInChrBuf);
2197 //wrap buf index around to stay inside the ring buffer
2198 if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
2199 if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
2201 break; //we can't output a dstY line so let's try with the next slice
2204 updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf);
2206 if (dstY >= dstH-2) {
2207 // hmm looks like we can't use MMX here without overwriting this array's tail
2208 find_c_packed_planar_out_funcs(c, &yuv2yuv1, &yuv2yuvX,
2209 &yuv2packed1, &yuv2packed2,
2214 const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
2215 const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2216 const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2217 const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
2218 if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
2219 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2220 if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
2221 if (c->yuv2yuv1 && vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
2222 const int16_t *lumBuf = lumSrcPtr[0];
2223 const int16_t *chrUBuf= chrUSrcPtr[0];
2224 const int16_t *chrVBuf= chrVSrcPtr[0];
2225 const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
2226 yuv2yuv1(c, lumBuf, chrUBuf, chrVBuf, alpBuf, dest,
2227 uDest, vDest, aDest, dstW, chrDstW);
2228 } else { //General YV12
2230 vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
2231 vChrFilter+chrDstY*vChrFilterSize, chrUSrcPtr,
2232 chrVSrcPtr, vChrFilterSize,
2233 alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW);
2236 assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
2237 assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize*2);
2238 if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
2239 int chrAlpha= vChrFilter[2*dstY+1];
2240 yuv2packed1(c, *lumSrcPtr, *chrUSrcPtr, *(chrUSrcPtr+1),
2241 *chrVSrcPtr, *(chrVSrcPtr+1),
2242 alpPixBuf ? *alpSrcPtr : NULL,
2243 dest, dstW, chrAlpha, dstFormat, flags, dstY);
2244 } else if (c->yuv2packed2 && vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
2245 int lumAlpha= vLumFilter[2*dstY+1];
2246 int chrAlpha= vChrFilter[2*dstY+1];
2248 lumMmxFilter[3]= vLumFilter[2*dstY ]*0x10001;
2250 chrMmxFilter[3]= vChrFilter[2*chrDstY]*0x10001;
2251 yuv2packed2(c, *lumSrcPtr, *(lumSrcPtr+1), *chrUSrcPtr, *(chrUSrcPtr+1),
2252 *chrVSrcPtr, *(chrVSrcPtr+1),
2253 alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *(alpSrcPtr+1) : NULL,
2254 dest, dstW, lumAlpha, chrAlpha, dstY);
2255 } else { //general RGB
2257 vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
2258 vChrFilter+dstY*vChrFilterSize, chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2259 alpSrcPtr, dest, dstW, dstY);
2265 if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
2266 fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
2269 if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2)
2270 __asm__ volatile("sfence":::"memory");
2274 /* store changed local vars back in the context */
2276 c->lumBufIndex= lumBufIndex;
2277 c->chrBufIndex= chrBufIndex;
2278 c->lastInLumBuf= lastInLumBuf;
2279 c->lastInChrBuf= lastInChrBuf;
2281 return dstY - lastDstY;
2284 static av_cold void sws_init_swScale_c(SwsContext *c)
2286 enum PixelFormat srcFormat = c->srcFormat;
2288 find_c_packed_planar_out_funcs(c, &c->yuv2yuv1, &c->yuv2yuvX,
2289 &c->yuv2packed1, &c->yuv2packed2,
2292 c->hScale = hScale_c;
2294 if (c->flags & SWS_FAST_BILINEAR) {
2295 c->hyscale_fast = hyscale_fast_c;
2296 c->hcscale_fast = hcscale_fast_c;
2299 c->chrToYV12 = NULL;
2301 case PIX_FMT_YUYV422 : c->chrToYV12 = yuy2ToUV_c; break;
2302 case PIX_FMT_UYVY422 : c->chrToYV12 = uyvyToUV_c; break;
2303 case PIX_FMT_NV12 : c->chrToYV12 = nv12ToUV_c; break;
2304 case PIX_FMT_NV21 : c->chrToYV12 = nv21ToUV_c; break;
2308 case PIX_FMT_BGR4_BYTE:
2309 case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
2310 case PIX_FMT_YUV444P9BE:
2311 case PIX_FMT_YUV420P9BE: c->chrToYV12 = BE9ToUV_c; break;
2312 case PIX_FMT_YUV444P9LE:
2313 case PIX_FMT_YUV420P9LE: c->chrToYV12 = LE9ToUV_c; break;
2314 case PIX_FMT_YUV444P10BE:
2315 case PIX_FMT_YUV422P10BE:
2316 case PIX_FMT_YUV420P10BE: c->chrToYV12 = BE10ToUV_c; break;
2317 case PIX_FMT_YUV422P10LE:
2318 case PIX_FMT_YUV444P10LE:
2319 case PIX_FMT_YUV420P10LE: c->chrToYV12 = LE10ToUV_c; break;
2320 case PIX_FMT_YUV420P16BE:
2321 case PIX_FMT_YUV422P16BE:
2322 case PIX_FMT_YUV444P16BE: c->chrToYV12 = BEToUV_c; break;
2323 case PIX_FMT_YUV420P16LE:
2324 case PIX_FMT_YUV422P16LE:
2325 case PIX_FMT_YUV444P16LE: c->chrToYV12 = LEToUV_c; break;
2327 if (c->chrSrcHSubSample) {
2329 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_half_c; break;
2330 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_half_c; break;
2331 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_half_c; break;
2332 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_half_c; break;
2333 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_half_c; break;
2334 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_half_c; break;
2335 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_half_c; break;
2336 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_half_c; break;
2337 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_half_c; break;
2338 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_half_c; break;
2339 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_half_c; break;
2340 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_half_c; break;
2341 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_half_c; break;
2342 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_half_c; break;
2343 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_half_c; break;
2344 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_half_c; break;
2345 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_half_c; break;
2346 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_half_c; break;
2350 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_c; break;
2351 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_c; break;
2352 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_c; break;
2353 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_c; break;
2354 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_c; break;
2355 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_c; break;
2356 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_c; break;
2357 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_c; break;
2358 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_c; break;
2359 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_c; break;
2360 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_c; break;
2361 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_c; break;
2362 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_c; break;
2363 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_c; break;
2364 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_c; break;
2365 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_c; break;
2366 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_c; break;
2367 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_c; break;
2371 c->lumToYV12 = NULL;
2372 c->alpToYV12 = NULL;
2373 switch (srcFormat) {
2374 case PIX_FMT_YUV444P9BE:
2375 case PIX_FMT_YUV420P9BE: c->lumToYV12 = BE9ToY_c; break;
2376 case PIX_FMT_YUV444P9LE:
2377 case PIX_FMT_YUV420P9LE: c->lumToYV12 = LE9ToY_c; break;
2378 case PIX_FMT_YUV444P10BE:
2379 case PIX_FMT_YUV422P10BE:
2380 case PIX_FMT_YUV420P10BE: c->lumToYV12 = BE10ToY_c; break;
2381 case PIX_FMT_YUV444P10LE:
2382 case PIX_FMT_YUV422P10LE:
2383 case PIX_FMT_YUV420P10LE: c->lumToYV12 = LE10ToY_c; break;
2384 case PIX_FMT_YUYV422 :
2385 case PIX_FMT_YUV420P16BE:
2386 case PIX_FMT_YUV422P16BE:
2387 case PIX_FMT_YUV444P16BE:
2388 case PIX_FMT_Y400A :
2389 case PIX_FMT_GRAY16BE : c->lumToYV12 = yuy2ToY_c; break;
2390 case PIX_FMT_UYVY422 :
2391 case PIX_FMT_YUV420P16LE:
2392 case PIX_FMT_YUV422P16LE:
2393 case PIX_FMT_YUV444P16LE:
2394 case PIX_FMT_GRAY16LE : c->lumToYV12 = uyvyToY_c; break;
2395 case PIX_FMT_BGR24 : c->lumToYV12 = bgr24ToY_c; break;
2396 case PIX_FMT_BGR565LE : c->lumToYV12 = bgr16leToY_c; break;
2397 case PIX_FMT_BGR565BE : c->lumToYV12 = bgr16beToY_c; break;
2398 case PIX_FMT_BGR555LE : c->lumToYV12 = bgr15leToY_c; break;
2399 case PIX_FMT_BGR555BE : c->lumToYV12 = bgr15beToY_c; break;
2400 case PIX_FMT_RGB24 : c->lumToYV12 = rgb24ToY_c; break;
2401 case PIX_FMT_RGB565LE : c->lumToYV12 = rgb16leToY_c; break;
2402 case PIX_FMT_RGB565BE : c->lumToYV12 = rgb16beToY_c; break;
2403 case PIX_FMT_RGB555LE : c->lumToYV12 = rgb15leToY_c; break;
2404 case PIX_FMT_RGB555BE : c->lumToYV12 = rgb15beToY_c; break;
2408 case PIX_FMT_BGR4_BYTE:
2409 case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY_c; break;
2410 case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y_c; break;
2411 case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y_c; break;
2412 case PIX_FMT_RGB32 : c->lumToYV12 = bgr32ToY_c; break;
2413 case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY_c; break;
2414 case PIX_FMT_BGR32 : c->lumToYV12 = rgb32ToY_c; break;
2415 case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY_c; break;
2416 case PIX_FMT_RGB48BE: c->lumToYV12 = rgb48BEToY_c; break;
2417 case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break;
2418 case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break;
2419 case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break;
2422 switch (srcFormat) {
2424 case PIX_FMT_RGBA: c->alpToYV12 = rgbaToA_c; break;
2426 case PIX_FMT_ARGB: c->alpToYV12 = abgrToA_c; break;
2427 case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
2431 if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
2433 c->lumConvertRange = lumRangeFromJpeg_c;
2434 c->chrConvertRange = chrRangeFromJpeg_c;
2436 c->lumConvertRange = lumRangeToJpeg_c;
2437 c->chrConvertRange = chrRangeToJpeg_c;
2441 if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
2442 srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE))
2443 c->needs_hcscale = 1;
2446 SwsFunc ff_getSwsFunc(SwsContext *c)
2448 sws_init_swScale_c(c);
2451 ff_sws_init_swScale_mmx(c);
2453 ff_sws_init_swScale_altivec(c);