diff options
author | Frank Barchard <fbarchard@google.com> | 2022-06-06 18:30:15 -0700 |
---|---|---|
committer | Frank Barchard <fbarchard@chromium.org> | 2022-06-07 01:41:56 +0000 |
commit | 60254a1d846a93a4d7559009004cdd91bcc04d82 (patch) | |
tree | a56a3667ace9c3e5394bfd58787ea7d5883c05b6 /source/row_common.cc | |
parent | c0c8c40b31636e575eaf07921d58d8f4ff3aa983 (diff) | |
download | libyuv-60254a1d846a93a4d7559009004cdd91bcc04d82.tar.gz |
I210ToI420, InterpolatePlane_16, and ScalePlane Vertical-only asan fix
- Add I210ToI420 to convert 10 bit 4:2:2 YUV to 4:2:0 8 bit
- Add NEON InterpolateRow_16 for fast 10 bit scaling
- When scaling up, set step to interpolate toward height - 1 to avoid buffer overread
- When scaling down, center the 2 rows used for source to achieve filtering.
- CopyPlane check for 0 size and return
Bug: libyuv:931, b/228605787, b/233233302, b/233634772, b/234558395, b/234340482
Change-Id: I63e8580710a57812b683c2fe40583ac5a179c4f1
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/3687552
Reviewed-by: Mirko Bonadei <mbonadei@chromium.org>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Diffstat (limited to 'source/row_common.cc')
-rw-r--r-- | source/row_common.cc | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/source/row_common.cc b/source/row_common.cc index 8cf826ec..3bfc5618 100644 --- a/source/row_common.cc +++ b/source/row_common.cc @@ -11,7 +11,6 @@ #include "libyuv/row.h" #include <assert.h> -#include <stdio.h> #include <string.h> // For memcpy and memset. #include "libyuv/basic_types.h" @@ -3402,6 +3401,18 @@ static void HalfRow_16_C(const uint16_t* src_uv, } } +static void HalfRow_16To8_C(const uint16_t* src_uv, + ptrdiff_t src_uv_stride, + uint8_t* dst_uv, + int scale, + int width) { + int x; + for (x = 0; x < width; ++x) { + dst_uv[x] = clamp255( + (((src_uv[x] + src_uv[src_uv_stride + x] + 1) >> 1) * scale) >> 16); + } +} + // C version 2x2 -> 2x1. void InterpolateRow_C(uint8_t* dst_ptr, const uint8_t* src_ptr, @@ -3435,6 +3446,51 @@ void InterpolateRow_C(uint8_t* dst_ptr, } } +// C version 2x2 16 bit-> 2x1 8 bit. +// Use scale to convert lsb formats to msb, depending how many bits there are: +// 32768 = 9 bits +// 16384 = 10 bits +// 4096 = 12 bits +// 256 = 16 bits +void InterpolateRow_16To8_C(uint8_t* dst_ptr, + const uint16_t* src_ptr, + ptrdiff_t src_stride, + int scale, + int width, + int source_y_fraction) { + int y1_fraction = source_y_fraction; + int y0_fraction = 256 - y1_fraction; + const uint16_t* src_ptr1 = src_ptr + src_stride; + int x; + if (source_y_fraction == 0) { + Convert16To8Row_C(src_ptr, dst_ptr, scale, width); + return; + } + if (source_y_fraction == 128) { + HalfRow_16To8_C(src_ptr, src_stride, dst_ptr, scale, width); + return; + } + for (x = 0; x < width - 1; x += 2) { + dst_ptr[0] = clamp255( + (((src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8) * + scale) >> + 16); + dst_ptr[1] = clamp255( + (((src_ptr[1] * y0_fraction + src_ptr1[1] * y1_fraction) >> 8) * + scale) >> + 16); + src_ptr += 2; + src_ptr1 += 2; + dst_ptr += 2; + } + if (width & 1) { + dst_ptr[0] = clamp255( + (((src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8) * + scale) >> + 16); + } +} + void InterpolateRow_16_C(uint16_t* dst_ptr, const uint16_t* src_ptr, ptrdiff_t src_stride, |