mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
Fix odd length HammingDistance
If length of HammingDistance was not a multiple of 4, the result was incorrect. The old tests did not catch this so a new test is done to count 1s. Bug: libyuv:740 Test: LibYUVCompareTest.TestHammingDistance Change-Id: I93db5437821c597f1f162ac263d4a594bb83231f Reviewed-on: https://chromium-review.googlesource.com/699614 Reviewed-by: richard winterton <rrwinterton@gmail.com> Reviewed-by: Cheng Wang <wangcheng@google.com> Reviewed-by: Frank Barchard <fbarchard@google.com> Commit-Queue: Frank Barchard <fbarchard@google.com>
This commit is contained in:
parent
fecd741794
commit
1734712a6f
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 1672
|
||||
Version: 1673
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -11,6 +11,6 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 1672
|
||||
#define LIBYUV_VERSION 1673
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
@ -115,8 +115,9 @@ uint64 ComputeHammingDistance(const uint8* src_a,
|
||||
const uint8* src_b,
|
||||
int count) {
|
||||
const int kBlockSize = 65536;
|
||||
const int kSimdSize = 64;
|
||||
// SIMD for multiple of 64, and C for remainder
|
||||
int remainder = count & (kBlockSize - 1) & ~63;
|
||||
int remainder = count & (kBlockSize - 1) & ~(kSimdSize - 1);
|
||||
uint64 diff = 0;
|
||||
int i;
|
||||
uint32 (*HammingDistance)(const uint8* src_a, const uint8* src_b, int count) =
|
||||
@ -159,7 +160,7 @@ uint64 ComputeHammingDistance(const uint8* src_a,
|
||||
src_a += remainder;
|
||||
src_b += remainder;
|
||||
}
|
||||
remainder = count & 31;
|
||||
remainder = count & (kSimdSize - 1);
|
||||
if (remainder) {
|
||||
diff += HammingDistance_C(src_a, src_b, remainder);
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if ORIGINAL_OPT
|
||||
uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) {
|
||||
uint32 HammingDistance_C1(const uint8* src_a, const uint8* src_b, int count) {
|
||||
uint32 diff = 0u;
|
||||
|
||||
int i;
|
||||
@ -58,6 +58,16 @@ uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) {
|
||||
src_a += 4;
|
||||
src_b += 4;
|
||||
}
|
||||
|
||||
for (; i < count; ++i) {
|
||||
uint32 x = *src_a ^ *src_b;
|
||||
uint32 u = x - ((x >> 1) & 0x55);
|
||||
u = ((u >> 2) & 0x33) + (u & 0x33);
|
||||
diff += (u + (u >> 4)) & 0x0f;
|
||||
src_a += 1;
|
||||
src_b += 1;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
||||
@ -316,6 +316,23 @@ TEST_F(LibYUVCompareTest, BenchmarkHammingDistance) {
|
||||
free_aligned_buffer_page_end(src_b);
|
||||
}
|
||||
|
||||
TEST_F(LibYUVCompareTest, TestHammingDistance) {
|
||||
align_buffer_page_end(src_a, benchmark_width_ * benchmark_height_);
|
||||
align_buffer_page_end(src_b, benchmark_width_ * benchmark_height_);
|
||||
memset(src_a, 255u, benchmark_width_ * benchmark_height_);
|
||||
memset(src_b, 0, benchmark_width_ * benchmark_height_);
|
||||
|
||||
uint64 h1 = 0;
|
||||
for (int i = 0; i < benchmark_iterations_; ++i) {
|
||||
h1 = ComputeHammingDistance(src_a, src_b,
|
||||
benchmark_width_ * benchmark_height_);
|
||||
}
|
||||
EXPECT_EQ(benchmark_width_ * benchmark_height_ * 8ULL, h1);
|
||||
|
||||
free_aligned_buffer_page_end(src_a);
|
||||
free_aligned_buffer_page_end(src_b);
|
||||
}
|
||||
|
||||
TEST_F(LibYUVCompareTest, BenchmarkSumSquareError_Opt) {
|
||||
const int kMaxWidth = 4096 * 3;
|
||||
align_buffer_page_end(src_a, kMaxWidth);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user