/*
 *  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 <tuple>

#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_dsp_rtcd.h"
#include "vpx/vpx_integer.h"
#include "vpx_dsp/postproc.h"
#include "vpx_mem/vpx_mem.h"

namespace {

static const int kNoiseSize = 3072;

// TODO(jimbankoski): make width and height integers not unsigned.
typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise,
                             int blackclamp, int whiteclamp, int width,
                             int height, int pitch);

typedef std::tuple<double, AddNoiseFunc> AddNoiseTestFPParam;

class AddNoiseTest : public ::testing::Test,
                     public ::testing::WithParamInterface<AddNoiseTestFPParam> {
 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);
}

TEST_P(AddNoiseTest, CheckNoiseAdded) {
  const int width = 64;
  const int height = 64;
  const int image_size = width * height;
  int8_t noise[kNoiseSize];
  const int clamp = vpx_setup_noise(GET_PARAM(0), noise, kNoiseSize);
  uint8_t *const s =
      reinterpret_cast<uint8_t *>(vpx_calloc(image_size, sizeof(*s)));
  ASSERT_TRUE(s != NULL);
  memset(s, 99, image_size * sizeof(*s));

  ASM_REGISTER_STATE_CHECK(
      GET_PARAM(1)(s, noise, clamp, clamp, 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(
      GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));

  // Check to make sure don't roll over.
  for (int i = 0; i < image_size; ++i) {
    EXPECT_GT(static_cast<int>(s[i]), clamp) << "i = " << i;
  }

  // Initialize pixels in the image to 0 and check for roll under.
  memset(s, 0, image_size);

  ASM_REGISTER_STATE_CHECK(
      GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));

  // Check to make sure don't roll under.
  for (int i = 0; i < image_size; ++i) {
    EXPECT_LT(static_cast<int>(s[i]), 255 - clamp) << "i = " << i;
  }

  vpx_free(s);
}

TEST_P(AddNoiseTest, CheckCvsAssembly) {
  const int width = 64;
  const int height = 64;
  const int image_size = width * height;
  int8_t noise[kNoiseSize];
  const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);

  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));
  ASSERT_TRUE(s != NULL);
  ASSERT_TRUE(d != NULL);

  memset(s, 99, image_size);
  memset(d, 99, image_size);

  srand(0);
  ASM_REGISTER_STATE_CHECK(
      GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
  srand(0);
  ASM_REGISTER_STATE_CHECK(
      vpx_plane_add_noise_c(d, noise, clamp, clamp, width, height, width));

  for (int i = 0; i < image_size; ++i) {
    EXPECT_EQ(static_cast<int>(s[i]), static_cast<int>(d[i])) << "i = " << i;
  }

  vpx_free(d);
  vpx_free(s);
}

using std::make_tuple;

INSTANTIATE_TEST_SUITE_P(
    C, AddNoiseTest,
    ::testing::Values(make_tuple(3.25, vpx_plane_add_noise_c),
                      make_tuple(4.4, vpx_plane_add_noise_c)));

#if HAVE_SSE2
INSTANTIATE_TEST_SUITE_P(
    SSE2, AddNoiseTest,
    ::testing::Values(make_tuple(3.25, vpx_plane_add_noise_sse2),
                      make_tuple(4.4, vpx_plane_add_noise_sse2)));
#endif

#if HAVE_MSA
INSTANTIATE_TEST_SUITE_P(
    MSA, AddNoiseTest,
    ::testing::Values(make_tuple(3.25, vpx_plane_add_noise_msa),
                      make_tuple(4.4, vpx_plane_add_noise_msa)));
#endif
}  // namespace
