vp10_fwd_txfm2d.c 6.31 KB
Newer Older
Angie Chiang's avatar
Angie Chiang committed
1
/*
2
 *  Copyright (c) 2016 The WebM project authors. All Rights Reserved.
Angie Chiang's avatar
Angie Chiang committed
3
4
5
6
7
8
9
10
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

11
12
13
#include <assert.h>

#include "vp10/common/enums.h"
14
#include "vp10/common/vp10_fwd_txfm1d.h"
15
16
#include "vp10/common/vp10_fwd_txfm2d_cfg.h"
#include "vp10/common/vp10_txfm.h"
Angie Chiang's avatar
Angie Chiang committed
17

Yaowu Xu's avatar
Yaowu Xu committed
18
static INLINE TxfmFunc fwd_txfm_type_to_func(TXFM_TYPE txfm_type) {
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  switch (txfm_type) {
    case TXFM_TYPE_DCT4:
      return vp10_fdct4_new;
      break;
    case TXFM_TYPE_DCT8:
      return vp10_fdct8_new;
      break;
    case TXFM_TYPE_DCT16:
      return vp10_fdct16_new;
      break;
    case TXFM_TYPE_DCT32:
      return vp10_fdct32_new;
      break;
    case TXFM_TYPE_DCT64:
      return vp10_fdct64_new;
      break;
    case TXFM_TYPE_ADST4:
      return vp10_fadst4_new;
      break;
    case TXFM_TYPE_ADST8:
      return vp10_fadst8_new;
      break;
    case TXFM_TYPE_ADST16:
      return vp10_fadst16_new;
      break;
    case TXFM_TYPE_ADST32:
      return vp10_fadst32_new;
      break;
    default:
      assert(0);
      return NULL;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
53
static INLINE void fwd_txfm2d_c(const int16_t *input, int32_t *output,
Angie Chiang's avatar
Angie Chiang committed
54
                                const int stride, const TXFM_2D_CFG *cfg,
55
                                int32_t *buf) {
Angie Chiang's avatar
Angie Chiang committed
56
57
58
59
60
61
62
  int i, j;
  const int txfm_size = cfg->txfm_size;
  const int8_t *shift = cfg->shift;
  const int8_t *stage_range_col = cfg->stage_range_col;
  const int8_t *stage_range_row = cfg->stage_range_row;
  const int8_t *cos_bit_col = cfg->cos_bit_col;
  const int8_t *cos_bit_row = cfg->cos_bit_row;
63
64
  const TxfmFunc txfm_func_col = fwd_txfm_type_to_func(cfg->txfm_type_col);
  const TxfmFunc txfm_func_row = fwd_txfm_type_to_func(cfg->txfm_type_row);
Angie Chiang's avatar
Angie Chiang committed
65

66
67
68
  // use output buffer as temp buffer
  int32_t* temp_in = output;
  int32_t* temp_out = output + txfm_size;
Angie Chiang's avatar
Angie Chiang committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82

  // Columns
  for (i = 0; i < txfm_size; ++i) {
    for (j = 0; j < txfm_size; ++j)
      temp_in[j] = input[j * stride + i];
    round_shift_array(temp_in, txfm_size, -shift[0]);
    txfm_func_col(temp_in, temp_out, cos_bit_col, stage_range_col);
    round_shift_array(temp_out, txfm_size, -shift[1]);
    for (j = 0; j < txfm_size; ++j)
      buf[j * txfm_size + i] = temp_out[j];
  }

  // Rows
  for (i = 0; i < txfm_size; ++i) {
83
84
85
    txfm_func_row(buf + i * txfm_size, output + i * txfm_size, cos_bit_row,
                  stage_range_row);
    round_shift_array(output + i * txfm_size, txfm_size, -shift[2]);
Angie Chiang's avatar
Angie Chiang committed
86
87
88
  }
}

89
void vp10_fwd_txfm2d_4x4_c(const int16_t *input, int32_t *output,
90
                         const int stride, int tx_type,
Angie Chiang's avatar
Angie Chiang committed
91
                         const int bd) {
92
  int32_t txfm_buf[4 * 4];
93
  const TXFM_2D_CFG* cfg = vp10_get_txfm_4x4_cfg(tx_type);
Angie Chiang's avatar
Angie Chiang committed
94
95
96
  (void)bd;
  fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
}
97

98
void vp10_fwd_txfm2d_8x8_c(const int16_t *input, int32_t *output,
99
                         const int stride, int tx_type,
100
                         const int bd) {
101
  int32_t txfm_buf[8 * 8];
102
  const TXFM_2D_CFG* cfg = vp10_get_txfm_8x8_cfg(tx_type);
103
104
105
106
  (void)bd;
  fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
}

107
void vp10_fwd_txfm2d_16x16_c(const int16_t *input, int32_t *output,
108
                           const int stride, int tx_type,
109
                           const int bd) {
110
  int32_t txfm_buf[16 * 16];
111
  const TXFM_2D_CFG* cfg = vp10_get_txfm_16x16_cfg(tx_type);
112
113
114
115
  (void)bd;
  fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
}

116
void vp10_fwd_txfm2d_32x32_c(const int16_t *input, int32_t *output,
117
                           const int stride, int tx_type,
118
                           const int bd) {
119
  int32_t txfm_buf[32 * 32];
120
  const TXFM_2D_CFG* cfg = vp10_get_txfm_32x32_cfg(tx_type);
121
122
123
  (void)bd;
  fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
}
Angie Chiang's avatar
Angie Chiang committed
124

125
void vp10_fwd_txfm2d_64x64_c(const int16_t *input, int32_t *output,
126
                           const int stride, int tx_type,
Angie Chiang's avatar
Angie Chiang committed
127
                           const int bd) {
128
  int32_t txfm_buf[64 * 64];
129
  const TXFM_2D_CFG* cfg = vp10_get_txfm_64x64_cfg(tx_type);
Angie Chiang's avatar
Angie Chiang committed
130
131
132
  (void)bd;
  fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
}
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

const TXFM_2D_CFG* vp10_get_txfm_4x4_cfg(int tx_type) {
  const TXFM_2D_CFG* cfg = NULL;
  switch (tx_type) {
    case DCT_DCT:
      cfg = &fwd_txfm_2d_cfg_dct_dct_4;
      break;
    case ADST_DCT:
      cfg = &fwd_txfm_2d_cfg_adst_dct_4;
      break;
    case DCT_ADST:
      cfg = &fwd_txfm_2d_cfg_dct_adst_4;
      break;
    case ADST_ADST:
      cfg = &fwd_txfm_2d_cfg_adst_adst_4;
      break;
    default:
      assert(0);
  }
  return cfg;
}

const TXFM_2D_CFG* vp10_get_txfm_8x8_cfg(int tx_type) {
  const TXFM_2D_CFG* cfg = NULL;
  switch (tx_type) {
    case DCT_DCT:
      cfg = &fwd_txfm_2d_cfg_dct_dct_8;
      break;
    case ADST_DCT:
      cfg = &fwd_txfm_2d_cfg_adst_dct_8;
      break;
    case DCT_ADST:
      cfg = &fwd_txfm_2d_cfg_dct_adst_8;
      break;
    case ADST_ADST:
      cfg = &fwd_txfm_2d_cfg_adst_adst_8;
      break;
    default:
      assert(0);
  }
  return cfg;
}

const TXFM_2D_CFG* vp10_get_txfm_16x16_cfg(int tx_type) {
  const TXFM_2D_CFG* cfg = NULL;
  switch (tx_type) {
    case DCT_DCT:
      cfg = &fwd_txfm_2d_cfg_dct_dct_16;
      break;
    case ADST_DCT:
      cfg = &fwd_txfm_2d_cfg_adst_dct_16;
      break;
    case DCT_ADST:
      cfg = &fwd_txfm_2d_cfg_dct_adst_16;
      break;
    case ADST_ADST:
      cfg = &fwd_txfm_2d_cfg_adst_adst_16;
      break;
    default:
      assert(0);
  }
  return cfg;
}

const TXFM_2D_CFG* vp10_get_txfm_32x32_cfg(int tx_type) {
  const TXFM_2D_CFG* cfg = NULL;
  switch (tx_type) {
    case DCT_DCT:
      cfg = &fwd_txfm_2d_cfg_dct_dct_32;
      break;
    case ADST_DCT:
      cfg = &fwd_txfm_2d_cfg_adst_dct_32;
      break;
    case DCT_ADST:
      cfg = &fwd_txfm_2d_cfg_dct_adst_32;
      break;
    case ADST_ADST:
      cfg = &fwd_txfm_2d_cfg_adst_adst_32;
      break;
    default:
      assert(0);
  }
  return cfg;
}

const TXFM_2D_CFG* vp10_get_txfm_64x64_cfg(int tx_type) {
  const TXFM_2D_CFG* cfg = NULL;
  switch (tx_type) {
    case DCT_DCT:
      cfg = &fwd_txfm_2d_cfg_dct_dct_64;
      break;
    case ADST_DCT:
    case DCT_ADST:
    case ADST_ADST:
    default:
      assert(0);
  }
  return cfg;
}