2 * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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/avassert.h"
64 #include "libavutil/intreadwrite.h"
65 #include "libavutil/cpu.h"
66 #include "libavutil/avutil.h"
67 #include "libavutil/mathematics.h"
68 #include "libavutil/bswap.h"
69 #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 DECLARE_ALIGNED(8, const uint8_t, dithers)[8][8][8]={
199 { 0, 1, 0, 1, 0, 1, 0, 1,},
200 { 1, 0, 1, 0, 1, 0, 1, 0,},
201 { 0, 1, 0, 1, 0, 1, 0, 1,},
202 { 1, 0, 1, 0, 1, 0, 1, 0,},
203 { 0, 1, 0, 1, 0, 1, 0, 1,},
204 { 1, 0, 1, 0, 1, 0, 1, 0,},
205 { 0, 1, 0, 1, 0, 1, 0, 1,},
206 { 1, 0, 1, 0, 1, 0, 1, 0,},
208 { 1, 2, 1, 2, 1, 2, 1, 2,},
209 { 3, 0, 3, 0, 3, 0, 3, 0,},
210 { 1, 2, 1, 2, 1, 2, 1, 2,},
211 { 3, 0, 3, 0, 3, 0, 3, 0,},
212 { 1, 2, 1, 2, 1, 2, 1, 2,},
213 { 3, 0, 3, 0, 3, 0, 3, 0,},
214 { 1, 2, 1, 2, 1, 2, 1, 2,},
215 { 3, 0, 3, 0, 3, 0, 3, 0,},
217 { 2, 4, 3, 5, 2, 4, 3, 5,},
218 { 6, 0, 7, 1, 6, 0, 7, 1,},
219 { 3, 5, 2, 4, 3, 5, 2, 4,},
220 { 7, 1, 6, 0, 7, 1, 6, 0,},
221 { 2, 4, 3, 5, 2, 4, 3, 5,},
222 { 6, 0, 7, 1, 6, 0, 7, 1,},
223 { 3, 5, 2, 4, 3, 5, 2, 4,},
224 { 7, 1, 6, 0, 7, 1, 6, 0,},
226 { 4, 8, 7, 11, 4, 8, 7, 11,},
227 { 12, 0, 15, 3, 12, 0, 15, 3,},
228 { 6, 10, 5, 9, 6, 10, 5, 9,},
229 { 14, 2, 13, 1, 14, 2, 13, 1,},
230 { 4, 8, 7, 11, 4, 8, 7, 11,},
231 { 12, 0, 15, 3, 12, 0, 15, 3,},
232 { 6, 10, 5, 9, 6, 10, 5, 9,},
233 { 14, 2, 13, 1, 14, 2, 13, 1,},
235 { 9, 17, 15, 23, 8, 16, 14, 22,},
236 { 25, 1, 31, 7, 24, 0, 30, 6,},
237 { 13, 21, 11, 19, 12, 20, 10, 18,},
238 { 29, 5, 27, 3, 28, 4, 26, 2,},
239 { 8, 16, 14, 22, 9, 17, 15, 23,},
240 { 24, 0, 30, 6, 25, 1, 31, 7,},
241 { 12, 20, 10, 18, 13, 21, 11, 19,},
242 { 28, 4, 26, 2, 29, 5, 27, 3,},
244 { 18, 34, 30, 46, 17, 33, 29, 45,},
245 { 50, 2, 62, 14, 49, 1, 61, 13,},
246 { 26, 42, 22, 38, 25, 41, 21, 37,},
247 { 58, 10, 54, 6, 57, 9, 53, 5,},
248 { 16, 32, 28, 44, 19, 35, 31, 47,},
249 { 48, 0, 60, 12, 51, 3, 63, 15,},
250 { 24, 40, 20, 36, 27, 43, 23, 39,},
251 { 56, 8, 52, 4, 59, 11, 55, 7,},
253 { 18, 34, 30, 46, 17, 33, 29, 45,},
254 { 50, 2, 62, 14, 49, 1, 61, 13,},
255 { 26, 42, 22, 38, 25, 41, 21, 37,},
256 { 58, 10, 54, 6, 57, 9, 53, 5,},
257 { 16, 32, 28, 44, 19, 35, 31, 47,},
258 { 48, 0, 60, 12, 51, 3, 63, 15,},
259 { 24, 40, 20, 36, 27, 43, 23, 39,},
260 { 56, 8, 52, 4, 59, 11, 55, 7,},
262 { 36, 68, 60, 92, 34, 66, 58, 90,},
263 { 100, 4,124, 28, 98, 2,122, 26,},
264 { 52, 84, 44, 76, 50, 82, 42, 74,},
265 { 116, 20,108, 12,114, 18,106, 10,},
266 { 32, 64, 56, 88, 38, 70, 62, 94,},
267 { 96, 0,120, 24,102, 6,126, 30,},
268 { 48, 80, 40, 72, 54, 86, 46, 78,},
269 { 112, 16,104, 8,118, 22,110, 14,},
272 static const uint8_t flat64[8]={64,64,64,64,64,64,64,64};
274 const uint16_t dither_scale[15][16]={
275 { 2, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,},
276 { 2, 3, 7, 7, 13, 13, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,},
277 { 3, 3, 4, 15, 15, 29, 57, 57, 57, 113, 113, 113, 113, 113, 113, 113,},
278 { 3, 4, 4, 5, 31, 31, 61, 121, 241, 241, 241, 241, 481, 481, 481, 481,},
279 { 3, 4, 5, 5, 6, 63, 63, 125, 249, 497, 993, 993, 993, 993, 993, 1985,},
280 { 3, 5, 6, 6, 6, 7, 127, 127, 253, 505, 1009, 2017, 4033, 4033, 4033, 4033,},
281 { 3, 5, 6, 7, 7, 7, 8, 255, 255, 509, 1017, 2033, 4065, 8129,16257,16257,},
282 { 3, 5, 6, 8, 8, 8, 8, 9, 511, 511, 1021, 2041, 4081, 8161,16321,32641,},
283 { 3, 5, 7, 8, 9, 9, 9, 9, 10, 1023, 1023, 2045, 4089, 8177,16353,32705,},
284 { 3, 5, 7, 8, 10, 10, 10, 10, 10, 11, 2047, 2047, 4093, 8185,16369,32737,},
285 { 3, 5, 7, 8, 10, 11, 11, 11, 11, 11, 12, 4095, 4095, 8189,16377,32753,},
286 { 3, 5, 7, 9, 10, 12, 12, 12, 12, 12, 12, 13, 8191, 8191,16381,32761,},
287 { 3, 5, 7, 9, 10, 12, 13, 13, 13, 13, 13, 13, 14,16383,16383,32765,},
288 { 3, 5, 7, 9, 10, 12, 14, 14, 14, 14, 14, 14, 14, 15,32767,32767,},
289 { 3, 5, 7, 9, 11, 12, 14, 15, 15, 15, 15, 15, 15, 15, 16,65535,},
292 static av_always_inline void
293 yuv2yuvX16_c_template(const int16_t *lumFilter, const int16_t **lumSrc,
294 int lumFilterSize, const int16_t *chrFilter,
295 const int16_t **chrUSrc, const int16_t **chrVSrc,
296 int chrFilterSize, const int16_t **alpSrc,
297 uint16_t *dest[4], int dstW, int chrDstW,
298 int big_endian, int output_bits)
300 //FIXME Optimize (just quickly written not optimized..)
302 int shift = 11 + 16 - output_bits;
303 uint16_t *yDest = dest[0], *uDest = dest[1], *vDest = dest[2],
304 *aDest = CONFIG_SWSCALE_ALPHA ? dest[3] : NULL;
306 #define output_pixel(pos, val) \
308 if (output_bits == 16) { \
309 AV_WB16(pos, av_clip_uint16(val >> shift)); \
311 AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
314 if (output_bits == 16) { \
315 AV_WL16(pos, av_clip_uint16(val >> shift)); \
317 AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
320 for (i = 0; i < dstW; i++) {
321 int val = 1 << (26-output_bits);
324 for (j = 0; j < lumFilterSize; j++)
325 val += lumSrc[j][i] * lumFilter[j];
327 output_pixel(&yDest[i], val);
331 for (i = 0; i < chrDstW; i++) {
332 int u = 1 << (26-output_bits);
333 int v = 1 << (26-output_bits);
336 for (j = 0; j < chrFilterSize; j++) {
337 u += chrUSrc[j][i] * chrFilter[j];
338 v += chrVSrc[j][i] * chrFilter[j];
341 output_pixel(&uDest[i], u);
342 output_pixel(&vDest[i], v);
346 if (CONFIG_SWSCALE_ALPHA && aDest) {
347 for (i = 0; i < dstW; i++) {
348 int val = 1 << (26-output_bits);
351 for (j = 0; j < lumFilterSize; j++)
352 val += alpSrc[j][i] * lumFilter[j];
354 output_pixel(&aDest[i], val);
360 #define yuv2NBPS(bits, BE_LE, is_be) \
361 static void yuv2yuvX ## bits ## BE_LE ## _c(SwsContext *c, const int16_t *lumFilter, \
362 const int16_t **lumSrc, int lumFilterSize, \
363 const int16_t *chrFilter, const int16_t **chrUSrc, \
364 const int16_t **chrVSrc, \
365 int chrFilterSize, const int16_t **alpSrc, \
366 uint8_t *_dest[4], int dstW, int chrDstW) \
368 yuv2yuvX16_c_template(lumFilter, lumSrc, lumFilterSize, \
369 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
370 alpSrc, (uint16_t **) _dest, \
371 dstW, chrDstW, is_be, bits); \
380 static void yuv2yuvX_c(SwsContext *c, const int16_t *lumFilter,
381 const int16_t **lumSrc, int lumFilterSize,
382 const int16_t *chrFilter, const int16_t **chrUSrc,
383 const int16_t **chrVSrc,
384 int chrFilterSize, const int16_t **alpSrc,
385 uint8_t *dest[4], int dstW, int chrDstW,
386 const uint8_t *lumDither, const uint8_t *chrDither)
388 uint8_t *yDest = dest[0], *uDest = dest[1], *vDest = dest[2],
389 *aDest = CONFIG_SWSCALE_ALPHA ? dest[3] : NULL;
392 //FIXME Optimize (just quickly written not optimized..)
393 for (i=0; i<dstW; i++) {
394 int val = lumDither[i&7] << 12;
396 for (j=0; j<lumFilterSize; j++)
397 val += lumSrc[j][i] * lumFilter[j];
399 yDest[i]= av_clip_uint8(val>>19);
403 for (i=0; i<chrDstW; i++) {
404 int u = chrDither[i&7] << 12;
405 int v = chrDither[(i+3)&7] << 12;
407 for (j=0; j<chrFilterSize; j++) {
408 u += chrUSrc[j][i] * chrFilter[j];
409 v += chrVSrc[j][i] * chrFilter[j];
412 uDest[i]= av_clip_uint8(u>>19);
413 vDest[i]= av_clip_uint8(v>>19);
416 if (CONFIG_SWSCALE_ALPHA && aDest)
417 for (i=0; i<dstW; i++) {
418 int val = lumDither[i&7] << 12;
420 for (j=0; j<lumFilterSize; j++)
421 val += alpSrc[j][i] * lumFilter[j];
423 aDest[i]= av_clip_uint8(val>>19);
427 static void yuv2yuv1_c(SwsContext *c, const int16_t *lumSrc,
428 const int16_t *chrUSrc, const int16_t *chrVSrc,
429 const int16_t *alpSrc,
430 uint8_t *dest[4], int dstW, int chrDstW,
431 const uint8_t *lumDither, const uint8_t *chrDither)
433 uint8_t *yDest = dest[0], *uDest = dest[1], *vDest = dest[2],
434 *aDest = CONFIG_SWSCALE_ALPHA ? dest[3] : NULL;
437 for (i=0; i<dstW; i++) {
438 int val= (lumSrc[i]+lumDither[i&7])>>7;
439 yDest[i]= av_clip_uint8(val);
443 for (i=0; i<chrDstW; i++) {
444 int u=(chrUSrc[i]+chrDither[i&7])>>7;
445 int v=(chrVSrc[i]+chrDither[(i+3)&7])>>7;
446 uDest[i]= av_clip_uint8(u);
447 vDest[i]= av_clip_uint8(v);
450 if (CONFIG_SWSCALE_ALPHA && aDest)
451 for (i=0; i<dstW; i++) {
452 int val= (alpSrc[i]+lumDither[i&7])>>7;
453 aDest[i]= av_clip_uint8(val);
457 static void yuv2nv12X_c(SwsContext *c, const int16_t *lumFilter,
458 const int16_t **lumSrc, int lumFilterSize,
459 const int16_t *chrFilter, const int16_t **chrUSrc,
460 const int16_t **chrVSrc, int chrFilterSize,
461 const int16_t **alpSrc, uint8_t *dest[4],
462 int dstW, int chrDstW,
463 const uint8_t *lumDither, const uint8_t *chrDither)
465 uint8_t *yDest = dest[0], *uDest = dest[1];
466 enum PixelFormat dstFormat = c->dstFormat;
468 //FIXME Optimize (just quickly written not optimized..)
470 for (i=0; i<dstW; i++) {
471 int val = lumDither[i&7]<<12;
473 for (j=0; j<lumFilterSize; j++)
474 val += lumSrc[j][i] * lumFilter[j];
476 yDest[i]= av_clip_uint8(val>>19);
482 if (dstFormat == PIX_FMT_NV12)
483 for (i=0; i<chrDstW; i++) {
484 int u = chrDither[i&7]<<12;
485 int v = chrDither[(i+3)&7]<<12;
487 for (j=0; j<chrFilterSize; j++) {
488 u += chrUSrc[j][i] * chrFilter[j];
489 v += chrVSrc[j][i] * chrFilter[j];
492 uDest[2*i]= av_clip_uint8(u>>19);
493 uDest[2*i+1]= av_clip_uint8(v>>19);
496 for (i=0; i<chrDstW; i++) {
497 int u = chrDither[i&7]<<12;
498 int v = chrDither[(i+3)&7]<<12;
500 for (j=0; j<chrFilterSize; j++) {
501 u += chrUSrc[j][i] * chrFilter[j];
502 v += chrVSrc[j][i] * chrFilter[j];
505 uDest[2*i]= av_clip_uint8(v>>19);
506 uDest[2*i+1]= av_clip_uint8(u>>19);
510 #define output_pixel(pos, val) \
511 if (target == PIX_FMT_GRAY16BE) { \
517 static av_always_inline void
518 yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter,
519 const int16_t **lumSrc, int lumFilterSize,
520 const int16_t *chrFilter, const int16_t **chrUSrc,
521 const int16_t **chrVSrc, int chrFilterSize,
522 const int16_t **alpSrc, uint8_t *dest, int dstW,
523 int y, enum PixelFormat target)
527 for (i = 0; i < (dstW >> 1); i++) {
531 const int i2 = 2 * i;
533 for (j = 0; j < lumFilterSize; j++) {
534 Y1 += lumSrc[j][i2] * lumFilter[j];
535 Y2 += lumSrc[j][i2+1] * lumFilter[j];
539 if ((Y1 | Y2) & 0x10000) {
540 Y1 = av_clip_uint16(Y1);
541 Y2 = av_clip_uint16(Y2);
543 output_pixel(&dest[2 * i2 + 0], Y1);
544 output_pixel(&dest[2 * i2 + 2], Y2);
548 static av_always_inline void
549 yuv2gray16_2_c_template(SwsContext *c, const int16_t *buf[2],
550 const int16_t *ubuf[2], const int16_t *vbuf[2],
551 const int16_t *abuf[2], uint8_t *dest, int dstW,
552 int yalpha, int uvalpha, int y,
553 enum PixelFormat target)
555 int yalpha1 = 4095 - yalpha;
557 const int16_t *buf0 = buf[0], *buf1 = buf[1];
559 for (i = 0; i < (dstW >> 1); i++) {
560 const int i2 = 2 * i;
561 int Y1 = (buf0[i2 ] * yalpha1 + buf1[i2 ] * yalpha) >> 11;
562 int Y2 = (buf0[i2+1] * yalpha1 + buf1[i2+1] * yalpha) >> 11;
564 output_pixel(&dest[2 * i2 + 0], Y1);
565 output_pixel(&dest[2 * i2 + 2], Y2);
569 static av_always_inline void
570 yuv2gray16_1_c_template(SwsContext *c, const int16_t *buf0,
571 const int16_t *ubuf[2], const int16_t *vbuf[2],
572 const int16_t *abuf0, uint8_t *dest, int dstW,
573 int uvalpha, int y, enum PixelFormat target)
577 for (i = 0; i < (dstW >> 1); i++) {
578 const int i2 = 2 * i;
579 int Y1 = buf0[i2 ] << 1;
580 int Y2 = buf0[i2+1] << 1;
582 output_pixel(&dest[2 * i2 + 0], Y1);
583 output_pixel(&dest[2 * i2 + 2], Y2);
589 #define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
590 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
591 const int16_t **lumSrc, int lumFilterSize, \
592 const int16_t *chrFilter, const int16_t **chrUSrc, \
593 const int16_t **chrVSrc, int chrFilterSize, \
594 const int16_t **alpSrc, uint8_t *dest, int dstW, \
597 name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
598 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
599 alpSrc, dest, dstW, y, fmt); \
602 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
603 const int16_t *ubuf[2], const int16_t *vbuf[2], \
604 const int16_t *abuf[2], uint8_t *dest, int dstW, \
605 int yalpha, int uvalpha, int y) \
607 name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
608 dest, dstW, yalpha, uvalpha, y, fmt); \
611 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
612 const int16_t *ubuf[2], const int16_t *vbuf[2], \
613 const int16_t *abuf0, uint8_t *dest, int dstW, \
614 int uvalpha, int y) \
616 name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
617 dstW, uvalpha, y, fmt); \
620 YUV2PACKEDWRAPPER(yuv2gray16,, LE, PIX_FMT_GRAY16LE);
621 YUV2PACKEDWRAPPER(yuv2gray16,, BE, PIX_FMT_GRAY16BE);
623 #define output_pixel(pos, acc) \
624 if (target == PIX_FMT_MONOBLACK) { \
630 static av_always_inline void
631 yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
632 const int16_t **lumSrc, int lumFilterSize,
633 const int16_t *chrFilter, const int16_t **chrUSrc,
634 const int16_t **chrVSrc, int chrFilterSize,
635 const int16_t **alpSrc, uint8_t *dest, int dstW,
636 int y, enum PixelFormat target)
638 const uint8_t * const d128=dither_8x8_220[y&7];
639 uint8_t *g = c->table_gU[128] + c->table_gV[128];
643 for (i = 0; i < dstW - 1; i += 2) {
648 for (j = 0; j < lumFilterSize; j++) {
649 Y1 += lumSrc[j][i] * lumFilter[j];
650 Y2 += lumSrc[j][i+1] * lumFilter[j];
654 if ((Y1 | Y2) & 0x100) {
655 Y1 = av_clip_uint8(Y1);
656 Y2 = av_clip_uint8(Y2);
658 acc += acc + g[Y1 + d128[(i + 0) & 7]];
659 acc += acc + g[Y2 + d128[(i + 1) & 7]];
661 output_pixel(*dest++, acc);
666 static av_always_inline void
667 yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2],
668 const int16_t *ubuf[2], const int16_t *vbuf[2],
669 const int16_t *abuf[2], uint8_t *dest, int dstW,
670 int yalpha, int uvalpha, int y,
671 enum PixelFormat target)
673 const int16_t *buf0 = buf[0], *buf1 = buf[1];
674 const uint8_t * const d128 = dither_8x8_220[y & 7];
675 uint8_t *g = c->table_gU[128] + c->table_gV[128];
676 int yalpha1 = 4095 - yalpha;
679 for (i = 0; i < dstW - 7; i += 8) {
680 int acc = g[((buf0[i ] * yalpha1 + buf1[i ] * yalpha) >> 19) + d128[0]];
681 acc += acc + g[((buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19) + d128[1]];
682 acc += acc + g[((buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19) + d128[2]];
683 acc += acc + g[((buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19) + d128[3]];
684 acc += acc + g[((buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19) + d128[4]];
685 acc += acc + g[((buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19) + d128[5]];
686 acc += acc + g[((buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19) + d128[6]];
687 acc += acc + g[((buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19) + d128[7]];
688 output_pixel(*dest++, acc);
692 static av_always_inline void
693 yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0,
694 const int16_t *ubuf[2], const int16_t *vbuf[2],
695 const int16_t *abuf0, uint8_t *dest, int dstW,
696 int uvalpha, int y, enum PixelFormat target)
698 const uint8_t * const d128 = dither_8x8_220[y & 7];
699 uint8_t *g = c->table_gU[128] + c->table_gV[128];
702 for (i = 0; i < dstW - 7; i += 8) {
703 int acc = g[(buf0[i ] >> 7) + d128[0]];
704 acc += acc + g[(buf0[i + 1] >> 7) + d128[1]];
705 acc += acc + g[(buf0[i + 2] >> 7) + d128[2]];
706 acc += acc + g[(buf0[i + 3] >> 7) + d128[3]];
707 acc += acc + g[(buf0[i + 4] >> 7) + d128[4]];
708 acc += acc + g[(buf0[i + 5] >> 7) + d128[5]];
709 acc += acc + g[(buf0[i + 6] >> 7) + d128[6]];
710 acc += acc + g[(buf0[i + 7] >> 7) + d128[7]];
711 output_pixel(*dest++, acc);
717 YUV2PACKEDWRAPPER(yuv2mono,, white, PIX_FMT_MONOWHITE);
718 YUV2PACKEDWRAPPER(yuv2mono,, black, PIX_FMT_MONOBLACK);
720 #define output_pixels(pos, Y1, U, Y2, V) \
721 if (target == PIX_FMT_YUYV422) { \
722 dest[pos + 0] = Y1; \
724 dest[pos + 2] = Y2; \
728 dest[pos + 1] = Y1; \
730 dest[pos + 3] = Y2; \
733 static av_always_inline void
734 yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
735 const int16_t **lumSrc, int lumFilterSize,
736 const int16_t *chrFilter, const int16_t **chrUSrc,
737 const int16_t **chrVSrc, int chrFilterSize,
738 const int16_t **alpSrc, uint8_t *dest, int dstW,
739 int y, enum PixelFormat target)
743 for (i = 0; i < (dstW >> 1); i++) {
750 for (j = 0; j < lumFilterSize; j++) {
751 Y1 += lumSrc[j][i * 2] * lumFilter[j];
752 Y2 += lumSrc[j][i * 2 + 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);
768 output_pixels(4*i, Y1, U, Y2, V);
772 static av_always_inline void
773 yuv2422_2_c_template(SwsContext *c, const int16_t *buf[2],
774 const int16_t *ubuf[2], const int16_t *vbuf[2],
775 const int16_t *abuf[2], uint8_t *dest, int dstW,
776 int yalpha, int uvalpha, int y,
777 enum PixelFormat target)
779 const int16_t *buf0 = buf[0], *buf1 = buf[1],
780 *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
781 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
782 int yalpha1 = 4095 - yalpha;
783 int uvalpha1 = 4095 - uvalpha;
786 for (i = 0; i < (dstW >> 1); i++) {
787 int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19;
788 int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
789 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
790 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
792 output_pixels(i * 4, Y1, U, Y2, V);
796 static av_always_inline void
797 yuv2422_1_c_template(SwsContext *c, const int16_t *buf0,
798 const int16_t *ubuf[2], const int16_t *vbuf[2],
799 const int16_t *abuf0, uint8_t *dest, int dstW,
800 int uvalpha, int y, enum PixelFormat target)
802 const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
803 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
806 if (uvalpha < 2048) {
807 for (i = 0; i < (dstW >> 1); i++) {
808 int Y1 = buf0[i * 2] >> 7;
809 int Y2 = buf0[i * 2 + 1] >> 7;
810 int U = ubuf1[i] >> 7;
811 int V = vbuf1[i] >> 7;
813 output_pixels(i * 4, Y1, U, Y2, V);
816 for (i = 0; i < (dstW >> 1); i++) {
817 int Y1 = buf0[i * 2] >> 7;
818 int Y2 = buf0[i * 2 + 1] >> 7;
819 int U = (ubuf0[i] + ubuf1[i]) >> 8;
820 int V = (vbuf0[i] + vbuf1[i]) >> 8;
822 output_pixels(i * 4, Y1, U, Y2, V);
829 YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, PIX_FMT_YUYV422);
830 YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, PIX_FMT_UYVY422);
832 #define r_b ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? r : b)
833 #define b_r ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? b : r)
835 static av_always_inline void
836 yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
837 const int16_t **lumSrc, int lumFilterSize,
838 const int16_t *chrFilter, const int16_t **chrUSrc,
839 const int16_t **chrVSrc, int chrFilterSize,
840 const int16_t **alpSrc, uint8_t *dest, int dstW,
841 int y, enum PixelFormat target)
845 for (i = 0; i < (dstW >> 1); i++) {
851 const uint8_t *r, *g, *b;
853 for (j = 0; j < lumFilterSize; j++) {
854 Y1 += lumSrc[j][i * 2] * lumFilter[j];
855 Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
857 for (j = 0; j < chrFilterSize; j++) {
858 U += chrUSrc[j][i] * chrFilter[j];
859 V += chrVSrc[j][i] * chrFilter[j];
865 if ((Y1 | Y2 | U | V) & 0x100) {
866 Y1 = av_clip_uint8(Y1);
867 Y2 = av_clip_uint8(Y2);
868 U = av_clip_uint8(U);
869 V = av_clip_uint8(V);
872 /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/
873 r = (const uint8_t *) c->table_rV[V];
874 g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]);
875 b = (const uint8_t *) c->table_bU[U];
877 dest[ 0] = dest[ 1] = r_b[Y1];
878 dest[ 2] = dest[ 3] = g[Y1];
879 dest[ 4] = dest[ 5] = b_r[Y1];
880 dest[ 6] = dest[ 7] = r_b[Y2];
881 dest[ 8] = dest[ 9] = g[Y2];
882 dest[10] = dest[11] = b_r[Y2];
887 static av_always_inline void
888 yuv2rgb48_2_c_template(SwsContext *c, const int16_t *buf[2],
889 const int16_t *ubuf[2], const int16_t *vbuf[2],
890 const int16_t *abuf[2], uint8_t *dest, int dstW,
891 int yalpha, int uvalpha, int y,
892 enum PixelFormat target)
894 const int16_t *buf0 = buf[0], *buf1 = buf[1],
895 *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
896 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
897 int yalpha1 = 4095 - yalpha;
898 int uvalpha1 = 4095 - uvalpha;
901 for (i = 0; i < (dstW >> 1); i++) {
902 int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19;
903 int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
904 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
905 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
906 const uint8_t *r = (const uint8_t *) c->table_rV[V],
907 *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
908 *b = (const uint8_t *) c->table_bU[U];
910 dest[ 0] = dest[ 1] = r_b[Y1];
911 dest[ 2] = dest[ 3] = g[Y1];
912 dest[ 4] = dest[ 5] = b_r[Y1];
913 dest[ 6] = dest[ 7] = r_b[Y2];
914 dest[ 8] = dest[ 9] = g[Y2];
915 dest[10] = dest[11] = b_r[Y2];
920 static av_always_inline void
921 yuv2rgb48_1_c_template(SwsContext *c, const int16_t *buf0,
922 const int16_t *ubuf[2], const int16_t *vbuf[2],
923 const int16_t *abuf0, uint8_t *dest, int dstW,
924 int uvalpha, int y, enum PixelFormat target)
926 const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
927 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
930 if (uvalpha < 2048) {
931 for (i = 0; i < (dstW >> 1); i++) {
932 int Y1 = buf0[i * 2] >> 7;
933 int Y2 = buf0[i * 2 + 1] >> 7;
934 int U = ubuf1[i] >> 7;
935 int V = vbuf1[i] >> 7;
936 const uint8_t *r = (const uint8_t *) c->table_rV[V],
937 *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
938 *b = (const uint8_t *) c->table_bU[U];
940 dest[ 0] = dest[ 1] = r_b[Y1];
941 dest[ 2] = dest[ 3] = g[Y1];
942 dest[ 4] = dest[ 5] = b_r[Y1];
943 dest[ 6] = dest[ 7] = r_b[Y2];
944 dest[ 8] = dest[ 9] = g[Y2];
945 dest[10] = dest[11] = b_r[Y2];
949 for (i = 0; i < (dstW >> 1); i++) {
950 int Y1 = buf0[i * 2] >> 7;
951 int Y2 = buf0[i * 2 + 1] >> 7;
952 int U = (ubuf0[i] + ubuf1[i]) >> 8;
953 int V = (vbuf0[i] + vbuf1[i]) >> 8;
954 const uint8_t *r = (const uint8_t *) c->table_rV[V],
955 *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
956 *b = (const uint8_t *) c->table_bU[U];
958 dest[ 0] = dest[ 1] = r_b[Y1];
959 dest[ 2] = dest[ 3] = g[Y1];
960 dest[ 4] = dest[ 5] = b_r[Y1];
961 dest[ 6] = dest[ 7] = r_b[Y2];
962 dest[ 8] = dest[ 9] = g[Y2];
963 dest[10] = dest[11] = b_r[Y2];
972 YUV2PACKEDWRAPPER(yuv2, rgb48, rgb48be, PIX_FMT_RGB48BE);
973 //YUV2PACKEDWRAPPER(yuv2, rgb48, rgb48le, PIX_FMT_RGB48LE);
974 YUV2PACKEDWRAPPER(yuv2, rgb48, bgr48be, PIX_FMT_BGR48BE);
975 //YUV2PACKEDWRAPPER(yuv2, rgb48, bgr48le, PIX_FMT_BGR48LE);
977 static av_always_inline void
978 yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2,
979 int U, int V, int A1, int A2,
980 const void *_r, const void *_g, const void *_b, int y,
981 enum PixelFormat target, int hasAlpha)
983 if (target == PIX_FMT_ARGB || target == PIX_FMT_RGBA ||
984 target == PIX_FMT_ABGR || target == PIX_FMT_BGRA) {
985 uint32_t *dest = (uint32_t *) _dest;
986 const uint32_t *r = (const uint32_t *) _r;
987 const uint32_t *g = (const uint32_t *) _g;
988 const uint32_t *b = (const uint32_t *) _b;
991 int sh = hasAlpha ? ((target == PIX_FMT_RGB32_1 || target == PIX_FMT_BGR32_1) ? 0 : 24) : 0;
993 dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0);
994 dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0);
997 int sh = (target == PIX_FMT_RGB32_1 || target == PIX_FMT_BGR32_1) ? 0 : 24;
999 dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (A1 << sh);
1000 dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (A2 << sh);
1002 dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1];
1003 dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2];
1006 } else if (target == PIX_FMT_RGB24 || target == PIX_FMT_BGR24) {
1007 uint8_t *dest = (uint8_t *) _dest;
1008 const uint8_t *r = (const uint8_t *) _r;
1009 const uint8_t *g = (const uint8_t *) _g;
1010 const uint8_t *b = (const uint8_t *) _b;
1012 #define r_b ((target == PIX_FMT_RGB24) ? r : b)
1013 #define b_r ((target == PIX_FMT_RGB24) ? b : r)
1014 dest[i * 6 + 0] = r_b[Y1];
1015 dest[i * 6 + 1] = g[Y1];
1016 dest[i * 6 + 2] = b_r[Y1];
1017 dest[i * 6 + 3] = r_b[Y2];
1018 dest[i * 6 + 4] = g[Y2];
1019 dest[i * 6 + 5] = b_r[Y2];
1022 } else if (target == PIX_FMT_RGB565 || target == PIX_FMT_BGR565 ||
1023 target == PIX_FMT_RGB555 || target == PIX_FMT_BGR555 ||
1024 target == PIX_FMT_RGB444 || target == PIX_FMT_BGR444) {
1025 uint16_t *dest = (uint16_t *) _dest;
1026 const uint16_t *r = (const uint16_t *) _r;
1027 const uint16_t *g = (const uint16_t *) _g;
1028 const uint16_t *b = (const uint16_t *) _b;
1029 int dr1, dg1, db1, dr2, dg2, db2;
1031 if (target == PIX_FMT_RGB565 || target == PIX_FMT_BGR565) {
1032 dr1 = dither_2x2_8[ y & 1 ][0];
1033 dg1 = dither_2x2_4[ y & 1 ][0];
1034 db1 = dither_2x2_8[(y & 1) ^ 1][0];
1035 dr2 = dither_2x2_8[ y & 1 ][1];
1036 dg2 = dither_2x2_4[ y & 1 ][1];
1037 db2 = dither_2x2_8[(y & 1) ^ 1][1];
1038 } else if (target == PIX_FMT_RGB555 || target == PIX_FMT_BGR555) {
1039 dr1 = dither_2x2_8[ y & 1 ][0];
1040 dg1 = dither_2x2_8[ y & 1 ][1];
1041 db1 = dither_2x2_8[(y & 1) ^ 1][0];
1042 dr2 = dither_2x2_8[ y & 1 ][1];
1043 dg2 = dither_2x2_8[ y & 1 ][0];
1044 db2 = dither_2x2_8[(y & 1) ^ 1][1];
1046 dr1 = dither_4x4_16[ y & 3 ][0];
1047 dg1 = dither_4x4_16[ y & 3 ][1];
1048 db1 = dither_4x4_16[(y & 3) ^ 3][0];
1049 dr2 = dither_4x4_16[ y & 3 ][1];
1050 dg2 = dither_4x4_16[ y & 3 ][0];
1051 db2 = dither_4x4_16[(y & 3) ^ 3][1];
1054 dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
1055 dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
1056 } else /* 8/4-bit */ {
1057 uint8_t *dest = (uint8_t *) _dest;
1058 const uint8_t *r = (const uint8_t *) _r;
1059 const uint8_t *g = (const uint8_t *) _g;
1060 const uint8_t *b = (const uint8_t *) _b;
1061 int dr1, dg1, db1, dr2, dg2, db2;
1063 if (target == PIX_FMT_RGB8 || target == PIX_FMT_BGR8) {
1064 const uint8_t * const d64 = dither_8x8_73[y & 7];
1065 const uint8_t * const d32 = dither_8x8_32[y & 7];
1066 dr1 = dg1 = d32[(i * 2 + 0) & 7];
1067 db1 = d64[(i * 2 + 0) & 7];
1068 dr2 = dg2 = d32[(i * 2 + 1) & 7];
1069 db2 = d64[(i * 2 + 1) & 7];
1071 const uint8_t * const d64 = dither_8x8_73 [y & 7];
1072 const uint8_t * const d128 = dither_8x8_220[y & 7];
1073 dr1 = db1 = d128[(i * 2 + 0) & 7];
1074 dg1 = d64[(i * 2 + 0) & 7];
1075 dr2 = db2 = d128[(i * 2 + 1) & 7];
1076 dg2 = d64[(i * 2 + 1) & 7];
1079 if (target == PIX_FMT_RGB4 || target == PIX_FMT_BGR4) {
1080 dest[i] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1] +
1081 ((r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]) << 4);
1083 dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
1084 dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
1089 static av_always_inline void
1090 yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter,
1091 const int16_t **lumSrc, int lumFilterSize,
1092 const int16_t *chrFilter, const int16_t **chrUSrc,
1093 const int16_t **chrVSrc, int chrFilterSize,
1094 const int16_t **alpSrc, uint8_t *dest, int dstW,
1095 int y, enum PixelFormat target, int hasAlpha)
1099 for (i = 0; i < (dstW >> 1); i++) {
1105 int av_unused A1, A2;
1106 const void *r, *g, *b;
1108 for (j = 0; j < lumFilterSize; j++) {
1109 Y1 += lumSrc[j][i * 2] * lumFilter[j];
1110 Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
1112 for (j = 0; j < chrFilterSize; j++) {
1113 U += chrUSrc[j][i] * chrFilter[j];
1114 V += chrVSrc[j][i] * chrFilter[j];
1120 if ((Y1 | Y2 | U | V) & 0x100) {
1121 Y1 = av_clip_uint8(Y1);
1122 Y2 = av_clip_uint8(Y2);
1123 U = av_clip_uint8(U);
1124 V = av_clip_uint8(V);
1129 for (j = 0; j < lumFilterSize; j++) {
1130 A1 += alpSrc[j][i * 2 ] * lumFilter[j];
1131 A2 += alpSrc[j][i * 2 + 1] * lumFilter[j];
1135 if ((A1 | A2) & 0x100) {
1136 A1 = av_clip_uint8(A1);
1137 A2 = av_clip_uint8(A2);
1141 /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/
1143 g = (c->table_gU[U] + c->table_gV[V]);
1146 yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1147 r, g, b, y, target, hasAlpha);
1151 static av_always_inline void
1152 yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
1153 const int16_t *ubuf[2], const int16_t *vbuf[2],
1154 const int16_t *abuf[2], uint8_t *dest, int dstW,
1155 int yalpha, int uvalpha, int y,
1156 enum PixelFormat target, int hasAlpha)
1158 const int16_t *buf0 = buf[0], *buf1 = buf[1],
1159 *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1160 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
1161 *abuf0 = abuf[0], *abuf1 = abuf[1];
1162 int yalpha1 = 4095 - yalpha;
1163 int uvalpha1 = 4095 - uvalpha;
1166 for (i = 0; i < (dstW >> 1); i++) {
1167 int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19;
1168 int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
1169 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
1170 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
1172 const void *r = c->table_rV[V],
1173 *g = (c->table_gU[U] + c->table_gV[V]),
1174 *b = c->table_bU[U];
1177 A1 = (abuf0[i * 2 ] * yalpha1 + abuf1[i * 2 ] * yalpha) >> 19;
1178 A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
1181 yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1182 r, g, b, y, target, hasAlpha);
1186 static av_always_inline void
1187 yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
1188 const int16_t *ubuf[2], const int16_t *vbuf[2],
1189 const int16_t *abuf0, uint8_t *dest, int dstW,
1190 int uvalpha, int y, enum PixelFormat target,
1193 const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1194 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
1197 if (uvalpha < 2048) {
1198 for (i = 0; i < (dstW >> 1); i++) {
1199 int Y1 = buf0[i * 2] >> 7;
1200 int Y2 = buf0[i * 2 + 1] >> 7;
1201 int U = ubuf1[i] >> 7;
1202 int V = vbuf1[i] >> 7;
1204 const void *r = c->table_rV[V],
1205 *g = (c->table_gU[U] + c->table_gV[V]),
1206 *b = c->table_bU[U];
1209 A1 = abuf0[i * 2 ] >> 7;
1210 A2 = abuf0[i * 2 + 1] >> 7;
1213 yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1214 r, g, b, y, target, hasAlpha);
1217 for (i = 0; i < (dstW >> 1); i++) {
1218 int Y1 = buf0[i * 2] >> 7;
1219 int Y2 = buf0[i * 2 + 1] >> 7;
1220 int U = (ubuf0[i] + ubuf1[i]) >> 8;
1221 int V = (vbuf0[i] + vbuf1[i]) >> 8;
1223 const void *r = c->table_rV[V],
1224 *g = (c->table_gU[U] + c->table_gV[V]),
1225 *b = c->table_bU[U];
1228 A1 = abuf0[i * 2 ] >> 7;
1229 A2 = abuf0[i * 2 + 1] >> 7;
1232 yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1233 r, g, b, y, target, hasAlpha);
1238 #define YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1239 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
1240 const int16_t **lumSrc, int lumFilterSize, \
1241 const int16_t *chrFilter, const int16_t **chrUSrc, \
1242 const int16_t **chrVSrc, int chrFilterSize, \
1243 const int16_t **alpSrc, uint8_t *dest, int dstW, \
1246 name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
1247 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
1248 alpSrc, dest, dstW, y, fmt, hasAlpha); \
1250 #define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha) \
1251 YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1252 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
1253 const int16_t *ubuf[2], const int16_t *vbuf[2], \
1254 const int16_t *abuf[2], uint8_t *dest, int dstW, \
1255 int yalpha, int uvalpha, int y) \
1257 name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
1258 dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
1261 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
1262 const int16_t *ubuf[2], const int16_t *vbuf[2], \
1263 const int16_t *abuf0, uint8_t *dest, int dstW, \
1264 int uvalpha, int y) \
1266 name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
1267 dstW, uvalpha, y, fmt, hasAlpha); \
1271 YUV2RGBWRAPPER(yuv2rgb,, 32_1, PIX_FMT_RGB32_1, CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1272 YUV2RGBWRAPPER(yuv2rgb,, 32, PIX_FMT_RGB32, CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1274 #if CONFIG_SWSCALE_ALPHA
1275 YUV2RGBWRAPPER(yuv2rgb,, a32_1, PIX_FMT_RGB32_1, 1);
1276 YUV2RGBWRAPPER(yuv2rgb,, a32, PIX_FMT_RGB32, 1);
1278 YUV2RGBWRAPPER(yuv2rgb,, x32_1, PIX_FMT_RGB32_1, 0);
1279 YUV2RGBWRAPPER(yuv2rgb,, x32, PIX_FMT_RGB32, 0);
1281 YUV2RGBWRAPPER(yuv2, rgb, rgb24, PIX_FMT_RGB24, 0);
1282 YUV2RGBWRAPPER(yuv2, rgb, bgr24, PIX_FMT_BGR24, 0);
1283 YUV2RGBWRAPPER(yuv2rgb,, 16, PIX_FMT_RGB565, 0);
1284 YUV2RGBWRAPPER(yuv2rgb,, 15, PIX_FMT_RGB555, 0);
1285 YUV2RGBWRAPPER(yuv2rgb,, 12, PIX_FMT_RGB444, 0);
1286 YUV2RGBWRAPPER(yuv2rgb,, 8, PIX_FMT_RGB8, 0);
1287 YUV2RGBWRAPPER(yuv2rgb,, 4, PIX_FMT_RGB4, 0);
1288 YUV2RGBWRAPPER(yuv2rgb,, 4b, PIX_FMT_RGB4_BYTE, 0);
1290 static av_always_inline void
1291 yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
1292 const int16_t **lumSrc, int lumFilterSize,
1293 const int16_t *chrFilter, const int16_t **chrUSrc,
1294 const int16_t **chrVSrc, int chrFilterSize,
1295 const int16_t **alpSrc, uint8_t *dest,
1296 int dstW, int y, enum PixelFormat target, int hasAlpha)
1299 int step = (target == PIX_FMT_RGB24 || target == PIX_FMT_BGR24) ? 3 : 4;
1301 for (i = 0; i < dstW; i++) {
1304 int U = (1<<9)-(128 << 19);
1305 int V = (1<<9)-(128 << 19);
1309 for (j = 0; j < lumFilterSize; j++) {
1310 Y += lumSrc[j][i] * lumFilter[j];
1312 for (j = 0; j < chrFilterSize; j++) {
1313 U += chrUSrc[j][i] * chrFilter[j];
1314 V += chrVSrc[j][i] * chrFilter[j];
1321 for (j = 0; j < lumFilterSize; j++) {
1322 A += alpSrc[j][i] * lumFilter[j];
1326 A = av_clip_uint8(A);
1328 Y -= c->yuv2rgb_y_offset;
1329 Y *= c->yuv2rgb_y_coeff;
1331 R = Y + V*c->yuv2rgb_v2r_coeff;
1332 G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
1333 B = Y + U*c->yuv2rgb_u2b_coeff;
1334 if ((R | G | B) & 0xC0000000) {
1335 R = av_clip_uintp2(R, 30);
1336 G = av_clip_uintp2(G, 30);
1337 B = av_clip_uintp2(B, 30);
1342 dest[0] = hasAlpha ? A : 255;
1356 dest[3] = hasAlpha ? A : 255;
1359 dest[0] = hasAlpha ? A : 255;
1373 dest[3] = hasAlpha ? A : 255;
1381 YUV2RGBWRAPPERX(yuv2, rgb_full, bgra32_full, PIX_FMT_BGRA, CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1382 YUV2RGBWRAPPERX(yuv2, rgb_full, abgr32_full, PIX_FMT_ABGR, CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1383 YUV2RGBWRAPPERX(yuv2, rgb_full, rgba32_full, PIX_FMT_RGBA, CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1384 YUV2RGBWRAPPERX(yuv2, rgb_full, argb32_full, PIX_FMT_ARGB, CONFIG_SWSCALE_ALPHA && c->alpPixBuf);
1386 #if CONFIG_SWSCALE_ALPHA
1387 YUV2RGBWRAPPERX(yuv2, rgb_full, bgra32_full, PIX_FMT_BGRA, 1);
1388 YUV2RGBWRAPPERX(yuv2, rgb_full, abgr32_full, PIX_FMT_ABGR, 1);
1389 YUV2RGBWRAPPERX(yuv2, rgb_full, rgba32_full, PIX_FMT_RGBA, 1);
1390 YUV2RGBWRAPPERX(yuv2, rgb_full, argb32_full, PIX_FMT_ARGB, 1);
1392 YUV2RGBWRAPPERX(yuv2, rgb_full, bgrx32_full, PIX_FMT_BGRA, 0);
1393 YUV2RGBWRAPPERX(yuv2, rgb_full, xbgr32_full, PIX_FMT_ABGR, 0);
1394 YUV2RGBWRAPPERX(yuv2, rgb_full, rgbx32_full, PIX_FMT_RGBA, 0);
1395 YUV2RGBWRAPPERX(yuv2, rgb_full, xrgb32_full, PIX_FMT_ARGB, 0);
1397 YUV2RGBWRAPPERX(yuv2, rgb_full, bgr24_full, PIX_FMT_BGR24, 0);
1398 YUV2RGBWRAPPERX(yuv2, rgb_full, rgb24_full, PIX_FMT_RGB24, 0);
1400 static av_always_inline void fillPlane(uint8_t* plane, int stride,
1401 int width, int height,
1405 uint8_t *ptr = plane + stride*y;
1406 for (i=0; i<height; i++) {
1407 memset(ptr, val, width);
1412 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1414 #define r ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? b_r : r_b)
1415 #define b ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? r_b : b_r)
1417 static av_always_inline void
1418 rgb48ToY_c_template(int16_t *dst, const uint16_t *src, int width,
1419 enum PixelFormat origin)
1422 for (i = 0; i < width; i++) {
1423 int r_b = input_pixel(&src[i*3+0]);
1424 int g = input_pixel(&src[i*3+1]);
1425 int b_r = input_pixel(&src[i*3+2]);
1427 dst[i] = (RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8);
1431 static av_always_inline void
1432 rgb48ToUV_c_template(int16_t *dstU, int16_t *dstV,
1433 const uint16_t *src1, const uint16_t *src2,
1434 int width, enum PixelFormat origin)
1438 for (i = 0; i < width; i++) {
1439 int r_b = input_pixel(&src1[i*3+0]);
1440 int g = input_pixel(&src1[i*3+1]);
1441 int b_r = input_pixel(&src1[i*3+2]);
1443 dstU[i] = (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8);
1444 dstV[i] = (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8);
1448 static av_always_inline void
1449 rgb48ToUV_half_c_template(int16_t *dstU, int16_t *dstV,
1450 const uint16_t *src1, const uint16_t *src2,
1451 int width, enum PixelFormat origin)
1455 for (i = 0; i < width; i++) {
1456 int r_b = (input_pixel(&src1[6*i + 0])) + (input_pixel(&src1[6*i + 3]));
1457 int g = (input_pixel(&src1[6*i + 1])) + (input_pixel(&src1[6*i + 4]));
1458 int b_r = (input_pixel(&src1[6*i + 2])) + (input_pixel(&src1[6*i + 5]));
1460 dstU[i]= (RU*r + GU*g + BU*b + (256U<<(RGB2YUV_SHIFT+8)) + (1<<(RGB2YUV_SHIFT-6+8))) >> (RGB2YUV_SHIFT-5+8);
1461 dstV[i]= (RV*r + GV*g + BV*b + (256U<<(RGB2YUV_SHIFT+8)) + (1<<(RGB2YUV_SHIFT-6+8))) >> (RGB2YUV_SHIFT-5+8);
1469 #define rgb48funcs(pattern, BE_LE, origin) \
1470 static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *dst, const uint8_t *src, \
1471 int width, uint32_t *unused) \
1473 rgb48ToY_c_template(dst, src, width, origin); \
1476 static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1477 const uint8_t *src1, const uint8_t *src2, \
1478 int width, uint32_t *unused) \
1480 rgb48ToUV_c_template(dstU, dstV, src1, src2, width, origin); \
1483 static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
1484 const uint8_t *src1, const uint8_t *src2, \
1485 int width, uint32_t *unused) \
1487 rgb48ToUV_half_c_template(dstU, dstV, src1, src2, width, origin); \
1490 rgb48funcs(rgb, LE, PIX_FMT_RGB48LE);
1491 rgb48funcs(rgb, BE, PIX_FMT_RGB48BE);
1492 rgb48funcs(bgr, LE, PIX_FMT_BGR48LE);
1493 rgb48funcs(bgr, BE, PIX_FMT_BGR48BE);
1495 #define input_pixel(i) ((origin == PIX_FMT_RGBA || origin == PIX_FMT_BGRA || \
1496 origin == PIX_FMT_ARGB || origin == PIX_FMT_ABGR) ? AV_RN32A(&src[(i)*4]) : \
1497 (isBE(origin) ? AV_RB16(&src[(i)*2]) : AV_RL16(&src[(i)*2])))
1499 static av_always_inline void
1500 rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src,
1501 int width, enum PixelFormat origin,
1502 int shr, int shg, int shb, int shp,
1503 int maskr, int maskg, int maskb,
1504 int rsh, int gsh, int bsh, int S)
1506 const int ry = RY << rsh, gy = GY << gsh, by = BY << bsh,
1507 rnd = (32<<((S)-1)) + (1<<(S-7));
1510 for (i = 0; i < width; i++) {
1511 int px = input_pixel(i) >> shp;
1512 int b = (px & maskb) >> shb;
1513 int g = (px & maskg) >> shg;
1514 int r = (px & maskr) >> shr;
1516 dst[i] = (ry * r + gy * g + by * b + rnd) >> ((S)-6);
1520 static av_always_inline void
1521 rgb16_32ToUV_c_template(int16_t *dstU, int16_t *dstV,
1522 const uint8_t *src, int width,
1523 enum PixelFormat origin,
1524 int shr, int shg, int shb, int shp,
1525 int maskr, int maskg, int maskb,
1526 int rsh, int gsh, int bsh, int S)
1528 const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1529 rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1530 rnd = (256<<((S)-1)) + (1<<(S-7));
1533 for (i = 0; i < width; i++) {
1534 int px = input_pixel(i) >> shp;
1535 int b = (px & maskb) >> shb;
1536 int g = (px & maskg) >> shg;
1537 int r = (px & maskr) >> shr;
1539 dstU[i] = (ru * r + gu * g + bu * b + rnd) >> ((S)-6);
1540 dstV[i] = (rv * r + gv * g + bv * b + rnd) >> ((S)-6);
1544 static av_always_inline void
1545 rgb16_32ToUV_half_c_template(int16_t *dstU, int16_t *dstV,
1546 const uint8_t *src, int width,
1547 enum PixelFormat origin,
1548 int shr, int shg, int shb, int shp,
1549 int maskr, int maskg, int maskb,
1550 int rsh, int gsh, int bsh, int S)
1552 const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
1553 rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
1554 rnd = (256U<<(S)) + (1<<(S-6)), maskgx = ~(maskr | maskb);
1557 maskr |= maskr << 1; maskb |= maskb << 1; maskg |= maskg << 1;
1558 for (i = 0; i < width; i++) {
1559 int px0 = input_pixel(2 * i + 0) >> shp;
1560 int px1 = input_pixel(2 * i + 1) >> shp;
1561 int b, r, g = (px0 & maskgx) + (px1 & maskgx);
1562 int rb = px0 + px1 - g;
1564 b = (rb & maskb) >> shb;
1565 if (shp || origin == PIX_FMT_BGR565LE || origin == PIX_FMT_BGR565BE ||
1566 origin == PIX_FMT_RGB565LE || origin == PIX_FMT_RGB565BE) {
1569 g = (g & maskg) >> shg;
1571 r = (rb & maskr) >> shr;
1573 dstU[i] = (ru * r + gu * g + bu * b + (unsigned)rnd) >> ((S)-6+1);
1574 dstV[i] = (rv * r + gv * g + bv * b + (unsigned)rnd) >> ((S)-6+1);
1580 #define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr, \
1581 maskg, maskb, rsh, gsh, bsh, S) \
1582 static void name ## ToY_c(uint8_t *dst, const uint8_t *src, \
1583 int width, uint32_t *unused) \
1585 rgb16_32ToY_c_template(dst, src, width, fmt, shr, shg, shb, shp, \
1586 maskr, maskg, maskb, rsh, gsh, bsh, S); \
1589 static void name ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1590 const uint8_t *src, const uint8_t *dummy, \
1591 int width, uint32_t *unused) \
1593 rgb16_32ToUV_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1594 maskr, maskg, maskb, rsh, gsh, bsh, S); \
1597 static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
1598 const uint8_t *src, const uint8_t *dummy, \
1599 int width, uint32_t *unused) \
1601 rgb16_32ToUV_half_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
1602 maskr, maskg, maskb, rsh, gsh, bsh, S); \
1605 rgb16_32_wrapper(PIX_FMT_BGR32, bgr32, 16, 0, 0, 0, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8);
1606 rgb16_32_wrapper(PIX_FMT_BGR32_1, bgr321, 16, 0, 0, 8, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8);
1607 rgb16_32_wrapper(PIX_FMT_RGB32, rgb32, 0, 0, 16, 0, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8);
1608 rgb16_32_wrapper(PIX_FMT_RGB32_1, rgb321, 0, 0, 16, 8, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8);
1609 rgb16_32_wrapper(PIX_FMT_BGR565LE, bgr16le, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8);
1610 rgb16_32_wrapper(PIX_FMT_BGR555LE, bgr15le, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7);
1611 rgb16_32_wrapper(PIX_FMT_RGB565LE, rgb16le, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8);
1612 rgb16_32_wrapper(PIX_FMT_RGB555LE, rgb15le, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7);
1613 rgb16_32_wrapper(PIX_FMT_BGR565BE, bgr16be, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8);
1614 rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr15be, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7);
1615 rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8);
1616 rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7);
1618 static void abgrToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1621 for (i=0; i<width; i++) {
1622 dst[i]= src[4*i]<<6;
1626 static void rgbaToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1629 for (i=0; i<width; i++) {
1630 dst[i]= src[4*i+3]<<6;
1634 static void palToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *pal)
1637 for (i=0; i<width; i++) {
1640 dst[i]= (pal[d] >> 24)<<6;
1644 static void palToY_c(int16_t *dst, const uint8_t *src, long width, uint32_t *pal)
1647 for (i=0; i<width; i++) {
1650 dst[i]= (pal[d] & 0xFF)<<6;
1654 static void palToUV_c(uint16_t *dstU, int16_t *dstV,
1655 const uint8_t *src1, const uint8_t *src2,
1656 int width, uint32_t *pal)
1659 assert(src1 == src2);
1660 for (i=0; i<width; i++) {
1661 int p= pal[src1[i]];
1663 dstU[i]= (uint8_t)(p>> 8)<<6;
1664 dstV[i]= (uint8_t)(p>>16)<<6;
1668 static void monowhite2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1671 for (i=0; i<width/8; i++) {
1674 dst[8*i+j]= ((d>>(7-j))&1)*16383;
1678 for(j=0; j<(width&7); j++)
1679 dst[8*i+j]= ((d>>(7-j))&1)*16383;
1683 static void monoblack2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
1686 for (i=0; i<width/8; i++) {
1689 dst[8*i+j]= ((d>>(7-j))&1)*16383;
1693 for(j=0; j<(width&7); j++)
1694 dst[8*i+j]= ((d>>(7-j))&1)*16383;
1698 //FIXME yuy2* can read up to 7 samples too much
1700 static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, int width,
1704 for (i=0; i<width; i++)
1708 static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1709 const uint8_t *src2, int width, uint32_t *unused)
1712 for (i=0; i<width; i++) {
1713 dstU[i]= src1[4*i + 1];
1714 dstV[i]= src1[4*i + 3];
1716 assert(src1 == src2);
1719 static void LEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1720 const uint8_t *src2, int width, uint32_t *unused)
1723 for (i=0; i<width; i++) {
1724 dstU[i]= src1[2*i + 1];
1725 dstV[i]= src2[2*i + 1];
1729 /* This is almost identical to the previous, end exists only because
1730 * yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
1731 static void uyvyToY_c(uint8_t *dst, const uint8_t *src, int width,
1735 for (i=0; i<width; i++)
1739 static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1740 const uint8_t *src2, int width, uint32_t *unused)
1743 for (i=0; i<width; i++) {
1744 dstU[i]= src1[4*i + 0];
1745 dstV[i]= src1[4*i + 2];
1747 assert(src1 == src2);
1750 static void BEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
1751 const uint8_t *src2, int width, uint32_t *unused)
1754 for (i=0; i<width; i++) {
1760 static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
1761 const uint8_t *src, int width)
1764 for (i = 0; i < width; i++) {
1765 dst1[i] = src[2*i+0];
1766 dst2[i] = src[2*i+1];
1770 static void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
1771 const uint8_t *src1, const uint8_t *src2,
1772 int width, uint32_t *unused)
1774 nvXXtoUV_c(dstU, dstV, src1, width);
1777 static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
1778 const uint8_t *src1, const uint8_t *src2,
1779 int width, uint32_t *unused)
1781 nvXXtoUV_c(dstV, dstU, src1, width);
1784 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
1786 static void bgr24ToY_c(int16_t *dst, const uint8_t *src,
1787 int width, uint32_t *unused)
1790 for (i=0; i<width; i++) {
1795 dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
1799 static void bgr24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1800 const uint8_t *src2, int width, uint32_t *unused)
1803 for (i=0; i<width; i++) {
1804 int b= src1[3*i + 0];
1805 int g= src1[3*i + 1];
1806 int r= src1[3*i + 2];
1808 dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1809 dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1811 assert(src1 == src2);
1814 static void bgr24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1815 const uint8_t *src2, int width, uint32_t *unused)
1818 for (i=0; i<width; i++) {
1819 int b= src1[6*i + 0] + src1[6*i + 3];
1820 int g= src1[6*i + 1] + src1[6*i + 4];
1821 int r= src1[6*i + 2] + src1[6*i + 5];
1823 dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1824 dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1826 assert(src1 == src2);
1829 static void rgb24ToY_c(int16_t *dst, const uint8_t *src, int width,
1833 for (i=0; i<width; i++) {
1838 dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
1842 static void rgb24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1843 const uint8_t *src2, int width, uint32_t *unused)
1847 for (i=0; i<width; i++) {
1848 int r= src1[3*i + 0];
1849 int g= src1[3*i + 1];
1850 int b= src1[3*i + 2];
1852 dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1853 dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1857 static void rgb24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1858 const uint8_t *src2, int width, uint32_t *unused)
1862 for (i=0; i<width; i++) {
1863 int r= src1[6*i + 0] + src1[6*i + 3];
1864 int g= src1[6*i + 1] + src1[6*i + 4];
1865 int b= src1[6*i + 2] + src1[6*i + 5];
1867 dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1868 dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1872 // bilinear / bicubic scaling
1873 static void hScale_c(int16_t *dst, int dstW, const uint8_t *src,
1874 const int16_t *filter, const int16_t *filterPos,
1878 for (i=0; i<dstW; i++) {
1880 int srcPos= filterPos[i];
1882 for (j=0; j<filterSize; j++) {
1883 val += ((int)src[srcPos + j])*filter[filterSize*i + j];
1885 //filter += hFilterSize;
1886 dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
1891 static inline void hScale16_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
1892 const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
1896 for (i=0; i<dstW; i++) {
1897 int srcPos= filterPos[i];
1899 for (j=0; j<filterSize; j++) {
1900 val += ((int)src[srcPos + j])*filter[filterSize*i + j];
1902 dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
1906 static inline void hScale16X_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
1907 const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
1910 for (i=0; i<dstW; i++) {
1911 int srcPos= filterPos[i];
1913 for (j=0; j<filterSize; j++) {
1914 val += ((int)av_bswap16(src[srcPos + j]))*filter[filterSize*i + j];
1916 dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
1920 //FIXME all pal and rgb srcFormats could do this convertion as well
1921 //FIXME all scalers more complex than bilinear could do half of this transform
1922 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1925 for (i = 0; i < width; i++) {
1926 dstU[i] = (FFMIN(dstU[i],30775)*4663 - 9289992)>>12; //-264
1927 dstV[i] = (FFMIN(dstV[i],30775)*4663 - 9289992)>>12; //-264
1930 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1933 for (i = 0; i < width; i++) {
1934 dstU[i] = (dstU[i]*1799 + 4081085)>>11; //1469
1935 dstV[i] = (dstV[i]*1799 + 4081085)>>11; //1469
1938 static void lumRangeToJpeg_c(int16_t *dst, int width)
1941 for (i = 0; i < width; i++)
1942 dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
1944 static void lumRangeFromJpeg_c(int16_t *dst, int width)
1947 for (i = 0; i < width; i++)
1948 dst[i] = (dst[i]*14071 + 33561947)>>14;
1951 static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
1952 const uint8_t *src, int srcW, int xInc)
1955 unsigned int xpos=0;
1956 for (i=0;i<dstWidth;i++) {
1957 register unsigned int xx=xpos>>16;
1958 register unsigned int xalpha=(xpos&0xFFFF)>>9;
1959 dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
1962 for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
1963 dst[i] = src[srcW-1]*128;
1966 // *** horizontal scale Y line to temp buffer
1967 static av_always_inline void hyscale(SwsContext *c, uint16_t *dst, int dstWidth,
1968 const uint8_t *src, int srcW, int xInc,
1969 const int16_t *hLumFilter,
1970 const int16_t *hLumFilterPos, int hLumFilterSize,
1971 uint8_t *formatConvBuffer,
1972 uint32_t *pal, int isAlpha)
1974 void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
1975 void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
1978 toYV12(formatConvBuffer, src, srcW, pal);
1979 src= formatConvBuffer;
1983 int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
1984 c->hScale16(dst, dstWidth, (const uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, shift);
1985 } else if (!c->hyscale_fast) {
1986 c->hScale(dst, dstWidth, src, hLumFilter, hLumFilterPos, hLumFilterSize);
1987 } else { // fast bilinear upscale / crap downscale
1988 c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
1992 convertRange(dst, dstWidth);
1995 static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
1996 int dstWidth, const uint8_t *src1,
1997 const uint8_t *src2, int srcW, int xInc)
2000 unsigned int xpos=0;
2001 for (i=0;i<dstWidth;i++) {
2002 register unsigned int xx=xpos>>16;
2003 register unsigned int xalpha=(xpos&0xFFFF)>>9;
2004 dst1[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
2005 dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
2008 for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {
2009 dst1[i] = src1[srcW-1]*128;
2010 dst2[i] = src2[srcW-1]*128;
2014 static av_always_inline void hcscale(SwsContext *c, uint16_t *dst1, uint16_t *dst2, int dstWidth,
2015 const uint8_t *src1, const uint8_t *src2,
2016 int srcW, int xInc, const int16_t *hChrFilter,
2017 const int16_t *hChrFilterPos, int hChrFilterSize,
2018 uint8_t *formatConvBuffer, uint32_t *pal)
2021 uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16);
2022 c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
2023 src1= formatConvBuffer;
2028 int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
2029 c->hScale16(dst1, dstWidth, (const uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
2030 c->hScale16(dst2, dstWidth, (const uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
2031 } else if (!c->hcscale_fast) {
2032 c->hScale(dst1, dstWidth, src1, hChrFilter, hChrFilterPos, hChrFilterSize);
2033 c->hScale(dst2, dstWidth, src2, hChrFilter, hChrFilterPos, hChrFilterSize);
2034 } else { // fast bilinear upscale / crap downscale
2035 c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc);
2038 if (c->chrConvertRange)
2039 c->chrConvertRange(dst1, dst2, dstWidth);
2042 static av_always_inline void
2043 find_c_packed_planar_out_funcs(SwsContext *c,
2044 yuv2planar1_fn *yuv2yuv1, yuv2planarX_fn *yuv2yuvX,
2045 yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2,
2046 yuv2packedX_fn *yuv2packedX)
2048 enum PixelFormat dstFormat = c->dstFormat;
2050 if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
2051 *yuv2yuvX = yuv2nv12X_c;
2052 } else if (is16BPS(dstFormat)) {
2053 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX16BE_c : yuv2yuvX16LE_c;
2054 } else if (is9_OR_10BPS(dstFormat)) {
2055 if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
2056 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c : yuv2yuvX9LE_c;
2058 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c;
2061 *yuv2yuv1 = yuv2yuv1_c;
2062 *yuv2yuvX = yuv2yuvX_c;
2064 if(c->flags & SWS_FULL_CHR_H_INT) {
2065 switch (dstFormat) {
2068 *yuv2packedX = yuv2rgba32_full_X_c;
2070 #if CONFIG_SWSCALE_ALPHA
2072 *yuv2packedX = yuv2rgba32_full_X_c;
2074 #endif /* CONFIG_SWSCALE_ALPHA */
2076 *yuv2packedX = yuv2rgbx32_full_X_c;
2078 #endif /* !CONFIG_SMALL */
2082 *yuv2packedX = yuv2argb32_full_X_c;
2084 #if CONFIG_SWSCALE_ALPHA
2086 *yuv2packedX = yuv2argb32_full_X_c;
2088 #endif /* CONFIG_SWSCALE_ALPHA */
2090 *yuv2packedX = yuv2xrgb32_full_X_c;
2092 #endif /* !CONFIG_SMALL */
2096 *yuv2packedX = yuv2bgra32_full_X_c;
2098 #if CONFIG_SWSCALE_ALPHA
2100 *yuv2packedX = yuv2bgra32_full_X_c;
2102 #endif /* CONFIG_SWSCALE_ALPHA */
2104 *yuv2packedX = yuv2bgrx32_full_X_c;
2106 #endif /* !CONFIG_SMALL */
2110 *yuv2packedX = yuv2abgr32_full_X_c;
2112 #if CONFIG_SWSCALE_ALPHA
2114 *yuv2packedX = yuv2abgr32_full_X_c;
2116 #endif /* CONFIG_SWSCALE_ALPHA */
2118 *yuv2packedX = yuv2xbgr32_full_X_c;
2120 #endif /* !CONFIG_SMALL */
2123 *yuv2packedX = yuv2rgb24_full_X_c;
2126 *yuv2packedX = yuv2bgr24_full_X_c;
2133 switch (dstFormat) {
2134 case PIX_FMT_GRAY16BE:
2135 *yuv2packed1 = yuv2gray16BE_1_c;
2136 *yuv2packed2 = yuv2gray16BE_2_c;
2137 *yuv2packedX = yuv2gray16BE_X_c;
2139 case PIX_FMT_GRAY16LE:
2140 *yuv2packed1 = yuv2gray16LE_1_c;
2141 *yuv2packed2 = yuv2gray16LE_2_c;
2142 *yuv2packedX = yuv2gray16LE_X_c;
2144 case PIX_FMT_MONOWHITE:
2145 *yuv2packed1 = yuv2monowhite_1_c;
2146 *yuv2packed2 = yuv2monowhite_2_c;
2147 *yuv2packedX = yuv2monowhite_X_c;
2149 case PIX_FMT_MONOBLACK:
2150 *yuv2packed1 = yuv2monoblack_1_c;
2151 *yuv2packed2 = yuv2monoblack_2_c;
2152 *yuv2packedX = yuv2monoblack_X_c;
2154 case PIX_FMT_YUYV422:
2155 *yuv2packed1 = yuv2yuyv422_1_c;
2156 *yuv2packed2 = yuv2yuyv422_2_c;
2157 *yuv2packedX = yuv2yuyv422_X_c;
2159 case PIX_FMT_UYVY422:
2160 *yuv2packed1 = yuv2uyvy422_1_c;
2161 *yuv2packed2 = yuv2uyvy422_2_c;
2162 *yuv2packedX = yuv2uyvy422_X_c;
2164 case PIX_FMT_RGB48LE:
2165 //*yuv2packed1 = yuv2rgb48le_1_c;
2166 //*yuv2packed2 = yuv2rgb48le_2_c;
2167 //*yuv2packedX = yuv2rgb48le_X_c;
2169 case PIX_FMT_RGB48BE:
2170 *yuv2packed1 = yuv2rgb48be_1_c;
2171 *yuv2packed2 = yuv2rgb48be_2_c;
2172 *yuv2packedX = yuv2rgb48be_X_c;
2174 case PIX_FMT_BGR48LE:
2175 //*yuv2packed1 = yuv2bgr48le_1_c;
2176 //*yuv2packed2 = yuv2bgr48le_2_c;
2177 //*yuv2packedX = yuv2bgr48le_X_c;
2179 case PIX_FMT_BGR48BE:
2180 *yuv2packed1 = yuv2bgr48be_1_c;
2181 *yuv2packed2 = yuv2bgr48be_2_c;
2182 *yuv2packedX = yuv2bgr48be_X_c;
2187 *yuv2packed1 = yuv2rgb32_1_c;
2188 *yuv2packed2 = yuv2rgb32_2_c;
2189 *yuv2packedX = yuv2rgb32_X_c;
2191 #if CONFIG_SWSCALE_ALPHA
2193 *yuv2packed1 = yuv2rgba32_1_c;
2194 *yuv2packed2 = yuv2rgba32_2_c;
2195 *yuv2packedX = yuv2rgba32_X_c;
2197 #endif /* CONFIG_SWSCALE_ALPHA */
2199 *yuv2packed1 = yuv2rgbx32_1_c;
2200 *yuv2packed2 = yuv2rgbx32_2_c;
2201 *yuv2packedX = yuv2rgbx32_X_c;
2203 #endif /* !CONFIG_SMALL */
2205 case PIX_FMT_RGB32_1:
2206 case PIX_FMT_BGR32_1:
2208 *yuv2packed1 = yuv2rgb32_1_1_c;
2209 *yuv2packed2 = yuv2rgb32_1_2_c;
2210 *yuv2packedX = yuv2rgb32_1_X_c;
2212 #if CONFIG_SWSCALE_ALPHA
2214 *yuv2packed1 = yuv2rgba32_1_1_c;
2215 *yuv2packed2 = yuv2rgba32_1_2_c;
2216 *yuv2packedX = yuv2rgba32_1_X_c;
2218 #endif /* CONFIG_SWSCALE_ALPHA */
2220 *yuv2packed1 = yuv2rgbx32_1_1_c;
2221 *yuv2packed2 = yuv2rgbx32_1_2_c;
2222 *yuv2packedX = yuv2rgbx32_1_X_c;
2224 #endif /* !CONFIG_SMALL */
2227 *yuv2packed1 = yuv2rgb24_1_c;
2228 *yuv2packed2 = yuv2rgb24_2_c;
2229 *yuv2packedX = yuv2rgb24_X_c;
2232 *yuv2packed1 = yuv2bgr24_1_c;
2233 *yuv2packed2 = yuv2bgr24_2_c;
2234 *yuv2packedX = yuv2bgr24_X_c;
2236 case PIX_FMT_RGB565LE:
2237 case PIX_FMT_RGB565BE:
2238 case PIX_FMT_BGR565LE:
2239 case PIX_FMT_BGR565BE:
2240 *yuv2packed1 = yuv2rgb16_1_c;
2241 *yuv2packed2 = yuv2rgb16_2_c;
2242 *yuv2packedX = yuv2rgb16_X_c;
2244 case PIX_FMT_RGB555LE:
2245 case PIX_FMT_RGB555BE:
2246 case PIX_FMT_BGR555LE:
2247 case PIX_FMT_BGR555BE:
2248 *yuv2packed1 = yuv2rgb15_1_c;
2249 *yuv2packed2 = yuv2rgb15_2_c;
2250 *yuv2packedX = yuv2rgb15_X_c;
2252 case PIX_FMT_RGB444LE:
2253 case PIX_FMT_RGB444BE:
2254 case PIX_FMT_BGR444LE:
2255 case PIX_FMT_BGR444BE:
2256 *yuv2packed1 = yuv2rgb12_1_c;
2257 *yuv2packed2 = yuv2rgb12_2_c;
2258 *yuv2packedX = yuv2rgb12_X_c;
2262 *yuv2packed1 = yuv2rgb8_1_c;
2263 *yuv2packed2 = yuv2rgb8_2_c;
2264 *yuv2packedX = yuv2rgb8_X_c;
2268 *yuv2packed1 = yuv2rgb4_1_c;
2269 *yuv2packed2 = yuv2rgb4_2_c;
2270 *yuv2packedX = yuv2rgb4_X_c;
2272 case PIX_FMT_RGB4_BYTE:
2273 case PIX_FMT_BGR4_BYTE:
2274 *yuv2packed1 = yuv2rgb4b_1_c;
2275 *yuv2packed2 = yuv2rgb4b_2_c;
2276 *yuv2packedX = yuv2rgb4b_X_c;
2282 #define DEBUG_SWSCALE_BUFFERS 0
2283 #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
2285 static int swScale(SwsContext *c, const uint8_t* src[],
2286 int srcStride[], int srcSliceY,
2287 int srcSliceH, uint8_t* dst[], int dstStride[])
2289 /* load a few things into local vars to make the code more readable? and faster */
2290 const int srcW= c->srcW;
2291 const int dstW= c->dstW;
2292 const int dstH= c->dstH;
2293 const int chrDstW= c->chrDstW;
2294 const int chrSrcW= c->chrSrcW;
2295 const int lumXInc= c->lumXInc;
2296 const int chrXInc= c->chrXInc;
2297 const enum PixelFormat dstFormat= c->dstFormat;
2298 const int flags= c->flags;
2299 int16_t *vLumFilterPos= c->vLumFilterPos;
2300 int16_t *vChrFilterPos= c->vChrFilterPos;
2301 int16_t *hLumFilterPos= c->hLumFilterPos;
2302 int16_t *hChrFilterPos= c->hChrFilterPos;
2303 int16_t *vLumFilter= c->vLumFilter;
2304 int16_t *vChrFilter= c->vChrFilter;
2305 int16_t *hLumFilter= c->hLumFilter;
2306 int16_t *hChrFilter= c->hChrFilter;
2307 int32_t *lumMmxFilter= c->lumMmxFilter;
2308 int32_t *chrMmxFilter= c->chrMmxFilter;
2309 int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
2310 const int vLumFilterSize= c->vLumFilterSize;
2311 const int vChrFilterSize= c->vChrFilterSize;
2312 const int hLumFilterSize= c->hLumFilterSize;
2313 const int hChrFilterSize= c->hChrFilterSize;
2314 int16_t **lumPixBuf= c->lumPixBuf;
2315 int16_t **chrUPixBuf= c->chrUPixBuf;
2316 int16_t **chrVPixBuf= c->chrVPixBuf;
2317 int16_t **alpPixBuf= c->alpPixBuf;
2318 const int vLumBufSize= c->vLumBufSize;
2319 const int vChrBufSize= c->vChrBufSize;
2320 uint8_t *formatConvBuffer= c->formatConvBuffer;
2321 const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
2322 const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
2324 uint32_t *pal=c->pal_yuv;
2325 int should_dither= isNBPS(c->srcFormat) || is16BPS(c->srcFormat);
2326 yuv2planar1_fn yuv2yuv1 = c->yuv2yuv1;
2327 yuv2planarX_fn yuv2yuvX = c->yuv2yuvX;
2328 yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
2329 yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
2330 yuv2packedX_fn yuv2packedX = c->yuv2packedX;
2332 /* vars which will change and which we need to store back in the context */
2334 int lumBufIndex= c->lumBufIndex;
2335 int chrBufIndex= c->chrBufIndex;
2336 int lastInLumBuf= c->lastInLumBuf;
2337 int lastInChrBuf= c->lastInChrBuf;
2339 if (isPacked(c->srcFormat)) {
2347 srcStride[3]= srcStride[0];
2349 srcStride[1]<<= c->vChrDrop;
2350 srcStride[2]<<= c->vChrDrop;
2352 DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
2353 src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
2354 dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
2355 DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
2356 srcSliceY, srcSliceH, dstY, dstH);
2357 DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
2358 vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize);
2360 if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
2361 static int warnedAlready=0; //FIXME move this into the context perhaps
2362 if (flags & SWS_PRINT_INFO && !warnedAlready) {
2363 av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
2364 " ->cannot do aligned memory accesses anymore\n");
2369 /* Note the user might start scaling the picture in the middle so this
2370 will not get executed. This is not really intended but works
2371 currently, so people might do it. */
2372 if (srcSliceY ==0) {
2382 for (;dstY < dstH; dstY++) {
2383 const int chrDstY= dstY>>c->chrDstVSubSample;
2384 uint8_t *dest[4] = {
2385 dst[0] + dstStride[0] * dstY,
2386 dst[1] + dstStride[1] * chrDstY,
2387 dst[2] + dstStride[2] * chrDstY,
2388 (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3] + dstStride[3] * dstY : NULL,
2390 const uint8_t *lumDither= should_dither ? dithers[7][dstY &7] : flat64;
2391 const uint8_t *chrDither= should_dither ? dithers[7][chrDstY&7] : flat64;
2393 const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
2394 const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
2395 const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
2396 int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
2397 int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
2398 int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
2401 //handle holes (FAST_BILINEAR & weird filters)
2402 if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
2403 if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
2404 assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
2405 assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
2407 DEBUG_BUFFERS("dstY: %d\n", dstY);
2408 DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
2409 firstLumSrcY, lastLumSrcY, lastInLumBuf);
2410 DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
2411 firstChrSrcY, lastChrSrcY, lastInChrBuf);
2413 // Do we have enough lines in this slice to output the dstY line
2414 enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
2416 if (!enough_lines) {
2417 lastLumSrcY = srcSliceY + srcSliceH - 1;
2418 lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
2419 DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
2420 lastLumSrcY, lastChrSrcY);
2423 //Do horizontal scaling
2424 while(lastInLumBuf < lastLumSrcY) {
2425 const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
2426 const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
2428 assert(lumBufIndex < 2*vLumBufSize);
2429 assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
2430 assert(lastInLumBuf + 1 - srcSliceY >= 0);
2431 hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
2432 hLumFilter, hLumFilterPos, hLumFilterSize,
2435 if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
2436 hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW,
2437 lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
2441 DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
2442 lumBufIndex, lastInLumBuf);
2444 while(lastInChrBuf < lastChrSrcY) {
2445 const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
2446 const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
2448 assert(chrBufIndex < 2*vChrBufSize);
2449 assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
2450 assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
2451 //FIXME replace parameters through context struct (some at least)
2453 if (c->needs_hcscale)
2454 hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
2455 chrDstW, src1, src2, chrSrcW, chrXInc,
2456 hChrFilter, hChrFilterPos, hChrFilterSize,
2457 formatConvBuffer, pal);
2459 DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
2460 chrBufIndex, lastInChrBuf);
2462 //wrap buf index around to stay inside the ring buffer
2463 if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
2464 if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
2466 break; //we can't output a dstY line so let's try with the next slice
2469 updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf);
2471 if (dstY >= dstH-2) {
2472 // hmm looks like we can't use MMX here without overwriting this array's tail
2473 find_c_packed_planar_out_funcs(c, &yuv2yuv1, &yuv2yuvX,
2474 &yuv2packed1, &yuv2packed2,
2479 const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
2480 const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2481 const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2482 const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
2484 if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
2485 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2486 if ((dstY&chrSkipMask) || isGray(dstFormat))
2487 dest[1] = dest[2] = NULL; //FIXME split functions in lumi / chromi
2488 if (c->yuv2yuv1 && vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
2489 const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
2490 yuv2yuv1(c, lumSrcPtr[0], chrUSrcPtr[0], chrVSrcPtr[0], alpBuf,
2491 dest, dstW, chrDstW, lumDither, chrDither);
2492 } else { //General YV12
2493 yuv2yuvX(c, vLumFilter + dstY * vLumFilterSize,
2494 lumSrcPtr, vLumFilterSize,
2495 vChrFilter + chrDstY * vChrFilterSize,
2496 chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2497 alpSrcPtr, dest, dstW, chrDstW, lumDither, chrDither);
2500 assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
2501 assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize*2);
2502 if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
2503 int chrAlpha = vChrFilter[2 * dstY + 1];
2504 yuv2packed1(c, *lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
2505 alpPixBuf ? *alpSrcPtr : NULL,
2506 dest[0], dstW, chrAlpha, dstY);
2507 } else if (c->yuv2packed2 && vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
2508 int lumAlpha = vLumFilter[2 * dstY + 1];
2509 int chrAlpha = vChrFilter[2 * dstY + 1];
2511 lumMmxFilter[3] = vLumFilter[2 * dstY ] * 0x10001;
2513 chrMmxFilter[3] = vChrFilter[2 * chrDstY] * 0x10001;
2514 yuv2packed2(c, lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
2515 alpPixBuf ? alpSrcPtr : NULL,
2516 dest[0], dstW, lumAlpha, chrAlpha, dstY);
2517 } else { //general RGB
2518 yuv2packedX(c, vLumFilter + dstY * vLumFilterSize,
2519 lumSrcPtr, vLumFilterSize,
2520 vChrFilter + dstY * vChrFilterSize,
2521 chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2522 alpSrcPtr, dest[0], dstW, dstY);
2528 if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
2529 fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
2532 if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2)
2533 __asm__ volatile("sfence":::"memory");
2537 /* store changed local vars back in the context */
2539 c->lumBufIndex= lumBufIndex;
2540 c->chrBufIndex= chrBufIndex;
2541 c->lastInLumBuf= lastInLumBuf;
2542 c->lastInChrBuf= lastInChrBuf;
2544 return dstY - lastDstY;
2547 static av_cold void sws_init_swScale_c(SwsContext *c)
2549 enum PixelFormat srcFormat = c->srcFormat;
2551 find_c_packed_planar_out_funcs(c, &c->yuv2yuv1, &c->yuv2yuvX,
2552 &c->yuv2packed1, &c->yuv2packed2,
2555 c->hScale = hScale_c;
2557 if (c->flags & SWS_FAST_BILINEAR) {
2558 c->hyscale_fast = hyscale_fast_c;
2559 c->hcscale_fast = hcscale_fast_c;
2562 c->chrToYV12 = NULL;
2564 case PIX_FMT_YUYV422 : c->chrToYV12 = yuy2ToUV_c; break;
2565 case PIX_FMT_UYVY422 : c->chrToYV12 = uyvyToUV_c; break;
2566 case PIX_FMT_NV12 : c->chrToYV12 = nv12ToUV_c; break;
2567 case PIX_FMT_NV21 : c->chrToYV12 = nv21ToUV_c; break;
2571 case PIX_FMT_BGR4_BYTE:
2572 case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
2573 case PIX_FMT_GRAY16BE :
2574 case PIX_FMT_YUV444P9BE:
2575 case PIX_FMT_YUV420P9BE:
2576 case PIX_FMT_YUV444P10BE:
2577 case PIX_FMT_YUV422P10BE:
2578 case PIX_FMT_YUV420P10BE:
2579 case PIX_FMT_YUV420P16BE:
2580 case PIX_FMT_YUV422P16BE:
2581 case PIX_FMT_YUV444P16BE: c->hScale16= HAVE_BIGENDIAN ? hScale16_c : hScale16X_c; break;
2582 case PIX_FMT_GRAY16LE :
2583 case PIX_FMT_YUV444P9LE:
2584 case PIX_FMT_YUV420P9LE:
2585 case PIX_FMT_YUV422P10LE:
2586 case PIX_FMT_YUV420P10LE:
2587 case PIX_FMT_YUV444P10LE:
2588 case PIX_FMT_YUV420P16LE:
2589 case PIX_FMT_YUV422P16LE:
2590 case PIX_FMT_YUV444P16LE: c->hScale16= HAVE_BIGENDIAN ? hScale16X_c : hScale16_c; break;
2592 if (c->chrSrcHSubSample) {
2594 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_half_c; break;
2595 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_half_c; break;
2596 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_half_c; break;
2597 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_half_c; break;
2598 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_half_c; break;
2599 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_half_c; break;
2600 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_half_c; break;
2601 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_half_c; break;
2602 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_half_c; break;
2603 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_half_c; break;
2604 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_half_c; break;
2605 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_half_c; break;
2606 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_half_c; break;
2607 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_half_c; break;
2608 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_half_c; break;
2609 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_half_c; break;
2610 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_half_c; break;
2611 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_half_c; break;
2615 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_c; break;
2616 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_c; break;
2617 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_c; break;
2618 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_c; break;
2619 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_c; break;
2620 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_c; break;
2621 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_c; break;
2622 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_c; break;
2623 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_c; break;
2624 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_c; break;
2625 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_c; break;
2626 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_c; break;
2627 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_c; break;
2628 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_c; break;
2629 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_c; break;
2630 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_c; break;
2631 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_c; break;
2632 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_c; break;
2636 c->lumToYV12 = NULL;
2637 c->alpToYV12 = NULL;
2638 switch (srcFormat) {
2639 case PIX_FMT_YUYV422 :
2640 case PIX_FMT_GRAY8A :
2641 c->lumToYV12 = yuy2ToY_c; break;
2642 case PIX_FMT_UYVY422 :
2643 c->lumToYV12 = uyvyToY_c; break;
2644 case PIX_FMT_BGR24 : c->lumToYV12 = bgr24ToY_c; break;
2645 case PIX_FMT_BGR565LE : c->lumToYV12 = bgr16leToY_c; break;
2646 case PIX_FMT_BGR565BE : c->lumToYV12 = bgr16beToY_c; break;
2647 case PIX_FMT_BGR555LE : c->lumToYV12 = bgr15leToY_c; break;
2648 case PIX_FMT_BGR555BE : c->lumToYV12 = bgr15beToY_c; break;
2649 case PIX_FMT_RGB24 : c->lumToYV12 = rgb24ToY_c; break;
2650 case PIX_FMT_RGB565LE : c->lumToYV12 = rgb16leToY_c; break;
2651 case PIX_FMT_RGB565BE : c->lumToYV12 = rgb16beToY_c; break;
2652 case PIX_FMT_RGB555LE : c->lumToYV12 = rgb15leToY_c; break;
2653 case PIX_FMT_RGB555BE : c->lumToYV12 = rgb15beToY_c; break;
2657 case PIX_FMT_BGR4_BYTE:
2658 case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY_c; break;
2659 case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y_c; break;
2660 case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y_c; break;
2661 case PIX_FMT_RGB32 : c->lumToYV12 = bgr32ToY_c; break;
2662 case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY_c; break;
2663 case PIX_FMT_BGR32 : c->lumToYV12 = rgb32ToY_c; break;
2664 case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY_c; break;
2665 case PIX_FMT_RGB48BE: c->lumToYV12 = rgb48BEToY_c; break;
2666 case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break;
2667 case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break;
2668 case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break;
2671 switch (srcFormat) {
2673 case PIX_FMT_RGBA: c->alpToYV12 = rgbaToA_c; break;
2675 case PIX_FMT_ARGB: c->alpToYV12 = abgrToA_c; break;
2676 case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
2677 case PIX_FMT_PAL8 : c->alpToYV12 = palToA_c; break;
2681 if(isAnyRGB(c->srcFormat) || c->srcFormat == PIX_FMT_PAL8)
2682 c->hScale16= hScale16_c;
2684 if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
2686 c->lumConvertRange = lumRangeFromJpeg_c;
2687 c->chrConvertRange = chrRangeFromJpeg_c;
2689 c->lumConvertRange = lumRangeToJpeg_c;
2690 c->chrConvertRange = chrRangeToJpeg_c;
2694 if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
2695 srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE))
2696 c->needs_hcscale = 1;
2699 SwsFunc ff_getSwsFunc(SwsContext *c)
2701 sws_init_swScale_c(c);
2704 ff_sws_init_swScale_mmx(c);
2706 ff_sws_init_swScale_altivec(c);