/*
 *  Copyright (c) 2012 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 <limits.h>
#include <stdio.h>
#include <string.h>

#include "third_party/googletest/src/include/gtest/gtest.h"

#include "./vpx_config.h"
#if CONFIG_VP9_ENCODER
#include "./vp9_rtcd.h"
#endif

#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vpx_dsp/ssim.h"
#include "vpx_mem/vpx_mem.h"

extern "C" double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
                                       uint8_t *img2, int img2_pitch, int width,
                                       int height, Ssimv *sv2, Metrics *m,
                                       int do_inconsistency);

using libvpx_test::ACMRandom;

namespace {
class ConsistencyTestBase : public ::testing::Test {
 public:
  ConsistencyTestBase(int width, int height) : width_(width), height_(height) {}

  static void SetUpTestCase() {
    source_data_[0] = reinterpret_cast<uint8_t *>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
    reference_data_[0] = reinterpret_cast<uint8_t *>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
    source_data_[1] = reinterpret_cast<uint8_t *>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
    reference_data_[1] = reinterpret_cast<uint8_t *>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
    ssim_array_ = new Ssimv[kDataBufferSize / 16];
  }

  static void ClearSsim() { memset(ssim_array_, 0, kDataBufferSize / 16); }
  static void TearDownTestCase() {
    vpx_free(source_data_[0]);
    source_data_[0] = NULL;
    vpx_free(reference_data_[0]);
    reference_data_[0] = NULL;
    vpx_free(source_data_[1]);
    source_data_[1] = NULL;
    vpx_free(reference_data_[1]);
    reference_data_[1] = NULL;

    delete[] ssim_array_;
  }

  virtual void TearDown() { libvpx_test::ClearSystemState(); }

 protected:
  // Handle frames up to 640x480
  static const int kDataAlignment = 16;
  static const int kDataBufferSize = 640 * 480;

  virtual void SetUp() {
    source_stride_ = (width_ + 31) & ~31;
    reference_stride_ = width_ * 2;
    rnd_.Reset(ACMRandom::DeterministicSeed());
  }

  void FillRandom(uint8_t *data, int stride, int width, int height) {
    for (int h = 0; h < height; ++h) {
      for (int w = 0; w < width; ++w) {
        data[h * stride + w] = rnd_.Rand8();
      }
    }
  }

  void FillRandom(uint8_t *data, int stride) {
    FillRandom(data, stride, width_, height_);
  }

  void Copy(uint8_t *reference, uint8_t *source) {
    memcpy(reference, source, kDataBufferSize);
  }

  void Blur(uint8_t *data, int stride, int taps) {
    int sum = 0;
    int half_taps = taps / 2;
    for (int h = 0; h < height_; ++h) {
      for (int w = 0; w < taps; ++w) {
        sum += data[w + h * stride];
      }
      for (int w = taps; w < width_; ++w) {
        sum += data[w + h * stride] - data[w - taps + h * stride];
        data[w - half_taps + h * stride] = (sum + half_taps) / taps;
      }
    }
    for (int w = 0; w < width_; ++w) {
      for (int h = 0; h < taps; ++h) {
        sum += data[h + w * stride];
      }
      for (int h = taps; h < height_; ++h) {
        sum += data[w + h * stride] - data[(h - taps) * stride + w];
        data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
      }
    }
  }
  int width_, height_;
  static uint8_t *source_data_[2];
  int source_stride_;
  static uint8_t *reference_data_[2];
  int reference_stride_;
  static Ssimv *ssim_array_;
  Metrics metrics_;

  ACMRandom rnd_;
};

#if CONFIG_VP9_ENCODER
typedef std::tr1::tuple<int, int> ConsistencyParam;
class ConsistencyVP9Test
    : public ConsistencyTestBase,
      public ::testing::WithParamInterface<ConsistencyParam> {
 public:
  ConsistencyVP9Test() : ConsistencyTestBase(GET_PARAM(0), GET_PARAM(1)) {}

 protected:
  double CheckConsistency(int frame) {
    EXPECT_LT(frame, 2) << "Frame to check has to be less than 2.";
    return vpx_get_ssim_metrics(source_data_[frame], source_stride_,
                                reference_data_[frame], reference_stride_,
                                width_, height_, ssim_array_, &metrics_, 1);
  }
};
#endif  // CONFIG_VP9_ENCODER

uint8_t *ConsistencyTestBase::source_data_[2] = { NULL, NULL };
uint8_t *ConsistencyTestBase::reference_data_[2] = { NULL, NULL };
Ssimv *ConsistencyTestBase::ssim_array_ = NULL;

#if CONFIG_VP9_ENCODER
TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
  FillRandom(source_data_[0], source_stride_);
  Copy(source_data_[1], source_data_[0]);
  Copy(reference_data_[0], source_data_[0]);
  Blur(reference_data_[0], reference_stride_, 3);
  Copy(reference_data_[1], source_data_[0]);
  Blur(reference_data_[1], reference_stride_, 3);

  double inconsistency = CheckConsistency(1);
  inconsistency = CheckConsistency(0);
  EXPECT_EQ(inconsistency, 0.0)
      << "Should have 0 inconsistency if they are exactly the same.";

  // If sources are not consistent reference frames inconsistency should
  // be less than if the source is consistent.
  FillRandom(source_data_[0], source_stride_);
  FillRandom(source_data_[1], source_stride_);
  FillRandom(reference_data_[0], reference_stride_);
  FillRandom(reference_data_[1], reference_stride_);
  CheckConsistency(0);
  inconsistency = CheckConsistency(1);

  Copy(source_data_[1], source_data_[0]);
  CheckConsistency(0);
  double inconsistency2 = CheckConsistency(1);
  EXPECT_LT(inconsistency, inconsistency2)
      << "Should have less inconsistency if source itself is inconsistent.";

  // Less of a blur should be less inconsistent than more blur coming off a
  // a frame with no blur.
  ClearSsim();
  FillRandom(source_data_[0], source_stride_);
  Copy(source_data_[1], source_data_[0]);
  Copy(reference_data_[0], source_data_[0]);
  Copy(reference_data_[1], source_data_[0]);
  Blur(reference_data_[1], reference_stride_, 4);
  CheckConsistency(0);
  inconsistency = CheckConsistency(1);
  ClearSsim();
  Copy(reference_data_[1], source_data_[0]);
  Blur(reference_data_[1], reference_stride_, 8);
  CheckConsistency(0);
  inconsistency2 = CheckConsistency(1);

  EXPECT_LT(inconsistency, inconsistency2)
      << "Stronger Blur should produce more inconsistency.";
}
#endif  // CONFIG_VP9_ENCODER

using std::tr1::make_tuple;

//------------------------------------------------------------------------------
// C functions

#if CONFIG_VP9_ENCODER
const ConsistencyParam c_vp9_tests[] = {
  make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
};
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
                        ::testing::ValuesIn(c_vp9_tests));
#endif

}  // namespace
