aboutsummaryrefslogtreecommitdiff
path: root/source/row_common.cc
diff options
context:
space:
mode:
authorFrank Barchard <fbarchard@google.com>2022-09-20 13:40:07 -0700
committerlibyuv LUCI CQ <libyuv-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-09-20 20:56:43 +0000
commit8fc02134c838294ca1fe1ee60e24111ad311cfb1 (patch)
tree2de9d92989de4013cffd018f21f828a003bf980c /source/row_common.cc
parente4b1ddd8fef58e465563ecfe75a2974f4fd40f2a (diff)
downloadlibyuv-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.cc51
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,