1 /*
2 * Copyright (c) 2016 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10 #include <math.h>
11 #include <tuple>
12
13 #include "test/clear_system_state.h"
14 #include "test/register_state_check.h"
15 #include "test/util.h"
16 #include "third_party/googletest/src/include/gtest/gtest.h"
17 #include "./vpx_dsp_rtcd.h"
18 #include "vpx/vpx_integer.h"
19 #include "vpx_dsp/postproc.h"
20 #include "vpx_mem/vpx_mem.h"
21
22 namespace {
23
24 static const int kNoiseSize = 3072;
25
26 typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise,
27 int blackclamp, int whiteclamp, int width,
28 int height, int pitch);
29
30 typedef std::tuple<double, AddNoiseFunc> AddNoiseTestFPParam;
31
32 class AddNoiseTest : public ::testing::Test,
33 public ::testing::WithParamInterface<AddNoiseTestFPParam> {
34 public:
TearDown()35 void TearDown() override { libvpx_test::ClearSystemState(); }
36 ~AddNoiseTest() override = default;
37 };
38
stddev6(char a,char b,char c,char d,char e,char f)39 double stddev6(char a, char b, char c, char d, char e, char f) {
40 const double n = (a + b + c + d + e + f) / 6.0;
41 const double v = ((a - n) * (a - n) + (b - n) * (b - n) + (c - n) * (c - n) +
42 (d - n) * (d - n) + (e - n) * (e - n) + (f - n) * (f - n)) /
43 6.0;
44 return sqrt(v);
45 }
46
TEST_P(AddNoiseTest,CheckNoiseAdded)47 TEST_P(AddNoiseTest, CheckNoiseAdded) {
48 const int width = 64;
49 const int height = 64;
50 const int image_size = width * height;
51 int8_t noise[kNoiseSize];
52 const int clamp = vpx_setup_noise(GET_PARAM(0), noise, kNoiseSize);
53 uint8_t *const s =
54 reinterpret_cast<uint8_t *>(vpx_calloc(image_size, sizeof(*s)));
55 ASSERT_NE(s, nullptr);
56 memset(s, 99, image_size * sizeof(*s));
57
58 ASM_REGISTER_STATE_CHECK(
59 GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
60
61 // Check to make sure we don't end up having either the same or no added
62 // noise either vertically or horizontally.
63 for (int i = 0; i < image_size - 6 * width - 6; ++i) {
64 const double hd = stddev6(s[i] - 99, s[i + 1] - 99, s[i + 2] - 99,
65 s[i + 3] - 99, s[i + 4] - 99, s[i + 5] - 99);
66 const double vd = stddev6(s[i] - 99, s[i + width] - 99,
67 s[i + 2 * width] - 99, s[i + 3 * width] - 99,
68 s[i + 4 * width] - 99, s[i + 5 * width] - 99);
69
70 EXPECT_NE(hd, 0);
71 EXPECT_NE(vd, 0);
72 }
73
74 // Initialize pixels in the image to 255 and check for roll over.
75 memset(s, 255, image_size);
76
77 ASM_REGISTER_STATE_CHECK(
78 GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
79
80 // Check to make sure don't roll over.
81 for (int i = 0; i < image_size; ++i) {
82 EXPECT_GT(static_cast<int>(s[i]), clamp) << "i = " << i;
83 }
84
85 // Initialize pixels in the image to 0 and check for roll under.
86 memset(s, 0, image_size);
87
88 ASM_REGISTER_STATE_CHECK(
89 GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
90
91 // Check to make sure don't roll under.
92 for (int i = 0; i < image_size; ++i) {
93 EXPECT_LT(static_cast<int>(s[i]), 255 - clamp) << "i = " << i;
94 }
95
96 vpx_free(s);
97 }
98
TEST_P(AddNoiseTest,CheckCvsAssembly)99 TEST_P(AddNoiseTest, CheckCvsAssembly) {
100 const int width = 64;
101 const int height = 64;
102 const int image_size = width * height;
103 int8_t noise[kNoiseSize];
104 const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
105
106 uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
107 uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
108 ASSERT_NE(s, nullptr);
109 ASSERT_NE(d, nullptr);
110
111 memset(s, 99, image_size);
112 memset(d, 99, image_size);
113
114 srand(0);
115 ASM_REGISTER_STATE_CHECK(
116 GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
117 srand(0);
118 ASM_REGISTER_STATE_CHECK(
119 vpx_plane_add_noise_c(d, noise, clamp, clamp, width, height, width));
120
121 for (int i = 0; i < image_size; ++i) {
122 EXPECT_EQ(static_cast<int>(s[i]), static_cast<int>(d[i])) << "i = " << i;
123 }
124
125 vpx_free(d);
126 vpx_free(s);
127 }
128
129 using std::make_tuple;
130
131 INSTANTIATE_TEST_SUITE_P(
132 C, AddNoiseTest,
133 ::testing::Values(make_tuple(3.25, vpx_plane_add_noise_c),
134 make_tuple(4.4, vpx_plane_add_noise_c)));
135
136 #if HAVE_SSE2
137 INSTANTIATE_TEST_SUITE_P(
138 SSE2, AddNoiseTest,
139 ::testing::Values(make_tuple(3.25, vpx_plane_add_noise_sse2),
140 make_tuple(4.4, vpx_plane_add_noise_sse2)));
141 #endif
142
143 #if HAVE_MSA
144 INSTANTIATE_TEST_SUITE_P(
145 MSA, AddNoiseTest,
146 ::testing::Values(make_tuple(3.25, vpx_plane_add_noise_msa),
147 make_tuple(4.4, vpx_plane_add_noise_msa)));
148 #endif
149 } // namespace
150