Commit dcd87ffb authored by fbarchard@google.com's avatar fbarchard@google.com

Vertical-only scale for YUV.

BUG=260
TEST=ScaleDownByVertical2by3_Bilinear
R=jingning@google.com, thorcarpenter@google.com

Review URL: https://webrtc-codereview.appspot.com/2165004

git-svn-id: http://libyuv.googlecode.com/svn/trunk@779 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent ae0091e3
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 778 Version: 779
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -11,6 +11,6 @@ ...@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT #ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 778 #define LIBYUV_VERSION 779
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT #endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#include "libyuv/planar_functions.h" // For CopyPlane #include "libyuv/planar_functions.h" // For CopyPlane
#include "libyuv/row.h" #include "libyuv/row.h"
#include "libyuv/scale_row.h"
#ifdef __cplusplus #ifdef __cplusplus
namespace libyuv { namespace libyuv {
...@@ -2260,6 +2261,13 @@ void ScalePlane(const uint8* src, int src_stride, ...@@ -2260,6 +2261,13 @@ void ScalePlane(const uint8* src, int src_stride,
if (dst_width == src_width && dst_height == src_height) { if (dst_width == src_width && dst_height == src_height) {
// Straight copy. // Straight copy.
CopyPlane(src, src_stride, dst, dst_stride, dst_width, dst_height); CopyPlane(src, src_stride, dst, dst_stride, dst_width, dst_height);
} else if (dst_width == src_width) {
int dy = FixedDiv(src_height, dst_height);
// Arbitrary scale vertically, but unscaled vertically.
ScalePlaneVertical(src_height,
dst_width, dst_height,
src_stride, dst_stride, src, dst,
0, 0, dy, 1, filtering);
} else if (dst_width <= Abs(src_width) && dst_height <= src_height) { } else if (dst_width <= Abs(src_width) && dst_height <= src_height) {
// Scale down. // Scale down.
if (use_reference_impl_) { if (use_reference_impl_) {
......
...@@ -194,38 +194,39 @@ static int ARGBClipTestFilter(int src_width, int src_height, ...@@ -194,38 +194,39 @@ static int ARGBClipTestFilter(int src_width, int src_height,
return max_diff; return max_diff;
} }
#define TEST_FACTOR1(name, filter, factor, max_diff) \ #define TEST_FACTOR1(name, filter, hfactor, vfactor, max_diff) \
TEST_F(libyuvTest, ARGBScaleDownBy##name##_##filter) { \ TEST_F(libyuvTest, ARGBScaleDownBy##name##_##filter) { \
int diff = ARGBTestFilter(benchmark_width_, benchmark_height_, \ int diff = ARGBTestFilter(benchmark_width_, benchmark_height_, \
Abs(benchmark_width_) / factor, \ Abs(benchmark_width_) * hfactor, \
Abs(benchmark_height_) / factor, \ Abs(benchmark_height_) * vfactor, \
kFilter##filter, benchmark_iterations_); \ kFilter##filter, benchmark_iterations_); \
EXPECT_LE(diff, max_diff); \ EXPECT_LE(diff, max_diff); \
} \ } \
TEST_F(libyuvTest, ARGBScaleDownClipBy##name##_##filter) { \ TEST_F(libyuvTest, ARGBScaleDownClipBy##name##_##filter) { \
int diff = ARGBClipTestFilter(benchmark_width_, benchmark_height_, \ int diff = ARGBClipTestFilter(benchmark_width_, benchmark_height_, \
Abs(benchmark_width_) / factor, \ Abs(benchmark_width_) * hfactor, \
Abs(benchmark_height_) / factor, \ Abs(benchmark_height_) * vfactor, \
kFilter##filter, benchmark_iterations_); \ kFilter##filter, benchmark_iterations_); \
EXPECT_LE(diff, max_diff); \ EXPECT_LE(diff, max_diff); \
} }
// Test a scale factor with all 2 filters. Expect unfiltered to be exact, but // Test a scale factor with 2 filters. Expect unfiltered to be exact, but
// filtering is different fixed point implementations for SSSE3, Neon and C. // filtering is different fixed point implementations for SSSE3, Neon and C.
#define TEST_FACTOR(name, factor) \ #define TEST_FACTOR(name, hfactor, vfactor) \
TEST_FACTOR1(name, None, factor, 0) \ TEST_FACTOR1(name, None, hfactor, vfactor, 0) \
TEST_FACTOR1(name, Bilinear, factor, 2) TEST_FACTOR1(name, Bilinear, hfactor, vfactor, 2)
// TODO(fbarchard): ScaleDownBy1 should be lossless, but Box has error of 2. // TODO(fbarchard): ScaleDownBy1 should be lossless, but Box has error of 2.
TEST_FACTOR(1, 1) TEST_FACTOR(1, 1 / 1, 1 / 1)
TEST_FACTOR(2, 2) TEST_FACTOR(2, 1 / 2, 1 / 2)
TEST_FACTOR(4, 4) TEST_FACTOR(4, 1 / 4, 1 / 4)
TEST_FACTOR(5, 5) TEST_FACTOR(5, 1 / 5, 1 / 5)
TEST_FACTOR(8, 8) TEST_FACTOR(8, 1 / 8, 1 / 8)
TEST_FACTOR(16, 16) TEST_FACTOR(16, 1 / 16, 1 / 16)
TEST_FACTOR(2by3, 2 / 3) TEST_FACTOR(2by3, 2 / 3, 2 / 3)
TEST_FACTOR(3by4, 3 / 4) TEST_FACTOR(3by4, 3 / 4, 3 / 4)
TEST_FACTOR(3by8, 3 / 8) TEST_FACTOR(3by8, 3 / 8, 3 / 8)
TEST_FACTOR(Vertical2by3, 1, 2 / 3)
#undef TEST_FACTOR1 #undef TEST_FACTOR1
#undef TEST_FACTOR #undef TEST_FACTOR
......
...@@ -132,32 +132,33 @@ static int TestFilter(int src_width, int src_height, ...@@ -132,32 +132,33 @@ static int TestFilter(int src_width, int src_height,
return max_diff; return max_diff;
} }
#define TEST_FACTOR1(name, filter, factor, max_diff) \ #define TEST_FACTOR1(name, filter, hfactor, vfactor, max_diff) \
TEST_F(libyuvTest, ScaleDownBy##name##_##filter) { \ TEST_F(libyuvTest, ScaleDownBy##name##_##filter) { \
int diff = TestFilter(benchmark_width_, benchmark_height_, \ int diff = TestFilter(benchmark_width_, benchmark_height_, \
Abs(benchmark_width_) / factor, \ Abs(benchmark_width_) * hfactor, \
Abs(benchmark_height_) / factor, \ Abs(benchmark_height_) * vfactor, \
kFilter##filter, benchmark_iterations_); \ kFilter##filter, benchmark_iterations_); \
EXPECT_LE(diff, max_diff); \ EXPECT_LE(diff, max_diff); \
} }
// Test a scale factor with all 3 filters. Expect unfiltered to be exact, but // Test a scale factor with all 3 filters. Expect unfiltered to be exact, but
// filtering is different fixed point implementations for SSSE3, Neon and C. // filtering is different fixed point implementations for SSSE3, Neon and C.
#define TEST_FACTOR(name, factor) \ #define TEST_FACTOR(name, hfactor, vfactor) \
TEST_FACTOR1(name, None, factor, 0) \ TEST_FACTOR1(name, None, hfactor, vfactor, 0) \
TEST_FACTOR1(name, Bilinear, factor, 2) \ TEST_FACTOR1(name, Bilinear, hfactor, vfactor, 2) \
TEST_FACTOR1(name, Box, factor, 2) \ TEST_FACTOR1(name, Box, hfactor, vfactor, 2) \
// TODO(fbarchard): ScaleDownBy1 should be lossless, but Box has error of 2. // TODO(fbarchard): ScaleDownBy1 should be lossless, but Box has error of 2.
TEST_FACTOR(1, 1) TEST_FACTOR(1, 1 / 1, 1 / 1)
TEST_FACTOR(2, 2) TEST_FACTOR(2, 1 / 2, 1 / 2)
TEST_FACTOR(4, 4) TEST_FACTOR(4, 1 / 4, 1 / 4)
TEST_FACTOR(5, 5) TEST_FACTOR(5, 1 / 5, 1 / 5)
TEST_FACTOR(8, 8) TEST_FACTOR(8, 1 / 8, 1 / 8)
TEST_FACTOR(16, 16) TEST_FACTOR(16, 1 / 16, 1 / 16)
TEST_FACTOR(2by3, 2 / 3) TEST_FACTOR(2by3, 2 / 3, 2 / 3)
TEST_FACTOR(3by4, 3 / 4) TEST_FACTOR(3by4, 3 / 4, 3 / 4)
TEST_FACTOR(3by8, 3 / 8) TEST_FACTOR(3by8, 3 / 8, 3 / 8)
TEST_FACTOR(Vertical2by3, 1, 2 / 3)
#undef TEST_FACTOR1 #undef TEST_FACTOR1
#undef TEST_FACTOR #undef TEST_FACTOR
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment