summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJames Bankoski <jimbankoski@google.com>2016-05-04 13:09:05 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2016-05-04 13:09:05 +0000
commit89f905e5e526820fb65e878eb84bfd6a283d1581 (patch)
treeced2e206318f4b0a9688861d7d368dc0099e9998 /test
parentfe193ad2ac439ded0f8b54d9f6b95dd20f7d879f (diff)
parent34d5aff747b3c545de497675f372c6b599860cbd (diff)
downloadlibvpx-89f905e5e526820fb65e878eb84bfd6a283d1581.tar
libvpx-89f905e5e526820fb65e878eb84bfd6a283d1581.tar.gz
libvpx-89f905e5e526820fb65e878eb84bfd6a283d1581.tar.bz2
libvpx-89f905e5e526820fb65e878eb84bfd6a283d1581.zip
Merge "libvpx: add a unit test for plane_add_noise."
Diffstat (limited to 'test')
-rw-r--r--test/add_noise_test.cc201
-rw-r--r--test/test.mk1
2 files changed, 202 insertions, 0 deletions
diff --git a/test/add_noise_test.cc b/test/add_noise_test.cc
new file mode 100644
index 000000000..96e3afbee
--- /dev/null
+++ b/test/add_noise_test.cc
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2016 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include <math.h>
+#include "test/clear_system_state.h"
+#include "test/register_state_check.h"
+#include "third_party/googletest/src/include/gtest/gtest.h"
+#include "./vpx_dsp_rtcd.h"
+#include "vpx/vpx_integer.h"
+#include "vpx_mem/vpx_mem.h"
+
+namespace {
+
+// TODO(jimbankoski): make width and height integers not unsigned.
+typedef void (*AddNoiseFunc)(unsigned char *start, char *noise,
+ char blackclamp[16], char whiteclamp[16],
+ char bothclamp[16], unsigned int width,
+ unsigned int height, int pitch);
+
+class AddNoiseTest
+ : public ::testing::TestWithParam<AddNoiseFunc> {
+ public:
+ virtual void TearDown() {
+ libvpx_test::ClearSystemState();
+ }
+ virtual ~AddNoiseTest() {}
+};
+
+double stddev6(char a, char b, char c, char d, char e, char f) {
+ const double n = (a + b + c + d + e + f) / 6.0;
+ const double v = ((a - n) * (a - n) + (b - n) * (b - n) + (c - n) * (c - n) +
+ (d - n) * (d - n) + (e - n) * (e - n) + (f - n) * (f - n)) /
+ 6.0;
+ return sqrt(v);
+}
+
+// TODO(jimbankoski): The following 2 functions are duplicated in each codec.
+// For now the vp9 one has been copied into the test as is. We should normalize
+// these in vpx_dsp and not have 3 copies of these unless there is different
+// noise we add for each codec.
+
+double gaussian(double sigma, double mu, double x) {
+ return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
+ (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
+}
+
+int setup_noise(int size_noise, char *noise) {
+ char char_dist[300];
+ const int ai = 4;
+ const int qi = 24;
+ const double sigma = ai + .5 + .6 * (63 - qi) / 63.0;
+
+ /* set up a lookup table of 256 entries that matches
+ * a gaussian distribution with sigma determined by q.
+ */
+ int next = 0;
+
+ for (int i = -32; i < 32; i++) {
+ int a_i = (int) (0.5 + 256 * gaussian(sigma, 0, i));
+
+ if (a_i) {
+ for (int j = 0; j < a_i; j++) {
+ char_dist[next + j] = (char)(i);
+ }
+
+ next = next + a_i;
+ }
+ }
+
+ for (; next < 256; next++)
+ char_dist[next] = 0;
+
+ for (int i = 0; i < size_noise; i++) {
+ noise[i] = char_dist[rand() & 0xff]; // NOLINT
+ }
+
+ // Returns the most negative value in distribution.
+ return char_dist[0];
+}
+
+TEST_P(AddNoiseTest, CheckNoiseAdded) {
+ DECLARE_ALIGNED(16, char, blackclamp[16]);
+ DECLARE_ALIGNED(16, char, whiteclamp[16]);
+ DECLARE_ALIGNED(16, char, bothclamp[16]);
+ const int width = 64;
+ const int height = 64;
+ const int image_size = width * height;
+ char noise[3072];
+
+ const int clamp = setup_noise(3072, noise);
+ for (int i = 0; i < 16; i++) {
+ blackclamp[i] = -clamp;
+ whiteclamp[i] = -clamp;
+ bothclamp[i] = -2 * clamp;
+ }
+
+ uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
+ memset(s, 99, image_size);
+
+ ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
+ bothclamp, width, height, width));
+
+ // Check to make sure we don't end up having either the same or no added
+ // noise either vertically or horizontally.
+ for (int i = 0; i < image_size - 6 * width - 6; ++i) {
+ const double hd = stddev6(s[i] - 99, s[i + 1] - 99, s[i + 2] - 99,
+ s[i + 3] - 99, s[i + 4] - 99, s[i + 5] - 99);
+ const double vd = stddev6(s[i] - 99, s[i + width] - 99,
+ s[i + 2 * width] - 99, s[i + 3 * width] - 99,
+ s[i + 4 * width] - 99, s[i + 5 * width] - 99);
+
+ EXPECT_NE(hd, 0);
+ EXPECT_NE(vd, 0);
+ }
+
+ // Initialize pixels in the image to 255 and check for roll over.
+ memset(s, 255, image_size);
+
+ ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
+ bothclamp, width, height, width));
+
+ // Check to make sure don't roll over.
+ for (int i = 0; i < image_size; ++i) {
+ EXPECT_GT((int)s[i], 10) << "i = " << i;
+ }
+
+ // Initialize pixels in the image to 0 and check for roll under.
+ memset(s, 0, image_size);
+
+ ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
+ bothclamp, width, height, width));
+
+ // Check to make sure don't roll under.
+ for (int i = 0; i < image_size; ++i) {
+ EXPECT_LT((int)s[i], 245) << "i = " << i;
+ }
+
+ vpx_free(s);
+}
+
+// TODO(jimbankoski): Make the c work like assembly so we can enable this.
+TEST_P(AddNoiseTest, DISABLED_CheckCvsAssembly) {
+ DECLARE_ALIGNED(16, char, blackclamp[16]);
+ DECLARE_ALIGNED(16, char, whiteclamp[16]);
+ DECLARE_ALIGNED(16, char, bothclamp[16]);
+ const int width = 64;
+ const int height = 64;
+ const int image_size = width * height;
+ char noise[3072];
+
+ const int clamp = setup_noise(3072, noise);
+ for (int i = 0; i < 16; i++) {
+ blackclamp[i] = -clamp;
+ whiteclamp[i] = -clamp;
+ bothclamp[i] = -2 * clamp;
+ }
+
+ uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
+ uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
+
+ memset(s, 99, image_size);
+ memset(d, 99, image_size);
+
+ ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
+ bothclamp, width, height, width));
+ ASM_REGISTER_STATE_CHECK(vpx_plane_add_noise_c(d, noise, blackclamp,
+ whiteclamp, bothclamp,
+ width, height, width));
+
+ for (int i = 0; i < image_size; ++i) {
+ EXPECT_EQ((int)s[i], (int)d[i]) << "i = " << i;
+ }
+
+ vpx_free(d);
+ vpx_free(s);
+}
+
+INSTANTIATE_TEST_CASE_P(C, AddNoiseTest,
+ ::testing::Values(vpx_plane_add_noise_c));
+
+#if HAVE_MMX
+INSTANTIATE_TEST_CASE_P(MMX, AddNoiseTest,
+ ::testing::Values(vpx_plane_add_noise_mmx));
+#endif
+
+#if HAVE_SSE2
+INSTANTIATE_TEST_CASE_P(SSE2, AddNoiseTest,
+ ::testing::Values(vpx_plane_add_noise_sse2));
+#endif
+
+#if HAVE_MSA
+INSTANTIATE_TEST_CASE_P(MSA, AddNoiseTest,
+ ::testing::Values(vpx_plane_add_noise_msa));
+#endif
+} // namespace
diff --git a/test/test.mk b/test/test.mk
index 7c22ca501..390bc2369 100644
--- a/test/test.mk
+++ b/test/test.mk
@@ -103,6 +103,7 @@ LIBVPX_TEST_SRCS-yes += vp8_boolcoder_test.cc
LIBVPX_TEST_SRCS-yes += vp8_fragments_test.cc
endif
+LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += add_noise_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += pp_filter_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_DECODER) += vp8_decrypt_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += quantize_test.cc