diff options
author | Frank Barchard <fbarchard@google.com> | 2022-09-20 13:40:07 -0700 |
---|---|---|
committer | libyuv LUCI CQ <libyuv-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-09-20 20:56:43 +0000 |
commit | 8fc02134c838294ca1fe1ee60e24111ad311cfb1 (patch) | |
tree | 2de9d92989de4013cffd018f21f828a003bf980c /source/row_common.cc | |
parent | e4b1ddd8fef58e465563ecfe75a2974f4fd40f2a (diff) | |
download | libyuv-8fc02134c838294ca1fe1ee60e24111ad311cfb1.tar.gz |
10/12 bit YUV replicate upper bits to low bits before converting to RGB
- shift high bits of 10 and 12 bit into lower bits
Bug: libyuv:941, libyuv:942,
Change-Id: I14381dbf226ef27dcce06893ea88860835639baa
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/3906085
Reviewed-by: Mirko Bonadei <mbonadei@chromium.org>
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Diffstat (limited to 'source/row_common.cc')
-rw-r--r-- | source/row_common.cc | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/source/row_common.cc b/source/row_common.cc index 2531c85b..20eb48ec 100644 --- a/source/row_common.cc +++ b/source/row_common.cc @@ -1723,7 +1723,7 @@ static __inline void YuvPixel10_16(uint16_t y, int* r, const struct YuvConstants* yuvconstants) { LOAD_YUV_CONSTANTS; - uint32_t y32 = y << 6; + uint32_t y32 = (y << 6) | (y >> 4); u = clamp255(u >> 2); v = clamp255(v >> 2); CALC_RGB16; @@ -1742,7 +1742,7 @@ static __inline void YuvPixel12_16(int16_t y, int* r, const struct YuvConstants* yuvconstants) { LOAD_YUV_CONSTANTS; - uint32_t y32 = y << 4; + uint32_t y32 = (y << 4) | (y >> 8); u = clamp255(u >> 4); v = clamp255(v >> 4); CALC_RGB16; @@ -4052,6 +4052,30 @@ void I422ToARGB4444Row_AVX2(const uint8_t* src_y, } #endif +// SSSE3 implemented in row_gcc.cc row_win.cc for 32 bit +// For row_win Visual C (not clangcl) +#if defined(HAS_I422TORGB24ROW_SSSE3) && defined(_M_X64) && !defined(__clang__) +void I422ToRGB24Row_SSSE3(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgb24, + const struct YuvConstants* yuvconstants, + int width) { + // Row buffer for intermediate ARGB pixels. + SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); + while (width > 0) { + int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; + I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth); + ARGBToRGB24Row_SSSE3(row, dst_rgb24, twidth); + src_y += twidth; + src_u += twidth / 2; + src_v += twidth / 2; + dst_rgb24 += twidth * 3; + width -= twidth; + } +} +#endif + #if defined(HAS_I422TORGB24ROW_AVX2) void I422ToRGB24Row_AVX2(const uint8_t* src_y, const uint8_t* src_u, @@ -4078,6 +4102,29 @@ void I422ToRGB24Row_AVX2(const uint8_t* src_y, } #endif +// For row_win Visual C (not clangcl) +#if defined(HAS_I444TORGB24ROW_SSSE3) && defined(_M_X64) && !defined(__clang__) +void I444ToRGB24Row_SSSE3(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgb24, + const struct YuvConstants* yuvconstants, + int width) { + // Row buffer for intermediate ARGB pixels. + SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); + while (width > 0) { + int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; + I444ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth); + ARGBToRGB24Row_SSSE3(row, dst_rgb24, twidth); + src_y += twidth; + src_u += twidth; + src_v += twidth; + dst_rgb24 += twidth * 3; + width -= twidth; + } +} +#endif + #if defined(HAS_I444TORGB24ROW_AVX2) void I444ToRGB24Row_AVX2(const uint8_t* src_y, const uint8_t* src_u, |