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