/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include "./av1_rtcd.h"
#include "test/acm_random.h"
#include "test/util.h"
#include "test/av1_txfm_test.h"
#include "av1/common/av1_inv_txfm1d_cfg.h"

using libaom_test::ACMRandom;
using libaom_test::input_base;
using libaom_test::bd;
using libaom_test::compute_avg_abs_error;
using libaom_test::Fwd_Txfm2d_Func;
using libaom_test::Inv_Txfm2d_Func;

namespace {

#if CONFIG_HIGHBITDEPTH
// AV1InvTxfm2dParam argument list:
// tx_type_, tx_size_, max_error_, max_avg_error_
typedef std::tr1::tuple<TX_TYPE, TX_SIZE, int, double> AV1InvTxfm2dParam;

class AV1InvTxfm2d : public ::testing::TestWithParam<AV1InvTxfm2dParam> {
 public:
  virtual void SetUp() {
    tx_type_ = GET_PARAM(0);
    tx_size_ = GET_PARAM(1);
    max_error_ = GET_PARAM(2);
    max_avg_error_ = GET_PARAM(3);
    txfm1d_size_ = libaom_test::get_txfm1d_size(tx_size_);
    txfm2d_size_ = txfm1d_size_ * txfm1d_size_;
  }

  void RunRoundtripCheck() {
    const Fwd_Txfm2d_Func fwd_txfm_func =
        libaom_test::fwd_txfm_func_ls[tx_size_];
    const Inv_Txfm2d_Func inv_txfm_func =
        libaom_test::inv_txfm_func_ls[tx_size_];
    double avg_abs_error = 0;
    ACMRandom rnd(ACMRandom::DeterministicSeed());

    const int count = 500;

    for (int ci = 0; ci < count; ci++) {
      int16_t expected[64 * 64] = { 0 };
      assert(txfm2d_size_ < ARRAY_SIZE(expected));

      for (int ni = 0; ni < txfm2d_size_; ++ni) {
        if (ci == 0) {
          int extreme_input = input_base - 1;
          expected[ni] = extreme_input;  // extreme case
        } else {
          expected[ni] = rnd.Rand16() % input_base;
        }
      }

      int32_t coeffs[64 * 64] = { 0 };
      assert(txfm2d_size_ < ARRAY_SIZE(coeffs));
      fwd_txfm_func(expected, coeffs, txfm1d_size_, tx_type_, bd);

      uint16_t actual[64 * 64] = { 0 };
      assert(txfm2d_size_ < ARRAY_SIZE(actual));
      inv_txfm_func(coeffs, actual, txfm1d_size_, tx_type_, bd);

      for (int ni = 0; ni < txfm2d_size_; ++ni) {
        EXPECT_GE(max_error_, abs(expected[ni] - actual[ni]));
      }
      avg_abs_error += compute_avg_abs_error<int16_t, uint16_t>(
          expected, actual, txfm2d_size_);
    }

    avg_abs_error /= count;
    // max_abs_avg_error comes from upper bound of
    // printf("txfm1d_size: %d accuracy_avg_abs_error: %f\n",
    // txfm1d_size_, avg_abs_error);
    EXPECT_GE(max_avg_error_, avg_abs_error);
  }

 private:
  int max_error_;
  double max_avg_error_;
  TX_TYPE tx_type_;
  TX_SIZE tx_size_;
  int txfm1d_size_;
  int txfm2d_size_;
};

TEST_P(AV1InvTxfm2d, RunRoundtripCheck) { RunRoundtripCheck(); }

const AV1InvTxfm2dParam av1_inv_txfm2d_param[] = {
#if CONFIG_EXT_TX
  AV1InvTxfm2dParam(FLIPADST_DCT, TX_4X4, 2, 0.002),
  AV1InvTxfm2dParam(DCT_FLIPADST, TX_4X4, 2, 0.002),
  AV1InvTxfm2dParam(FLIPADST_FLIPADST, TX_4X4, 2, 0.002),
  AV1InvTxfm2dParam(ADST_FLIPADST, TX_4X4, 2, 0.002),
  AV1InvTxfm2dParam(FLIPADST_ADST, TX_4X4, 2, 0.002),
  AV1InvTxfm2dParam(FLIPADST_DCT, TX_8X8, 2, 0.02),
  AV1InvTxfm2dParam(DCT_FLIPADST, TX_8X8, 2, 0.02),
  AV1InvTxfm2dParam(FLIPADST_FLIPADST, TX_8X8, 2, 0.02),
  AV1InvTxfm2dParam(ADST_FLIPADST, TX_8X8, 2, 0.02),
  AV1InvTxfm2dParam(FLIPADST_ADST, TX_8X8, 2, 0.02),
  AV1InvTxfm2dParam(FLIPADST_DCT, TX_16X16, 2, 0.04),
  AV1InvTxfm2dParam(DCT_FLIPADST, TX_16X16, 2, 0.04),
  AV1InvTxfm2dParam(FLIPADST_FLIPADST, TX_16X16, 11, 0.04),
  AV1InvTxfm2dParam(ADST_FLIPADST, TX_16X16, 2, 0.04),
  AV1InvTxfm2dParam(FLIPADST_ADST, TX_16X16, 2, 0.04),
  AV1InvTxfm2dParam(FLIPADST_DCT, TX_32X32, 4, 0.4),
  AV1InvTxfm2dParam(DCT_FLIPADST, TX_32X32, 4, 0.4),
  AV1InvTxfm2dParam(FLIPADST_FLIPADST, TX_32X32, 4, 0.4),
  AV1InvTxfm2dParam(ADST_FLIPADST, TX_32X32, 4, 0.4),
  AV1InvTxfm2dParam(FLIPADST_ADST, TX_32X32, 4, 0.4),
#endif
  AV1InvTxfm2dParam(DCT_DCT, TX_4X4, 2, 0.002),
  AV1InvTxfm2dParam(ADST_DCT, TX_4X4, 2, 0.002),
  AV1InvTxfm2dParam(DCT_ADST, TX_4X4, 2, 0.002),
  AV1InvTxfm2dParam(ADST_ADST, TX_4X4, 2, 0.002),
  AV1InvTxfm2dParam(DCT_DCT, TX_8X8, 2, 0.02),
  AV1InvTxfm2dParam(ADST_DCT, TX_8X8, 2, 0.02),
  AV1InvTxfm2dParam(DCT_ADST, TX_8X8, 2, 0.02),
  AV1InvTxfm2dParam(ADST_ADST, TX_8X8, 2, 0.02),
  AV1InvTxfm2dParam(DCT_DCT, TX_16X16, 2, 0.04),
  AV1InvTxfm2dParam(ADST_DCT, TX_16X16, 2, 0.04),
  AV1InvTxfm2dParam(DCT_ADST, TX_16X16, 2, 0.04),
  AV1InvTxfm2dParam(ADST_ADST, TX_16X16, 2, 0.04),
  AV1InvTxfm2dParam(DCT_DCT, TX_32X32, 4, 0.4),
  AV1InvTxfm2dParam(ADST_DCT, TX_32X32, 4, 0.4),
  AV1InvTxfm2dParam(DCT_ADST, TX_32X32, 4, 0.4),
  AV1InvTxfm2dParam(ADST_ADST, TX_32X32, 4, 0.4)
};

INSTANTIATE_TEST_CASE_P(C, AV1InvTxfm2d,
                        ::testing::ValuesIn(av1_inv_txfm2d_param));

#endif  // CONFIG_HIGHBITDEPTH

}  // namespace
