From aae7deb5cf7269144e04045d3e0fa05054759dbe Mon Sep 17 00:00:00 2001 From: "fbarchard@google.com" Date: Sat, 7 Dec 2013 00:55:23 +0000 Subject: [PATCH] yuv use scale slope calc BUG=none TEST=drmem R=tpsiaki@google.com Review URL: https://webrtc-codereview.appspot.com/5319004 git-svn-id: http://libyuv.googlecode.com/svn/trunk@899 16f28f9a-4ce2-e073-06de-1de4eb20be90 --- include/libyuv/scale.h | 2 +- source/planar_functions.cc | 8 +++- source/scale.cc | 95 ++++++++++---------------------------- source/scale_common.cc | 2 +- 4 files changed, 34 insertions(+), 73 deletions(-) diff --git a/include/libyuv/scale.h b/include/libyuv/scale.h index 3bfddb29d..b672dbfce 100644 --- a/include/libyuv/scale.h +++ b/include/libyuv/scale.h @@ -21,7 +21,7 @@ extern "C" { // Supported filtering. enum FilterMode { kFilterNone = 0, // Point sample; Fastest. - kFilterLinear = 1, // Filter horizontally only. + kFilterLinear = 1, // Filter horizontally only. kFilterBilinear = 2, // Faster than box, but lower quality scaling down. kFilterBox = 3 // Highest quality. }; diff --git a/source/planar_functions.cc b/source/planar_functions.cc index 7d3cfa9ce..114faaef6 100644 --- a/source/planar_functions.cc +++ b/source/planar_functions.cc @@ -172,10 +172,16 @@ int I420ToI400(const uint8* src_y, int src_stride_y, return 0; } -// Mirror a plane of data +// Mirror a plane of data. void MirrorPlane(const uint8* src_y, int src_stride_y, uint8* dst_y, int dst_stride_y, int width, int height) { + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_y = src_y + (height - 1) * src_stride_y; + src_stride_y = -src_stride_y; + } void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C; #if defined(HAS_MIRRORROW_NEON) if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16)) { diff --git a/source/scale.cc b/source/scale.cc index f9ca3bf44..e48d80cfa 100644 --- a/source/scale.cc +++ b/source/scale.cc @@ -382,16 +382,14 @@ static void ScalePlaneBox(int src_width, int src_height, const uint8* src_ptr, uint8* dst_ptr) { assert(dst_width > 0); assert(dst_height > 0); - int dx = FixedDiv(Abs(src_width), dst_width); - int dy = FixedDiv(src_height, dst_height); + + // Initial source x/y coordinate and step values as 16.16 fixed point. int x = 0; int y = 0; - // Negative src_width means horizontally mirror. - if (src_width < 0) { - x += (dst_width - 1) * dx; - dx = -dx; - src_width = -src_width; - } + int dx = 0; + int dy = 0; + ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterBox, + &x, &y, &dx, &dy); const int max_y = (src_height << 16); if (!IS_ALIGNED(src_width, 16) || (src_width > kMaxStride) || dst_height * 2 > src_height) { @@ -457,6 +455,14 @@ void ScalePlaneBilinearDown(int src_width, int src_height, assert(dst_height > 0); assert(Abs(src_width) <= kMaxStride); + // Initial source x/y coordinate and step values as 16.16 fixed point. + int x = 0; + int y = 0; + int dx = 0; + int dy = 0; + ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, + &x, &y, &dx, &dy); + SIMD_ALIGNED(uint8 row[kMaxStride + 16]); void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, @@ -517,28 +523,6 @@ void ScalePlaneBilinearDown(int src_width, int src_height, } #endif - int dx = 0; - int dy = 0; - int x = 0; - int y = 0; - if (dst_width <= Abs(src_width)) { - dx = FixedDiv(Abs(src_width), dst_width); - x = (dx >> 1) - 32768; - } else if (dst_width > 1) { - dx = FixedDiv(Abs(src_width) - 1, dst_width - 1); - } - // Negative src_width means horizontally mirror. - if (src_width < 0) { - x += (dst_width - 1) * dx; - dx = -dx; - src_width = -src_width; - } - if (dst_height <= src_height) { - dy = FixedDiv(src_height, dst_height); - y = (dy >> 1) - 32768; - } else if (dst_height > 1) { - dy = FixedDiv(src_height - 1, dst_height - 1); - } const int max_y = (src_height - 1) << 16; for (int j = 0; j < dst_height; ++j) { if (y > max_y) { @@ -570,28 +554,14 @@ void ScalePlaneBilinearUp(int src_width, int src_height, assert(dst_width > 0); assert(dst_height > 0); assert(Abs(dst_width) <= kMaxStride); - int dx = 0; - int dy = 0; + + // Initial source x/y coordinate and step values as 16.16 fixed point. int x = 0; int y = 0; - if (dst_width <= Abs(src_width)) { - dx = FixedDiv(Abs(src_width), dst_width); - x = (dx >> 1) - 32768; - } else if (dst_width > 1) { - dx = FixedDiv(Abs(src_width) - 1, dst_width - 1); - } - // Negative src_width means horizontally mirror. - if (src_width < 0) { - x += (dst_width - 1) * dx; - dx = -dx; - src_width = -src_width; - } - if (dst_height <= src_height) { - dy = FixedDiv(src_height, dst_height); - y = (dy >> 1) - 32768; - } else if (dst_height > 1) { - dy = FixedDiv(src_height - 1, dst_height - 1); - } + int dx = 0; + int dy = 0; + ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, + &x, &y, &dx, &dy); void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, ptrdiff_t src_stride, int dst_width, int source_y_fraction) = @@ -715,28 +685,13 @@ static void ScalePlaneSimple(int src_width, int src_height, int dst_width, int dst_height, int src_stride, int dst_stride, const uint8* src_ptr, uint8* dst_ptr) { - int dx = 0; - int dy = 0; + // Initial source x/y coordinate and step values as 16.16 fixed point. int x = 0; int y = 0; - if (dst_width <= Abs(src_width)) { - dx = FixedDiv(Abs(src_width), dst_width); - x = (dx >> 1) - 32768; - } else if (dst_width > 1) { - dx = FixedDiv(Abs(src_width) - 1, dst_width - 1); - } - // Negative src_width means horizontally mirror. - if (src_width < 0) { - x += (dst_width - 1) * dx; - dx = -dx; - src_width = -src_width; - } - if (dst_height <= src_height) { - dy = FixedDiv(src_height, dst_height); - y = (dy >> 1) - 32768; - } else if (dst_height > 1) { - dy = FixedDiv(src_height - 1, dst_height - 1); - } + int dx = 0; + int dy = 0; + ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterNone, + &x, &y, &dx, &dy); void (*ScaleCols)(uint8* dst_ptr, const uint8* src_ptr, int dst_width, int x, int dx) = ScaleCols_C; diff --git a/source/scale_common.cc b/source/scale_common.cc index 468aaa267..b0ba1e846 100644 --- a/source/scale_common.cc +++ b/source/scale_common.cc @@ -613,7 +613,7 @@ void ScaleSlope(int src_width, int src_height, } if (dst_height <= src_height) { *dy = FixedDiv(src_height, dst_height); - *y = CENTERSTART(*dy, -32768); + *y = CENTERSTART(*dy, -32768); // 32768 = -0.5 to center bilinear. } else if (dst_height > 1) { *dy = FIXEDDIV1(src_height, dst_height); *y = 0;