/*
 * 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 "test/av1_txfm_test.h"
#include "test/util.h"
#include "av1/common/av1_inv_txfm1d.h"
#include "av1/encoder/av1_fwd_txfm1d.h"

using libaom_test::ACMRandom;
using libaom_test::input_base;

namespace {
const int txfm_type_num = 2;
const int txfm_size_ls[] = { 4, 8, 16, 32, 64 };

const TxfmFunc fwd_txfm_func_ls[][txfm_type_num] = {
  { av1_fdct4_new, av1_fadst4_new },
  { av1_fdct8_new, av1_fadst8_new },
  { av1_fdct16_new, av1_fadst16_new },
  { av1_fdct32_new, NULL },
  { av1_fdct64_new, NULL },
};

const TxfmFunc inv_txfm_func_ls[][txfm_type_num] = {
  { av1_idct4_new, av1_iadst4_new },
  { av1_idct8_new, av1_iadst8_new },
  { av1_idct16_new, av1_iadst16_new },
  { av1_idct32_new, NULL },
  { av1_idct64_new, NULL },
};

// the maximum stage number of fwd/inv 1d dct/adst txfm is 12
const int8_t cos_bit = 13;
const int8_t range_bit[12] = { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 };

void reference_idct_1d_int(const int32_t *in, int32_t *out, int size) {
  double input[64];
  for (int i = 0; i < size; ++i) input[i] = in[i];

  double output[64];
  libaom_test::reference_idct_1d(input, output, size);

  for (int i = 0; i < size; ++i) {
    ASSERT_GE(output[i], INT32_MIN);
    ASSERT_LE(output[i], INT32_MAX);
    out[i] = static_cast<int32_t>(round(output[i]));
  }
}

void random_matrix(int32_t *dst, int len, ACMRandom *rnd) {
  const int bits = 16;
  const int maxVal = (1 << (bits - 1)) - 1;
  const int minVal = -(1 << (bits - 1));
  for (int i = 0; i < len; ++i) {
    if (rnd->Rand8() % 10)
      dst[i] = minVal + rnd->Rand16() % (1 << bits);
    else
      dst[i] = rnd->Rand8() % 2 ? minVal : maxVal;
  }
}

TEST(av1_inv_txfm1d, InvAccuracyCheck) {
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  const int count_test_block = 20000;
  const int max_error[] = { 6, 10, 19, 31, 40 };
  ASSERT_EQ(NELEMENTS(max_error), TX_SIZES);
  ASSERT_EQ(NELEMENTS(inv_txfm_func_ls), TX_SIZES);
  for (int k = 0; k < count_test_block; ++k) {
    // choose a random transform to test
    const TX_SIZE tx_size = static_cast<TX_SIZE>(rnd.Rand8() % TX_SIZES);
    const int tx_size_pix = txfm_size_ls[tx_size];
    const TxfmFunc inv_txfm_func = inv_txfm_func_ls[tx_size][0];

    int32_t input[64];
    random_matrix(input, tx_size_pix, &rnd);

    // 64x64 transform assumes last 32 values are zero.
    memset(input + 32, 0, 32 * sizeof(input[0]));

    int32_t ref_output[64];
    reference_idct_1d_int(input, ref_output, tx_size_pix);

    int32_t output[64];
    inv_txfm_func(input, output, cos_bit, range_bit);

    for (int i = 0; i < tx_size_pix; ++i) {
      EXPECT_LE(abs(output[i] - ref_output[i]), max_error[tx_size])
          << "tx_size = " << tx_size << ", i = " << i
          << ", output[i] = " << output[i]
          << ", ref_output[i] = " << ref_output[i];
    }
  }
}

static INLINE int get_max_bit(int x) {
  int max_bit = -1;
  while (x) {
    x = x >> 1;
    max_bit++;
  }
  return max_bit;
}

TEST(av1_inv_txfm1d, get_max_bit) {
  int max_bit = get_max_bit(8);
  EXPECT_EQ(max_bit, 3);
}

TEST(av1_inv_txfm1d, round_trip) {
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  for (int si = 0; si < NELEMENTS(fwd_txfm_func_ls); ++si) {
    int txfm_size = txfm_size_ls[si];

    for (int ti = 0; ti < txfm_type_num; ++ti) {
      TxfmFunc fwd_txfm_func = fwd_txfm_func_ls[si][ti];
      TxfmFunc inv_txfm_func = inv_txfm_func_ls[si][ti];
      int max_error = 2;

      if (!fwd_txfm_func) continue;

      const int count_test_block = 5000;
      for (int ci = 0; ci < count_test_block; ++ci) {
        int32_t input[64];
        int32_t output[64];
        int32_t round_trip_output[64];

        ASSERT_LE(txfm_size, NELEMENTS(input));

        for (int ni = 0; ni < txfm_size; ++ni) {
          input[ni] = rnd.Rand16() % input_base - rnd.Rand16() % input_base;
        }

        fwd_txfm_func(input, output, cos_bit, range_bit);
        inv_txfm_func(output, round_trip_output, cos_bit, range_bit);

        for (int ni = 0; ni < txfm_size; ++ni) {
          int node_err =
              abs(input[ni] - round_shift(round_trip_output[ni],
                                          get_max_bit(txfm_size) - 1));
          EXPECT_LE(node_err, max_error);
        }
      }
    }
  }
}

}  // namespace
