1/* 2 * Copyright (C) 2001-2012 Michael Niedermayer <michaelni@gmx.at> 3 * 4 * This file is part of FFmpeg. 5 * 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. 10 * 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. 15 * 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 19 */ 20 21#include <math.h> 22#include <stdint.h> 23#include <stdio.h> 24#include <string.h> 25 26#include "libavutil/attributes.h" 27#include "libavutil/avutil.h" 28#include "libavutil/avassert.h" 29#include "libavutil/bswap.h" 30#include "libavutil/intreadwrite.h" 31#include "libavutil/mathematics.h" 32#include "libavutil/mem_internal.h" 33#include "libavutil/pixdesc.h" 34#include "config.h" 35#include "rgb2rgb.h" 36#include "swscale.h" 37#include "swscale_internal.h" 38 39DECLARE_ALIGNED(8, const uint8_t, ff_dither_2x2_4)[][8] = { 40{ 1, 3, 1, 3, 1, 3, 1, 3, }, 41{ 2, 0, 2, 0, 2, 0, 2, 0, }, 42{ 1, 3, 1, 3, 1, 3, 1, 3, }, 43}; 44 45DECLARE_ALIGNED(8, const uint8_t, ff_dither_2x2_8)[][8] = { 46{ 6, 2, 6, 2, 6, 2, 6, 2, }, 47{ 0, 4, 0, 4, 0, 4, 0, 4, }, 48{ 6, 2, 6, 2, 6, 2, 6, 2, }, 49}; 50 51DECLARE_ALIGNED(8, const uint8_t, ff_dither_4x4_16)[][8] = { 52{ 8, 4, 11, 7, 8, 4, 11, 7, }, 53{ 2, 14, 1, 13, 2, 14, 1, 13, }, 54{ 10, 6, 9, 5, 10, 6, 9, 5, }, 55{ 0, 12, 3, 15, 0, 12, 3, 15, }, 56{ 8, 4, 11, 7, 8, 4, 11, 7, }, 57}; 58 59DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_32)[][8] = { 60{ 17, 9, 23, 15, 16, 8, 22, 14, }, 61{ 5, 29, 3, 27, 4, 28, 2, 26, }, 62{ 21, 13, 19, 11, 20, 12, 18, 10, }, 63{ 0, 24, 6, 30, 1, 25, 7, 31, }, 64{ 16, 8, 22, 14, 17, 9, 23, 15, }, 65{ 4, 28, 2, 26, 5, 29, 3, 27, }, 66{ 20, 12, 18, 10, 21, 13, 19, 11, }, 67{ 1, 25, 7, 31, 0, 24, 6, 30, }, 68{ 17, 9, 23, 15, 16, 8, 22, 14, }, 69}; 70 71DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_73)[][8] = { 72{ 0, 55, 14, 68, 3, 58, 17, 72, }, 73{ 37, 18, 50, 32, 40, 22, 54, 35, }, 74{ 9, 64, 5, 59, 13, 67, 8, 63, }, 75{ 46, 27, 41, 23, 49, 31, 44, 26, }, 76{ 2, 57, 16, 71, 1, 56, 15, 70, }, 77{ 39, 21, 52, 34, 38, 19, 51, 33, }, 78{ 11, 66, 7, 62, 10, 65, 6, 60, }, 79{ 48, 30, 43, 25, 47, 29, 42, 24, }, 80{ 0, 55, 14, 68, 3, 58, 17, 72, }, 81}; 82 83#if 1 84DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = { 85{117, 62, 158, 103, 113, 58, 155, 100, }, 86{ 34, 199, 21, 186, 31, 196, 17, 182, }, 87{144, 89, 131, 76, 141, 86, 127, 72, }, 88{ 0, 165, 41, 206, 10, 175, 52, 217, }, 89{110, 55, 151, 96, 120, 65, 162, 107, }, 90{ 28, 193, 14, 179, 38, 203, 24, 189, }, 91{138, 83, 124, 69, 148, 93, 134, 79, }, 92{ 7, 172, 48, 213, 3, 168, 45, 210, }, 93{117, 62, 158, 103, 113, 58, 155, 100, }, 94}; 95#elif 1 96// tries to correct a gamma of 1.5 97DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = { 98{ 0, 143, 18, 200, 2, 156, 25, 215, }, 99{ 78, 28, 125, 64, 89, 36, 138, 74, }, 100{ 10, 180, 3, 161, 16, 195, 8, 175, }, 101{109, 51, 93, 38, 121, 60, 105, 47, }, 102{ 1, 152, 23, 210, 0, 147, 20, 205, }, 103{ 85, 33, 134, 71, 81, 30, 130, 67, }, 104{ 14, 190, 6, 171, 12, 185, 5, 166, }, 105{117, 57, 101, 44, 113, 54, 97, 41, }, 106{ 0, 143, 18, 200, 2, 156, 25, 215, }, 107}; 108#elif 1 109// tries to correct a gamma of 2.0 110DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = { 111{ 0, 124, 8, 193, 0, 140, 12, 213, }, 112{ 55, 14, 104, 42, 66, 19, 119, 52, }, 113{ 3, 168, 1, 145, 6, 187, 3, 162, }, 114{ 86, 31, 70, 21, 99, 39, 82, 28, }, 115{ 0, 134, 11, 206, 0, 129, 9, 200, }, 116{ 62, 17, 114, 48, 58, 16, 109, 45, }, 117{ 5, 181, 2, 157, 4, 175, 1, 151, }, 118{ 95, 36, 78, 26, 90, 34, 74, 24, }, 119{ 0, 124, 8, 193, 0, 140, 12, 213, }, 120}; 121#else 122// tries to correct a gamma of 2.5 123DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = { 124{ 0, 107, 3, 187, 0, 125, 6, 212, }, 125{ 39, 7, 86, 28, 49, 11, 102, 36, }, 126{ 1, 158, 0, 131, 3, 180, 1, 151, }, 127{ 68, 19, 52, 12, 81, 25, 64, 17, }, 128{ 0, 119, 5, 203, 0, 113, 4, 195, }, 129{ 45, 9, 96, 33, 42, 8, 91, 30, }, 130{ 2, 172, 1, 144, 2, 165, 0, 137, }, 131{ 77, 23, 60, 15, 72, 21, 56, 14, }, 132{ 0, 107, 3, 187, 0, 125, 6, 212, }, 133}; 134#endif 135 136#define output_pixel(pos, val, bias, signedness) \ 137 if (big_endian) { \ 138 AV_WB16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \ 139 } else { \ 140 AV_WL16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \ 141 } 142 143static av_always_inline void 144yuv2plane1_16_c_template(const int32_t *src, uint16_t *dest, int dstW, 145 int big_endian, int output_bits) 146{ 147 int i; 148 int shift = 3; 149 av_assert0(output_bits == 16); 150 151 for (i = 0; i < dstW; i++) { 152 int val = src[i] + (1 << (shift - 1)); 153 output_pixel(&dest[i], val, 0, uint); 154 } 155} 156 157static av_always_inline void 158yuv2planeX_16_c_template(const int16_t *filter, int filterSize, 159 const int32_t **src, uint16_t *dest, int dstW, 160 int big_endian, int output_bits) 161{ 162 int i; 163 int shift = 15; 164 av_assert0(output_bits == 16); 165 166 for (i = 0; i < dstW; i++) { 167 int val = 1 << (shift - 1); 168 int j; 169 170 /* range of val is [0,0x7FFFFFFF], so 31 bits, but with lanczos/spline 171 * filters (or anything with negative coeffs, the range can be slightly 172 * wider in both directions. To account for this overflow, we subtract 173 * a constant so it always fits in the signed range (assuming a 174 * reasonable filterSize), and re-add that at the end. */ 175 val -= 0x40000000; 176 for (j = 0; j < filterSize; j++) 177 val += src[j][i] * (unsigned)filter[j]; 178 179 output_pixel(&dest[i], val, 0x8000, int); 180 } 181} 182 183static av_always_inline void 184yuv2nv12cX_16_c_template(int big_endian, const uint8_t *chrDither, 185 const int16_t *chrFilter, int chrFilterSize, 186 const int16_t **chrUSrc, const int16_t **chrVSrc, 187 uint8_t *dest8, int chrDstW, int output_bits) 188{ 189 uint16_t *dest = (uint16_t*)dest8; 190 const int32_t **uSrc = (const int32_t **)chrUSrc; 191 const int32_t **vSrc = (const int32_t **)chrVSrc; 192 int shift = 15; 193 int i, j; 194 av_assert0(output_bits == 16); 195 196 for (i = 0; i < chrDstW; i++) { 197 int u = 1 << (shift - 1); 198 int v = 1 << (shift - 1); 199 200 /* See yuv2planeX_16_c_template for details. */ 201 u -= 0x40000000; 202 v -= 0x40000000; 203 for (j = 0; j < chrFilterSize; j++) { 204 u += uSrc[j][i] * (unsigned)chrFilter[j]; 205 v += vSrc[j][i] * (unsigned)chrFilter[j]; 206 } 207 208 output_pixel(&dest[2*i] , u, 0x8000, int); 209 output_pixel(&dest[2*i+1], v, 0x8000, int); 210 } 211} 212 213static av_always_inline void 214yuv2plane1_float_c_template(const int32_t *src, float *dest, int dstW) 215{ 216 static const int big_endian = HAVE_BIGENDIAN; 217 static const int shift = 3; 218 static const float float_mult = 1.0f / 65535.0f; 219 int i, val; 220 uint16_t val_uint; 221 222 for (i = 0; i < dstW; ++i){ 223 val = src[i] + (1 << (shift - 1)); 224 output_pixel(&val_uint, val, 0, uint); 225 dest[i] = float_mult * (float)val_uint; 226 } 227} 228 229static av_always_inline void 230yuv2plane1_float_bswap_c_template(const int32_t *src, uint32_t *dest, int dstW) 231{ 232 static const int big_endian = HAVE_BIGENDIAN; 233 static const int shift = 3; 234 static const float float_mult = 1.0f / 65535.0f; 235 int i, val; 236 uint16_t val_uint; 237 238 for (i = 0; i < dstW; ++i){ 239 val = src[i] + (1 << (shift - 1)); 240 output_pixel(&val_uint, val, 0, uint); 241 dest[i] = av_bswap32(av_float2int(float_mult * (float)val_uint)); 242 } 243} 244 245static av_always_inline void 246yuv2planeX_float_c_template(const int16_t *filter, int filterSize, const int32_t **src, 247 float *dest, int dstW) 248{ 249 static const int big_endian = HAVE_BIGENDIAN; 250 static const int shift = 15; 251 static const float float_mult = 1.0f / 65535.0f; 252 int i, j, val; 253 uint16_t val_uint; 254 255 for (i = 0; i < dstW; ++i){ 256 val = (1 << (shift - 1)) - 0x40000000; 257 for (j = 0; j < filterSize; ++j){ 258 val += src[j][i] * (unsigned)filter[j]; 259 } 260 output_pixel(&val_uint, val, 0x8000, int); 261 dest[i] = float_mult * (float)val_uint; 262 } 263} 264 265static av_always_inline void 266yuv2planeX_float_bswap_c_template(const int16_t *filter, int filterSize, const int32_t **src, 267 uint32_t *dest, int dstW) 268{ 269 static const int big_endian = HAVE_BIGENDIAN; 270 static const int shift = 15; 271 static const float float_mult = 1.0f / 65535.0f; 272 int i, j, val; 273 uint16_t val_uint; 274 275 for (i = 0; i < dstW; ++i){ 276 val = (1 << (shift - 1)) - 0x40000000; 277 for (j = 0; j < filterSize; ++j){ 278 val += src[j][i] * (unsigned)filter[j]; 279 } 280 output_pixel(&val_uint, val, 0x8000, int); 281 dest[i] = av_bswap32(av_float2int(float_mult * (float)val_uint)); 282 } 283} 284 285#define yuv2plane1_float(template, dest_type, BE_LE) \ 286static void yuv2plane1_float ## BE_LE ## _c(const int16_t *src, uint8_t *dest, int dstW, \ 287 const uint8_t *dither, int offset) \ 288{ \ 289 template((const int32_t *)src, (dest_type *)dest, dstW); \ 290} 291 292#define yuv2planeX_float(template, dest_type, BE_LE) \ 293static void yuv2planeX_float ## BE_LE ## _c(const int16_t *filter, int filterSize, \ 294 const int16_t **src, uint8_t *dest, int dstW, \ 295 const uint8_t *dither, int offset) \ 296{ \ 297 template(filter, filterSize, (const int32_t **)src, (dest_type *)dest, dstW); \ 298} 299 300#if HAVE_BIGENDIAN 301yuv2plane1_float(yuv2plane1_float_c_template, float, BE) 302yuv2plane1_float(yuv2plane1_float_bswap_c_template, uint32_t, LE) 303yuv2planeX_float(yuv2planeX_float_c_template, float, BE) 304yuv2planeX_float(yuv2planeX_float_bswap_c_template, uint32_t, LE) 305#else 306yuv2plane1_float(yuv2plane1_float_c_template, float, LE) 307yuv2plane1_float(yuv2plane1_float_bswap_c_template, uint32_t, BE) 308yuv2planeX_float(yuv2planeX_float_c_template, float, LE) 309yuv2planeX_float(yuv2planeX_float_bswap_c_template, uint32_t, BE) 310#endif 311 312#undef output_pixel 313 314#define output_pixel(pos, val) \ 315 if (big_endian) { \ 316 AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \ 317 } else { \ 318 AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \ 319 } 320 321static av_always_inline void 322yuv2plane1_10_c_template(const int16_t *src, uint16_t *dest, int dstW, 323 int big_endian, int output_bits) 324{ 325 int i; 326 int shift = 15 - output_bits; 327 328 for (i = 0; i < dstW; i++) { 329 int val = src[i] + (1 << (shift - 1)); 330 output_pixel(&dest[i], val); 331 } 332} 333 334static av_always_inline void 335yuv2planeX_10_c_template(const int16_t *filter, int filterSize, 336 const int16_t **src, uint16_t *dest, int dstW, 337 int big_endian, int output_bits) 338{ 339 int i; 340 int shift = 11 + 16 - output_bits; 341 342 for (i = 0; i < dstW; i++) { 343 int val = 1 << (shift - 1); 344 int j; 345 346 for (j = 0; j < filterSize; j++) 347 val += src[j][i] * filter[j]; 348 349 output_pixel(&dest[i], val); 350 } 351} 352 353#undef output_pixel 354 355#define yuv2NBPS(bits, BE_LE, is_be, template_size, typeX_t) \ 356static void yuv2plane1_ ## bits ## BE_LE ## _c(const int16_t *src, \ 357 uint8_t *dest, int dstW, \ 358 const uint8_t *dither, int offset)\ 359{ \ 360 yuv2plane1_ ## template_size ## _c_template((const typeX_t *) src, \ 361 (uint16_t *) dest, dstW, is_be, bits); \ 362}\ 363static void yuv2planeX_ ## bits ## BE_LE ## _c(const int16_t *filter, int filterSize, \ 364 const int16_t **src, uint8_t *dest, int dstW, \ 365 const uint8_t *dither, int offset)\ 366{ \ 367 yuv2planeX_## template_size ## _c_template(filter, \ 368 filterSize, (const typeX_t **) src, \ 369 (uint16_t *) dest, dstW, is_be, bits); \ 370} 371 372yuv2NBPS( 9, BE, 1, 10, int16_t) 373yuv2NBPS( 9, LE, 0, 10, int16_t) 374yuv2NBPS(10, BE, 1, 10, int16_t) 375yuv2NBPS(10, LE, 0, 10, int16_t) 376yuv2NBPS(12, BE, 1, 10, int16_t) 377yuv2NBPS(12, LE, 0, 10, int16_t) 378yuv2NBPS(14, BE, 1, 10, int16_t) 379yuv2NBPS(14, LE, 0, 10, int16_t) 380yuv2NBPS(16, BE, 1, 16, int32_t) 381yuv2NBPS(16, LE, 0, 16, int32_t) 382 383 384static void yuv2nv12cX_16LE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, 385 const int16_t *chrFilter, int chrFilterSize, 386 const int16_t **chrUSrc, const int16_t **chrVSrc, 387 uint8_t *dest8, int chrDstW) 388{ 389 yuv2nv12cX_16_c_template(0, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW, 16); 390} 391 392static void yuv2nv12cX_16BE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, 393 const int16_t *chrFilter, int chrFilterSize, 394 const int16_t **chrUSrc, const int16_t **chrVSrc, 395 uint8_t *dest8, int chrDstW) 396{ 397 yuv2nv12cX_16_c_template(1, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW, 16); 398} 399 400static void yuv2planeX_8_c(const int16_t *filter, int filterSize, 401 const int16_t **src, uint8_t *dest, int dstW, 402 const uint8_t *dither, int offset) 403{ 404 int i; 405 for (i=0; i<dstW; i++) { 406 int val = dither[(i + offset) & 7] << 12; 407 int j; 408 for (j=0; j<filterSize; j++) 409 val += src[j][i] * filter[j]; 410 411 dest[i]= av_clip_uint8(val>>19); 412 } 413} 414 415static void yuv2plane1_8_c(const int16_t *src, uint8_t *dest, int dstW, 416 const uint8_t *dither, int offset) 417{ 418 int i; 419 for (i=0; i<dstW; i++) { 420 int val = (src[i] + dither[(i + offset) & 7]) >> 7; 421 dest[i]= av_clip_uint8(val); 422 } 423} 424 425static void yuv2nv12cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, 426 const int16_t *chrFilter, int chrFilterSize, 427 const int16_t **chrUSrc, const int16_t **chrVSrc, 428 uint8_t *dest, int chrDstW) 429{ 430 int i; 431 432 if (!isSwappedChroma(dstFormat)) 433 for (i=0; i<chrDstW; i++) { 434 int u = chrDither[i & 7] << 12; 435 int v = chrDither[(i + 3) & 7] << 12; 436 int j; 437 for (j=0; j<chrFilterSize; j++) { 438 u += chrUSrc[j][i] * chrFilter[j]; 439 v += chrVSrc[j][i] * chrFilter[j]; 440 } 441 442 dest[2*i]= av_clip_uint8(u>>19); 443 dest[2*i+1]= av_clip_uint8(v>>19); 444 } 445 else 446 for (i=0; i<chrDstW; i++) { 447 int u = chrDither[i & 7] << 12; 448 int v = chrDither[(i + 3) & 7] << 12; 449 int j; 450 for (j=0; j<chrFilterSize; j++) { 451 u += chrUSrc[j][i] * chrFilter[j]; 452 v += chrVSrc[j][i] * chrFilter[j]; 453 } 454 455 dest[2*i]= av_clip_uint8(v>>19); 456 dest[2*i+1]= av_clip_uint8(u>>19); 457 } 458} 459 460 461#define output_pixel(pos, val) \ 462 if (big_endian) { \ 463 AV_WB16(pos, av_clip_uintp2(val >> shift, 10) << 6); \ 464 } else { \ 465 AV_WL16(pos, av_clip_uintp2(val >> shift, 10) << 6); \ 466 } 467 468static void yuv2p010l1_c(const int16_t *src, 469 uint16_t *dest, int dstW, 470 int big_endian) 471{ 472 int i; 473 int shift = 5; 474 475 for (i = 0; i < dstW; i++) { 476 int val = src[i] + (1 << (shift - 1)); 477 output_pixel(&dest[i], val); 478 } 479} 480 481static void yuv2p010lX_c(const int16_t *filter, int filterSize, 482 const int16_t **src, uint16_t *dest, int dstW, 483 int big_endian) 484{ 485 int i, j; 486 int shift = 17; 487 488 for (i = 0; i < dstW; i++) { 489 int val = 1 << (shift - 1); 490 491 for (j = 0; j < filterSize; j++) 492 val += src[j][i] * filter[j]; 493 494 output_pixel(&dest[i], val); 495 } 496} 497 498static void yuv2p010cX_c(int big_endian, const uint8_t *chrDither, 499 const int16_t *chrFilter, int chrFilterSize, 500 const int16_t **chrUSrc, const int16_t **chrVSrc, 501 uint8_t *dest8, int chrDstW) 502{ 503 uint16_t *dest = (uint16_t*)dest8; 504 int shift = 17; 505 int i, j; 506 507 for (i = 0; i < chrDstW; i++) { 508 int u = 1 << (shift - 1); 509 int v = 1 << (shift - 1); 510 511 for (j = 0; j < chrFilterSize; j++) { 512 u += chrUSrc[j][i] * chrFilter[j]; 513 v += chrVSrc[j][i] * chrFilter[j]; 514 } 515 516 output_pixel(&dest[2*i] , u); 517 output_pixel(&dest[2*i+1], v); 518 } 519} 520 521static void yuv2p010l1_LE_c(const int16_t *src, 522 uint8_t *dest, int dstW, 523 const uint8_t *dither, int offset) 524{ 525 yuv2p010l1_c(src, (uint16_t*)dest, dstW, 0); 526} 527 528static void yuv2p010l1_BE_c(const int16_t *src, 529 uint8_t *dest, int dstW, 530 const uint8_t *dither, int offset) 531{ 532 yuv2p010l1_c(src, (uint16_t*)dest, dstW, 1); 533} 534 535static void yuv2p010lX_LE_c(const int16_t *filter, int filterSize, 536 const int16_t **src, uint8_t *dest, int dstW, 537 const uint8_t *dither, int offset) 538{ 539 yuv2p010lX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 0); 540} 541 542static void yuv2p010lX_BE_c(const int16_t *filter, int filterSize, 543 const int16_t **src, uint8_t *dest, int dstW, 544 const uint8_t *dither, int offset) 545{ 546 yuv2p010lX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 1); 547} 548 549static void yuv2p010cX_LE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, 550 const int16_t *chrFilter, int chrFilterSize, 551 const int16_t **chrUSrc, const int16_t **chrVSrc, 552 uint8_t *dest8, int chrDstW) 553{ 554 yuv2p010cX_c(0, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW); 555} 556 557static void yuv2p010cX_BE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, 558 const int16_t *chrFilter, int chrFilterSize, 559 const int16_t **chrUSrc, const int16_t **chrVSrc, 560 uint8_t *dest8, int chrDstW) 561{ 562 yuv2p010cX_c(1, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW); 563} 564 565#undef output_pixel 566 567 568#define accumulate_bit(acc, val) \ 569 acc <<= 1; \ 570 acc |= (val) >= 234 571#define output_pixel(pos, acc) \ 572 if (target == AV_PIX_FMT_MONOBLACK) { \ 573 pos = acc; \ 574 } else { \ 575 pos = ~acc; \ 576 } 577 578static av_always_inline void 579yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter, 580 const int16_t **lumSrc, int lumFilterSize, 581 const int16_t *chrFilter, const int16_t **chrUSrc, 582 const int16_t **chrVSrc, int chrFilterSize, 583 const int16_t **alpSrc, uint8_t *dest, int dstW, 584 int y, enum AVPixelFormat target) 585{ 586 const uint8_t * const d128 = ff_dither_8x8_220[y&7]; 587 int i; 588 unsigned acc = 0; 589 int err = 0; 590 591 for (i = 0; i < dstW; i += 2) { 592 int j; 593 int Y1 = 1 << 18; 594 int Y2 = 1 << 18; 595 596 for (j = 0; j < lumFilterSize; j++) { 597 Y1 += lumSrc[j][i] * lumFilter[j]; 598 Y2 += lumSrc[j][i+1] * lumFilter[j]; 599 } 600 Y1 >>= 19; 601 Y2 >>= 19; 602 if ((Y1 | Y2) & 0x100) { 603 Y1 = av_clip_uint8(Y1); 604 Y2 = av_clip_uint8(Y2); 605 } 606 if (c->dither == SWS_DITHER_ED) { 607 Y1 += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4; 608 c->dither_error[0][i] = err; 609 acc = 2*acc + (Y1 >= 128); 610 Y1 -= 220*(acc&1); 611 612 err = Y2 + ((7*Y1 + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4); 613 c->dither_error[0][i+1] = Y1; 614 acc = 2*acc + (err >= 128); 615 err -= 220*(acc&1); 616 } else { 617 accumulate_bit(acc, Y1 + d128[(i + 0) & 7]); 618 accumulate_bit(acc, Y2 + d128[(i + 1) & 7]); 619 } 620 if ((i & 7) == 6) { 621 output_pixel(*dest++, acc); 622 } 623 } 624 c->dither_error[0][i] = err; 625 626 if (i & 6) { 627 output_pixel(*dest, acc); 628 } 629} 630 631static av_always_inline void 632yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2], 633 const int16_t *ubuf[2], const int16_t *vbuf[2], 634 const int16_t *abuf[2], uint8_t *dest, int dstW, 635 int yalpha, int uvalpha, int y, 636 enum AVPixelFormat target) 637{ 638 const int16_t *buf0 = buf[0], *buf1 = buf[1]; 639 const uint8_t * const d128 = ff_dither_8x8_220[y & 7]; 640 int yalpha1 = 4096 - yalpha; 641 int i; 642 av_assert2(yalpha <= 4096U); 643 644 if (c->dither == SWS_DITHER_ED) { 645 int err = 0; 646 int acc = 0; 647 for (i = 0; i < dstW; i +=2) { 648 int Y; 649 650 Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19; 651 Y += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4; 652 c->dither_error[0][i] = err; 653 acc = 2*acc + (Y >= 128); 654 Y -= 220*(acc&1); 655 656 err = (buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19; 657 err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4; 658 c->dither_error[0][i+1] = Y; 659 acc = 2*acc + (err >= 128); 660 err -= 220*(acc&1); 661 662 if ((i & 7) == 6) 663 output_pixel(*dest++, acc); 664 } 665 c->dither_error[0][i] = err; 666 } else { 667 for (i = 0; i < dstW; i += 8) { 668 int Y, acc = 0; 669 670 Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19; 671 accumulate_bit(acc, Y + d128[0]); 672 Y = (buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19; 673 accumulate_bit(acc, Y + d128[1]); 674 Y = (buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19; 675 accumulate_bit(acc, Y + d128[2]); 676 Y = (buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19; 677 accumulate_bit(acc, Y + d128[3]); 678 Y = (buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19; 679 accumulate_bit(acc, Y + d128[4]); 680 Y = (buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19; 681 accumulate_bit(acc, Y + d128[5]); 682 Y = (buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19; 683 accumulate_bit(acc, Y + d128[6]); 684 Y = (buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19; 685 accumulate_bit(acc, Y + d128[7]); 686 687 output_pixel(*dest++, acc); 688 } 689 } 690} 691 692static av_always_inline void 693yuv2mono_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 AVPixelFormat target) 697{ 698 const uint8_t * const d128 = ff_dither_8x8_220[y & 7]; 699 int i; 700 701 if (c->dither == SWS_DITHER_ED) { 702 int err = 0; 703 int acc = 0; 704 for (i = 0; i < dstW; i +=2) { 705 int Y; 706 707 Y = ((buf0[i + 0] + 64) >> 7); 708 Y += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4; 709 c->dither_error[0][i] = err; 710 acc = 2*acc + (Y >= 128); 711 Y -= 220*(acc&1); 712 713 err = ((buf0[i + 1] + 64) >> 7); 714 err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4; 715 c->dither_error[0][i+1] = Y; 716 acc = 2*acc + (err >= 128); 717 err -= 220*(acc&1); 718 719 if ((i & 7) == 6) 720 output_pixel(*dest++, acc); 721 } 722 c->dither_error[0][i] = err; 723 } else { 724 for (i = 0; i < dstW; i += 8) { 725 int acc = 0; 726 accumulate_bit(acc, ((buf0[i + 0] + 64) >> 7) + d128[0]); 727 accumulate_bit(acc, ((buf0[i + 1] + 64) >> 7) + d128[1]); 728 accumulate_bit(acc, ((buf0[i + 2] + 64) >> 7) + d128[2]); 729 accumulate_bit(acc, ((buf0[i + 3] + 64) >> 7) + d128[3]); 730 accumulate_bit(acc, ((buf0[i + 4] + 64) >> 7) + d128[4]); 731 accumulate_bit(acc, ((buf0[i + 5] + 64) >> 7) + d128[5]); 732 accumulate_bit(acc, ((buf0[i + 6] + 64) >> 7) + d128[6]); 733 accumulate_bit(acc, ((buf0[i + 7] + 64) >> 7) + d128[7]); 734 735 output_pixel(*dest++, acc); 736 } 737 } 738} 739 740#undef output_pixel 741#undef accumulate_bit 742 743#define YUV2PACKEDWRAPPER(name, base, ext, fmt) \ 744static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \ 745 const int16_t **lumSrc, int lumFilterSize, \ 746 const int16_t *chrFilter, const int16_t **chrUSrc, \ 747 const int16_t **chrVSrc, int chrFilterSize, \ 748 const int16_t **alpSrc, uint8_t *dest, int dstW, \ 749 int y) \ 750{ \ 751 name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \ 752 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \ 753 alpSrc, dest, dstW, y, fmt); \ 754} \ 755 \ 756static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \ 757 const int16_t *ubuf[2], const int16_t *vbuf[2], \ 758 const int16_t *abuf[2], uint8_t *dest, int dstW, \ 759 int yalpha, int uvalpha, int y) \ 760{ \ 761 name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \ 762 dest, dstW, yalpha, uvalpha, y, fmt); \ 763} \ 764 \ 765static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \ 766 const int16_t *ubuf[2], const int16_t *vbuf[2], \ 767 const int16_t *abuf0, uint8_t *dest, int dstW, \ 768 int uvalpha, int y) \ 769{ \ 770 name ## base ## _1_c_template(c, buf0, ubuf, vbuf, \ 771 abuf0, dest, dstW, uvalpha, \ 772 y, fmt); \ 773} 774 775YUV2PACKEDWRAPPER(yuv2mono,, white, AV_PIX_FMT_MONOWHITE) 776YUV2PACKEDWRAPPER(yuv2mono,, black, AV_PIX_FMT_MONOBLACK) 777 778#define output_pixels(pos, Y1, U, Y2, V) \ 779 if (target == AV_PIX_FMT_YUYV422) { \ 780 dest[pos + 0] = Y1; \ 781 dest[pos + 1] = U; \ 782 dest[pos + 2] = Y2; \ 783 dest[pos + 3] = V; \ 784 } else if (target == AV_PIX_FMT_YVYU422) { \ 785 dest[pos + 0] = Y1; \ 786 dest[pos + 1] = V; \ 787 dest[pos + 2] = Y2; \ 788 dest[pos + 3] = U; \ 789 } else { /* AV_PIX_FMT_UYVY422 */ \ 790 dest[pos + 0] = U; \ 791 dest[pos + 1] = Y1; \ 792 dest[pos + 2] = V; \ 793 dest[pos + 3] = Y2; \ 794 } 795 796static av_always_inline void 797yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter, 798 const int16_t **lumSrc, int lumFilterSize, 799 const int16_t *chrFilter, const int16_t **chrUSrc, 800 const int16_t **chrVSrc, int chrFilterSize, 801 const int16_t **alpSrc, uint8_t *dest, int dstW, 802 int y, enum AVPixelFormat target) 803{ 804 int i; 805 806 for (i = 0; i < ((dstW + 1) >> 1); i++) { 807 int j; 808 int Y1 = 1 << 18; 809 int Y2 = 1 << 18; 810 int U = 1 << 18; 811 int V = 1 << 18; 812 813 for (j = 0; j < lumFilterSize; j++) { 814 Y1 += lumSrc[j][i * 2] * lumFilter[j]; 815 Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j]; 816 } 817 for (j = 0; j < chrFilterSize; j++) { 818 U += chrUSrc[j][i] * chrFilter[j]; 819 V += chrVSrc[j][i] * chrFilter[j]; 820 } 821 Y1 >>= 19; 822 Y2 >>= 19; 823 U >>= 19; 824 V >>= 19; 825 if ((Y1 | Y2 | U | V) & 0x100) { 826 Y1 = av_clip_uint8(Y1); 827 Y2 = av_clip_uint8(Y2); 828 U = av_clip_uint8(U); 829 V = av_clip_uint8(V); 830 } 831 output_pixels(4*i, Y1, U, Y2, V); 832 } 833} 834 835static av_always_inline void 836yuv2422_2_c_template(SwsContext *c, const int16_t *buf[2], 837 const int16_t *ubuf[2], const int16_t *vbuf[2], 838 const int16_t *abuf[2], uint8_t *dest, int dstW, 839 int yalpha, int uvalpha, int y, 840 enum AVPixelFormat target) 841{ 842 const int16_t *buf0 = buf[0], *buf1 = buf[1], 843 *ubuf0 = ubuf[0], *ubuf1 = ubuf[1], 844 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1]; 845 int yalpha1 = 4096 - yalpha; 846 int uvalpha1 = 4096 - uvalpha; 847 int i; 848 av_assert2(yalpha <= 4096U); 849 av_assert2(uvalpha <= 4096U); 850 851 for (i = 0; i < ((dstW + 1) >> 1); i++) { 852 int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19; 853 int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19; 854 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19; 855 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19; 856 857 if ((Y1 | Y2 | U | V) & 0x100) { 858 Y1 = av_clip_uint8(Y1); 859 Y2 = av_clip_uint8(Y2); 860 U = av_clip_uint8(U); 861 V = av_clip_uint8(V); 862 } 863 864 output_pixels(i * 4, Y1, U, Y2, V); 865 } 866} 867 868static av_always_inline void 869yuv2422_1_c_template(SwsContext *c, const int16_t *buf0, 870 const int16_t *ubuf[2], const int16_t *vbuf[2], 871 const int16_t *abuf0, uint8_t *dest, int dstW, 872 int uvalpha, int y, enum AVPixelFormat target) 873{ 874 const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; 875 int i; 876 877 if (uvalpha < 2048) { 878 for (i = 0; i < ((dstW + 1) >> 1); i++) { 879 int Y1 = (buf0[i * 2 ]+64) >> 7; 880 int Y2 = (buf0[i * 2 + 1]+64) >> 7; 881 int U = (ubuf0[i] +64) >> 7; 882 int V = (vbuf0[i] +64) >> 7; 883 884 if ((Y1 | Y2 | U | V) & 0x100) { 885 Y1 = av_clip_uint8(Y1); 886 Y2 = av_clip_uint8(Y2); 887 U = av_clip_uint8(U); 888 V = av_clip_uint8(V); 889 } 890 891 output_pixels(i * 4, Y1, U, Y2, V); 892 } 893 } else { 894 const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; 895 for (i = 0; i < ((dstW + 1) >> 1); i++) { 896 int Y1 = (buf0[i * 2 ] + 64) >> 7; 897 int Y2 = (buf0[i * 2 + 1] + 64) >> 7; 898 int U = (ubuf0[i] + ubuf1[i]+128) >> 8; 899 int V = (vbuf0[i] + vbuf1[i]+128) >> 8; 900 901 if ((Y1 | Y2 | U | V) & 0x100) { 902 Y1 = av_clip_uint8(Y1); 903 Y2 = av_clip_uint8(Y2); 904 U = av_clip_uint8(U); 905 V = av_clip_uint8(V); 906 } 907 908 output_pixels(i * 4, Y1, U, Y2, V); 909 } 910 } 911} 912 913#undef output_pixels 914 915YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, AV_PIX_FMT_YUYV422) 916YUV2PACKEDWRAPPER(yuv2, 422, yvyu422, AV_PIX_FMT_YVYU422) 917YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, AV_PIX_FMT_UYVY422) 918 919#define R_B ((target == AV_PIX_FMT_RGB48LE || target == AV_PIX_FMT_RGB48BE || target == AV_PIX_FMT_RGBA64LE || target == AV_PIX_FMT_RGBA64BE) ? R : B) 920#define B_R ((target == AV_PIX_FMT_RGB48LE || target == AV_PIX_FMT_RGB48BE || target == AV_PIX_FMT_RGBA64LE || target == AV_PIX_FMT_RGBA64BE) ? B : R) 921#define output_pixel(pos, val) \ 922 if (isBE(target)) { \ 923 AV_WB16(pos, val); \ 924 } else { \ 925 AV_WL16(pos, val); \ 926 } 927 928static av_always_inline void 929yuv2ya16_X_c_template(SwsContext *c, const int16_t *lumFilter, 930 const int32_t **lumSrc, int lumFilterSize, 931 const int16_t *chrFilter, const int32_t **unused_chrUSrc, 932 const int32_t **unused_chrVSrc, int unused_chrFilterSize, 933 const int32_t **alpSrc, uint16_t *dest, int dstW, 934 int y, enum AVPixelFormat target, int unused_hasAlpha, int unused_eightbytes) 935{ 936 int hasAlpha = !!alpSrc; 937 int i; 938 939 for (i = 0; i < dstW; i++) { 940 int j; 941 int Y = -0x40000000; 942 int A = 0xffff; 943 944 for (j = 0; j < lumFilterSize; j++) 945 Y += lumSrc[j][i] * lumFilter[j]; 946 947 Y >>= 15; 948 Y += (1<<3) + 0x8000; 949 Y = av_clip_uint16(Y); 950 951 if (hasAlpha) { 952 A = -0x40000000 + (1<<14); 953 for (j = 0; j < lumFilterSize; j++) 954 A += alpSrc[j][i] * lumFilter[j]; 955 956 A >>= 15; 957 A += 0x8000; 958 A = av_clip_uint16(A); 959 } 960 961 output_pixel(&dest[2 * i ], Y); 962 output_pixel(&dest[2 * i + 1], A); 963 } 964} 965 966static av_always_inline void 967yuv2ya16_2_c_template(SwsContext *c, const int32_t *buf[2], 968 const int32_t *unused_ubuf[2], const int32_t *unused_vbuf[2], 969 const int32_t *abuf[2], uint16_t *dest, int dstW, 970 int yalpha, int unused_uvalpha, int y, 971 enum AVPixelFormat target, int unused_hasAlpha, int unused_eightbytes) 972{ 973 int hasAlpha = abuf && abuf[0] && abuf[1]; 974 const int32_t *buf0 = buf[0], *buf1 = buf[1], 975 *abuf0 = hasAlpha ? abuf[0] : NULL, 976 *abuf1 = hasAlpha ? abuf[1] : NULL; 977 int yalpha1 = 4096 - yalpha; 978 int i; 979 980 av_assert2(yalpha <= 4096U); 981 982 for (i = 0; i < dstW; i++) { 983 int Y = (buf0[i] * yalpha1 + buf1[i] * yalpha) >> 15; 984 int A; 985 986 Y = av_clip_uint16(Y); 987 988 if (hasAlpha) { 989 A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha) >> 15; 990 A = av_clip_uint16(A); 991 } 992 993 output_pixel(&dest[2 * i ], Y); 994 output_pixel(&dest[2 * i + 1], hasAlpha ? A : 65535); 995 } 996} 997 998static av_always_inline void 999yuv2ya16_1_c_template(SwsContext *c, const int32_t *buf0, 1000 const int32_t *unused_ubuf[2], const int32_t *unused_vbuf[2], 1001 const int32_t *abuf0, uint16_t *dest, int dstW, 1002 int unused_uvalpha, int y, enum AVPixelFormat target, int unused_hasAlpha, int unused_eightbytes) 1003{ 1004 int hasAlpha = !!abuf0; 1005 int i; 1006 1007 for (i = 0; i < dstW; i++) { 1008 int Y = buf0[i] >> 3;/* 19 - 16 */ 1009 int A; 1010 1011 Y = av_clip_uint16(Y); 1012 1013 if (hasAlpha) { 1014 A = abuf0[i] >> 3; 1015 if (A & 0x100) 1016 A = av_clip_uint16(A); 1017 } 1018 1019 output_pixel(&dest[2 * i ], Y); 1020 output_pixel(&dest[2 * i + 1], hasAlpha ? A : 65535); 1021 } 1022} 1023 1024static av_always_inline void 1025yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter, 1026 const int32_t **lumSrc, int lumFilterSize, 1027 const int16_t *chrFilter, const int32_t **chrUSrc, 1028 const int32_t **chrVSrc, int chrFilterSize, 1029 const int32_t **alpSrc, uint16_t *dest, int dstW, 1030 int y, enum AVPixelFormat target, int hasAlpha, int eightbytes) 1031{ 1032 int i; 1033 int A1 = 0xffff<<14, A2 = 0xffff<<14; 1034 1035 for (i = 0; i < ((dstW + 1) >> 1); i++) { 1036 int j; 1037 int Y1 = -0x40000000; 1038 int Y2 = -0x40000000; 1039 int U = -(128 << 23); // 19 1040 int V = -(128 << 23); 1041 int R, G, B; 1042 1043 for (j = 0; j < lumFilterSize; j++) { 1044 Y1 += lumSrc[j][i * 2] * (unsigned)lumFilter[j]; 1045 Y2 += lumSrc[j][i * 2 + 1] * (unsigned)lumFilter[j]; 1046 } 1047 for (j = 0; j < chrFilterSize; j++) {; 1048 U += chrUSrc[j][i] * (unsigned)chrFilter[j]; 1049 V += chrVSrc[j][i] * (unsigned)chrFilter[j]; 1050 } 1051 1052 if (hasAlpha) { 1053 A1 = -0x40000000; 1054 A2 = -0x40000000; 1055 for (j = 0; j < lumFilterSize; j++) { 1056 A1 += alpSrc[j][i * 2] * (unsigned)lumFilter[j]; 1057 A2 += alpSrc[j][i * 2 + 1] * (unsigned)lumFilter[j]; 1058 } 1059 A1 >>= 1; 1060 A1 += 0x20002000; 1061 A2 >>= 1; 1062 A2 += 0x20002000; 1063 } 1064 1065 // 8 bits: 12+15=27; 16 bits: 12+19=31 1066 Y1 >>= 14; // 10 1067 Y1 += 0x10000; 1068 Y2 >>= 14; 1069 Y2 += 0x10000; 1070 U >>= 14; 1071 V >>= 14; 1072 1073 // 8 bits: 27 -> 17 bits, 16 bits: 31 - 14 = 17 bits 1074 Y1 -= c->yuv2rgb_y_offset; 1075 Y2 -= c->yuv2rgb_y_offset; 1076 Y1 *= c->yuv2rgb_y_coeff; 1077 Y2 *= c->yuv2rgb_y_coeff; 1078 Y1 += (1 << 13) - (1 << 29); // 21 1079 Y2 += (1 << 13) - (1 << 29); 1080 // 8 bits: 17 + 13 bits = 30 bits, 16 bits: 17 + 13 bits = 30 bits 1081 1082 R = V * c->yuv2rgb_v2r_coeff; 1083 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 1084 B = U * c->yuv2rgb_u2b_coeff; 1085 1086 // 8 bits: 30 - 22 = 8 bits, 16 bits: 30 bits - 14 = 16 bits 1087 output_pixel(&dest[0], av_clip_uintp2(((R_B + Y1) >> 14) + (1<<15), 16)); 1088 output_pixel(&dest[1], av_clip_uintp2((( G + Y1) >> 14) + (1<<15), 16)); 1089 output_pixel(&dest[2], av_clip_uintp2(((B_R + Y1) >> 14) + (1<<15), 16)); 1090 if (eightbytes) { 1091 output_pixel(&dest[3], av_clip_uintp2(A1 , 30) >> 14); 1092 output_pixel(&dest[4], av_clip_uintp2(((R_B + Y2) >> 14) + (1<<15), 16)); 1093 output_pixel(&dest[5], av_clip_uintp2((( G + Y2) >> 14) + (1<<15), 16)); 1094 output_pixel(&dest[6], av_clip_uintp2(((B_R + Y2) >> 14) + (1<<15), 16)); 1095 output_pixel(&dest[7], av_clip_uintp2(A2 , 30) >> 14); 1096 dest += 8; 1097 } else { 1098 output_pixel(&dest[3], av_clip_uintp2(((R_B + Y2) >> 14) + (1<<15), 16)); 1099 output_pixel(&dest[4], av_clip_uintp2((( G + Y2) >> 14) + (1<<15), 16)); 1100 output_pixel(&dest[5], av_clip_uintp2(((B_R + Y2) >> 14) + (1<<15), 16)); 1101 dest += 6; 1102 } 1103 } 1104} 1105 1106static av_always_inline void 1107yuv2rgba64_2_c_template(SwsContext *c, const int32_t *buf[2], 1108 const int32_t *ubuf[2], const int32_t *vbuf[2], 1109 const int32_t *abuf[2], uint16_t *dest, int dstW, 1110 int yalpha, int uvalpha, int y, 1111 enum AVPixelFormat target, int hasAlpha, int eightbytes) 1112{ 1113 const int32_t *buf0 = buf[0], *buf1 = buf[1], 1114 *ubuf0 = ubuf[0], *ubuf1 = ubuf[1], 1115 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1], 1116 *abuf0 = hasAlpha ? abuf[0] : NULL, 1117 *abuf1 = hasAlpha ? abuf[1] : NULL; 1118 int yalpha1 = 4096 - yalpha; 1119 int uvalpha1 = 4096 - uvalpha; 1120 int i; 1121 int A1 = 0xffff<<14, A2 = 0xffff<<14; 1122 1123 av_assert2(yalpha <= 4096U); 1124 av_assert2(uvalpha <= 4096U); 1125 1126 for (i = 0; i < ((dstW + 1) >> 1); i++) { 1127 unsigned Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 14; 1128 unsigned Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 14; 1129 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha - (128 << 23)) >> 14; 1130 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha - (128 << 23)) >> 14; 1131 int R, G, B; 1132 1133 Y1 -= c->yuv2rgb_y_offset; 1134 Y2 -= c->yuv2rgb_y_offset; 1135 Y1 *= c->yuv2rgb_y_coeff; 1136 Y2 *= c->yuv2rgb_y_coeff; 1137 Y1 += (1 << 13) - (1 << 29); 1138 Y2 += (1 << 13) - (1 << 29); 1139 1140 R = V * c->yuv2rgb_v2r_coeff; 1141 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 1142 B = U * c->yuv2rgb_u2b_coeff; 1143 1144 if (hasAlpha) { 1145 A1 = (abuf0[i * 2 ] * yalpha1 + abuf1[i * 2 ] * yalpha) >> 1; 1146 A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 1; 1147 1148 A1 += 1 << 13; 1149 A2 += 1 << 13; 1150 } 1151 1152 output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + Y1) >> 14) + (1<<15), 16)); 1153 output_pixel(&dest[1], av_clip_uintp2(((int)( G + Y1) >> 14) + (1<<15), 16)); 1154 output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + Y1) >> 14) + (1<<15), 16)); 1155 if (eightbytes) { 1156 output_pixel(&dest[3], av_clip_uintp2(A1 , 30) >> 14); 1157 output_pixel(&dest[4], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); 1158 output_pixel(&dest[5], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); 1159 output_pixel(&dest[6], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); 1160 output_pixel(&dest[7], av_clip_uintp2(A2 , 30) >> 14); 1161 dest += 8; 1162 } else { 1163 output_pixel(&dest[3], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); 1164 output_pixel(&dest[4], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); 1165 output_pixel(&dest[5], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); 1166 dest += 6; 1167 } 1168 } 1169} 1170 1171static av_always_inline void 1172yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0, 1173 const int32_t *ubuf[2], const int32_t *vbuf[2], 1174 const int32_t *abuf0, uint16_t *dest, int dstW, 1175 int uvalpha, int y, enum AVPixelFormat target, int hasAlpha, int eightbytes) 1176{ 1177 const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; 1178 int i; 1179 int A1 = 0xffff<<14, A2= 0xffff<<14; 1180 1181 if (uvalpha < 2048) { 1182 for (i = 0; i < ((dstW + 1) >> 1); i++) { 1183 SUINT Y1 = (buf0[i * 2] ) >> 2; 1184 SUINT Y2 = (buf0[i * 2 + 1]) >> 2; 1185 int U = (ubuf0[i] - (128 << 11)) >> 2; 1186 int V = (vbuf0[i] - (128 << 11)) >> 2; 1187 int R, G, B; 1188 1189 Y1 -= c->yuv2rgb_y_offset; 1190 Y2 -= c->yuv2rgb_y_offset; 1191 Y1 *= c->yuv2rgb_y_coeff; 1192 Y2 *= c->yuv2rgb_y_coeff; 1193 Y1 += (1 << 13) - (1 << 29); 1194 Y2 += (1 << 13) - (1 << 29); 1195 1196 if (hasAlpha) { 1197 A1 = abuf0[i * 2 ] << 11; 1198 A2 = abuf0[i * 2 + 1] << 11; 1199 1200 A1 += 1 << 13; 1201 A2 += 1 << 13; 1202 } 1203 1204 R = V * c->yuv2rgb_v2r_coeff; 1205 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 1206 B = U * c->yuv2rgb_u2b_coeff; 1207 1208 output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + Y1) >> 14) + (1<<15), 16)); 1209 output_pixel(&dest[1], av_clip_uintp2(((int)( G + Y1) >> 14) + (1<<15), 16)); 1210 output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + Y1) >> 14) + (1<<15), 16)); 1211 if (eightbytes) { 1212 output_pixel(&dest[3], av_clip_uintp2(A1 , 30) >> 14); 1213 output_pixel(&dest[4], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); 1214 output_pixel(&dest[5], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); 1215 output_pixel(&dest[6], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); 1216 output_pixel(&dest[7], av_clip_uintp2(A2 , 30) >> 14); 1217 dest += 8; 1218 } else { 1219 output_pixel(&dest[3], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); 1220 output_pixel(&dest[4], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); 1221 output_pixel(&dest[5], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); 1222 dest += 6; 1223 } 1224 } 1225 } else { 1226 const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; 1227 int A1 = 0xffff<<14, A2 = 0xffff<<14; 1228 for (i = 0; i < ((dstW + 1) >> 1); i++) { 1229 SUINT Y1 = (buf0[i * 2] ) >> 2; 1230 SUINT Y2 = (buf0[i * 2 + 1]) >> 2; 1231 int U = (ubuf0[i] + ubuf1[i] - (128 << 12)) >> 3; 1232 int V = (vbuf0[i] + vbuf1[i] - (128 << 12)) >> 3; 1233 int R, G, B; 1234 1235 Y1 -= c->yuv2rgb_y_offset; 1236 Y2 -= c->yuv2rgb_y_offset; 1237 Y1 *= c->yuv2rgb_y_coeff; 1238 Y2 *= c->yuv2rgb_y_coeff; 1239 Y1 += (1 << 13) - (1 << 29); 1240 Y2 += (1 << 13) - (1 << 29); 1241 1242 if (hasAlpha) { 1243 A1 = abuf0[i * 2 ] << 11; 1244 A2 = abuf0[i * 2 + 1] << 11; 1245 1246 A1 += 1 << 13; 1247 A2 += 1 << 13; 1248 } 1249 1250 R = V * c->yuv2rgb_v2r_coeff; 1251 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 1252 B = U * c->yuv2rgb_u2b_coeff; 1253 1254 output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + Y1) >> 14) + (1<<15), 16)); 1255 output_pixel(&dest[1], av_clip_uintp2(((int)( G + Y1) >> 14) + (1<<15), 16)); 1256 output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + Y1) >> 14) + (1<<15), 16)); 1257 if (eightbytes) { 1258 output_pixel(&dest[3], av_clip_uintp2(A1 , 30) >> 14); 1259 output_pixel(&dest[4], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); 1260 output_pixel(&dest[5], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); 1261 output_pixel(&dest[6], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); 1262 output_pixel(&dest[7], av_clip_uintp2(A2 , 30) >> 14); 1263 dest += 8; 1264 } else { 1265 output_pixel(&dest[3], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); 1266 output_pixel(&dest[4], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); 1267 output_pixel(&dest[5], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); 1268 dest += 6; 1269 } 1270 } 1271 } 1272} 1273 1274static av_always_inline void 1275yuv2rgba64_full_X_c_template(SwsContext *c, const int16_t *lumFilter, 1276 const int32_t **lumSrc, int lumFilterSize, 1277 const int16_t *chrFilter, const int32_t **chrUSrc, 1278 const int32_t **chrVSrc, int chrFilterSize, 1279 const int32_t **alpSrc, uint16_t *dest, int dstW, 1280 int y, enum AVPixelFormat target, int hasAlpha, int eightbytes) 1281{ 1282 int i; 1283 int A = 0xffff<<14; 1284 1285 for (i = 0; i < dstW; i++) { 1286 int j; 1287 int Y = -0x40000000; 1288 int U = -(128 << 23); // 19 1289 int V = -(128 << 23); 1290 int R, G, B; 1291 1292 for (j = 0; j < lumFilterSize; j++) { 1293 Y += lumSrc[j][i] * (unsigned)lumFilter[j]; 1294 } 1295 for (j = 0; j < chrFilterSize; j++) {; 1296 U += chrUSrc[j][i] * (unsigned)chrFilter[j]; 1297 V += chrVSrc[j][i] * (unsigned)chrFilter[j]; 1298 } 1299 1300 if (hasAlpha) { 1301 A = -0x40000000; 1302 for (j = 0; j < lumFilterSize; j++) { 1303 A += alpSrc[j][i] * (unsigned)lumFilter[j]; 1304 } 1305 A >>= 1; 1306 A += 0x20002000; 1307 } 1308 1309 // 8bit: 12+15=27; 16-bit: 12+19=31 1310 Y >>= 14; // 10 1311 Y += 0x10000; 1312 U >>= 14; 1313 V >>= 14; 1314 1315 // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit 1316 Y -= c->yuv2rgb_y_offset; 1317 Y *= c->yuv2rgb_y_coeff; 1318 Y += (1 << 13) - (1<<29); // 21 1319 // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit 1320 1321 R = V * c->yuv2rgb_v2r_coeff; 1322 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 1323 B = U * c->yuv2rgb_u2b_coeff; 1324 1325 // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit 1326 output_pixel(&dest[0], av_clip_uintp2(((R_B + Y)>>14) + (1<<15), 16)); 1327 output_pixel(&dest[1], av_clip_uintp2((( G + Y)>>14) + (1<<15), 16)); 1328 output_pixel(&dest[2], av_clip_uintp2(((B_R + Y)>>14) + (1<<15), 16)); 1329 if (eightbytes) { 1330 output_pixel(&dest[3], av_clip_uintp2(A, 30) >> 14); 1331 dest += 4; 1332 } else { 1333 dest += 3; 1334 } 1335 } 1336} 1337 1338static av_always_inline void 1339yuv2rgba64_full_2_c_template(SwsContext *c, const int32_t *buf[2], 1340 const int32_t *ubuf[2], const int32_t *vbuf[2], 1341 const int32_t *abuf[2], uint16_t *dest, int dstW, 1342 int yalpha, int uvalpha, int y, 1343 enum AVPixelFormat target, int hasAlpha, int eightbytes) 1344{ 1345 const int32_t *buf0 = buf[0], *buf1 = buf[1], 1346 *ubuf0 = ubuf[0], *ubuf1 = ubuf[1], 1347 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1], 1348 *abuf0 = hasAlpha ? abuf[0] : NULL, 1349 *abuf1 = hasAlpha ? abuf[1] : NULL; 1350 int yalpha1 = 4096 - yalpha; 1351 int uvalpha1 = 4096 - uvalpha; 1352 int i; 1353 int A = 0xffff<<14; 1354 1355 av_assert2(yalpha <= 4096U); 1356 av_assert2(uvalpha <= 4096U); 1357 1358 for (i = 0; i < dstW; i++) { 1359 int Y = (buf0[i] * yalpha1 + buf1[i] * yalpha) >> 14; 1360 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha - (128 << 23)) >> 14; 1361 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha - (128 << 23)) >> 14; 1362 int R, G, B; 1363 1364 Y -= c->yuv2rgb_y_offset; 1365 Y *= c->yuv2rgb_y_coeff; 1366 Y += (1 << 13) - (1 << 29); 1367 1368 R = V * c->yuv2rgb_v2r_coeff; 1369 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 1370 B = U * c->yuv2rgb_u2b_coeff; 1371 1372 if (hasAlpha) { 1373 A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha) >> 1; 1374 1375 A += 1 << 13; 1376 } 1377 1378 output_pixel(&dest[0], av_clip_uintp2(((R_B + Y) >> 14) + (1<<15), 16)); 1379 output_pixel(&dest[1], av_clip_uintp2((( G + Y) >> 14) + (1<<15), 16)); 1380 output_pixel(&dest[2], av_clip_uintp2(((B_R + Y) >> 14) + (1<<15), 16)); 1381 if (eightbytes) { 1382 output_pixel(&dest[3], av_clip_uintp2(A, 30) >> 14); 1383 dest += 4; 1384 } else { 1385 dest += 3; 1386 } 1387 } 1388} 1389 1390static av_always_inline void 1391yuv2rgba64_full_1_c_template(SwsContext *c, const int32_t *buf0, 1392 const int32_t *ubuf[2], const int32_t *vbuf[2], 1393 const int32_t *abuf0, uint16_t *dest, int dstW, 1394 int uvalpha, int y, enum AVPixelFormat target, int hasAlpha, int eightbytes) 1395{ 1396 const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; 1397 int i; 1398 int A = 0xffff<<14; 1399 1400 if (uvalpha < 2048) { 1401 for (i = 0; i < dstW; i++) { 1402 int Y = (buf0[i]) >> 2; 1403 int U = (ubuf0[i] - (128 << 11)) >> 2; 1404 int V = (vbuf0[i] - (128 << 11)) >> 2; 1405 int R, G, B; 1406 1407 Y -= c->yuv2rgb_y_offset; 1408 Y *= c->yuv2rgb_y_coeff; 1409 Y += (1 << 13) - (1 << 29); 1410 1411 if (hasAlpha) { 1412 A = abuf0[i] << 11; 1413 1414 A += 1 << 13; 1415 } 1416 1417 R = V * c->yuv2rgb_v2r_coeff; 1418 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 1419 B = U * c->yuv2rgb_u2b_coeff; 1420 1421 output_pixel(&dest[0], av_clip_uintp2(((R_B + Y) >> 14) + (1<<15), 16)); 1422 output_pixel(&dest[1], av_clip_uintp2((( G + Y) >> 14) + (1<<15), 16)); 1423 output_pixel(&dest[2], av_clip_uintp2(((B_R + Y) >> 14) + (1<<15), 16)); 1424 if (eightbytes) { 1425 output_pixel(&dest[3], av_clip_uintp2(A, 30) >> 14); 1426 dest += 4; 1427 } else { 1428 dest += 3; 1429 } 1430 } 1431 } else { 1432 const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; 1433 int A = 0xffff<<14; 1434 for (i = 0; i < dstW; i++) { 1435 int Y = (buf0[i] ) >> 2; 1436 int U = (ubuf0[i] + ubuf1[i] - (128 << 12)) >> 3; 1437 int V = (vbuf0[i] + vbuf1[i] - (128 << 12)) >> 3; 1438 int R, G, B; 1439 1440 Y -= c->yuv2rgb_y_offset; 1441 Y *= c->yuv2rgb_y_coeff; 1442 Y += (1 << 13) - (1 << 29); 1443 1444 if (hasAlpha) { 1445 A = abuf0[i] << 11; 1446 1447 A += 1 << 13; 1448 } 1449 1450 R = V * c->yuv2rgb_v2r_coeff; 1451 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 1452 B = U * c->yuv2rgb_u2b_coeff; 1453 1454 output_pixel(&dest[0], av_clip_uintp2(((R_B + Y) >> 14) + (1<<15), 16)); 1455 output_pixel(&dest[1], av_clip_uintp2((( G + Y) >> 14) + (1<<15), 16)); 1456 output_pixel(&dest[2], av_clip_uintp2(((B_R + Y) >> 14) + (1<<15), 16)); 1457 if (eightbytes) { 1458 output_pixel(&dest[3], av_clip_uintp2(A, 30) >> 14); 1459 dest += 4; 1460 } else { 1461 dest += 3; 1462 } 1463 } 1464 } 1465} 1466 1467#undef output_pixel 1468#undef r_b 1469#undef b_r 1470 1471#define YUV2PACKED16WRAPPER(name, base, ext, fmt, hasAlpha, eightbytes) \ 1472static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \ 1473 const int16_t **_lumSrc, int lumFilterSize, \ 1474 const int16_t *chrFilter, const int16_t **_chrUSrc, \ 1475 const int16_t **_chrVSrc, int chrFilterSize, \ 1476 const int16_t **_alpSrc, uint8_t *_dest, int dstW, \ 1477 int y) \ 1478{ \ 1479 const int32_t **lumSrc = (const int32_t **) _lumSrc, \ 1480 **chrUSrc = (const int32_t **) _chrUSrc, \ 1481 **chrVSrc = (const int32_t **) _chrVSrc, \ 1482 **alpSrc = (const int32_t **) _alpSrc; \ 1483 uint16_t *dest = (uint16_t *) _dest; \ 1484 name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \ 1485 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \ 1486 alpSrc, dest, dstW, y, fmt, hasAlpha, eightbytes); \ 1487} \ 1488 \ 1489static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \ 1490 const int16_t *_ubuf[2], const int16_t *_vbuf[2], \ 1491 const int16_t *_abuf[2], uint8_t *_dest, int dstW, \ 1492 int yalpha, int uvalpha, int y) \ 1493{ \ 1494 const int32_t **buf = (const int32_t **) _buf, \ 1495 **ubuf = (const int32_t **) _ubuf, \ 1496 **vbuf = (const int32_t **) _vbuf, \ 1497 **abuf = (const int32_t **) _abuf; \ 1498 uint16_t *dest = (uint16_t *) _dest; \ 1499 name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \ 1500 dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha, eightbytes); \ 1501} \ 1502 \ 1503static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \ 1504 const int16_t *_ubuf[2], const int16_t *_vbuf[2], \ 1505 const int16_t *_abuf0, uint8_t *_dest, int dstW, \ 1506 int uvalpha, int y) \ 1507{ \ 1508 const int32_t *buf0 = (const int32_t *) _buf0, \ 1509 **ubuf = (const int32_t **) _ubuf, \ 1510 **vbuf = (const int32_t **) _vbuf, \ 1511 *abuf0 = (const int32_t *) _abuf0; \ 1512 uint16_t *dest = (uint16_t *) _dest; \ 1513 name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \ 1514 dstW, uvalpha, y, fmt, hasAlpha, eightbytes); \ 1515} 1516 1517YUV2PACKED16WRAPPER(yuv2, rgba64, rgb48be, AV_PIX_FMT_RGB48BE, 0, 0) 1518YUV2PACKED16WRAPPER(yuv2, rgba64, rgb48le, AV_PIX_FMT_RGB48LE, 0, 0) 1519YUV2PACKED16WRAPPER(yuv2, rgba64, bgr48be, AV_PIX_FMT_BGR48BE, 0, 0) 1520YUV2PACKED16WRAPPER(yuv2, rgba64, bgr48le, AV_PIX_FMT_BGR48LE, 0, 0) 1521YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64be, AV_PIX_FMT_RGBA64BE, 1, 1) 1522YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64le, AV_PIX_FMT_RGBA64LE, 1, 1) 1523YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64be, AV_PIX_FMT_RGBA64BE, 0, 1) 1524YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64le, AV_PIX_FMT_RGBA64LE, 0, 1) 1525YUV2PACKED16WRAPPER(yuv2, rgba64, bgra64be, AV_PIX_FMT_BGRA64BE, 1, 1) 1526YUV2PACKED16WRAPPER(yuv2, rgba64, bgra64le, AV_PIX_FMT_BGRA64LE, 1, 1) 1527YUV2PACKED16WRAPPER(yuv2, rgba64, bgrx64be, AV_PIX_FMT_BGRA64BE, 0, 1) 1528YUV2PACKED16WRAPPER(yuv2, rgba64, bgrx64le, AV_PIX_FMT_BGRA64LE, 0, 1) 1529YUV2PACKED16WRAPPER(yuv2, ya16, ya16be, AV_PIX_FMT_YA16BE, 1, 0) 1530YUV2PACKED16WRAPPER(yuv2, ya16, ya16le, AV_PIX_FMT_YA16LE, 1, 0) 1531 1532YUV2PACKED16WRAPPER(yuv2, rgba64_full, rgb48be_full, AV_PIX_FMT_RGB48BE, 0, 0) 1533YUV2PACKED16WRAPPER(yuv2, rgba64_full, rgb48le_full, AV_PIX_FMT_RGB48LE, 0, 0) 1534YUV2PACKED16WRAPPER(yuv2, rgba64_full, bgr48be_full, AV_PIX_FMT_BGR48BE, 0, 0) 1535YUV2PACKED16WRAPPER(yuv2, rgba64_full, bgr48le_full, AV_PIX_FMT_BGR48LE, 0, 0) 1536YUV2PACKED16WRAPPER(yuv2, rgba64_full, rgba64be_full, AV_PIX_FMT_RGBA64BE, 1, 1) 1537YUV2PACKED16WRAPPER(yuv2, rgba64_full, rgba64le_full, AV_PIX_FMT_RGBA64LE, 1, 1) 1538YUV2PACKED16WRAPPER(yuv2, rgba64_full, rgbx64be_full, AV_PIX_FMT_RGBA64BE, 0, 1) 1539YUV2PACKED16WRAPPER(yuv2, rgba64_full, rgbx64le_full, AV_PIX_FMT_RGBA64LE, 0, 1) 1540YUV2PACKED16WRAPPER(yuv2, rgba64_full, bgra64be_full, AV_PIX_FMT_BGRA64BE, 1, 1) 1541YUV2PACKED16WRAPPER(yuv2, rgba64_full, bgra64le_full, AV_PIX_FMT_BGRA64LE, 1, 1) 1542YUV2PACKED16WRAPPER(yuv2, rgba64_full, bgrx64be_full, AV_PIX_FMT_BGRA64BE, 0, 1) 1543YUV2PACKED16WRAPPER(yuv2, rgba64_full, bgrx64le_full, AV_PIX_FMT_BGRA64LE, 0, 1) 1544 1545/* 1546 * Write out 2 RGB pixels in the target pixel format. This function takes a 1547 * R/G/B LUT as generated by ff_yuv2rgb_c_init_tables(), which takes care of 1548 * things like endianness conversion and shifting. The caller takes care of 1549 * setting the correct offset in these tables from the chroma (U/V) values. 1550 * This function then uses the luminance (Y1/Y2) values to write out the 1551 * correct RGB values into the destination buffer. 1552 */ 1553static av_always_inline void 1554yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2, 1555 unsigned A1, unsigned A2, 1556 const void *_r, const void *_g, const void *_b, int y, 1557 enum AVPixelFormat target, int hasAlpha) 1558{ 1559 if (target == AV_PIX_FMT_ARGB || target == AV_PIX_FMT_RGBA || 1560 target == AV_PIX_FMT_ABGR || target == AV_PIX_FMT_BGRA) { 1561 uint32_t *dest = (uint32_t *) _dest; 1562 const uint32_t *r = (const uint32_t *) _r; 1563 const uint32_t *g = (const uint32_t *) _g; 1564 const uint32_t *b = (const uint32_t *) _b; 1565 1566#if CONFIG_SMALL 1567 int sh = hasAlpha ? ((target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24) : 0; 1568 1569 dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0); 1570 dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0); 1571#else 1572 if (hasAlpha) { 1573 int sh = (target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24; 1574 1575 av_assert2((((r[Y1] + g[Y1] + b[Y1]) >> sh) & 0xFF) == 0); 1576 dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (A1 << sh); 1577 dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (A2 << sh); 1578 } else { 1579#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 1580 int sh = (target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24; 1581 1582 av_assert2((((r[Y1] + g[Y1] + b[Y1]) >> sh) & 0xFF) == 0xFF); 1583#endif 1584 dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1]; 1585 dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2]; 1586 } 1587#endif 1588 } else if (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) { 1589 uint8_t *dest = (uint8_t *) _dest; 1590 const uint8_t *r = (const uint8_t *) _r; 1591 const uint8_t *g = (const uint8_t *) _g; 1592 const uint8_t *b = (const uint8_t *) _b; 1593 1594#define r_b ((target == AV_PIX_FMT_RGB24) ? r : b) 1595#define b_r ((target == AV_PIX_FMT_RGB24) ? b : r) 1596 1597 dest[i * 6 + 0] = r_b[Y1]; 1598 dest[i * 6 + 1] = g[Y1]; 1599 dest[i * 6 + 2] = b_r[Y1]; 1600 dest[i * 6 + 3] = r_b[Y2]; 1601 dest[i * 6 + 4] = g[Y2]; 1602 dest[i * 6 + 5] = b_r[Y2]; 1603#undef r_b 1604#undef b_r 1605 } else if (target == AV_PIX_FMT_RGB565 || target == AV_PIX_FMT_BGR565 || 1606 target == AV_PIX_FMT_RGB555 || target == AV_PIX_FMT_BGR555 || 1607 target == AV_PIX_FMT_RGB444 || target == AV_PIX_FMT_BGR444) { 1608 uint16_t *dest = (uint16_t *) _dest; 1609 const uint16_t *r = (const uint16_t *) _r; 1610 const uint16_t *g = (const uint16_t *) _g; 1611 const uint16_t *b = (const uint16_t *) _b; 1612 int dr1, dg1, db1, dr2, dg2, db2; 1613 1614 if (target == AV_PIX_FMT_RGB565 || target == AV_PIX_FMT_BGR565) { 1615 dr1 = ff_dither_2x2_8[ y & 1 ][0]; 1616 dg1 = ff_dither_2x2_4[ y & 1 ][0]; 1617 db1 = ff_dither_2x2_8[(y & 1) ^ 1][0]; 1618 dr2 = ff_dither_2x2_8[ y & 1 ][1]; 1619 dg2 = ff_dither_2x2_4[ y & 1 ][1]; 1620 db2 = ff_dither_2x2_8[(y & 1) ^ 1][1]; 1621 } else if (target == AV_PIX_FMT_RGB555 || target == AV_PIX_FMT_BGR555) { 1622 dr1 = ff_dither_2x2_8[ y & 1 ][0]; 1623 dg1 = ff_dither_2x2_8[ y & 1 ][1]; 1624 db1 = ff_dither_2x2_8[(y & 1) ^ 1][0]; 1625 dr2 = ff_dither_2x2_8[ y & 1 ][1]; 1626 dg2 = ff_dither_2x2_8[ y & 1 ][0]; 1627 db2 = ff_dither_2x2_8[(y & 1) ^ 1][1]; 1628 } else { 1629 dr1 = ff_dither_4x4_16[ y & 3 ][0]; 1630 dg1 = ff_dither_4x4_16[ y & 3 ][1]; 1631 db1 = ff_dither_4x4_16[(y & 3) ^ 3][0]; 1632 dr2 = ff_dither_4x4_16[ y & 3 ][1]; 1633 dg2 = ff_dither_4x4_16[ y & 3 ][0]; 1634 db2 = ff_dither_4x4_16[(y & 3) ^ 3][1]; 1635 } 1636 1637 dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1]; 1638 dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]; 1639 } else if (target == AV_PIX_FMT_X2RGB10 || target == AV_PIX_FMT_X2BGR10) { 1640 uint32_t *dest = (uint32_t *) _dest; 1641 const uint32_t *r = (const uint32_t *) _r; 1642 const uint32_t *g = (const uint32_t *) _g; 1643 const uint32_t *b = (const uint32_t *) _b; 1644 dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1]; 1645 dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2]; 1646 } else /* 8/4 bits */ { 1647 uint8_t *dest = (uint8_t *) _dest; 1648 const uint8_t *r = (const uint8_t *) _r; 1649 const uint8_t *g = (const uint8_t *) _g; 1650 const uint8_t *b = (const uint8_t *) _b; 1651 int dr1, dg1, db1, dr2, dg2, db2; 1652 1653 if (target == AV_PIX_FMT_RGB8 || target == AV_PIX_FMT_BGR8) { 1654 const uint8_t * const d64 = ff_dither_8x8_73[y & 7]; 1655 const uint8_t * const d32 = ff_dither_8x8_32[y & 7]; 1656 dr1 = dg1 = d32[(i * 2 + 0) & 7]; 1657 db1 = d64[(i * 2 + 0) & 7]; 1658 dr2 = dg2 = d32[(i * 2 + 1) & 7]; 1659 db2 = d64[(i * 2 + 1) & 7]; 1660 } else { 1661 const uint8_t * const d64 = ff_dither_8x8_73 [y & 7]; 1662 const uint8_t * const d128 = ff_dither_8x8_220[y & 7]; 1663 dr1 = db1 = d128[(i * 2 + 0) & 7]; 1664 dg1 = d64[(i * 2 + 0) & 7]; 1665 dr2 = db2 = d128[(i * 2 + 1) & 7]; 1666 dg2 = d64[(i * 2 + 1) & 7]; 1667 } 1668 1669 if (target == AV_PIX_FMT_RGB4 || target == AV_PIX_FMT_BGR4) { 1670 dest[i] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1] + 1671 ((r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]) << 4); 1672 } else { 1673 dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1]; 1674 dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]; 1675 } 1676 } 1677} 1678 1679static av_always_inline void 1680yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter, 1681 const int16_t **lumSrc, int lumFilterSize, 1682 const int16_t *chrFilter, const int16_t **chrUSrc, 1683 const int16_t **chrVSrc, int chrFilterSize, 1684 const int16_t **alpSrc, uint8_t *dest, int dstW, 1685 int y, enum AVPixelFormat target, int hasAlpha) 1686{ 1687 int i; 1688 1689 for (i = 0; i < ((dstW + 1) >> 1); i++) { 1690 int j, A1, A2; 1691 int Y1 = 1 << 18; 1692 int Y2 = 1 << 18; 1693 int U = 1 << 18; 1694 int V = 1 << 18; 1695 const void *r, *g, *b; 1696 1697 for (j = 0; j < lumFilterSize; j++) { 1698 Y1 += lumSrc[j][i * 2] * lumFilter[j]; 1699 Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j]; 1700 } 1701 for (j = 0; j < chrFilterSize; j++) { 1702 U += chrUSrc[j][i] * chrFilter[j]; 1703 V += chrVSrc[j][i] * chrFilter[j]; 1704 } 1705 Y1 >>= 19; 1706 Y2 >>= 19; 1707 U >>= 19; 1708 V >>= 19; 1709 if (hasAlpha) { 1710 A1 = 1 << 18; 1711 A2 = 1 << 18; 1712 for (j = 0; j < lumFilterSize; j++) { 1713 A1 += alpSrc[j][i * 2 ] * lumFilter[j]; 1714 A2 += alpSrc[j][i * 2 + 1] * lumFilter[j]; 1715 } 1716 A1 >>= 19; 1717 A2 >>= 19; 1718 if ((A1 | A2) & 0x100) { 1719 A1 = av_clip_uint8(A1); 1720 A2 = av_clip_uint8(A2); 1721 } 1722 } 1723 1724 r = c->table_rV[V + YUVRGB_TABLE_HEADROOM]; 1725 g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]); 1726 b = c->table_bU[U + YUVRGB_TABLE_HEADROOM]; 1727 1728 yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, 1729 r, g, b, y, target, hasAlpha); 1730 } 1731} 1732 1733static av_always_inline void 1734yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2], 1735 const int16_t *ubuf[2], const int16_t *vbuf[2], 1736 const int16_t *abuf[2], uint8_t *dest, int dstW, 1737 int yalpha, int uvalpha, int y, 1738 enum AVPixelFormat target, int hasAlpha) 1739{ 1740 const int16_t *buf0 = buf[0], *buf1 = buf[1], 1741 *ubuf0 = ubuf[0], *ubuf1 = ubuf[1], 1742 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1], 1743 *abuf0 = hasAlpha ? abuf[0] : NULL, 1744 *abuf1 = hasAlpha ? abuf[1] : NULL; 1745 int yalpha1 = 4096 - yalpha; 1746 int uvalpha1 = 4096 - uvalpha; 1747 int i; 1748 av_assert2(yalpha <= 4096U); 1749 av_assert2(uvalpha <= 4096U); 1750 1751 for (i = 0; i < ((dstW + 1) >> 1); i++) { 1752 int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19; 1753 int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19; 1754 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19; 1755 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19; 1756 int A1, A2; 1757 const void *r = c->table_rV[V + YUVRGB_TABLE_HEADROOM], 1758 *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]), 1759 *b = c->table_bU[U + YUVRGB_TABLE_HEADROOM]; 1760 1761 if (hasAlpha) { 1762 A1 = (abuf0[i * 2 ] * yalpha1 + abuf1[i * 2 ] * yalpha) >> 19; 1763 A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19; 1764 A1 = av_clip_uint8(A1); 1765 A2 = av_clip_uint8(A2); 1766 } 1767 1768 yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, 1769 r, g, b, y, target, hasAlpha); 1770 } 1771} 1772 1773static av_always_inline void 1774yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0, 1775 const int16_t *ubuf[2], const int16_t *vbuf[2], 1776 const int16_t *abuf0, uint8_t *dest, int dstW, 1777 int uvalpha, int y, enum AVPixelFormat target, 1778 int hasAlpha) 1779{ 1780 const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; 1781 int i; 1782 1783 if (uvalpha < 2048) { 1784 for (i = 0; i < ((dstW + 1) >> 1); i++) { 1785 int Y1 = (buf0[i * 2 ] + 64) >> 7; 1786 int Y2 = (buf0[i * 2 + 1] + 64) >> 7; 1787 int U = (ubuf0[i] + 64) >> 7; 1788 int V = (vbuf0[i] + 64) >> 7; 1789 int A1, A2; 1790 const void *r = c->table_rV[V + YUVRGB_TABLE_HEADROOM], 1791 *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]), 1792 *b = c->table_bU[U + YUVRGB_TABLE_HEADROOM]; 1793 1794 if (hasAlpha) { 1795 A1 = abuf0[i * 2 ] * 255 + 16384 >> 15; 1796 A2 = abuf0[i * 2 + 1] * 255 + 16384 >> 15; 1797 A1 = av_clip_uint8(A1); 1798 A2 = av_clip_uint8(A2); 1799 } 1800 1801 yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, 1802 r, g, b, y, target, hasAlpha); 1803 } 1804 } else { 1805 const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; 1806 for (i = 0; i < ((dstW + 1) >> 1); i++) { 1807 int Y1 = (buf0[i * 2 ] + 64) >> 7; 1808 int Y2 = (buf0[i * 2 + 1] + 64) >> 7; 1809 int U = (ubuf0[i] + ubuf1[i] + 128) >> 8; 1810 int V = (vbuf0[i] + vbuf1[i] + 128) >> 8; 1811 int A1, A2; 1812 const void *r = c->table_rV[V + YUVRGB_TABLE_HEADROOM], 1813 *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]), 1814 *b = c->table_bU[U + YUVRGB_TABLE_HEADROOM]; 1815 1816 if (hasAlpha) { 1817 A1 = (abuf0[i * 2 ] + 64) >> 7; 1818 A2 = (abuf0[i * 2 + 1] + 64) >> 7; 1819 A1 = av_clip_uint8(A1); 1820 A2 = av_clip_uint8(A2); 1821 } 1822 1823 yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0, 1824 r, g, b, y, target, hasAlpha); 1825 } 1826 } 1827} 1828 1829#define YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \ 1830static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \ 1831 const int16_t **lumSrc, int lumFilterSize, \ 1832 const int16_t *chrFilter, const int16_t **chrUSrc, \ 1833 const int16_t **chrVSrc, int chrFilterSize, \ 1834 const int16_t **alpSrc, uint8_t *dest, int dstW, \ 1835 int y) \ 1836{ \ 1837 name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \ 1838 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \ 1839 alpSrc, dest, dstW, y, fmt, hasAlpha); \ 1840} 1841 1842#define YUV2RGBWRAPPERX2(name, base, ext, fmt, hasAlpha) \ 1843YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \ 1844static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \ 1845 const int16_t *ubuf[2], const int16_t *vbuf[2], \ 1846 const int16_t *abuf[2], uint8_t *dest, int dstW, \ 1847 int yalpha, int uvalpha, int y) \ 1848{ \ 1849 name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \ 1850 dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \ 1851} 1852 1853#define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha) \ 1854YUV2RGBWRAPPERX2(name, base, ext, fmt, hasAlpha) \ 1855static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \ 1856 const int16_t *ubuf[2], const int16_t *vbuf[2], \ 1857 const int16_t *abuf0, uint8_t *dest, int dstW, \ 1858 int uvalpha, int y) \ 1859{ \ 1860 name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \ 1861 dstW, uvalpha, y, fmt, hasAlpha); \ 1862} 1863 1864#if CONFIG_SMALL 1865YUV2RGBWRAPPER(yuv2rgb,, 32_1, AV_PIX_FMT_RGB32_1, CONFIG_SWSCALE_ALPHA && c->needAlpha) 1866YUV2RGBWRAPPER(yuv2rgb,, 32, AV_PIX_FMT_RGB32, CONFIG_SWSCALE_ALPHA && c->needAlpha) 1867#else 1868#if CONFIG_SWSCALE_ALPHA 1869YUV2RGBWRAPPER(yuv2rgb,, a32_1, AV_PIX_FMT_RGB32_1, 1) 1870YUV2RGBWRAPPER(yuv2rgb,, a32, AV_PIX_FMT_RGB32, 1) 1871#endif 1872YUV2RGBWRAPPER(yuv2rgb,, x32_1, AV_PIX_FMT_RGB32_1, 0) 1873YUV2RGBWRAPPER(yuv2rgb,, x32, AV_PIX_FMT_RGB32, 0) 1874#endif 1875YUV2RGBWRAPPER(yuv2, rgb, rgb24, AV_PIX_FMT_RGB24, 0) 1876YUV2RGBWRAPPER(yuv2, rgb, bgr24, AV_PIX_FMT_BGR24, 0) 1877YUV2RGBWRAPPER(yuv2rgb,, 16, AV_PIX_FMT_RGB565, 0) 1878YUV2RGBWRAPPER(yuv2rgb,, 15, AV_PIX_FMT_RGB555, 0) 1879YUV2RGBWRAPPER(yuv2rgb,, 12, AV_PIX_FMT_RGB444, 0) 1880YUV2RGBWRAPPER(yuv2rgb,, 8, AV_PIX_FMT_RGB8, 0) 1881YUV2RGBWRAPPER(yuv2rgb,, 4, AV_PIX_FMT_RGB4, 0) 1882YUV2RGBWRAPPER(yuv2rgb,, 4b, AV_PIX_FMT_RGB4_BYTE, 0) 1883YUV2RGBWRAPPER(yuv2, rgb, x2rgb10, AV_PIX_FMT_X2RGB10, 0) 1884YUV2RGBWRAPPER(yuv2, rgb, x2bgr10, AV_PIX_FMT_X2BGR10, 0) 1885 1886static av_always_inline void yuv2rgb_write_full(SwsContext *c, 1887 uint8_t *dest, int i, int Y, int A, int U, int V, 1888 int y, enum AVPixelFormat target, int hasAlpha, int err[4]) 1889{ 1890 int R, G, B; 1891 int isrgb8 = target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8; 1892 1893 Y -= c->yuv2rgb_y_offset; 1894 Y *= c->yuv2rgb_y_coeff; 1895 Y += 1 << 21; 1896 R = (unsigned)Y + V*c->yuv2rgb_v2r_coeff; 1897 G = (unsigned)Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff; 1898 B = (unsigned)Y + U*c->yuv2rgb_u2b_coeff; 1899 if ((R | G | B) & 0xC0000000) { 1900 R = av_clip_uintp2(R, 30); 1901 G = av_clip_uintp2(G, 30); 1902 B = av_clip_uintp2(B, 30); 1903 } 1904 1905 switch(target) { 1906 case AV_PIX_FMT_ARGB: 1907 dest[0] = hasAlpha ? A : 255; 1908 dest[1] = R >> 22; 1909 dest[2] = G >> 22; 1910 dest[3] = B >> 22; 1911 break; 1912 case AV_PIX_FMT_RGB24: 1913 dest[0] = R >> 22; 1914 dest[1] = G >> 22; 1915 dest[2] = B >> 22; 1916 break; 1917 case AV_PIX_FMT_RGBA: 1918 dest[0] = R >> 22; 1919 dest[1] = G >> 22; 1920 dest[2] = B >> 22; 1921 dest[3] = hasAlpha ? A : 255; 1922 break; 1923 case AV_PIX_FMT_ABGR: 1924 dest[0] = hasAlpha ? A : 255; 1925 dest[1] = B >> 22; 1926 dest[2] = G >> 22; 1927 dest[3] = R >> 22; 1928 break; 1929 case AV_PIX_FMT_BGR24: 1930 dest[0] = B >> 22; 1931 dest[1] = G >> 22; 1932 dest[2] = R >> 22; 1933 break; 1934 case AV_PIX_FMT_BGRA: 1935 dest[0] = B >> 22; 1936 dest[1] = G >> 22; 1937 dest[2] = R >> 22; 1938 dest[3] = hasAlpha ? A : 255; 1939 break; 1940 case AV_PIX_FMT_BGR4_BYTE: 1941 case AV_PIX_FMT_RGB4_BYTE: 1942 case AV_PIX_FMT_BGR8: 1943 case AV_PIX_FMT_RGB8: 1944 { 1945 int r,g,b; 1946 1947 switch (c->dither) { 1948 case SWS_DITHER_NONE: 1949 if (isrgb8) { 1950 r = av_clip_uintp2(R >> 27, 3); 1951 g = av_clip_uintp2(G >> 27, 3); 1952 b = av_clip_uintp2(B >> 28, 2); 1953 } else { 1954 r = av_clip_uintp2(R >> 29, 1); 1955 g = av_clip_uintp2(G >> 28, 2); 1956 b = av_clip_uintp2(B >> 29, 1); 1957 } 1958 break; 1959 default: 1960 case SWS_DITHER_AUTO: 1961 case SWS_DITHER_ED: 1962 R >>= 22; 1963 G >>= 22; 1964 B >>= 22; 1965 R += (7*err[0] + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2])>>4; 1966 G += (7*err[1] + 1*c->dither_error[1][i] + 5*c->dither_error[1][i+1] + 3*c->dither_error[1][i+2])>>4; 1967 B += (7*err[2] + 1*c->dither_error[2][i] + 5*c->dither_error[2][i+1] + 3*c->dither_error[2][i+2])>>4; 1968 c->dither_error[0][i] = err[0]; 1969 c->dither_error[1][i] = err[1]; 1970 c->dither_error[2][i] = err[2]; 1971 r = R >> (isrgb8 ? 5 : 7); 1972 g = G >> (isrgb8 ? 5 : 6); 1973 b = B >> (isrgb8 ? 6 : 7); 1974 r = av_clip(r, 0, isrgb8 ? 7 : 1); 1975 g = av_clip(g, 0, isrgb8 ? 7 : 3); 1976 b = av_clip(b, 0, isrgb8 ? 3 : 1); 1977 err[0] = R - r*(isrgb8 ? 36 : 255); 1978 err[1] = G - g*(isrgb8 ? 36 : 85); 1979 err[2] = B - b*(isrgb8 ? 85 : 255); 1980 break; 1981 case SWS_DITHER_A_DITHER: 1982 if (isrgb8) { 1983 /* see http://pippin.gimp.org/a_dither/ for details/origin */ 1984#define A_DITHER(u,v) (((((u)+((v)*236))*119)&0xff)) 1985 r = (((R >> 19) + A_DITHER(i,y) -96)>>8); 1986 g = (((G >> 19) + A_DITHER(i + 17,y) - 96)>>8); 1987 b = (((B >> 20) + A_DITHER(i + 17*2,y) -96)>>8); 1988 r = av_clip_uintp2(r, 3); 1989 g = av_clip_uintp2(g, 3); 1990 b = av_clip_uintp2(b, 2); 1991 } else { 1992 r = (((R >> 21) + A_DITHER(i,y)-256)>>8); 1993 g = (((G >> 19) + A_DITHER(i + 17,y)-256)>>8); 1994 b = (((B >> 21) + A_DITHER(i + 17*2,y)-256)>>8); 1995 r = av_clip_uintp2(r, 1); 1996 g = av_clip_uintp2(g, 2); 1997 b = av_clip_uintp2(b, 1); 1998 } 1999 break; 2000 case SWS_DITHER_X_DITHER: 2001 if (isrgb8) { 2002 /* see http://pippin.gimp.org/a_dither/ for details/origin */ 2003#define X_DITHER(u,v) (((((u)^((v)*237))*181)&0x1ff)/2) 2004 r = (((R >> 19) + X_DITHER(i,y) - 96)>>8); 2005 g = (((G >> 19) + X_DITHER(i + 17,y) - 96)>>8); 2006 b = (((B >> 20) + X_DITHER(i + 17*2,y) - 96)>>8); 2007 r = av_clip_uintp2(r, 3); 2008 g = av_clip_uintp2(g, 3); 2009 b = av_clip_uintp2(b, 2); 2010 } else { 2011 r = (((R >> 21) + X_DITHER(i,y)-256)>>8); 2012 g = (((G >> 19) + X_DITHER(i + 17,y)-256)>>8); 2013 b = (((B >> 21) + X_DITHER(i + 17*2,y)-256)>>8); 2014 r = av_clip_uintp2(r, 1); 2015 g = av_clip_uintp2(g, 2); 2016 b = av_clip_uintp2(b, 1); 2017 } 2018 2019 break; 2020 } 2021 2022 if(target == AV_PIX_FMT_BGR4_BYTE) { 2023 dest[0] = r + 2*g + 8*b; 2024 } else if(target == AV_PIX_FMT_RGB4_BYTE) { 2025 dest[0] = b + 2*g + 8*r; 2026 } else if(target == AV_PIX_FMT_BGR8) { 2027 dest[0] = r + 8*g + 64*b; 2028 } else if(target == AV_PIX_FMT_RGB8) { 2029 dest[0] = b + 4*g + 32*r; 2030 } else 2031 av_assert2(0); 2032 break;} 2033 } 2034} 2035 2036static av_always_inline void 2037yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter, 2038 const int16_t **lumSrc, int lumFilterSize, 2039 const int16_t *chrFilter, const int16_t **chrUSrc, 2040 const int16_t **chrVSrc, int chrFilterSize, 2041 const int16_t **alpSrc, uint8_t *dest, 2042 int dstW, int y, enum AVPixelFormat target, int hasAlpha) 2043{ 2044 int i; 2045 int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4; 2046 int err[4] = {0}; 2047 int A = 0; //init to silence warning 2048 2049 if( target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE 2050 || target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8) 2051 step = 1; 2052 2053 for (i = 0; i < dstW; i++) { 2054 int j; 2055 int Y = 1<<9; 2056 int U = (1<<9)-(128 << 19); 2057 int V = (1<<9)-(128 << 19); 2058 2059 for (j = 0; j < lumFilterSize; j++) { 2060 Y += lumSrc[j][i] * lumFilter[j]; 2061 } 2062 for (j = 0; j < chrFilterSize; j++) { 2063 U += chrUSrc[j][i] * chrFilter[j]; 2064 V += chrVSrc[j][i] * chrFilter[j]; 2065 } 2066 Y >>= 10; 2067 U >>= 10; 2068 V >>= 10; 2069 if (hasAlpha) { 2070 A = 1 << 18; 2071 for (j = 0; j < lumFilterSize; j++) { 2072 A += alpSrc[j][i] * lumFilter[j]; 2073 } 2074 A >>= 19; 2075 if (A & 0x100) 2076 A = av_clip_uint8(A); 2077 } 2078 yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err); 2079 dest += step; 2080 } 2081 c->dither_error[0][i] = err[0]; 2082 c->dither_error[1][i] = err[1]; 2083 c->dither_error[2][i] = err[2]; 2084} 2085 2086static av_always_inline void 2087yuv2rgb_full_2_c_template(SwsContext *c, const int16_t *buf[2], 2088 const int16_t *ubuf[2], const int16_t *vbuf[2], 2089 const int16_t *abuf[2], uint8_t *dest, int dstW, 2090 int yalpha, int uvalpha, int y, 2091 enum AVPixelFormat target, int hasAlpha) 2092{ 2093 const int16_t *buf0 = buf[0], *buf1 = buf[1], 2094 *ubuf0 = ubuf[0], *ubuf1 = ubuf[1], 2095 *vbuf0 = vbuf[0], *vbuf1 = vbuf[1], 2096 *abuf0 = hasAlpha ? abuf[0] : NULL, 2097 *abuf1 = hasAlpha ? abuf[1] : NULL; 2098 int yalpha1 = 4096 - yalpha; 2099 int uvalpha1 = 4096 - uvalpha; 2100 int i; 2101 int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4; 2102 int err[4] = {0}; 2103 int A = 0; // init to silcene warning 2104 2105 av_assert2(yalpha <= 4096U); 2106 av_assert2(uvalpha <= 4096U); 2107 2108 if( target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE 2109 || target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8) 2110 step = 1; 2111 2112 for (i = 0; i < dstW; i++) { 2113 int Y = ( buf0[i] * yalpha1 + buf1[i] * yalpha ) >> 10; //FIXME rounding 2114 int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha-(128 << 19)) >> 10; 2115 int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha-(128 << 19)) >> 10; 2116 2117 if (hasAlpha) { 2118 A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha + (1<<18)) >> 19; 2119 if (A & 0x100) 2120 A = av_clip_uint8(A); 2121 } 2122 2123 yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err); 2124 dest += step; 2125 } 2126 c->dither_error[0][i] = err[0]; 2127 c->dither_error[1][i] = err[1]; 2128 c->dither_error[2][i] = err[2]; 2129} 2130 2131static av_always_inline void 2132yuv2rgb_full_1_c_template(SwsContext *c, const int16_t *buf0, 2133 const int16_t *ubuf[2], const int16_t *vbuf[2], 2134 const int16_t *abuf0, uint8_t *dest, int dstW, 2135 int uvalpha, int y, enum AVPixelFormat target, 2136 int hasAlpha) 2137{ 2138 const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; 2139 int i; 2140 int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4; 2141 int err[4] = {0}; 2142 2143 if( target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE 2144 || target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8) 2145 step = 1; 2146 2147 if (uvalpha < 2048) { 2148 int A = 0; //init to silence warning 2149 for (i = 0; i < dstW; i++) { 2150 int Y = buf0[i] * 4; 2151 int U = (ubuf0[i] - (128<<7)) * 4; 2152 int V = (vbuf0[i] - (128<<7)) * 4; 2153 2154 if (hasAlpha) { 2155 A = (abuf0[i] + 64) >> 7; 2156 if (A & 0x100) 2157 A = av_clip_uint8(A); 2158 } 2159 2160 yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err); 2161 dest += step; 2162 } 2163 } else { 2164 const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; 2165 int A = 0; //init to silence warning 2166 for (i = 0; i < dstW; i++) { 2167 int Y = buf0[i] * 4; 2168 int U = (ubuf0[i] + ubuf1[i] - (128<<8)) * 2; 2169 int V = (vbuf0[i] + vbuf1[i] - (128<<8)) * 2; 2170 2171 if (hasAlpha) { 2172 A = (abuf0[i] + 64) >> 7; 2173 if (A & 0x100) 2174 A = av_clip_uint8(A); 2175 } 2176 2177 yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err); 2178 dest += step; 2179 } 2180 } 2181 2182 c->dither_error[0][i] = err[0]; 2183 c->dither_error[1][i] = err[1]; 2184 c->dither_error[2][i] = err[2]; 2185} 2186 2187#if CONFIG_SMALL 2188YUV2RGBWRAPPER(yuv2, rgb_full, bgra32_full, AV_PIX_FMT_BGRA, CONFIG_SWSCALE_ALPHA && c->needAlpha) 2189YUV2RGBWRAPPER(yuv2, rgb_full, abgr32_full, AV_PIX_FMT_ABGR, CONFIG_SWSCALE_ALPHA && c->needAlpha) 2190YUV2RGBWRAPPER(yuv2, rgb_full, rgba32_full, AV_PIX_FMT_RGBA, CONFIG_SWSCALE_ALPHA && c->needAlpha) 2191YUV2RGBWRAPPER(yuv2, rgb_full, argb32_full, AV_PIX_FMT_ARGB, CONFIG_SWSCALE_ALPHA && c->needAlpha) 2192#else 2193#if CONFIG_SWSCALE_ALPHA 2194YUV2RGBWRAPPER(yuv2, rgb_full, bgra32_full, AV_PIX_FMT_BGRA, 1) 2195YUV2RGBWRAPPER(yuv2, rgb_full, abgr32_full, AV_PIX_FMT_ABGR, 1) 2196YUV2RGBWRAPPER(yuv2, rgb_full, rgba32_full, AV_PIX_FMT_RGBA, 1) 2197YUV2RGBWRAPPER(yuv2, rgb_full, argb32_full, AV_PIX_FMT_ARGB, 1) 2198#endif 2199YUV2RGBWRAPPER(yuv2, rgb_full, bgrx32_full, AV_PIX_FMT_BGRA, 0) 2200YUV2RGBWRAPPER(yuv2, rgb_full, xbgr32_full, AV_PIX_FMT_ABGR, 0) 2201YUV2RGBWRAPPER(yuv2, rgb_full, rgbx32_full, AV_PIX_FMT_RGBA, 0) 2202YUV2RGBWRAPPER(yuv2, rgb_full, xrgb32_full, AV_PIX_FMT_ARGB, 0) 2203#endif 2204YUV2RGBWRAPPER(yuv2, rgb_full, bgr24_full, AV_PIX_FMT_BGR24, 0) 2205YUV2RGBWRAPPER(yuv2, rgb_full, rgb24_full, AV_PIX_FMT_RGB24, 0) 2206 2207YUV2RGBWRAPPER(yuv2, rgb_full, bgr4_byte_full, AV_PIX_FMT_BGR4_BYTE, 0) 2208YUV2RGBWRAPPER(yuv2, rgb_full, rgb4_byte_full, AV_PIX_FMT_RGB4_BYTE, 0) 2209YUV2RGBWRAPPER(yuv2, rgb_full, bgr8_full, AV_PIX_FMT_BGR8, 0) 2210YUV2RGBWRAPPER(yuv2, rgb_full, rgb8_full, AV_PIX_FMT_RGB8, 0) 2211 2212static void 2213yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter, 2214 const int16_t **lumSrc, int lumFilterSize, 2215 const int16_t *chrFilter, const int16_t **chrUSrc, 2216 const int16_t **chrVSrc, int chrFilterSize, 2217 const int16_t **alpSrc, uint8_t **dest, 2218 int dstW, int y) 2219{ 2220 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat); 2221 int i; 2222 int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrc; 2223 uint16_t **dest16 = (uint16_t**)dest; 2224 int SH = 22 + 8 - desc->comp[0].depth; 2225 int A = 0; // init to silence warning 2226 2227 for (i = 0; i < dstW; i++) { 2228 int j; 2229 int Y = 1 << 9; 2230 int U = (1 << 9) - (128 << 19); 2231 int V = (1 << 9) - (128 << 19); 2232 int R, G, B; 2233 2234 for (j = 0; j < lumFilterSize; j++) 2235 Y += lumSrc[j][i] * lumFilter[j]; 2236 2237 for (j = 0; j < chrFilterSize; j++) { 2238 U += chrUSrc[j][i] * chrFilter[j]; 2239 V += chrVSrc[j][i] * chrFilter[j]; 2240 } 2241 2242 Y >>= 10; 2243 U >>= 10; 2244 V >>= 10; 2245 2246 if (hasAlpha) { 2247 A = 1 << 18; 2248 2249 for (j = 0; j < lumFilterSize; j++) 2250 A += alpSrc[j][i] * lumFilter[j]; 2251 2252 if (A & 0xF8000000) 2253 A = av_clip_uintp2(A, 27); 2254 } 2255 2256 Y -= c->yuv2rgb_y_offset; 2257 Y *= c->yuv2rgb_y_coeff; 2258 Y += 1 << (SH-1); 2259 R = Y + V * c->yuv2rgb_v2r_coeff; 2260 G = Y + V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 2261 B = Y + U * c->yuv2rgb_u2b_coeff; 2262 2263 if ((R | G | B) & 0xC0000000) { 2264 R = av_clip_uintp2(R, 30); 2265 G = av_clip_uintp2(G, 30); 2266 B = av_clip_uintp2(B, 30); 2267 } 2268 2269 if (SH != 22) { 2270 dest16[0][i] = G >> SH; 2271 dest16[1][i] = B >> SH; 2272 dest16[2][i] = R >> SH; 2273 if (hasAlpha) 2274 dest16[3][i] = A >> (SH - 3); 2275 } else { 2276 dest[0][i] = G >> 22; 2277 dest[1][i] = B >> 22; 2278 dest[2][i] = R >> 22; 2279 if (hasAlpha) 2280 dest[3][i] = A >> 19; 2281 } 2282 } 2283 if (SH != 22 && (!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) { 2284 for (i = 0; i < dstW; i++) { 2285 dest16[0][i] = av_bswap16(dest16[0][i]); 2286 dest16[1][i] = av_bswap16(dest16[1][i]); 2287 dest16[2][i] = av_bswap16(dest16[2][i]); 2288 if (hasAlpha) 2289 dest16[3][i] = av_bswap16(dest16[3][i]); 2290 } 2291 } 2292} 2293 2294static void 2295yuv2gbrp16_full_X_c(SwsContext *c, const int16_t *lumFilter, 2296 const int16_t **lumSrcx, int lumFilterSize, 2297 const int16_t *chrFilter, const int16_t **chrUSrcx, 2298 const int16_t **chrVSrcx, int chrFilterSize, 2299 const int16_t **alpSrcx, uint8_t **dest, 2300 int dstW, int y) 2301{ 2302 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat); 2303 int i; 2304 int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrcx; 2305 uint16_t **dest16 = (uint16_t**)dest; 2306 const int32_t **lumSrc = (const int32_t**)lumSrcx; 2307 const int32_t **chrUSrc = (const int32_t**)chrUSrcx; 2308 const int32_t **chrVSrc = (const int32_t**)chrVSrcx; 2309 const int32_t **alpSrc = (const int32_t**)alpSrcx; 2310 2311 for (i = 0; i < dstW; i++) { 2312 int j; 2313 int Y = -0x40000000; 2314 int U = -(128 << 23); 2315 int V = -(128 << 23); 2316 int R, G, B, A; 2317 2318 for (j = 0; j < lumFilterSize; j++) 2319 Y += lumSrc[j][i] * (unsigned)lumFilter[j]; 2320 2321 for (j = 0; j < chrFilterSize; j++) { 2322 U += chrUSrc[j][i] * (unsigned)chrFilter[j]; 2323 V += chrVSrc[j][i] * (unsigned)chrFilter[j]; 2324 } 2325 2326 Y >>= 14; 2327 Y += 0x10000; 2328 U >>= 14; 2329 V >>= 14; 2330 2331 if (hasAlpha) { 2332 A = -0x40000000; 2333 2334 for (j = 0; j < lumFilterSize; j++) 2335 A += alpSrc[j][i] * (unsigned)lumFilter[j]; 2336 2337 A >>= 1; 2338 A += 0x20002000; 2339 } 2340 2341 Y -= c->yuv2rgb_y_offset; 2342 Y *= c->yuv2rgb_y_coeff; 2343 Y += (1 << 13) - (1 << 29); 2344 R = V * c->yuv2rgb_v2r_coeff; 2345 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 2346 B = U * c->yuv2rgb_u2b_coeff; 2347 2348 dest16[2][i] = av_clip_uintp2(((Y + R) >> 14) + (1<<15), 16); 2349 dest16[0][i] = av_clip_uintp2(((Y + G) >> 14) + (1<<15), 16); 2350 dest16[1][i] = av_clip_uintp2(((Y + B) >> 14) + (1<<15), 16); 2351 2352 if (hasAlpha) 2353 dest16[3][i] = av_clip_uintp2(A, 30) >> 14; 2354 } 2355 if ((!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) { 2356 for (i = 0; i < dstW; i++) { 2357 dest16[0][i] = av_bswap16(dest16[0][i]); 2358 dest16[1][i] = av_bswap16(dest16[1][i]); 2359 dest16[2][i] = av_bswap16(dest16[2][i]); 2360 if (hasAlpha) 2361 dest16[3][i] = av_bswap16(dest16[3][i]); 2362 } 2363 } 2364} 2365 2366static void 2367yuv2gbrpf32_full_X_c(SwsContext *c, const int16_t *lumFilter, 2368 const int16_t **lumSrcx, int lumFilterSize, 2369 const int16_t *chrFilter, const int16_t **chrUSrcx, 2370 const int16_t **chrVSrcx, int chrFilterSize, 2371 const int16_t **alpSrcx, uint8_t **dest, 2372 int dstW, int y) 2373{ 2374 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat); 2375 int i; 2376 int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrcx; 2377 uint32_t **dest32 = (uint32_t**)dest; 2378 const int32_t **lumSrc = (const int32_t**)lumSrcx; 2379 const int32_t **chrUSrc = (const int32_t**)chrUSrcx; 2380 const int32_t **chrVSrc = (const int32_t**)chrVSrcx; 2381 const int32_t **alpSrc = (const int32_t**)alpSrcx; 2382 static const float float_mult = 1.0f / 65535.0f; 2383 2384 for (i = 0; i < dstW; i++) { 2385 int j; 2386 int Y = -0x40000000; 2387 int U = -(128 << 23); 2388 int V = -(128 << 23); 2389 int R, G, B, A; 2390 2391 for (j = 0; j < lumFilterSize; j++) 2392 Y += lumSrc[j][i] * (unsigned)lumFilter[j]; 2393 2394 for (j = 0; j < chrFilterSize; j++) { 2395 U += chrUSrc[j][i] * (unsigned)chrFilter[j]; 2396 V += chrVSrc[j][i] * (unsigned)chrFilter[j]; 2397 } 2398 2399 Y >>= 14; 2400 Y += 0x10000; 2401 U >>= 14; 2402 V >>= 14; 2403 2404 if (hasAlpha) { 2405 A = -0x40000000; 2406 2407 for (j = 0; j < lumFilterSize; j++) 2408 A += alpSrc[j][i] * (unsigned)lumFilter[j]; 2409 2410 A >>= 1; 2411 A += 0x20002000; 2412 } 2413 2414 Y -= c->yuv2rgb_y_offset; 2415 Y *= c->yuv2rgb_y_coeff; 2416 Y += (1 << 13) - (1 << 29); 2417 R = V * c->yuv2rgb_v2r_coeff; 2418 G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; 2419 B = U * c->yuv2rgb_u2b_coeff; 2420 2421 R = av_clip_uintp2(((Y + R) >> 14) + (1<<15), 16); 2422 G = av_clip_uintp2(((Y + G) >> 14) + (1<<15), 16); 2423 B = av_clip_uintp2(((Y + B) >> 14) + (1<<15), 16); 2424 2425 dest32[0][i] = av_float2int(float_mult * (float)G); 2426 dest32[1][i] = av_float2int(float_mult * (float)B); 2427 dest32[2][i] = av_float2int(float_mult * (float)R); 2428 if (hasAlpha) 2429 dest32[3][i] = av_float2int(float_mult * (float)(av_clip_uintp2(A, 30) >> 14)); 2430 } 2431 if ((!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) { 2432 for (i = 0; i < dstW; i++) { 2433 dest32[0][i] = av_bswap32(dest32[0][i]); 2434 dest32[1][i] = av_bswap32(dest32[1][i]); 2435 dest32[2][i] = av_bswap32(dest32[2][i]); 2436 if (hasAlpha) 2437 dest32[3][i] = av_bswap32(dest32[3][i]); 2438 } 2439 } 2440} 2441 2442static void 2443yuv2ya8_1_c(SwsContext *c, const int16_t *buf0, 2444 const int16_t *ubuf[2], const int16_t *vbuf[2], 2445 const int16_t *abuf0, uint8_t *dest, int dstW, 2446 int uvalpha, int y) 2447{ 2448 int hasAlpha = !!abuf0; 2449 int i; 2450 2451 for (i = 0; i < dstW; i++) { 2452 int Y = (buf0[i] + 64) >> 7; 2453 int A; 2454 2455 Y = av_clip_uint8(Y); 2456 2457 if (hasAlpha) { 2458 A = (abuf0[i] + 64) >> 7; 2459 if (A & 0x100) 2460 A = av_clip_uint8(A); 2461 } 2462 2463 dest[i * 2 ] = Y; 2464 dest[i * 2 + 1] = hasAlpha ? A : 255; 2465 } 2466} 2467 2468static void 2469yuv2ya8_2_c(SwsContext *c, const int16_t *buf[2], 2470 const int16_t *ubuf[2], const int16_t *vbuf[2], 2471 const int16_t *abuf[2], uint8_t *dest, int dstW, 2472 int yalpha, int uvalpha, int y) 2473{ 2474 int hasAlpha = abuf && abuf[0] && abuf[1]; 2475 const int16_t *buf0 = buf[0], *buf1 = buf[1], 2476 *abuf0 = hasAlpha ? abuf[0] : NULL, 2477 *abuf1 = hasAlpha ? abuf[1] : NULL; 2478 int yalpha1 = 4096 - yalpha; 2479 int i; 2480 2481 av_assert2(yalpha <= 4096U); 2482 2483 for (i = 0; i < dstW; i++) { 2484 int Y = (buf0[i] * yalpha1 + buf1[i] * yalpha) >> 19; 2485 int A; 2486 2487 Y = av_clip_uint8(Y); 2488 2489 if (hasAlpha) { 2490 A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha) >> 19; 2491 A = av_clip_uint8(A); 2492 } 2493 2494 dest[i * 2 ] = Y; 2495 dest[i * 2 + 1] = hasAlpha ? A : 255; 2496 } 2497} 2498 2499static void 2500yuv2ya8_X_c(SwsContext *c, const int16_t *lumFilter, 2501 const int16_t **lumSrc, int lumFilterSize, 2502 const int16_t *chrFilter, const int16_t **chrUSrc, 2503 const int16_t **chrVSrc, int chrFilterSize, 2504 const int16_t **alpSrc, uint8_t *dest, int dstW, int y) 2505{ 2506 int hasAlpha = !!alpSrc; 2507 int i; 2508 2509 for (i = 0; i < dstW; i++) { 2510 int j; 2511 int Y = 1 << 18, A = 1 << 18; 2512 2513 for (j = 0; j < lumFilterSize; j++) 2514 Y += lumSrc[j][i] * lumFilter[j]; 2515 2516 Y >>= 19; 2517 if (Y & 0x100) 2518 Y = av_clip_uint8(Y); 2519 2520 if (hasAlpha) { 2521 for (j = 0; j < lumFilterSize; j++) 2522 A += alpSrc[j][i] * lumFilter[j]; 2523 2524 A >>= 19; 2525 2526 if (A & 0x100) 2527 A = av_clip_uint8(A); 2528 } 2529 2530 dest[2 * i ] = Y; 2531 dest[2 * i + 1] = hasAlpha ? A : 255; 2532 } 2533} 2534 2535static void 2536yuv2ayuv64le_X_c(SwsContext *c, const int16_t *lumFilter, 2537 const int16_t **_lumSrc, int lumFilterSize, 2538 const int16_t *chrFilter, const int16_t **_chrUSrc, 2539 const int16_t **_chrVSrc, int chrFilterSize, 2540 const int16_t **_alpSrc, uint8_t *dest, int dstW, int y) 2541{ 2542 const int32_t **lumSrc = (const int32_t **) _lumSrc, 2543 **chrUSrc = (const int32_t **) _chrUSrc, 2544 **chrVSrc = (const int32_t **) _chrVSrc, 2545 **alpSrc = (const int32_t **) _alpSrc; 2546 int hasAlpha = !!alpSrc; 2547 int i; 2548 2549 for (i = 0; i < dstW; i++) { 2550 int Y = 1 << 14, U = 1 << 14; 2551 int V = 1 << 14, A = 1 << 14; 2552 int j; 2553 2554 Y -= 0x40000000; 2555 U -= 0x40000000; 2556 V -= 0x40000000; 2557 A -= 0x40000000; 2558 2559 for (j = 0; j < lumFilterSize; j++) 2560 Y += lumSrc[j][i] * (unsigned)lumFilter[j]; 2561 2562 for (j = 0; j < chrFilterSize; j++) 2563 U += chrUSrc[j][i] * (unsigned)chrFilter[j]; 2564 2565 for (j = 0; j < chrFilterSize; j++) 2566 V += chrVSrc[j][i] * (unsigned)chrFilter[j]; 2567 2568 if (hasAlpha) 2569 for (j = 0; j < lumFilterSize; j++) 2570 A += alpSrc[j][i] * (unsigned)lumFilter[j]; 2571 2572 Y = 0x8000 + av_clip_int16(Y >> 15); 2573 U = 0x8000 + av_clip_int16(U >> 15); 2574 V = 0x8000 + av_clip_int16(V >> 15); 2575 A = 0x8000 + av_clip_int16(A >> 15); 2576 2577 AV_WL16(dest + 8 * i, hasAlpha ? A : 65535); 2578 AV_WL16(dest + 8 * i + 2, Y); 2579 AV_WL16(dest + 8 * i + 4, U); 2580 AV_WL16(dest + 8 * i + 6, V); 2581 } 2582} 2583 2584av_cold void ff_sws_init_output_funcs(SwsContext *c, 2585 yuv2planar1_fn *yuv2plane1, 2586 yuv2planarX_fn *yuv2planeX, 2587 yuv2interleavedX_fn *yuv2nv12cX, 2588 yuv2packed1_fn *yuv2packed1, 2589 yuv2packed2_fn *yuv2packed2, 2590 yuv2packedX_fn *yuv2packedX, 2591 yuv2anyX_fn *yuv2anyX) 2592{ 2593 enum AVPixelFormat dstFormat = c->dstFormat; 2594 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat); 2595 2596 if (isSemiPlanarYUV(dstFormat) && isDataInHighBits(dstFormat)) { 2597 av_assert0(desc->comp[0].depth == 10); 2598 *yuv2plane1 = isBE(dstFormat) ? yuv2p010l1_BE_c : yuv2p010l1_LE_c; 2599 *yuv2planeX = isBE(dstFormat) ? yuv2p010lX_BE_c : yuv2p010lX_LE_c; 2600 *yuv2nv12cX = isBE(dstFormat) ? yuv2p010cX_BE_c : yuv2p010cX_LE_c; 2601 } else if (is16BPS(dstFormat)) { 2602 *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c : yuv2planeX_16LE_c; 2603 *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c : yuv2plane1_16LE_c; 2604 if (isSemiPlanarYUV(dstFormat)) { 2605 *yuv2nv12cX = isBE(dstFormat) ? yuv2nv12cX_16BE_c : yuv2nv12cX_16LE_c; 2606 } 2607 } else if (isNBPS(dstFormat)) { 2608 if (desc->comp[0].depth == 9) { 2609 *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c : yuv2planeX_9LE_c; 2610 *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_c : yuv2plane1_9LE_c; 2611 } else if (desc->comp[0].depth == 10) { 2612 *yuv2planeX = isBE(dstFormat) ? yuv2planeX_10BE_c : yuv2planeX_10LE_c; 2613 *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_10BE_c : yuv2plane1_10LE_c; 2614 } else if (desc->comp[0].depth == 12) { 2615 *yuv2planeX = isBE(dstFormat) ? yuv2planeX_12BE_c : yuv2planeX_12LE_c; 2616 *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_12BE_c : yuv2plane1_12LE_c; 2617 } else if (desc->comp[0].depth == 14) { 2618 *yuv2planeX = isBE(dstFormat) ? yuv2planeX_14BE_c : yuv2planeX_14LE_c; 2619 *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_14BE_c : yuv2plane1_14LE_c; 2620 } else 2621 av_assert0(0); 2622 } else if (dstFormat == AV_PIX_FMT_GRAYF32BE) { 2623 *yuv2planeX = yuv2planeX_floatBE_c; 2624 *yuv2plane1 = yuv2plane1_floatBE_c; 2625 } else if (dstFormat == AV_PIX_FMT_GRAYF32LE) { 2626 *yuv2planeX = yuv2planeX_floatLE_c; 2627 *yuv2plane1 = yuv2plane1_floatLE_c; 2628 } else { 2629 *yuv2plane1 = yuv2plane1_8_c; 2630 *yuv2planeX = yuv2planeX_8_c; 2631 if (isSemiPlanarYUV(dstFormat)) 2632 *yuv2nv12cX = yuv2nv12cX_c; 2633 } 2634 2635 if(c->flags & SWS_FULL_CHR_H_INT) { 2636 switch (dstFormat) { 2637 case AV_PIX_FMT_RGBA: 2638#if CONFIG_SMALL 2639 *yuv2packedX = yuv2rgba32_full_X_c; 2640 *yuv2packed2 = yuv2rgba32_full_2_c; 2641 *yuv2packed1 = yuv2rgba32_full_1_c; 2642#else 2643#if CONFIG_SWSCALE_ALPHA 2644 if (c->needAlpha) { 2645 *yuv2packedX = yuv2rgba32_full_X_c; 2646 *yuv2packed2 = yuv2rgba32_full_2_c; 2647 *yuv2packed1 = yuv2rgba32_full_1_c; 2648 } else 2649#endif /* CONFIG_SWSCALE_ALPHA */ 2650 { 2651 *yuv2packedX = yuv2rgbx32_full_X_c; 2652 *yuv2packed2 = yuv2rgbx32_full_2_c; 2653 *yuv2packed1 = yuv2rgbx32_full_1_c; 2654 } 2655#endif /* !CONFIG_SMALL */ 2656 break; 2657 case AV_PIX_FMT_ARGB: 2658#if CONFIG_SMALL 2659 *yuv2packedX = yuv2argb32_full_X_c; 2660 *yuv2packed2 = yuv2argb32_full_2_c; 2661 *yuv2packed1 = yuv2argb32_full_1_c; 2662#else 2663#if CONFIG_SWSCALE_ALPHA 2664 if (c->needAlpha) { 2665 *yuv2packedX = yuv2argb32_full_X_c; 2666 *yuv2packed2 = yuv2argb32_full_2_c; 2667 *yuv2packed1 = yuv2argb32_full_1_c; 2668 } else 2669#endif /* CONFIG_SWSCALE_ALPHA */ 2670 { 2671 *yuv2packedX = yuv2xrgb32_full_X_c; 2672 *yuv2packed2 = yuv2xrgb32_full_2_c; 2673 *yuv2packed1 = yuv2xrgb32_full_1_c; 2674 } 2675#endif /* !CONFIG_SMALL */ 2676 break; 2677 case AV_PIX_FMT_BGRA: 2678#if CONFIG_SMALL 2679 *yuv2packedX = yuv2bgra32_full_X_c; 2680 *yuv2packed2 = yuv2bgra32_full_2_c; 2681 *yuv2packed1 = yuv2bgra32_full_1_c; 2682#else 2683#if CONFIG_SWSCALE_ALPHA 2684 if (c->needAlpha) { 2685 *yuv2packedX = yuv2bgra32_full_X_c; 2686 *yuv2packed2 = yuv2bgra32_full_2_c; 2687 *yuv2packed1 = yuv2bgra32_full_1_c; 2688 } else 2689#endif /* CONFIG_SWSCALE_ALPHA */ 2690 { 2691 *yuv2packedX = yuv2bgrx32_full_X_c; 2692 *yuv2packed2 = yuv2bgrx32_full_2_c; 2693 *yuv2packed1 = yuv2bgrx32_full_1_c; 2694 } 2695#endif /* !CONFIG_SMALL */ 2696 break; 2697 case AV_PIX_FMT_ABGR: 2698#if CONFIG_SMALL 2699 *yuv2packedX = yuv2abgr32_full_X_c; 2700 *yuv2packed2 = yuv2abgr32_full_2_c; 2701 *yuv2packed1 = yuv2abgr32_full_1_c; 2702#else 2703#if CONFIG_SWSCALE_ALPHA 2704 if (c->needAlpha) { 2705 *yuv2packedX = yuv2abgr32_full_X_c; 2706 *yuv2packed2 = yuv2abgr32_full_2_c; 2707 *yuv2packed1 = yuv2abgr32_full_1_c; 2708 } else 2709#endif /* CONFIG_SWSCALE_ALPHA */ 2710 { 2711 *yuv2packedX = yuv2xbgr32_full_X_c; 2712 *yuv2packed2 = yuv2xbgr32_full_2_c; 2713 *yuv2packed1 = yuv2xbgr32_full_1_c; 2714 } 2715#endif /* !CONFIG_SMALL */ 2716 break; 2717 case AV_PIX_FMT_RGBA64LE: 2718#if CONFIG_SWSCALE_ALPHA 2719 if (c->needAlpha) { 2720 *yuv2packedX = yuv2rgba64le_full_X_c; 2721 *yuv2packed2 = yuv2rgba64le_full_2_c; 2722 *yuv2packed1 = yuv2rgba64le_full_1_c; 2723 } else 2724#endif /* CONFIG_SWSCALE_ALPHA */ 2725 { 2726 *yuv2packedX = yuv2rgbx64le_full_X_c; 2727 *yuv2packed2 = yuv2rgbx64le_full_2_c; 2728 *yuv2packed1 = yuv2rgbx64le_full_1_c; 2729 } 2730 break; 2731 case AV_PIX_FMT_RGBA64BE: 2732#if CONFIG_SWSCALE_ALPHA 2733 if (c->needAlpha) { 2734 *yuv2packedX = yuv2rgba64be_full_X_c; 2735 *yuv2packed2 = yuv2rgba64be_full_2_c; 2736 *yuv2packed1 = yuv2rgba64be_full_1_c; 2737 } else 2738#endif /* CONFIG_SWSCALE_ALPHA */ 2739 { 2740 *yuv2packedX = yuv2rgbx64be_full_X_c; 2741 *yuv2packed2 = yuv2rgbx64be_full_2_c; 2742 *yuv2packed1 = yuv2rgbx64be_full_1_c; 2743 } 2744 break; 2745 case AV_PIX_FMT_BGRA64LE: 2746#if CONFIG_SWSCALE_ALPHA 2747 if (c->needAlpha) { 2748 *yuv2packedX = yuv2bgra64le_full_X_c; 2749 *yuv2packed2 = yuv2bgra64le_full_2_c; 2750 *yuv2packed1 = yuv2bgra64le_full_1_c; 2751 } else 2752#endif /* CONFIG_SWSCALE_ALPHA */ 2753 { 2754 *yuv2packedX = yuv2bgrx64le_full_X_c; 2755 *yuv2packed2 = yuv2bgrx64le_full_2_c; 2756 *yuv2packed1 = yuv2bgrx64le_full_1_c; 2757 } 2758 break; 2759 case AV_PIX_FMT_BGRA64BE: 2760#if CONFIG_SWSCALE_ALPHA 2761 if (c->needAlpha) { 2762 *yuv2packedX = yuv2bgra64be_full_X_c; 2763 *yuv2packed2 = yuv2bgra64be_full_2_c; 2764 *yuv2packed1 = yuv2bgra64be_full_1_c; 2765 } else 2766#endif /* CONFIG_SWSCALE_ALPHA */ 2767 { 2768 *yuv2packedX = yuv2bgrx64be_full_X_c; 2769 *yuv2packed2 = yuv2bgrx64be_full_2_c; 2770 *yuv2packed1 = yuv2bgrx64be_full_1_c; 2771 } 2772 break; 2773 2774 case AV_PIX_FMT_RGB24: 2775 *yuv2packedX = yuv2rgb24_full_X_c; 2776 *yuv2packed2 = yuv2rgb24_full_2_c; 2777 *yuv2packed1 = yuv2rgb24_full_1_c; 2778 break; 2779 case AV_PIX_FMT_BGR24: 2780 *yuv2packedX = yuv2bgr24_full_X_c; 2781 *yuv2packed2 = yuv2bgr24_full_2_c; 2782 *yuv2packed1 = yuv2bgr24_full_1_c; 2783 break; 2784 case AV_PIX_FMT_RGB48LE: 2785 *yuv2packedX = yuv2rgb48le_full_X_c; 2786 *yuv2packed2 = yuv2rgb48le_full_2_c; 2787 *yuv2packed1 = yuv2rgb48le_full_1_c; 2788 break; 2789 case AV_PIX_FMT_BGR48LE: 2790 *yuv2packedX = yuv2bgr48le_full_X_c; 2791 *yuv2packed2 = yuv2bgr48le_full_2_c; 2792 *yuv2packed1 = yuv2bgr48le_full_1_c; 2793 break; 2794 case AV_PIX_FMT_RGB48BE: 2795 *yuv2packedX = yuv2rgb48be_full_X_c; 2796 *yuv2packed2 = yuv2rgb48be_full_2_c; 2797 *yuv2packed1 = yuv2rgb48be_full_1_c; 2798 break; 2799 case AV_PIX_FMT_BGR48BE: 2800 *yuv2packedX = yuv2bgr48be_full_X_c; 2801 *yuv2packed2 = yuv2bgr48be_full_2_c; 2802 *yuv2packed1 = yuv2bgr48be_full_1_c; 2803 break; 2804 case AV_PIX_FMT_BGR4_BYTE: 2805 *yuv2packedX = yuv2bgr4_byte_full_X_c; 2806 *yuv2packed2 = yuv2bgr4_byte_full_2_c; 2807 *yuv2packed1 = yuv2bgr4_byte_full_1_c; 2808 break; 2809 case AV_PIX_FMT_RGB4_BYTE: 2810 *yuv2packedX = yuv2rgb4_byte_full_X_c; 2811 *yuv2packed2 = yuv2rgb4_byte_full_2_c; 2812 *yuv2packed1 = yuv2rgb4_byte_full_1_c; 2813 break; 2814 case AV_PIX_FMT_BGR8: 2815 *yuv2packedX = yuv2bgr8_full_X_c; 2816 *yuv2packed2 = yuv2bgr8_full_2_c; 2817 *yuv2packed1 = yuv2bgr8_full_1_c; 2818 break; 2819 case AV_PIX_FMT_RGB8: 2820 *yuv2packedX = yuv2rgb8_full_X_c; 2821 *yuv2packed2 = yuv2rgb8_full_2_c; 2822 *yuv2packed1 = yuv2rgb8_full_1_c; 2823 break; 2824 case AV_PIX_FMT_GBRP: 2825 case AV_PIX_FMT_GBRP9BE: 2826 case AV_PIX_FMT_GBRP9LE: 2827 case AV_PIX_FMT_GBRP10BE: 2828 case AV_PIX_FMT_GBRP10LE: 2829 case AV_PIX_FMT_GBRP12BE: 2830 case AV_PIX_FMT_GBRP12LE: 2831 case AV_PIX_FMT_GBRP14BE: 2832 case AV_PIX_FMT_GBRP14LE: 2833 case AV_PIX_FMT_GBRAP: 2834 case AV_PIX_FMT_GBRAP10BE: 2835 case AV_PIX_FMT_GBRAP10LE: 2836 case AV_PIX_FMT_GBRAP12BE: 2837 case AV_PIX_FMT_GBRAP12LE: 2838 *yuv2anyX = yuv2gbrp_full_X_c; 2839 break; 2840 case AV_PIX_FMT_GBRP16BE: 2841 case AV_PIX_FMT_GBRP16LE: 2842 case AV_PIX_FMT_GBRAP16BE: 2843 case AV_PIX_FMT_GBRAP16LE: 2844 *yuv2anyX = yuv2gbrp16_full_X_c; 2845 break; 2846 case AV_PIX_FMT_GBRPF32BE: 2847 case AV_PIX_FMT_GBRPF32LE: 2848 case AV_PIX_FMT_GBRAPF32BE: 2849 case AV_PIX_FMT_GBRAPF32LE: 2850 *yuv2anyX = yuv2gbrpf32_full_X_c; 2851 break; 2852 } 2853 if (!*yuv2packedX && !*yuv2anyX) 2854 goto YUV_PACKED; 2855 } else { 2856 YUV_PACKED: 2857 switch (dstFormat) { 2858 case AV_PIX_FMT_RGBA64LE: 2859#if CONFIG_SWSCALE_ALPHA 2860 if (c->needAlpha) { 2861 *yuv2packed1 = yuv2rgba64le_1_c; 2862 *yuv2packed2 = yuv2rgba64le_2_c; 2863 *yuv2packedX = yuv2rgba64le_X_c; 2864 } else 2865#endif /* CONFIG_SWSCALE_ALPHA */ 2866 { 2867 *yuv2packed1 = yuv2rgbx64le_1_c; 2868 *yuv2packed2 = yuv2rgbx64le_2_c; 2869 *yuv2packedX = yuv2rgbx64le_X_c; 2870 } 2871 break; 2872 case AV_PIX_FMT_RGBA64BE: 2873#if CONFIG_SWSCALE_ALPHA 2874 if (c->needAlpha) { 2875 *yuv2packed1 = yuv2rgba64be_1_c; 2876 *yuv2packed2 = yuv2rgba64be_2_c; 2877 *yuv2packedX = yuv2rgba64be_X_c; 2878 } else 2879#endif /* CONFIG_SWSCALE_ALPHA */ 2880 { 2881 *yuv2packed1 = yuv2rgbx64be_1_c; 2882 *yuv2packed2 = yuv2rgbx64be_2_c; 2883 *yuv2packedX = yuv2rgbx64be_X_c; 2884 } 2885 break; 2886 case AV_PIX_FMT_BGRA64LE: 2887#if CONFIG_SWSCALE_ALPHA 2888 if (c->needAlpha) { 2889 *yuv2packed1 = yuv2bgra64le_1_c; 2890 *yuv2packed2 = yuv2bgra64le_2_c; 2891 *yuv2packedX = yuv2bgra64le_X_c; 2892 } else 2893#endif /* CONFIG_SWSCALE_ALPHA */ 2894 { 2895 *yuv2packed1 = yuv2bgrx64le_1_c; 2896 *yuv2packed2 = yuv2bgrx64le_2_c; 2897 *yuv2packedX = yuv2bgrx64le_X_c; 2898 } 2899 break; 2900 case AV_PIX_FMT_BGRA64BE: 2901#if CONFIG_SWSCALE_ALPHA 2902 if (c->needAlpha) { 2903 *yuv2packed1 = yuv2bgra64be_1_c; 2904 *yuv2packed2 = yuv2bgra64be_2_c; 2905 *yuv2packedX = yuv2bgra64be_X_c; 2906 } else 2907#endif /* CONFIG_SWSCALE_ALPHA */ 2908 { 2909 *yuv2packed1 = yuv2bgrx64be_1_c; 2910 *yuv2packed2 = yuv2bgrx64be_2_c; 2911 *yuv2packedX = yuv2bgrx64be_X_c; 2912 } 2913 break; 2914 case AV_PIX_FMT_RGB48LE: 2915 *yuv2packed1 = yuv2rgb48le_1_c; 2916 *yuv2packed2 = yuv2rgb48le_2_c; 2917 *yuv2packedX = yuv2rgb48le_X_c; 2918 break; 2919 case AV_PIX_FMT_RGB48BE: 2920 *yuv2packed1 = yuv2rgb48be_1_c; 2921 *yuv2packed2 = yuv2rgb48be_2_c; 2922 *yuv2packedX = yuv2rgb48be_X_c; 2923 break; 2924 case AV_PIX_FMT_BGR48LE: 2925 *yuv2packed1 = yuv2bgr48le_1_c; 2926 *yuv2packed2 = yuv2bgr48le_2_c; 2927 *yuv2packedX = yuv2bgr48le_X_c; 2928 break; 2929 case AV_PIX_FMT_BGR48BE: 2930 *yuv2packed1 = yuv2bgr48be_1_c; 2931 *yuv2packed2 = yuv2bgr48be_2_c; 2932 *yuv2packedX = yuv2bgr48be_X_c; 2933 break; 2934 case AV_PIX_FMT_RGB32: 2935 case AV_PIX_FMT_BGR32: 2936#if CONFIG_SMALL 2937 *yuv2packed1 = yuv2rgb32_1_c; 2938 *yuv2packed2 = yuv2rgb32_2_c; 2939 *yuv2packedX = yuv2rgb32_X_c; 2940#else 2941#if CONFIG_SWSCALE_ALPHA 2942 if (c->needAlpha) { 2943 *yuv2packed1 = yuv2rgba32_1_c; 2944 *yuv2packed2 = yuv2rgba32_2_c; 2945 *yuv2packedX = yuv2rgba32_X_c; 2946 } else 2947#endif /* CONFIG_SWSCALE_ALPHA */ 2948 { 2949 *yuv2packed1 = yuv2rgbx32_1_c; 2950 *yuv2packed2 = yuv2rgbx32_2_c; 2951 *yuv2packedX = yuv2rgbx32_X_c; 2952 } 2953#endif /* !CONFIG_SMALL */ 2954 break; 2955 case AV_PIX_FMT_RGB32_1: 2956 case AV_PIX_FMT_BGR32_1: 2957#if CONFIG_SMALL 2958 *yuv2packed1 = yuv2rgb32_1_1_c; 2959 *yuv2packed2 = yuv2rgb32_1_2_c; 2960 *yuv2packedX = yuv2rgb32_1_X_c; 2961#else 2962#if CONFIG_SWSCALE_ALPHA 2963 if (c->needAlpha) { 2964 *yuv2packed1 = yuv2rgba32_1_1_c; 2965 *yuv2packed2 = yuv2rgba32_1_2_c; 2966 *yuv2packedX = yuv2rgba32_1_X_c; 2967 } else 2968#endif /* CONFIG_SWSCALE_ALPHA */ 2969 { 2970 *yuv2packed1 = yuv2rgbx32_1_1_c; 2971 *yuv2packed2 = yuv2rgbx32_1_2_c; 2972 *yuv2packedX = yuv2rgbx32_1_X_c; 2973 } 2974#endif /* !CONFIG_SMALL */ 2975 break; 2976 case AV_PIX_FMT_RGB24: 2977 *yuv2packed1 = yuv2rgb24_1_c; 2978 *yuv2packed2 = yuv2rgb24_2_c; 2979 *yuv2packedX = yuv2rgb24_X_c; 2980 break; 2981 case AV_PIX_FMT_BGR24: 2982 *yuv2packed1 = yuv2bgr24_1_c; 2983 *yuv2packed2 = yuv2bgr24_2_c; 2984 *yuv2packedX = yuv2bgr24_X_c; 2985 break; 2986 case AV_PIX_FMT_RGB565LE: 2987 case AV_PIX_FMT_RGB565BE: 2988 case AV_PIX_FMT_BGR565LE: 2989 case AV_PIX_FMT_BGR565BE: 2990 *yuv2packed1 = yuv2rgb16_1_c; 2991 *yuv2packed2 = yuv2rgb16_2_c; 2992 *yuv2packedX = yuv2rgb16_X_c; 2993 break; 2994 case AV_PIX_FMT_RGB555LE: 2995 case AV_PIX_FMT_RGB555BE: 2996 case AV_PIX_FMT_BGR555LE: 2997 case AV_PIX_FMT_BGR555BE: 2998 *yuv2packed1 = yuv2rgb15_1_c; 2999 *yuv2packed2 = yuv2rgb15_2_c; 3000 *yuv2packedX = yuv2rgb15_X_c; 3001 break; 3002 case AV_PIX_FMT_RGB444LE: 3003 case AV_PIX_FMT_RGB444BE: 3004 case AV_PIX_FMT_BGR444LE: 3005 case AV_PIX_FMT_BGR444BE: 3006 *yuv2packed1 = yuv2rgb12_1_c; 3007 *yuv2packed2 = yuv2rgb12_2_c; 3008 *yuv2packedX = yuv2rgb12_X_c; 3009 break; 3010 case AV_PIX_FMT_RGB8: 3011 case AV_PIX_FMT_BGR8: 3012 *yuv2packed1 = yuv2rgb8_1_c; 3013 *yuv2packed2 = yuv2rgb8_2_c; 3014 *yuv2packedX = yuv2rgb8_X_c; 3015 break; 3016 case AV_PIX_FMT_RGB4: 3017 case AV_PIX_FMT_BGR4: 3018 *yuv2packed1 = yuv2rgb4_1_c; 3019 *yuv2packed2 = yuv2rgb4_2_c; 3020 *yuv2packedX = yuv2rgb4_X_c; 3021 break; 3022 case AV_PIX_FMT_RGB4_BYTE: 3023 case AV_PIX_FMT_BGR4_BYTE: 3024 *yuv2packed1 = yuv2rgb4b_1_c; 3025 *yuv2packed2 = yuv2rgb4b_2_c; 3026 *yuv2packedX = yuv2rgb4b_X_c; 3027 break; 3028 case AV_PIX_FMT_X2RGB10LE: 3029 case AV_PIX_FMT_X2RGB10BE: 3030 *yuv2packed1 = yuv2x2rgb10_1_c; 3031 *yuv2packed2 = yuv2x2rgb10_2_c; 3032 *yuv2packedX = yuv2x2rgb10_X_c; 3033 break; 3034 case AV_PIX_FMT_X2BGR10LE: 3035 case AV_PIX_FMT_X2BGR10BE: 3036 *yuv2packed1 = yuv2x2bgr10_1_c; 3037 *yuv2packed2 = yuv2x2bgr10_2_c; 3038 *yuv2packedX = yuv2x2bgr10_X_c; 3039 break; 3040 } 3041 } 3042 switch (dstFormat) { 3043 case AV_PIX_FMT_MONOWHITE: 3044 *yuv2packed1 = yuv2monowhite_1_c; 3045 *yuv2packed2 = yuv2monowhite_2_c; 3046 *yuv2packedX = yuv2monowhite_X_c; 3047 break; 3048 case AV_PIX_FMT_MONOBLACK: 3049 *yuv2packed1 = yuv2monoblack_1_c; 3050 *yuv2packed2 = yuv2monoblack_2_c; 3051 *yuv2packedX = yuv2monoblack_X_c; 3052 break; 3053 case AV_PIX_FMT_YUYV422: 3054 *yuv2packed1 = yuv2yuyv422_1_c; 3055 *yuv2packed2 = yuv2yuyv422_2_c; 3056 *yuv2packedX = yuv2yuyv422_X_c; 3057 break; 3058 case AV_PIX_FMT_YVYU422: 3059 *yuv2packed1 = yuv2yvyu422_1_c; 3060 *yuv2packed2 = yuv2yvyu422_2_c; 3061 *yuv2packedX = yuv2yvyu422_X_c; 3062 break; 3063 case AV_PIX_FMT_UYVY422: 3064 *yuv2packed1 = yuv2uyvy422_1_c; 3065 *yuv2packed2 = yuv2uyvy422_2_c; 3066 *yuv2packedX = yuv2uyvy422_X_c; 3067 break; 3068 case AV_PIX_FMT_YA8: 3069 *yuv2packed1 = yuv2ya8_1_c; 3070 *yuv2packed2 = yuv2ya8_2_c; 3071 *yuv2packedX = yuv2ya8_X_c; 3072 break; 3073 case AV_PIX_FMT_YA16LE: 3074 *yuv2packed1 = yuv2ya16le_1_c; 3075 *yuv2packed2 = yuv2ya16le_2_c; 3076 *yuv2packedX = yuv2ya16le_X_c; 3077 break; 3078 case AV_PIX_FMT_YA16BE: 3079 *yuv2packed1 = yuv2ya16be_1_c; 3080 *yuv2packed2 = yuv2ya16be_2_c; 3081 *yuv2packedX = yuv2ya16be_X_c; 3082 break; 3083 case AV_PIX_FMT_AYUV64LE: 3084 *yuv2packedX = yuv2ayuv64le_X_c; 3085 break; 3086 } 3087} 3088