Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2015 The WebM project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
| 11 | #include <stdio.h> |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 12 | #include "test/av1_txfm_test.h" |
Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 13 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 14 | namespace libaom_test { |
Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 15 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 16 | int get_txfm1d_size(TX_SIZE tx_size) { return 1 << (tx_size + 2); } |
Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 17 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 18 | void get_txfm1d_type(TX_TYPE txfm2d_type, TYPE_TXFM *type0, TYPE_TXFM *type1) { |
Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 19 | switch (txfm2d_type) { |
| 20 | case DCT_DCT: |
| 21 | *type0 = TYPE_DCT; |
| 22 | *type1 = TYPE_DCT; |
| 23 | break; |
| 24 | case ADST_DCT: |
| 25 | *type0 = TYPE_ADST; |
| 26 | *type1 = TYPE_DCT; |
| 27 | break; |
| 28 | case DCT_ADST: |
| 29 | *type0 = TYPE_DCT; |
| 30 | *type1 = TYPE_ADST; |
| 31 | break; |
| 32 | case ADST_ADST: |
| 33 | *type0 = TYPE_ADST; |
| 34 | *type1 = TYPE_ADST; |
| 35 | break; |
Angie Chiang | 6a75253 | 2016-05-11 18:50:47 -0700 | [diff] [blame] | 36 | #if CONFIG_EXT_TX |
| 37 | case FLIPADST_DCT: |
| 38 | *type0 = TYPE_ADST; |
| 39 | *type1 = TYPE_DCT; |
| 40 | break; |
| 41 | case DCT_FLIPADST: |
| 42 | *type0 = TYPE_DCT; |
| 43 | *type1 = TYPE_ADST; |
| 44 | break; |
| 45 | case FLIPADST_FLIPADST: |
| 46 | *type0 = TYPE_ADST; |
| 47 | *type1 = TYPE_ADST; |
| 48 | break; |
| 49 | case ADST_FLIPADST: |
| 50 | *type0 = TYPE_ADST; |
| 51 | *type1 = TYPE_ADST; |
| 52 | break; |
| 53 | case FLIPADST_ADST: |
| 54 | *type0 = TYPE_ADST; |
| 55 | *type1 = TYPE_ADST; |
| 56 | break; |
| 57 | #endif // CONFIG_EXT_TX |
Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 58 | default: |
| 59 | *type0 = TYPE_DCT; |
| 60 | *type1 = TYPE_DCT; |
| 61 | assert(0); |
| 62 | break; |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | double invSqrt2 = 1 / pow(2, 0.5); |
| 67 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 68 | void reference_dct_1d(const double *in, double *out, int size) { |
Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 69 | for (int k = 0; k < size; ++k) { |
| 70 | out[k] = 0; |
| 71 | for (int n = 0; n < size; ++n) { |
| 72 | out[k] += in[n] * cos(M_PI * (2 * n + 1) * k / (2 * size)); |
| 73 | } |
| 74 | if (k == 0) out[k] = out[k] * invSqrt2; |
| 75 | } |
| 76 | } |
| 77 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 78 | void reference_adst_1d(const double *in, double *out, int size) { |
Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 79 | for (int k = 0; k < size; ++k) { |
| 80 | out[k] = 0; |
| 81 | for (int n = 0; n < size; ++n) { |
| 82 | out[k] += in[n] * sin(M_PI * (2 * n + 1) * (2 * k + 1) / (4 * size)); |
| 83 | } |
| 84 | } |
| 85 | } |
| 86 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 87 | void reference_hybrid_1d(double *in, double *out, int size, int type) { |
Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 88 | if (type == TYPE_DCT) |
| 89 | reference_dct_1d(in, out, size); |
| 90 | else |
| 91 | reference_adst_1d(in, out, size); |
| 92 | } |
| 93 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 94 | void reference_hybrid_2d(double *in, double *out, int size, int type0, |
| 95 | int type1) { |
| 96 | double *tempOut = new double[size * size]; |
Angie Chiang | 716f1bd | 2016-05-11 16:41:36 -0700 | [diff] [blame] | 97 | |
| 98 | for (int r = 0; r < size; r++) { |
| 99 | // out ->tempOut |
| 100 | for (int c = 0; c < size; c++) { |
| 101 | tempOut[r * size + c] = in[c * size + r]; |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | // dct each row: in -> out |
| 106 | for (int r = 0; r < size; r++) { |
| 107 | reference_hybrid_1d(tempOut + r * size, out + r * size, size, type0); |
| 108 | } |
| 109 | |
| 110 | for (int r = 0; r < size; r++) { |
| 111 | // out ->tempOut |
| 112 | for (int c = 0; c < size; c++) { |
| 113 | tempOut[r * size + c] = out[c * size + r]; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | for (int r = 0; r < size; r++) { |
| 118 | reference_hybrid_1d(tempOut + r * size, out + r * size, size, type1); |
| 119 | } |
| 120 | delete[] tempOut; |
| 121 | } |
Angie Chiang | 6a75253 | 2016-05-11 18:50:47 -0700 | [diff] [blame] | 122 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 123 | template <typename Type> |
Angie Chiang | 6a75253 | 2016-05-11 18:50:47 -0700 | [diff] [blame] | 124 | void fliplr(Type *dest, int stride, int length) { |
| 125 | int i, j; |
| 126 | for (i = 0; i < length; ++i) { |
| 127 | for (j = 0; j < length / 2; ++j) { |
| 128 | const Type tmp = dest[i * stride + j]; |
| 129 | dest[i * stride + j] = dest[i * stride + length - 1 - j]; |
| 130 | dest[i * stride + length - 1 - j] = tmp; |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 135 | template <typename Type> |
Angie Chiang | 6a75253 | 2016-05-11 18:50:47 -0700 | [diff] [blame] | 136 | void flipud(Type *dest, int stride, int length) { |
| 137 | int i, j; |
| 138 | for (j = 0; j < length; ++j) { |
| 139 | for (i = 0; i < length / 2; ++i) { |
| 140 | const Type tmp = dest[i * stride + j]; |
| 141 | dest[i * stride + j] = dest[(length - 1 - i) * stride + j]; |
| 142 | dest[(length - 1 - i) * stride + j] = tmp; |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 147 | template <typename Type> |
Angie Chiang | 6a75253 | 2016-05-11 18:50:47 -0700 | [diff] [blame] | 148 | void fliplrud(Type *dest, int stride, int length) { |
| 149 | int i, j; |
| 150 | for (i = 0; i < length / 2; ++i) { |
| 151 | for (j = 0; j < length; ++j) { |
| 152 | const Type tmp = dest[i * stride + j]; |
| 153 | dest[i * stride + j] = dest[(length - 1 - i) * stride + length - 1 - j]; |
| 154 | dest[(length - 1 - i) * stride + length - 1 - j] = tmp; |
| 155 | } |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | template void fliplr<double>(double *dest, int stride, int length); |
| 160 | template void flipud<double>(double *dest, int stride, int length); |
| 161 | template void fliplrud<double>(double *dest, int stride, int length); |
| 162 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 163 | } // namespace libaom_test |