/*
 *  Copyright (c) 2013 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 <stdlib.h>
#include <string.h>

#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"

extern "C" {
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_blockd.h"
#include "vp9/common/vp9_scan.h"
}

#include "vpx/vpx_integer.h"

using libvpx_test::ACMRandom;

namespace {
typedef void (*fwd_txfm_t)(const int16_t *in, int16_t *out, int stride);
typedef void (*inv_txfm_t)(const int16_t *in, uint8_t *out, int stride);
typedef std::tr1::tuple<inv_txfm_t,
                        inv_txfm_t,
                        TX_SIZE, int> partial_itxfm_param_t;
const int kMaxNumCoeffs = 1024;
class PartialIDctTest : public ::testing::TestWithParam<partial_itxfm_param_t> {
 public:
  virtual ~PartialIDctTest() {}
  virtual void SetUp() {
    full_itxfm_ = GET_PARAM(0);
    partial_itxfm_ = GET_PARAM(1);
    tx_size_  = GET_PARAM(2);
    last_nonzero_ = GET_PARAM(3);
  }

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

 protected:
  int last_nonzero_;
  TX_SIZE tx_size_;
  inv_txfm_t full_itxfm_;
  inv_txfm_t partial_itxfm_;
};

TEST_P(PartialIDctTest, ResultsMatch) {
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  int size;
  switch (tx_size_) {
  case TX_4X4:
    size = 4;
    break;
  case TX_8X8:
    size = 8;
    break;
  case TX_16X16:
    size = 16;
    break;
  case TX_32X32:
    size = 32;
    break;
  default:
    ASSERT_TRUE(0) << "Wrong Size!";
    break;
  }
  DECLARE_ALIGNED_ARRAY(16, int16_t, test_coef_block1, kMaxNumCoeffs);
  DECLARE_ALIGNED_ARRAY(16, int16_t, test_coef_block2, kMaxNumCoeffs);
  DECLARE_ALIGNED_ARRAY(16, uint8_t, dst1, kMaxNumCoeffs);
  DECLARE_ALIGNED_ARRAY(16, uint8_t, dst2, kMaxNumCoeffs);
  const int count_test_block = 1000;
  const int max_coeff = 32766 / 4;
  const int block_size = size * size;
  int max_error = 0;
  for (int i = 0; i < count_test_block; ++i) {
    // clear out destination buffer
    memset(dst1, 0, sizeof(*dst1) * block_size);
    memset(dst2, 0, sizeof(*dst2) * block_size);
    memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
    memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);
    int max_energy_leftover = max_coeff * max_coeff;
    for (int j = 0; j < last_nonzero_; ++j) {
      int16_t coef = static_cast<int16_t>(sqrt(max_energy_leftover) *
                                          (rnd.Rand16() - 32768) / 65536);
      max_energy_leftover -= coef * coef;
      if (max_energy_leftover < 0) {
        max_energy_leftover = 0;
        coef = 0;
      }
      test_coef_block1[vp9_default_scan_orders[tx_size_].scan[j]] = coef;
    }

    memcpy(test_coef_block2, test_coef_block1,
           sizeof(*test_coef_block2) * block_size);

    REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
    REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block2, dst2, size));

    for (int j = 0; j < block_size; ++j) {
      const int diff = dst1[j] - dst2[j];
      const int error = diff * diff;
      if (max_error < error)
        max_error = error;
    }
  }

  EXPECT_EQ(0, max_error)
      << "Error: partial inverse transform produces different results";
}
using std::tr1::make_tuple;

INSTANTIATE_TEST_CASE_P(
    C, PartialIDctTest,
    ::testing::Values(
        make_tuple(vp9_idct32x32_1024_add_c,
                   vp9_idct32x32_34_add_c,
                   TX_32X32, 34),
        make_tuple(vp9_idct32x32_1024_add_c,
                   vp9_idct32x32_1_add_c,
                   TX_32X32, 1),
        make_tuple(vp9_idct16x16_256_add_c,
                   vp9_idct16x16_10_add_c,
                   TX_16X16, 10),
        make_tuple(vp9_idct16x16_256_add_c,
                   vp9_idct16x16_1_add_c,
                   TX_16X16, 1),
        make_tuple(vp9_idct8x8_64_add_c,
                   vp9_idct8x8_10_add_c,
                   TX_8X8, 10),
        make_tuple(vp9_idct8x8_64_add_c,
                   vp9_idct8x8_1_add_c,
                   TX_8X8, 1),
        make_tuple(vp9_idct4x4_16_add_c,
                   vp9_idct4x4_1_add_c,
                   TX_4X4, 1)));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
    SSE2, PartialIDctTest,
    ::testing::Values(
        make_tuple(vp9_idct32x32_1024_add_c,
                   vp9_idct32x32_34_add_sse2,
                   TX_32X32, 34),
        make_tuple(vp9_idct32x32_1024_add_c,
                   vp9_idct32x32_1_add_sse2,
                   TX_32X32, 1),
        make_tuple(vp9_idct16x16_256_add_c,
                   vp9_idct16x16_10_add_sse2,
                   TX_16X16, 10),
        make_tuple(vp9_idct16x16_256_add_c,
                   vp9_idct16x16_1_add_sse2,
                   TX_16X16, 1),
        make_tuple(vp9_idct8x8_64_add_c,
                   vp9_idct8x8_10_add_sse2,
                   TX_8X8, 10),
        make_tuple(vp9_idct8x8_64_add_c,
                   vp9_idct8x8_1_add_sse2,
                   TX_8X8, 1),
        make_tuple(vp9_idct4x4_16_add_c,
                   vp9_idct4x4_1_add_sse2,
                   TX_4X4, 1)));
#endif
}  // namespace
