From ba4b409d51c24bbb64650bbf40bbf23994e36532 Mon Sep 17 00:00:00 2001 From: Frank Barchard Date: Wed, 21 Oct 2015 12:22:24 -0700 Subject: [PATCH] Fix ARGBToI411 odd width bug. The any function for handling ARGBToI411 was not handling the pixel replication correctly. On 422 and odd width was handled by duplicating a pixel of source. 411 needs replication for remainders of 1, 2 or 3 pixels. The C version was handling odd width but with an average of the remainder pixels, which does not match the SIMD 'any' handling off remainder. This changes the odd width handling to mimic the any version. TBR=harryjin@google.com BUG=libyuv:491 Review URL: https://codereview.chromium.org/1411733004 . --- README.chromium | 2 +- include/libyuv/version.h | 2 +- source/row_any.cc | 18 +++++++++++++++++- source/row_common.cc | 7 ++++--- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/README.chromium b/README.chromium index 154ad3d97..bc655854b 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: http://code.google.com/p/libyuv/ -Version: 1517 +Version: 1518 License: BSD License File: LICENSE diff --git a/include/libyuv/version.h b/include/libyuv/version.h index 7fb745aec..643e9bd6f 100644 --- a/include/libyuv/version.h +++ b/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 1517 +#define LIBYUV_VERSION 1518 #endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT diff --git a/source/row_any.cc b/source/row_any.cc index c5a24d1ad..69562d7d8 100644 --- a/source/row_any.cc +++ b/source/row_any.cc @@ -672,7 +672,23 @@ ANY1(ARGBSetRow_Any_NEON, ARGBSetRow_NEON, uint32, 4, 3) ANY_SIMD(src_ptr, dst_u, dst_v, n); \ } \ memcpy(temp, src_ptr + (n >> UVSHIFT) * BPP, SS(r, UVSHIFT) * BPP); \ - if ((width & 1) && BPP == 4) { /* repeat last 4 bytes for subsampler */ \ + /* repeat last 4 bytes for 422 subsampler */ \ + if ((width & 1) && BPP == 4 && DUVSHIFT == 1) { \ + memcpy(temp + SS(r, UVSHIFT) * BPP, \ + temp + SS(r, UVSHIFT) * BPP - BPP, 4); \ + } \ + /* repeat last 4 - 12 bytes for 411 subsampler */ \ + if (((width & 1) == 1) && BPP == 4 && DUVSHIFT == 2) { \ + memcpy(temp + SS(r, UVSHIFT) * BPP, \ + temp + SS(r, UVSHIFT) * BPP - BPP, 4); \ + memcpy(temp + SS(r, UVSHIFT) * BPP + 4, \ + temp + SS(r, UVSHIFT) * BPP - BPP, 8); \ + } \ + if (((width & 1) == 2) && BPP == 4 && DUVSHIFT == 2) { \ + memcpy(temp + SS(r, UVSHIFT) * BPP, \ + temp + SS(r, UVSHIFT) * BPP - BPP * 2, 8); \ + } \ + if (((width & 1) == 3) && BPP == 4 && DUVSHIFT == 2) { \ memcpy(temp + SS(r, UVSHIFT) * BPP, \ temp + SS(r, UVSHIFT) * BPP - BPP, 4); \ } \ diff --git a/source/row_common.cc b/source/row_common.cc index 25d16aca0..b818fb8bc 100644 --- a/source/row_common.cc +++ b/source/row_common.cc @@ -679,10 +679,11 @@ void ARGBToUV411Row_C(const uint8* src_argb, dst_u += 1; dst_v += 1; } + // Odd width handling mimics 'any' function which replicates last pixel. if ((width & 3) == 3) { - uint8 ab = (src_argb[0] + src_argb[4] + src_argb[8]) / 3; - uint8 ag = (src_argb[1] + src_argb[5] + src_argb[9]) / 3; - uint8 ar = (src_argb[2] + src_argb[6] + src_argb[10]) / 3; + uint8 ab = (src_argb[0] + src_argb[4] + src_argb[8] + src_argb[8]) >> 2; + uint8 ag = (src_argb[1] + src_argb[5] + src_argb[9] + src_argb[9]) >> 2; + uint8 ar = (src_argb[2] + src_argb[6] + src_argb[10] + src_argb[10]) >> 2; dst_u[0] = RGBToU(ar, ag, ab); dst_v[0] = RGBToV(ar, ag, ab); } else if ((width & 3) == 2) {