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 // FIXME Maybe dither instead.
1787 static av_always_inline void
1788 yuv9_OR_10ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
1789 const uint8_t *_srcU, const uint8_t *_srcV,
1790 int width, enum PixelFormat origin, int depth)
1793 const uint16_t *srcU = (const uint16_t *) _srcU;
1794 const uint16_t *srcV = (const uint16_t *) _srcV;
1796 for (i = 0; i < width; i++) {
1797 dstU[i] = input_pixel(&srcU[i]) >> (depth - 8);
1798 dstV[i] = input_pixel(&srcV[i]) >> (depth - 8);
1802 static av_always_inline void
1803 yuv9_or_10ToY_c_template(uint8_t *dstY, const uint8_t *_srcY,
1804 int width, enum PixelFormat origin, int depth)
1807 const uint16_t *srcY = (const uint16_t*)_srcY;
1809 for (i = 0; i < width; i++)
1810 dstY[i] = input_pixel(&srcY[i]) >> (depth - 8);
1815 #define YUV_NBPS(depth, BE_LE, origin) \
1816 static void BE_LE ## depth ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
1817 const uint8_t *srcU, const uint8_t *srcV, \
1818 int width, uint32_t *unused) \
1820 yuv9_OR_10ToUV_c_template(dstU, dstV, srcU, srcV, width, origin, depth); \
1822 static void BE_LE ## depth ## ToY_c(uint8_t *dstY, const uint8_t *srcY, \
1823 int width, uint32_t *unused) \
1825 yuv9_or_10ToY_c_template(dstY, srcY, width, origin, depth); \
1828 YUV_NBPS( 9, LE, PIX_FMT_YUV420P9LE);
1829 YUV_NBPS( 9, BE, PIX_FMT_YUV420P9BE);
1830 YUV_NBPS(10, LE, PIX_FMT_YUV420P10LE);
1831 YUV_NBPS(10, BE, PIX_FMT_YUV420P10BE);
1833 static void bgr24ToY_c(int16_t *dst, const uint8_t *src,
1834 int width, uint32_t *unused)
1837 for (i=0; i<width; i++) {
1842 dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
1846 static void bgr24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1847 const uint8_t *src2, int width, uint32_t *unused)
1850 for (i=0; i<width; i++) {
1851 int b= src1[3*i + 0];
1852 int g= src1[3*i + 1];
1853 int r= src1[3*i + 2];
1855 dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1856 dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1858 assert(src1 == src2);
1861 static void bgr24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1862 const uint8_t *src2, int width, uint32_t *unused)
1865 for (i=0; i<width; i++) {
1866 int b= src1[6*i + 0] + src1[6*i + 3];
1867 int g= src1[6*i + 1] + src1[6*i + 4];
1868 int r= src1[6*i + 2] + src1[6*i + 5];
1870 dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1871 dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1873 assert(src1 == src2);
1876 static void rgb24ToY_c(int16_t *dst, const uint8_t *src, int width,
1880 for (i=0; i<width; i++) {
1885 dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
1889 static void rgb24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1890 const uint8_t *src2, int width, uint32_t *unused)
1894 for (i=0; i<width; i++) {
1895 int r= src1[3*i + 0];
1896 int g= src1[3*i + 1];
1897 int b= src1[3*i + 2];
1899 dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1900 dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
1904 static void rgb24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
1905 const uint8_t *src2, int width, uint32_t *unused)
1909 for (i=0; i<width; i++) {
1910 int r= src1[6*i + 0] + src1[6*i + 3];
1911 int g= src1[6*i + 1] + src1[6*i + 4];
1912 int b= src1[6*i + 2] + src1[6*i + 5];
1914 dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1915 dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
1919 // bilinear / bicubic scaling
1920 static void hScale_c(int16_t *dst, int dstW, const uint8_t *src,
1921 const int16_t *filter, const int16_t *filterPos,
1925 for (i=0; i<dstW; i++) {
1927 int srcPos= filterPos[i];
1929 for (j=0; j<filterSize; j++) {
1930 val += ((int)src[srcPos + j])*filter[filterSize*i + j];
1932 //filter += hFilterSize;
1933 dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
1938 static inline void hScale16_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
1939 const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
1943 for (i=0; i<dstW; i++) {
1944 int srcPos= filterPos[i];
1946 for (j=0; j<filterSize; j++) {
1947 val += ((int)src[srcPos + j])*filter[filterSize*i + j];
1949 dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
1953 static inline void hScale16X_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
1954 const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
1957 for (i=0; i<dstW; i++) {
1958 int srcPos= filterPos[i];
1960 for (j=0; j<filterSize; j++) {
1961 val += ((int)av_bswap16(src[srcPos + j]))*filter[filterSize*i + j];
1963 dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
1967 //FIXME all pal and rgb srcFormats could do this convertion as well
1968 //FIXME all scalers more complex than bilinear could do half of this transform
1969 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1972 for (i = 0; i < width; i++) {
1973 dstU[i] = (FFMIN(dstU[i],30775)*4663 - 9289992)>>12; //-264
1974 dstV[i] = (FFMIN(dstV[i],30775)*4663 - 9289992)>>12; //-264
1977 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
1980 for (i = 0; i < width; i++) {
1981 dstU[i] = (dstU[i]*1799 + 4081085)>>11; //1469
1982 dstV[i] = (dstV[i]*1799 + 4081085)>>11; //1469
1985 static void lumRangeToJpeg_c(int16_t *dst, int width)
1988 for (i = 0; i < width; i++)
1989 dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
1991 static void lumRangeFromJpeg_c(int16_t *dst, int width)
1994 for (i = 0; i < width; i++)
1995 dst[i] = (dst[i]*14071 + 33561947)>>14;
1998 static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
1999 const uint8_t *src, int srcW, int xInc)
2002 unsigned int xpos=0;
2003 for (i=0;i<dstWidth;i++) {
2004 register unsigned int xx=xpos>>16;
2005 register unsigned int xalpha=(xpos&0xFFFF)>>9;
2006 dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
2009 for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
2010 dst[i] = src[srcW-1]*128;
2013 // *** horizontal scale Y line to temp buffer
2014 static av_always_inline void hyscale(SwsContext *c, uint16_t *dst, int dstWidth,
2015 const uint8_t *src, int srcW, int xInc,
2016 const int16_t *hLumFilter,
2017 const int16_t *hLumFilterPos, int hLumFilterSize,
2018 uint8_t *formatConvBuffer,
2019 uint32_t *pal, int isAlpha)
2021 void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
2022 void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
2025 toYV12(formatConvBuffer, src, srcW, pal);
2026 src= formatConvBuffer;
2030 int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
2031 c->hScale16(dst, dstWidth, (const uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, shift);
2032 } else if (!c->hyscale_fast) {
2033 c->hScale(dst, dstWidth, src, hLumFilter, hLumFilterPos, hLumFilterSize);
2034 } else { // fast bilinear upscale / crap downscale
2035 c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
2039 convertRange(dst, dstWidth);
2042 static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
2043 int dstWidth, const uint8_t *src1,
2044 const uint8_t *src2, int srcW, int xInc)
2047 unsigned int xpos=0;
2048 for (i=0;i<dstWidth;i++) {
2049 register unsigned int xx=xpos>>16;
2050 register unsigned int xalpha=(xpos&0xFFFF)>>9;
2051 dst1[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
2052 dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
2055 for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {
2056 dst1[i] = src1[srcW-1]*128;
2057 dst2[i] = src2[srcW-1]*128;
2061 static av_always_inline void hcscale(SwsContext *c, uint16_t *dst1, uint16_t *dst2, int dstWidth,
2062 const uint8_t *src1, const uint8_t *src2,
2063 int srcW, int xInc, const int16_t *hChrFilter,
2064 const int16_t *hChrFilterPos, int hChrFilterSize,
2065 uint8_t *formatConvBuffer, uint32_t *pal)
2068 uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16);
2069 c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
2070 src1= formatConvBuffer;
2075 int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
2076 c->hScale16(dst1, dstWidth, (const uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
2077 c->hScale16(dst2, dstWidth, (const uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
2078 } else if (!c->hcscale_fast) {
2079 c->hScale(dst1, dstWidth, src1, hChrFilter, hChrFilterPos, hChrFilterSize);
2080 c->hScale(dst2, dstWidth, src2, hChrFilter, hChrFilterPos, hChrFilterSize);
2081 } else { // fast bilinear upscale / crap downscale
2082 c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc);
2085 if (c->chrConvertRange)
2086 c->chrConvertRange(dst1, dst2, dstWidth);
2089 static av_always_inline void
2090 find_c_packed_planar_out_funcs(SwsContext *c,
2091 yuv2planar1_fn *yuv2yuv1, yuv2planarX_fn *yuv2yuvX,
2092 yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2,
2093 yuv2packedX_fn *yuv2packedX)
2095 enum PixelFormat dstFormat = c->dstFormat;
2097 if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
2098 *yuv2yuvX = yuv2nv12X_c;
2099 } else if (is16BPS(dstFormat)) {
2100 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX16BE_c : yuv2yuvX16LE_c;
2101 } else if (is9_OR_10BPS(dstFormat)) {
2102 if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
2103 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c : yuv2yuvX9LE_c;
2105 *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c;
2108 *yuv2yuv1 = yuv2yuv1_c;
2109 *yuv2yuvX = yuv2yuvX_c;
2111 if(c->flags & SWS_FULL_CHR_H_INT) {
2112 switch (dstFormat) {
2115 *yuv2packedX = yuv2rgba32_full_X_c;
2117 #if CONFIG_SWSCALE_ALPHA
2119 *yuv2packedX = yuv2rgba32_full_X_c;
2121 #endif /* CONFIG_SWSCALE_ALPHA */
2123 *yuv2packedX = yuv2rgbx32_full_X_c;
2125 #endif /* !CONFIG_SMALL */
2129 *yuv2packedX = yuv2argb32_full_X_c;
2131 #if CONFIG_SWSCALE_ALPHA
2133 *yuv2packedX = yuv2argb32_full_X_c;
2135 #endif /* CONFIG_SWSCALE_ALPHA */
2137 *yuv2packedX = yuv2xrgb32_full_X_c;
2139 #endif /* !CONFIG_SMALL */
2143 *yuv2packedX = yuv2bgra32_full_X_c;
2145 #if CONFIG_SWSCALE_ALPHA
2147 *yuv2packedX = yuv2bgra32_full_X_c;
2149 #endif /* CONFIG_SWSCALE_ALPHA */
2151 *yuv2packedX = yuv2bgrx32_full_X_c;
2153 #endif /* !CONFIG_SMALL */
2157 *yuv2packedX = yuv2abgr32_full_X_c;
2159 #if CONFIG_SWSCALE_ALPHA
2161 *yuv2packedX = yuv2abgr32_full_X_c;
2163 #endif /* CONFIG_SWSCALE_ALPHA */
2165 *yuv2packedX = yuv2xbgr32_full_X_c;
2167 #endif /* !CONFIG_SMALL */
2170 *yuv2packedX = yuv2rgb24_full_X_c;
2173 *yuv2packedX = yuv2bgr24_full_X_c;
2180 switch (dstFormat) {
2181 case PIX_FMT_GRAY16BE:
2182 *yuv2packed1 = yuv2gray16BE_1_c;
2183 *yuv2packed2 = yuv2gray16BE_2_c;
2184 *yuv2packedX = yuv2gray16BE_X_c;
2186 case PIX_FMT_GRAY16LE:
2187 *yuv2packed1 = yuv2gray16LE_1_c;
2188 *yuv2packed2 = yuv2gray16LE_2_c;
2189 *yuv2packedX = yuv2gray16LE_X_c;
2191 case PIX_FMT_MONOWHITE:
2192 *yuv2packed1 = yuv2monowhite_1_c;
2193 *yuv2packed2 = yuv2monowhite_2_c;
2194 *yuv2packedX = yuv2monowhite_X_c;
2196 case PIX_FMT_MONOBLACK:
2197 *yuv2packed1 = yuv2monoblack_1_c;
2198 *yuv2packed2 = yuv2monoblack_2_c;
2199 *yuv2packedX = yuv2monoblack_X_c;
2201 case PIX_FMT_YUYV422:
2202 *yuv2packed1 = yuv2yuyv422_1_c;
2203 *yuv2packed2 = yuv2yuyv422_2_c;
2204 *yuv2packedX = yuv2yuyv422_X_c;
2206 case PIX_FMT_UYVY422:
2207 *yuv2packed1 = yuv2uyvy422_1_c;
2208 *yuv2packed2 = yuv2uyvy422_2_c;
2209 *yuv2packedX = yuv2uyvy422_X_c;
2211 case PIX_FMT_RGB48LE:
2212 //*yuv2packed1 = yuv2rgb48le_1_c;
2213 //*yuv2packed2 = yuv2rgb48le_2_c;
2214 //*yuv2packedX = yuv2rgb48le_X_c;
2216 case PIX_FMT_RGB48BE:
2217 *yuv2packed1 = yuv2rgb48be_1_c;
2218 *yuv2packed2 = yuv2rgb48be_2_c;
2219 *yuv2packedX = yuv2rgb48be_X_c;
2221 case PIX_FMT_BGR48LE:
2222 //*yuv2packed1 = yuv2bgr48le_1_c;
2223 //*yuv2packed2 = yuv2bgr48le_2_c;
2224 //*yuv2packedX = yuv2bgr48le_X_c;
2226 case PIX_FMT_BGR48BE:
2227 *yuv2packed1 = yuv2bgr48be_1_c;
2228 *yuv2packed2 = yuv2bgr48be_2_c;
2229 *yuv2packedX = yuv2bgr48be_X_c;
2234 *yuv2packed1 = yuv2rgb32_1_c;
2235 *yuv2packed2 = yuv2rgb32_2_c;
2236 *yuv2packedX = yuv2rgb32_X_c;
2238 #if CONFIG_SWSCALE_ALPHA
2240 *yuv2packed1 = yuv2rgba32_1_c;
2241 *yuv2packed2 = yuv2rgba32_2_c;
2242 *yuv2packedX = yuv2rgba32_X_c;
2244 #endif /* CONFIG_SWSCALE_ALPHA */
2246 *yuv2packed1 = yuv2rgbx32_1_c;
2247 *yuv2packed2 = yuv2rgbx32_2_c;
2248 *yuv2packedX = yuv2rgbx32_X_c;
2250 #endif /* !CONFIG_SMALL */
2252 case PIX_FMT_RGB32_1:
2253 case PIX_FMT_BGR32_1:
2255 *yuv2packed1 = yuv2rgb32_1_1_c;
2256 *yuv2packed2 = yuv2rgb32_1_2_c;
2257 *yuv2packedX = yuv2rgb32_1_X_c;
2259 #if CONFIG_SWSCALE_ALPHA
2261 *yuv2packed1 = yuv2rgba32_1_1_c;
2262 *yuv2packed2 = yuv2rgba32_1_2_c;
2263 *yuv2packedX = yuv2rgba32_1_X_c;
2265 #endif /* CONFIG_SWSCALE_ALPHA */
2267 *yuv2packed1 = yuv2rgbx32_1_1_c;
2268 *yuv2packed2 = yuv2rgbx32_1_2_c;
2269 *yuv2packedX = yuv2rgbx32_1_X_c;
2271 #endif /* !CONFIG_SMALL */
2274 *yuv2packed1 = yuv2rgb24_1_c;
2275 *yuv2packed2 = yuv2rgb24_2_c;
2276 *yuv2packedX = yuv2rgb24_X_c;
2279 *yuv2packed1 = yuv2bgr24_1_c;
2280 *yuv2packed2 = yuv2bgr24_2_c;
2281 *yuv2packedX = yuv2bgr24_X_c;
2283 case PIX_FMT_RGB565LE:
2284 case PIX_FMT_RGB565BE:
2285 case PIX_FMT_BGR565LE:
2286 case PIX_FMT_BGR565BE:
2287 *yuv2packed1 = yuv2rgb16_1_c;
2288 *yuv2packed2 = yuv2rgb16_2_c;
2289 *yuv2packedX = yuv2rgb16_X_c;
2291 case PIX_FMT_RGB555LE:
2292 case PIX_FMT_RGB555BE:
2293 case PIX_FMT_BGR555LE:
2294 case PIX_FMT_BGR555BE:
2295 *yuv2packed1 = yuv2rgb15_1_c;
2296 *yuv2packed2 = yuv2rgb15_2_c;
2297 *yuv2packedX = yuv2rgb15_X_c;
2299 case PIX_FMT_RGB444LE:
2300 case PIX_FMT_RGB444BE:
2301 case PIX_FMT_BGR444LE:
2302 case PIX_FMT_BGR444BE:
2303 *yuv2packed1 = yuv2rgb12_1_c;
2304 *yuv2packed2 = yuv2rgb12_2_c;
2305 *yuv2packedX = yuv2rgb12_X_c;
2309 *yuv2packed1 = yuv2rgb8_1_c;
2310 *yuv2packed2 = yuv2rgb8_2_c;
2311 *yuv2packedX = yuv2rgb8_X_c;
2315 *yuv2packed1 = yuv2rgb4_1_c;
2316 *yuv2packed2 = yuv2rgb4_2_c;
2317 *yuv2packedX = yuv2rgb4_X_c;
2319 case PIX_FMT_RGB4_BYTE:
2320 case PIX_FMT_BGR4_BYTE:
2321 *yuv2packed1 = yuv2rgb4b_1_c;
2322 *yuv2packed2 = yuv2rgb4b_2_c;
2323 *yuv2packedX = yuv2rgb4b_X_c;
2329 #define DEBUG_SWSCALE_BUFFERS 0
2330 #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
2332 static int swScale(SwsContext *c, const uint8_t* src[],
2333 int srcStride[], int srcSliceY,
2334 int srcSliceH, uint8_t* dst[], int dstStride[])
2336 /* load a few things into local vars to make the code more readable? and faster */
2337 const int srcW= c->srcW;
2338 const int dstW= c->dstW;
2339 const int dstH= c->dstH;
2340 const int chrDstW= c->chrDstW;
2341 const int chrSrcW= c->chrSrcW;
2342 const int lumXInc= c->lumXInc;
2343 const int chrXInc= c->chrXInc;
2344 const enum PixelFormat dstFormat= c->dstFormat;
2345 const int flags= c->flags;
2346 int16_t *vLumFilterPos= c->vLumFilterPos;
2347 int16_t *vChrFilterPos= c->vChrFilterPos;
2348 int16_t *hLumFilterPos= c->hLumFilterPos;
2349 int16_t *hChrFilterPos= c->hChrFilterPos;
2350 int16_t *vLumFilter= c->vLumFilter;
2351 int16_t *vChrFilter= c->vChrFilter;
2352 int16_t *hLumFilter= c->hLumFilter;
2353 int16_t *hChrFilter= c->hChrFilter;
2354 int32_t *lumMmxFilter= c->lumMmxFilter;
2355 int32_t *chrMmxFilter= c->chrMmxFilter;
2356 int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
2357 const int vLumFilterSize= c->vLumFilterSize;
2358 const int vChrFilterSize= c->vChrFilterSize;
2359 const int hLumFilterSize= c->hLumFilterSize;
2360 const int hChrFilterSize= c->hChrFilterSize;
2361 int16_t **lumPixBuf= c->lumPixBuf;
2362 int16_t **chrUPixBuf= c->chrUPixBuf;
2363 int16_t **chrVPixBuf= c->chrVPixBuf;
2364 int16_t **alpPixBuf= c->alpPixBuf;
2365 const int vLumBufSize= c->vLumBufSize;
2366 const int vChrBufSize= c->vChrBufSize;
2367 uint8_t *formatConvBuffer= c->formatConvBuffer;
2368 const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
2369 const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
2371 uint32_t *pal=c->pal_yuv;
2372 int should_dither= isNBPS(c->srcFormat) || is16BPS(c->srcFormat);
2373 yuv2planar1_fn yuv2yuv1 = c->yuv2yuv1;
2374 yuv2planarX_fn yuv2yuvX = c->yuv2yuvX;
2375 yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
2376 yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
2377 yuv2packedX_fn yuv2packedX = c->yuv2packedX;
2379 /* vars which will change and which we need to store back in the context */
2381 int lumBufIndex= c->lumBufIndex;
2382 int chrBufIndex= c->chrBufIndex;
2383 int lastInLumBuf= c->lastInLumBuf;
2384 int lastInChrBuf= c->lastInChrBuf;
2386 if (isPacked(c->srcFormat)) {
2394 srcStride[3]= srcStride[0];
2396 srcStride[1]<<= c->vChrDrop;
2397 srcStride[2]<<= c->vChrDrop;
2399 DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
2400 src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
2401 dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
2402 DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
2403 srcSliceY, srcSliceH, dstY, dstH);
2404 DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
2405 vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize);
2407 if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
2408 static int warnedAlready=0; //FIXME move this into the context perhaps
2409 if (flags & SWS_PRINT_INFO && !warnedAlready) {
2410 av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
2411 " ->cannot do aligned memory accesses anymore\n");
2416 /* Note the user might start scaling the picture in the middle so this
2417 will not get executed. This is not really intended but works
2418 currently, so people might do it. */
2419 if (srcSliceY ==0) {
2429 for (;dstY < dstH; dstY++) {
2430 const int chrDstY= dstY>>c->chrDstVSubSample;
2431 uint8_t *dest[4] = {
2432 dst[0] + dstStride[0] * dstY,
2433 dst[1] + dstStride[1] * chrDstY,
2434 dst[2] + dstStride[2] * chrDstY,
2435 (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3] + dstStride[3] * dstY : NULL,
2437 const uint8_t *lumDither= should_dither ? dithers[7][dstY &7] : flat64;
2438 const uint8_t *chrDither= should_dither ? dithers[7][chrDstY&7] : flat64;
2440 const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
2441 const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
2442 const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
2443 int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
2444 int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
2445 int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
2448 //handle holes (FAST_BILINEAR & weird filters)
2449 if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
2450 if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
2451 assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
2452 assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
2454 DEBUG_BUFFERS("dstY: %d\n", dstY);
2455 DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
2456 firstLumSrcY, lastLumSrcY, lastInLumBuf);
2457 DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
2458 firstChrSrcY, lastChrSrcY, lastInChrBuf);
2460 // Do we have enough lines in this slice to output the dstY line
2461 enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
2463 if (!enough_lines) {
2464 lastLumSrcY = srcSliceY + srcSliceH - 1;
2465 lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
2466 DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
2467 lastLumSrcY, lastChrSrcY);
2470 //Do horizontal scaling
2471 while(lastInLumBuf < lastLumSrcY) {
2472 const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
2473 const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
2475 assert(lumBufIndex < 2*vLumBufSize);
2476 assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
2477 assert(lastInLumBuf + 1 - srcSliceY >= 0);
2478 hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
2479 hLumFilter, hLumFilterPos, hLumFilterSize,
2482 if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
2483 hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW,
2484 lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
2488 DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
2489 lumBufIndex, lastInLumBuf);
2491 while(lastInChrBuf < lastChrSrcY) {
2492 const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
2493 const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
2495 assert(chrBufIndex < 2*vChrBufSize);
2496 assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
2497 assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
2498 //FIXME replace parameters through context struct (some at least)
2500 if (c->needs_hcscale)
2501 hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
2502 chrDstW, src1, src2, chrSrcW, chrXInc,
2503 hChrFilter, hChrFilterPos, hChrFilterSize,
2504 formatConvBuffer, pal);
2506 DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
2507 chrBufIndex, lastInChrBuf);
2509 //wrap buf index around to stay inside the ring buffer
2510 if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
2511 if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
2513 break; //we can't output a dstY line so let's try with the next slice
2516 updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf);
2518 if (dstY >= dstH-2) {
2519 // hmm looks like we can't use MMX here without overwriting this array's tail
2520 find_c_packed_planar_out_funcs(c, &yuv2yuv1, &yuv2yuvX,
2521 &yuv2packed1, &yuv2packed2,
2526 const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
2527 const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2528 const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2529 const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
2531 if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
2532 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2533 if ((dstY&chrSkipMask) || isGray(dstFormat))
2534 dest[1] = dest[2] = NULL; //FIXME split functions in lumi / chromi
2535 if (c->yuv2yuv1 && vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
2536 const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
2537 yuv2yuv1(c, lumSrcPtr[0], chrUSrcPtr[0], chrVSrcPtr[0], alpBuf,
2538 dest, dstW, chrDstW, lumDither, chrDither);
2539 } else { //General YV12
2540 yuv2yuvX(c, vLumFilter + dstY * vLumFilterSize,
2541 lumSrcPtr, vLumFilterSize,
2542 vChrFilter + chrDstY * vChrFilterSize,
2543 chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2544 alpSrcPtr, dest, dstW, chrDstW, lumDither, chrDither);
2547 assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
2548 assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize*2);
2549 if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
2550 int chrAlpha = vChrFilter[2 * dstY + 1];
2551 yuv2packed1(c, *lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
2552 alpPixBuf ? *alpSrcPtr : NULL,
2553 dest[0], dstW, chrAlpha, dstY);
2554 } else if (c->yuv2packed2 && vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
2555 int lumAlpha = vLumFilter[2 * dstY + 1];
2556 int chrAlpha = vChrFilter[2 * dstY + 1];
2558 lumMmxFilter[3] = vLumFilter[2 * dstY ] * 0x10001;
2560 chrMmxFilter[3] = vChrFilter[2 * chrDstY] * 0x10001;
2561 yuv2packed2(c, lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
2562 alpPixBuf ? alpSrcPtr : NULL,
2563 dest[0], dstW, lumAlpha, chrAlpha, dstY);
2564 } else { //general RGB
2565 yuv2packedX(c, vLumFilter + dstY * vLumFilterSize,
2566 lumSrcPtr, vLumFilterSize,
2567 vChrFilter + dstY * vChrFilterSize,
2568 chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
2569 alpSrcPtr, dest[0], dstW, dstY);
2575 if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
2576 fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
2579 if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2)
2580 __asm__ volatile("sfence":::"memory");
2584 /* store changed local vars back in the context */
2586 c->lumBufIndex= lumBufIndex;
2587 c->chrBufIndex= chrBufIndex;
2588 c->lastInLumBuf= lastInLumBuf;
2589 c->lastInChrBuf= lastInChrBuf;
2591 return dstY - lastDstY;
2594 static av_cold void sws_init_swScale_c(SwsContext *c)
2596 enum PixelFormat srcFormat = c->srcFormat;
2598 find_c_packed_planar_out_funcs(c, &c->yuv2yuv1, &c->yuv2yuvX,
2599 &c->yuv2packed1, &c->yuv2packed2,
2602 c->hScale = hScale_c;
2604 if (c->flags & SWS_FAST_BILINEAR) {
2605 c->hyscale_fast = hyscale_fast_c;
2606 c->hcscale_fast = hcscale_fast_c;
2609 c->chrToYV12 = NULL;
2611 case PIX_FMT_YUYV422 : c->chrToYV12 = yuy2ToUV_c; break;
2612 case PIX_FMT_UYVY422 : c->chrToYV12 = uyvyToUV_c; break;
2613 case PIX_FMT_NV12 : c->chrToYV12 = nv12ToUV_c; break;
2614 case PIX_FMT_NV21 : c->chrToYV12 = nv21ToUV_c; break;
2618 case PIX_FMT_BGR4_BYTE:
2619 case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
2620 case PIX_FMT_GRAY16BE :
2621 case PIX_FMT_YUV444P9BE:
2622 case PIX_FMT_YUV420P9BE:
2623 case PIX_FMT_YUV444P10BE:
2624 case PIX_FMT_YUV422P10BE:
2625 case PIX_FMT_YUV420P10BE:
2626 case PIX_FMT_YUV420P16BE:
2627 case PIX_FMT_YUV422P16BE:
2628 case PIX_FMT_YUV444P16BE: c->hScale16= HAVE_BIGENDIAN ? hScale16_c : hScale16X_c; break;
2629 case PIX_FMT_GRAY16LE :
2630 case PIX_FMT_YUV444P9LE:
2631 case PIX_FMT_YUV420P9LE:
2632 case PIX_FMT_YUV422P10LE:
2633 case PIX_FMT_YUV420P10LE:
2634 case PIX_FMT_YUV444P10LE:
2635 case PIX_FMT_YUV420P16LE:
2636 case PIX_FMT_YUV422P16LE:
2637 case PIX_FMT_YUV444P16LE: c->hScale16= HAVE_BIGENDIAN ? hScale16X_c : hScale16_c; break;
2639 if (c->chrSrcHSubSample) {
2641 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_half_c; break;
2642 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_half_c; break;
2643 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_half_c; break;
2644 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_half_c; break;
2645 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_half_c; break;
2646 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_half_c; break;
2647 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_half_c; break;
2648 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_half_c; break;
2649 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_half_c; break;
2650 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_half_c; break;
2651 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_half_c; break;
2652 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_half_c; break;
2653 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_half_c; break;
2654 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_half_c; break;
2655 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_half_c; break;
2656 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_half_c; break;
2657 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_half_c; break;
2658 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_half_c; break;
2662 case PIX_FMT_RGB48BE : c->chrToYV12 = rgb48BEToUV_c; break;
2663 case PIX_FMT_RGB48LE : c->chrToYV12 = rgb48LEToUV_c; break;
2664 case PIX_FMT_BGR48BE : c->chrToYV12 = bgr48BEToUV_c; break;
2665 case PIX_FMT_BGR48LE : c->chrToYV12 = bgr48LEToUV_c; break;
2666 case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_c; break;
2667 case PIX_FMT_RGB32_1 : c->chrToYV12 = bgr321ToUV_c; break;
2668 case PIX_FMT_BGR24 : c->chrToYV12 = bgr24ToUV_c; break;
2669 case PIX_FMT_BGR565LE: c->chrToYV12 = bgr16leToUV_c; break;
2670 case PIX_FMT_BGR565BE: c->chrToYV12 = bgr16beToUV_c; break;
2671 case PIX_FMT_BGR555LE: c->chrToYV12 = bgr15leToUV_c; break;
2672 case PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_c; break;
2673 case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_c; break;
2674 case PIX_FMT_BGR32_1 : c->chrToYV12 = rgb321ToUV_c; break;
2675 case PIX_FMT_RGB24 : c->chrToYV12 = rgb24ToUV_c; break;
2676 case PIX_FMT_RGB565LE: c->chrToYV12 = rgb16leToUV_c; break;
2677 case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_c; break;
2678 case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_c; break;
2679 case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_c; break;
2683 c->lumToYV12 = NULL;
2684 c->alpToYV12 = NULL;
2685 switch (srcFormat) {
2686 case PIX_FMT_YUYV422 :
2687 case PIX_FMT_GRAY8A :
2688 c->lumToYV12 = yuy2ToY_c; break;
2689 case PIX_FMT_UYVY422 :
2690 c->lumToYV12 = uyvyToY_c; break;
2691 case PIX_FMT_BGR24 : c->lumToYV12 = bgr24ToY_c; break;
2692 case PIX_FMT_BGR565LE : c->lumToYV12 = bgr16leToY_c; break;
2693 case PIX_FMT_BGR565BE : c->lumToYV12 = bgr16beToY_c; break;
2694 case PIX_FMT_BGR555LE : c->lumToYV12 = bgr15leToY_c; break;
2695 case PIX_FMT_BGR555BE : c->lumToYV12 = bgr15beToY_c; break;
2696 case PIX_FMT_RGB24 : c->lumToYV12 = rgb24ToY_c; break;
2697 case PIX_FMT_RGB565LE : c->lumToYV12 = rgb16leToY_c; break;
2698 case PIX_FMT_RGB565BE : c->lumToYV12 = rgb16beToY_c; break;
2699 case PIX_FMT_RGB555LE : c->lumToYV12 = rgb15leToY_c; break;
2700 case PIX_FMT_RGB555BE : c->lumToYV12 = rgb15beToY_c; break;
2704 case PIX_FMT_BGR4_BYTE:
2705 case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY_c; break;
2706 case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y_c; break;
2707 case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y_c; break;
2708 case PIX_FMT_RGB32 : c->lumToYV12 = bgr32ToY_c; break;
2709 case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY_c; break;
2710 case PIX_FMT_BGR32 : c->lumToYV12 = rgb32ToY_c; break;
2711 case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY_c; break;
2712 case PIX_FMT_RGB48BE: c->lumToYV12 = rgb48BEToY_c; break;
2713 case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break;
2714 case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break;
2715 case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break;
2718 switch (srcFormat) {
2720 case PIX_FMT_RGBA: c->alpToYV12 = rgbaToA_c; break;
2722 case PIX_FMT_ARGB: c->alpToYV12 = abgrToA_c; break;
2723 case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
2724 case PIX_FMT_PAL8 : c->alpToYV12 = palToA_c; break;
2728 if(isAnyRGB(c->srcFormat) || c->srcFormat == PIX_FMT_PAL8)
2729 c->hScale16= hScale16_c;
2731 if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
2733 c->lumConvertRange = lumRangeFromJpeg_c;
2734 c->chrConvertRange = chrRangeFromJpeg_c;
2736 c->lumConvertRange = lumRangeToJpeg_c;
2737 c->chrConvertRange = chrRangeToJpeg_c;
2741 if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
2742 srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE))
2743 c->needs_hcscale = 1;
2746 SwsFunc ff_getSwsFunc(SwsContext *c)
2748 sws_init_swScale_c(c);
2751 ff_sws_init_swScale_mmx(c);
2753 ff_sws_init_swScale_altivec(c);