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