1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/*
2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Use of this source code is governed by a BSD-style license
5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  that can be found in the LICENSE file in the root of the source
6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  tree. An additional intellectual property rights grant can be found
7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  in the file PATENTS.  All contributing project authors may
8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  be found in the AUTHORS file in the root of the source tree.
9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <math.h>
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <stdlib.h>
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <string.h>
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "third_party/googletest/src/include/gtest/gtest.h"
161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "test/acm_random.h"
171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "test/clear_system_state.h"
181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "test/register_state_check.h"
191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "test/util.h"
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "./vpx_config.h"
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vp9_rtcd.h"
23b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_entropy.h"
24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx/vpx_integer.h"
25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangusing libvpx_test::ACMRandom;
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangnamespace {
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef _MSC_VER
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int round(double x) {
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (x < 0)
321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    return static_cast<int>(ceil(x - 0.5));
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else
341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    return static_cast<int>(floor(x + 0.5));
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
381184aebb761cbeac9124c37189a80a1a58f04b6bhkuangconst int kNumCoeffs = 1024;
391184aebb761cbeac9124c37189a80a1a58f04b6bhkuangconst double kPi = 3.141592653589793238462643383279502884;
401184aebb761cbeac9124c37189a80a1a58f04b6bhkuangvoid reference_32x32_dct_1d(const double in[32], double out[32], int stride) {
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const double kInvSqrt2 = 0.707106781186547524400844362104;
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (int k = 0; k < 32; k++) {
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    out[k] = 0.0;
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (int n = 0; n < 32; n++)
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0);
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (k == 0)
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      out[k] = out[k] * kInvSqrt2;
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
511184aebb761cbeac9124c37189a80a1a58f04b6bhkuangvoid reference_32x32_dct_2d(const int16_t input[kNumCoeffs],
521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                            double output[kNumCoeffs]) {
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // First transform columns
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (int i = 0; i < 32; ++i) {
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    double temp_in[32], temp_out[32];
56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (int j = 0; j < 32; ++j)
57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      temp_in[j] = input[j*32 + i];
58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    reference_32x32_dct_1d(temp_in, temp_out, 1);
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (int j = 0; j < 32; ++j)
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      output[j * 32 + i] = temp_out[j];
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Then transform rows
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (int i = 0; i < 32; ++i) {
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    double temp_in[32], temp_out[32];
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (int j = 0; j < 32; ++j)
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      temp_in[j] = output[j + i*32];
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    reference_32x32_dct_1d(temp_in, temp_out, 1);
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Scale by some magic number
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (int j = 0; j < 32; ++j)
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      output[j + i * 32] = temp_out[j] / 4;
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangtypedef void (*fwd_txfm_t)(const int16_t *in, int16_t *out, int stride);
755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangtypedef void (*inv_txfm_t)(const int16_t *in, uint8_t *out, int stride);
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
77b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniantypedef std::tr1::tuple<fwd_txfm_t, inv_txfm_t, int> trans_32x32_param_t;
78b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
79b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianclass Trans32x32Test : public ::testing::TestWithParam<trans_32x32_param_t> {
801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang public:
811184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  virtual ~Trans32x32Test() {}
821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  virtual void SetUp() {
831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    fwd_txfm_ = GET_PARAM(0);
841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    inv_txfm_ = GET_PARAM(1);
851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    version_  = GET_PARAM(2);  // 0: high precision forward transform
861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                               // 1: low precision version for rd loop
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
891184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  virtual void TearDown() { libvpx_test::ClearSystemState(); }
901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang protected:
921184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int version_;
931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  fwd_txfm_t fwd_txfm_;
941184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  inv_txfm_t inv_txfm_;
951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang};
961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
971184aebb761cbeac9124c37189a80a1a58f04b6bhkuangTEST_P(Trans32x32Test, AccuracyCheck) {
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ACMRandom rnd(ACMRandom::DeterministicSeed());
991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  uint32_t max_error = 0;
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t total_error = 0;
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int count_test_block = 1000;
1021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
1031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, test_temp_block, kNumCoeffs);
1041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
1051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (int i = 0; i < count_test_block; ++i) {
1081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // Initialize a test block with input range [-255, 255].
1091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (int j = 0; j < kNumCoeffs; ++j) {
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      src[j] = rnd.Rand8();
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      dst[j] = rnd.Rand8();
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      test_input_block[j] = src[j] - dst[j];
1131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32));
1161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (int j = 0; j < kNumCoeffs; ++j) {
1191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const uint32_t diff = dst[j] - src[j];
1201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const uint32_t error = diff * diff;
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (max_error < error)
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        max_error = error;
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      total_error += error;
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (version_ == 1) {
1281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    max_error /= 2;
1291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    total_error /= 45;
1301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  }
1311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  EXPECT_GE(1u, max_error)
1331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      << "Error: 32x32 FDCT/IDCT has an individual round-trip error > 1";
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  EXPECT_GE(count_test_block, total_error)
1361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      << "Error: 32x32 FDCT/IDCT has average round-trip error > 1 per block";
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1391184aebb761cbeac9124c37189a80a1a58f04b6bhkuangTEST_P(Trans32x32Test, CoeffCheck) {
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ACMRandom rnd(ACMRandom::DeterministicSeed());
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int count_test_block = 1000;
1421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
1441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs);
1451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, output_block, kNumCoeffs);
1461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (int i = 0; i < count_test_block; ++i) {
1481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (int j = 0; j < kNumCoeffs; ++j)
1491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      input_block[j] = rnd.Rand8() - rnd.Rand8();
1501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    const int stride = 32;
1525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_fdct32x32_c(input_block, output_ref_block, stride);
1535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride));
1541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (version_ == 0) {
1561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (int j = 0; j < kNumCoeffs; ++j)
1571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        EXPECT_EQ(output_block[j], output_ref_block[j])
1581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            << "Error: 32x32 FDCT versions have mismatched coefficients";
1591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    } else {
1601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (int j = 0; j < kNumCoeffs; ++j)
1611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        EXPECT_GE(6, abs(output_block[j] - output_ref_block[j]))
1621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            << "Error: 32x32 FDCT rd has mismatched coefficients";
1631184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
1641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  }
1651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang}
1661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1671184aebb761cbeac9124c37189a80a1a58f04b6bhkuangTEST_P(Trans32x32Test, MemCheck) {
1681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  ACMRandom rnd(ACMRandom::DeterministicSeed());
1691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int count_test_block = 2000;
1701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
1721184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs);
1731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs);
1741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, output_block, kNumCoeffs);
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (int i = 0; i < count_test_block; ++i) {
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Initialize a test block with input range [-255, 255].
1781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (int j = 0; j < kNumCoeffs; ++j) {
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      input_block[j] = rnd.Rand8() - rnd.Rand8();
1801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      input_extreme_block[j] = rnd.Rand8() & 1 ? 255 : -255;
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (i == 0)
1831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (int j = 0; j < kNumCoeffs; ++j)
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        input_extreme_block[j] = 255;
1851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (i == 1)
1861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (int j = 0; j < kNumCoeffs; ++j)
1871184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        input_extreme_block[j] = -255;
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    const int stride = 32;
1905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_fdct32x32_c(input_extreme_block, output_ref_block, stride);
1915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    REGISTER_STATE_CHECK(fwd_txfm_(input_extreme_block, output_block, stride));
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // The minimum quant value is 4.
1941184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (int j = 0; j < kNumCoeffs; ++j) {
1951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      if (version_ == 0) {
1961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        EXPECT_EQ(output_block[j], output_ref_block[j])
1971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            << "Error: 32x32 FDCT versions have mismatched coefficients";
1981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      } else {
1991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        EXPECT_GE(6, abs(output_block[j] - output_ref_block[j]))
2001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            << "Error: 32x32 FDCT rd has mismatched coefficients";
2011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
2021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      EXPECT_GE(4 * DCT_MAX_VALUE, abs(output_ref_block[j]))
2031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          << "Error: 32x32 FDCT C has coefficient larger than 4*DCT_MAX_VALUE";
2041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      EXPECT_GE(4 * DCT_MAX_VALUE, abs(output_block[j]))
2051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          << "Error: 32x32 FDCT has coefficient larger than "
2061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          << "4*DCT_MAX_VALUE";
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2111184aebb761cbeac9124c37189a80a1a58f04b6bhkuangTEST_P(Trans32x32Test, InverseAccuracy) {
2121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  ACMRandom rnd(ACMRandom::DeterministicSeed());
2131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int count_test_block = 1000;
2141184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
2151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, int16_t, coeff, kNumCoeffs);
2161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
2171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
2181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (int i = 0; i < count_test_block; ++i) {
2201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    double out_r[kNumCoeffs];
2211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // Initialize a test block with input range [-255, 255]
2231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (int j = 0; j < kNumCoeffs; ++j) {
2241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      src[j] = rnd.Rand8();
2251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      dst[j] = rnd.Rand8();
2261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      in[j] = src[j] - dst[j];
2271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
2281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    reference_32x32_dct_2d(in, out_r);
2301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (int j = 0; j < kNumCoeffs; ++j)
2311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      coeff[j] = round(out_r[j]);
2321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
2331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (int j = 0; j < kNumCoeffs; ++j) {
2341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const int diff = dst[j] - src[j];
2351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const int error = diff * diff;
2361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      EXPECT_GE(1, error)
2371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          << "Error: 32x32 IDCT has error " << error
2381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          << " at index " << j;
2391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
2401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  }
2411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang}
2421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2431184aebb761cbeac9124c37189a80a1a58f04b6bhkuangusing std::tr1::make_tuple;
2441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2451184aebb761cbeac9124c37189a80a1a58f04b6bhkuangINSTANTIATE_TEST_CASE_P(
2461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    C, Trans32x32Test,
2471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    ::testing::Values(
2485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        make_tuple(&vp9_fdct32x32_c, &vp9_idct32x32_1024_add_c, 0),
2495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        make_tuple(&vp9_fdct32x32_rd_c, &vp9_idct32x32_1024_add_c, 1)));
2501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
251b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#if HAVE_NEON
252b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh VenkatasubramanianINSTANTIATE_TEST_CASE_P(
253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    NEON, Trans32x32Test,
254b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    ::testing::Values(
255b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        make_tuple(&vp9_fdct32x32_c,
256b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   &vp9_idct32x32_1024_add_neon, 0),
257b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        make_tuple(&vp9_fdct32x32_rd_c,
258b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   &vp9_idct32x32_1024_add_neon, 1)));
259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif
260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#if HAVE_SSE2
2621184aebb761cbeac9124c37189a80a1a58f04b6bhkuangINSTANTIATE_TEST_CASE_P(
2631184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    SSE2, Trans32x32Test,
2641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    ::testing::Values(
2655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        make_tuple(&vp9_fdct32x32_sse2,
2665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   &vp9_idct32x32_1024_add_sse2, 0),
2675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        make_tuple(&vp9_fdct32x32_rd_sse2,
2685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   &vp9_idct32x32_1024_add_sse2, 1)));
2691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#endif
270b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
271b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#if HAVE_AVX2
272b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh VenkatasubramanianINSTANTIATE_TEST_CASE_P(
273b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    AVX2, Trans32x32Test,
274b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    ::testing::Values(
275b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        make_tuple(&vp9_fdct32x32_avx2,
276b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   &vp9_idct32x32_1024_add_sse2, 0),
277b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        make_tuple(&vp9_fdct32x32_rd_avx2,
278b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   &vp9_idct32x32_1024_add_sse2, 1)));
279b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif
280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}  // namespace
281