tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

av1_fwd_txfm2d.c (17737B)


      1 /*
      2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
      3 *
      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.
     10 */
     11 
     12 #include <assert.h>
     13 
     14 #include "config/aom_dsp_rtcd.h"
     15 #include "config/av1_rtcd.h"
     16 
     17 #include "aom_dsp/txfm_common.h"
     18 #include "av1/common/enums.h"
     19 #include "av1/common/av1_txfm.h"
     20 #include "av1/encoder/av1_fwd_txfm1d.h"
     21 #include "av1/encoder/av1_fwd_txfm1d_cfg.h"
     22 
     23 static inline TxfmFunc fwd_txfm_type_to_func(TXFM_TYPE txfm_type) {
     24  switch (txfm_type) {
     25    case TXFM_TYPE_DCT4: return av1_fdct4;
     26    case TXFM_TYPE_DCT8: return av1_fdct8;
     27    case TXFM_TYPE_DCT16: return av1_fdct16;
     28    case TXFM_TYPE_DCT32: return av1_fdct32;
     29    case TXFM_TYPE_DCT64: return av1_fdct64;
     30    case TXFM_TYPE_ADST4: return av1_fadst4;
     31    case TXFM_TYPE_ADST8: return av1_fadst8;
     32    case TXFM_TYPE_ADST16: return av1_fadst16;
     33    case TXFM_TYPE_IDENTITY4: return av1_fidentity4_c;
     34    case TXFM_TYPE_IDENTITY8: return av1_fidentity8_c;
     35    case TXFM_TYPE_IDENTITY16: return av1_fidentity16_c;
     36    case TXFM_TYPE_IDENTITY32: return av1_fidentity32_c;
     37    default: assert(0); return NULL;
     38  }
     39 }
     40 
     41 void av1_gen_fwd_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
     42                             const TXFM_2D_FLIP_CFG *cfg, int bd) {
     43  // Take the shift from the larger dimension in the rectangular case.
     44  const int8_t *shift = cfg->shift;
     45  // i < MAX_TXFM_STAGE_NUM will mute above array bounds warning
     46  for (int i = 0; i < cfg->stage_num_col && i < MAX_TXFM_STAGE_NUM; ++i) {
     47    stage_range_col[i] = cfg->stage_range_col[i] + shift[0] + bd + 1;
     48  }
     49 
     50  // i < MAX_TXFM_STAGE_NUM will mute above array bounds warning
     51  for (int i = 0; i < cfg->stage_num_row && i < MAX_TXFM_STAGE_NUM; ++i) {
     52    stage_range_row[i] = cfg->stage_range_row[i] + shift[0] + shift[1] + bd + 1;
     53  }
     54 }
     55 
     56 static inline void fwd_txfm2d_c(const int16_t *input, int32_t *output,
     57                                const int stride, const TXFM_2D_FLIP_CFG *cfg,
     58                                int32_t *buf, int bd) {
     59  int c, r;
     60  // Note when assigning txfm_size_col, we use the txfm_size from the
     61  // row configuration and vice versa. This is intentionally done to
     62  // accurately perform rectangular transforms. When the transform is
     63  // rectangular, the number of columns will be the same as the
     64  // txfm_size stored in the row cfg struct. It will make no difference
     65  // for square transforms.
     66  const int txfm_size_col = tx_size_wide[cfg->tx_size];
     67  const int txfm_size_row = tx_size_high[cfg->tx_size];
     68  // Take the shift from the larger dimension in the rectangular case.
     69  const int8_t *shift = cfg->shift;
     70  const int rect_type = get_rect_tx_log_ratio(txfm_size_col, txfm_size_row);
     71  int8_t stage_range_col[MAX_TXFM_STAGE_NUM];
     72  int8_t stage_range_row[MAX_TXFM_STAGE_NUM];
     73  assert(cfg->stage_num_col <= MAX_TXFM_STAGE_NUM);
     74  assert(cfg->stage_num_row <= MAX_TXFM_STAGE_NUM);
     75  av1_gen_fwd_stage_range(stage_range_col, stage_range_row, cfg, bd);
     76 
     77  const int8_t cos_bit_col = cfg->cos_bit_col;
     78  const int8_t cos_bit_row = cfg->cos_bit_row;
     79  const TxfmFunc txfm_func_col = fwd_txfm_type_to_func(cfg->txfm_type_col);
     80  const TxfmFunc txfm_func_row = fwd_txfm_type_to_func(cfg->txfm_type_row);
     81 
     82  // use output buffer as temp buffer
     83  int32_t *temp_in = output;
     84  int32_t *temp_out = output + txfm_size_row;
     85 
     86  // Columns
     87  for (c = 0; c < txfm_size_col; ++c) {
     88    if (cfg->ud_flip == 0) {
     89      for (r = 0; r < txfm_size_row; ++r) temp_in[r] = input[r * stride + c];
     90    } else {
     91      for (r = 0; r < txfm_size_row; ++r)
     92        // flip upside down
     93        temp_in[r] = input[(txfm_size_row - r - 1) * stride + c];
     94    }
     95    av1_round_shift_array(temp_in, txfm_size_row, -shift[0]);
     96    txfm_func_col(temp_in, temp_out, cos_bit_col, stage_range_col);
     97    av1_round_shift_array(temp_out, txfm_size_row, -shift[1]);
     98    if (cfg->lr_flip == 0) {
     99      for (r = 0; r < txfm_size_row; ++r)
    100        buf[r * txfm_size_col + c] = temp_out[r];
    101    } else {
    102      for (r = 0; r < txfm_size_row; ++r)
    103        // flip from left to right
    104        buf[r * txfm_size_col + (txfm_size_col - c - 1)] = temp_out[r];
    105    }
    106  }
    107 
    108  DECLARE_ALIGNED(16, int32_t, row_buffer[MAX_TX_SIZE]);
    109 
    110  // Rows
    111  for (r = 0; r < txfm_size_row; ++r) {
    112    txfm_func_row(buf + r * txfm_size_col, row_buffer, cos_bit_row,
    113                  stage_range_row);
    114    av1_round_shift_array(row_buffer, txfm_size_col, -shift[2]);
    115    if (abs(rect_type) == 1) {
    116      // Multiply everything by Sqrt2 if the transform is rectangular and the
    117      // size difference is a factor of 2.
    118      for (c = 0; c < txfm_size_col; ++c) {
    119        row_buffer[c] =
    120            round_shift((int64_t)row_buffer[c] * NewSqrt2, NewSqrt2Bits);
    121      }
    122    }
    123    for (c = 0; c < txfm_size_col; ++c) {
    124      output[c * txfm_size_row + r] = row_buffer[c];
    125    }
    126  }
    127 }
    128 
    129 void av1_fwd_txfm2d_4x8_c(const int16_t *input, int32_t *output, int stride,
    130                          TX_TYPE tx_type, int bd) {
    131  DECLARE_ALIGNED(32, int32_t, txfm_buf[4 * 8]);
    132  TXFM_2D_FLIP_CFG cfg;
    133  av1_get_fwd_txfm_cfg(tx_type, TX_4X8, &cfg);
    134  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    135 }
    136 
    137 void av1_fwd_txfm2d_8x4_c(const int16_t *input, int32_t *output, int stride,
    138                          TX_TYPE tx_type, int bd) {
    139  int32_t txfm_buf[8 * 4];
    140  TXFM_2D_FLIP_CFG cfg;
    141  av1_get_fwd_txfm_cfg(tx_type, TX_8X4, &cfg);
    142  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    143 }
    144 
    145 void av1_fwd_txfm2d_8x16_c(const int16_t *input, int32_t *output, int stride,
    146                           TX_TYPE tx_type, int bd) {
    147  DECLARE_ALIGNED(32, int32_t, txfm_buf[8 * 16]);
    148  TXFM_2D_FLIP_CFG cfg;
    149  av1_get_fwd_txfm_cfg(tx_type, TX_8X16, &cfg);
    150  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    151 }
    152 
    153 void av1_fwd_txfm2d_16x8_c(const int16_t *input, int32_t *output, int stride,
    154                           TX_TYPE tx_type, int bd) {
    155  int32_t txfm_buf[16 * 8];
    156  TXFM_2D_FLIP_CFG cfg;
    157  av1_get_fwd_txfm_cfg(tx_type, TX_16X8, &cfg);
    158  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    159 }
    160 
    161 void av1_fwd_txfm2d_16x32_c(const int16_t *input, int32_t *output, int stride,
    162                            TX_TYPE tx_type, int bd) {
    163  DECLARE_ALIGNED(32, int32_t, txfm_buf[16 * 32]);
    164  TXFM_2D_FLIP_CFG cfg;
    165  av1_get_fwd_txfm_cfg(tx_type, TX_16X32, &cfg);
    166  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    167 }
    168 
    169 void av1_fwd_txfm2d_32x16_c(const int16_t *input, int32_t *output, int stride,
    170                            TX_TYPE tx_type, int bd) {
    171  int32_t txfm_buf[32 * 16];
    172  TXFM_2D_FLIP_CFG cfg;
    173  av1_get_fwd_txfm_cfg(tx_type, TX_32X16, &cfg);
    174  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    175 }
    176 
    177 #if !CONFIG_REALTIME_ONLY
    178 void av1_fwd_txfm2d_4x16_c(const int16_t *input, int32_t *output, int stride,
    179                           TX_TYPE tx_type, int bd) {
    180  DECLARE_ALIGNED(32, int32_t, txfm_buf[4 * 16]);
    181  TXFM_2D_FLIP_CFG cfg;
    182  av1_get_fwd_txfm_cfg(tx_type, TX_4X16, &cfg);
    183  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    184 }
    185 #endif  // !CONFIG_REALTIME_ONLY
    186 
    187 void av1_fwd_txfm2d_16x4_c(const int16_t *input, int32_t *output, int stride,
    188                           TX_TYPE tx_type, int bd) {
    189  int32_t txfm_buf[16 * 4];
    190  TXFM_2D_FLIP_CFG cfg;
    191  av1_get_fwd_txfm_cfg(tx_type, TX_16X4, &cfg);
    192  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    193 }
    194 
    195 #if !CONFIG_REALTIME_ONLY
    196 void av1_fwd_txfm2d_8x32_c(const int16_t *input, int32_t *output, int stride,
    197                           TX_TYPE tx_type, int bd) {
    198  DECLARE_ALIGNED(32, int32_t, txfm_buf[32 * 8]);
    199  TXFM_2D_FLIP_CFG cfg;
    200  av1_get_fwd_txfm_cfg(tx_type, TX_8X32, &cfg);
    201  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    202 }
    203 
    204 void av1_fwd_txfm2d_32x8_c(const int16_t *input, int32_t *output, int stride,
    205                           TX_TYPE tx_type, int bd) {
    206  int32_t txfm_buf[32 * 8];
    207  TXFM_2D_FLIP_CFG cfg;
    208  av1_get_fwd_txfm_cfg(tx_type, TX_32X8, &cfg);
    209  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    210 }
    211 #endif  // !CONFIG_REALTIME_ONLY
    212 
    213 void av1_fwd_txfm2d_4x4_c(const int16_t *input, int32_t *output, int stride,
    214                          TX_TYPE tx_type, int bd) {
    215  int32_t txfm_buf[4 * 4];
    216  TXFM_2D_FLIP_CFG cfg;
    217  av1_get_fwd_txfm_cfg(tx_type, TX_4X4, &cfg);
    218  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    219 }
    220 
    221 void av1_fwd_txfm2d_8x8_c(const int16_t *input, int32_t *output, int stride,
    222                          TX_TYPE tx_type, int bd) {
    223  int32_t txfm_buf[8 * 8];
    224  TXFM_2D_FLIP_CFG cfg;
    225  av1_get_fwd_txfm_cfg(tx_type, TX_8X8, &cfg);
    226  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    227 }
    228 
    229 void av1_fwd_txfm2d_16x16_c(const int16_t *input, int32_t *output, int stride,
    230                            TX_TYPE tx_type, int bd) {
    231  int32_t txfm_buf[16 * 16];
    232  TXFM_2D_FLIP_CFG cfg;
    233  av1_get_fwd_txfm_cfg(tx_type, TX_16X16, &cfg);
    234  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    235 }
    236 
    237 void av1_fwd_txfm2d_32x32_c(const int16_t *input, int32_t *output, int stride,
    238                            TX_TYPE tx_type, int bd) {
    239  int32_t txfm_buf[32 * 32];
    240  TXFM_2D_FLIP_CFG cfg;
    241  av1_get_fwd_txfm_cfg(tx_type, TX_32X32, &cfg);
    242  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    243 }
    244 
    245 void av1_fwd_txfm2d_64x64_c(const int16_t *input, int32_t *output, int stride,
    246                            TX_TYPE tx_type, int bd) {
    247  int32_t txfm_buf[64 * 64];
    248  TXFM_2D_FLIP_CFG cfg;
    249  av1_get_fwd_txfm_cfg(tx_type, TX_64X64, &cfg);
    250  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    251 
    252  // Zero out top-right 32x32 area.
    253  for (int col = 0; col < 32; ++col) {
    254    memset(output + col * 64 + 32, 0, 32 * sizeof(*output));
    255  }
    256  // Zero out the bottom 64x32 area.
    257  memset(output + 32 * 64, 0, 32 * 64 * sizeof(*output));
    258  // Re-pack non-zero coeffs in the first 32x32 indices.
    259  for (int col = 1; col < 32; ++col) {
    260    memcpy(output + col * 32, output + col * 64, 32 * sizeof(*output));
    261  }
    262 }
    263 
    264 void av1_fwd_txfm2d_32x64_c(const int16_t *input, int32_t *output, int stride,
    265                            TX_TYPE tx_type, int bd) {
    266  DECLARE_ALIGNED(32, int32_t, txfm_buf[32 * 64]);
    267  TXFM_2D_FLIP_CFG cfg;
    268  av1_get_fwd_txfm_cfg(tx_type, TX_32X64, &cfg);
    269  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    270  // Zero out right 32x32 area.
    271  for (int col = 0; col < 32; ++col) {
    272    memset(output + col * 64 + 32, 0, 32 * sizeof(*output));
    273  }
    274  // Re-pack non-zero coeffs in the first 32x32 indices.
    275  for (int col = 1; col < 32; ++col) {
    276    memcpy(output + col * 32, output + col * 64, 32 * sizeof(*output));
    277  }
    278 }
    279 
    280 void av1_fwd_txfm2d_64x32_c(const int16_t *input, int32_t *output, int stride,
    281                            TX_TYPE tx_type, int bd) {
    282  int32_t txfm_buf[64 * 32];
    283  TXFM_2D_FLIP_CFG cfg;
    284  av1_get_fwd_txfm_cfg(tx_type, TX_64X32, &cfg);
    285  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    286  // Zero out the bottom 32x32 area.
    287  memset(output + 32 * 32, 0, 32 * 32 * sizeof(*output));
    288  // Note: no repacking needed here.
    289 }
    290 
    291 #if !CONFIG_REALTIME_ONLY
    292 void av1_fwd_txfm2d_16x64_c(const int16_t *input, int32_t *output, int stride,
    293                            TX_TYPE tx_type, int bd) {
    294  DECLARE_ALIGNED(32, int32_t, txfm_buf[64 * 16]);
    295  TXFM_2D_FLIP_CFG cfg;
    296  av1_get_fwd_txfm_cfg(tx_type, TX_16X64, &cfg);
    297  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    298  // Zero out right 32x16 area.
    299  for (int row = 0; row < 16; ++row) {
    300    memset(output + row * 64 + 32, 0, 32 * sizeof(*output));
    301  }
    302  // Re-pack non-zero coeffs in the first 32x16 indices.
    303  for (int row = 1; row < 16; ++row) {
    304    memcpy(output + row * 32, output + row * 64, 32 * sizeof(*output));
    305  }
    306 }
    307 
    308 void av1_fwd_txfm2d_64x16_c(const int16_t *input, int32_t *output, int stride,
    309                            TX_TYPE tx_type, int bd) {
    310  int32_t txfm_buf[64 * 16];
    311  TXFM_2D_FLIP_CFG cfg;
    312  av1_get_fwd_txfm_cfg(tx_type, TX_64X16, &cfg);
    313  fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
    314  // Zero out the bottom 16x32 area.
    315  memset(output + 16 * 32, 0, 16 * 32 * sizeof(*output));
    316  // Note: no repacking needed here.
    317 }
    318 #endif  // !CONFIG_REALTIME_ONLY
    319 
    320 static const int8_t fwd_shift_4x4[3] = { 2, 0, 0 };
    321 static const int8_t fwd_shift_8x8[3] = { 2, -1, 0 };
    322 static const int8_t fwd_shift_16x16[3] = { 2, -2, 0 };
    323 static const int8_t fwd_shift_32x32[3] = { 2, -4, 0 };
    324 static const int8_t fwd_shift_64x64[3] = { 0, -2, -2 };
    325 static const int8_t fwd_shift_4x8[3] = { 2, -1, 0 };
    326 static const int8_t fwd_shift_8x4[3] = { 2, -1, 0 };
    327 static const int8_t fwd_shift_8x16[3] = { 2, -2, 0 };
    328 static const int8_t fwd_shift_16x8[3] = { 2, -2, 0 };
    329 static const int8_t fwd_shift_16x32[3] = { 2, -4, 0 };
    330 static const int8_t fwd_shift_32x16[3] = { 2, -4, 0 };
    331 static const int8_t fwd_shift_32x64[3] = { 0, -2, -2 };
    332 static const int8_t fwd_shift_64x32[3] = { 2, -4, -2 };
    333 static const int8_t fwd_shift_4x16[3] = { 2, -1, 0 };
    334 static const int8_t fwd_shift_16x4[3] = { 2, -1, 0 };
    335 static const int8_t fwd_shift_8x32[3] = { 2, -2, 0 };
    336 static const int8_t fwd_shift_32x8[3] = { 2, -2, 0 };
    337 static const int8_t fwd_shift_16x64[3] = { 0, -2, 0 };
    338 static const int8_t fwd_shift_64x16[3] = { 2, -4, 0 };
    339 
    340 const int8_t *av1_fwd_txfm_shift_ls[TX_SIZES_ALL] = {
    341  fwd_shift_4x4,   fwd_shift_8x8,   fwd_shift_16x16, fwd_shift_32x32,
    342  fwd_shift_64x64, fwd_shift_4x8,   fwd_shift_8x4,   fwd_shift_8x16,
    343  fwd_shift_16x8,  fwd_shift_16x32, fwd_shift_32x16, fwd_shift_32x64,
    344  fwd_shift_64x32, fwd_shift_4x16,  fwd_shift_16x4,  fwd_shift_8x32,
    345  fwd_shift_32x8,  fwd_shift_16x64, fwd_shift_64x16,
    346 };
    347 
    348 const int8_t av1_fwd_cos_bit_col[MAX_TXWH_IDX /*txw_idx*/]
    349                                [MAX_TXWH_IDX /*txh_idx*/] = {
    350                                  { 13, 13, 13, 0, 0 },
    351                                  { 13, 13, 13, 12, 0 },
    352                                  { 13, 13, 13, 12, 13 },
    353                                  { 0, 13, 13, 12, 13 },
    354                                  { 0, 0, 13, 12, 13 }
    355                                };
    356 
    357 const int8_t av1_fwd_cos_bit_row[MAX_TXWH_IDX /*txw_idx*/]
    358                                [MAX_TXWH_IDX /*txh_idx*/] = {
    359                                  { 13, 13, 12, 0, 0 },
    360                                  { 13, 13, 13, 12, 0 },
    361                                  { 13, 13, 12, 13, 12 },
    362                                  { 0, 12, 13, 12, 11 },
    363                                  { 0, 0, 12, 11, 10 }
    364                                };
    365 
    366 static const int8_t fdct4_range_mult2[4] = { 0, 2, 3, 3 };
    367 static const int8_t fdct8_range_mult2[6] = { 0, 2, 4, 5, 5, 5 };
    368 static const int8_t fdct16_range_mult2[8] = { 0, 2, 4, 6, 7, 7, 7, 7 };
    369 static const int8_t fdct32_range_mult2[10] = { 0, 2, 4, 6, 8, 9, 9, 9, 9, 9 };
    370 static const int8_t fdct64_range_mult2[12] = { 0,  2,  4,  6,  8,  10,
    371                                               11, 11, 11, 11, 11, 11 };
    372 
    373 static const int8_t fadst4_range_mult2[7] = { 0, 2, 4, 3, 3, 3, 3 };
    374 static const int8_t fadst8_range_mult2[8] = { 0, 0, 1, 3, 3, 5, 5, 5 };
    375 static const int8_t fadst16_range_mult2[10] = { 0, 0, 1, 3, 3, 5, 5, 7, 7, 7 };
    376 
    377 static const int8_t fidtx4_range_mult2[1] = { 1 };
    378 static const int8_t fidtx8_range_mult2[1] = { 2 };
    379 static const int8_t fidtx16_range_mult2[1] = { 3 };
    380 static const int8_t fidtx32_range_mult2[1] = { 4 };
    381 
    382 static const int8_t *fwd_txfm_range_mult2_list[TXFM_TYPES] = {
    383  fdct4_range_mult2,  fdct8_range_mult2,   fdct16_range_mult2,
    384  fdct32_range_mult2, fdct64_range_mult2,  fadst4_range_mult2,
    385  fadst8_range_mult2, fadst16_range_mult2, fidtx4_range_mult2,
    386  fidtx8_range_mult2, fidtx16_range_mult2, fidtx32_range_mult2
    387 };
    388 
    389 static inline void set_fwd_txfm_non_scale_range(TXFM_2D_FLIP_CFG *cfg) {
    390  av1_zero(cfg->stage_range_col);
    391  av1_zero(cfg->stage_range_row);
    392 
    393  const int8_t *const range_mult2_col =
    394      fwd_txfm_range_mult2_list[cfg->txfm_type_col];
    395  const int stage_num_col = cfg->stage_num_col;
    396  // i < MAX_TXFM_STAGE_NUM will quiet -Wstringop-overflow.
    397  for (int i = 0; i < stage_num_col && i < MAX_TXFM_STAGE_NUM; ++i)
    398    cfg->stage_range_col[i] = (range_mult2_col[i] + 1) >> 1;
    399 
    400  const int8_t *const range_mult2_row =
    401      fwd_txfm_range_mult2_list[cfg->txfm_type_row];
    402  const int stage_num_row = cfg->stage_num_row;
    403  // i < MAX_TXFM_STAGE_NUM will quiet -Wstringop-overflow.
    404  for (int i = 0; i < stage_num_row && i < MAX_TXFM_STAGE_NUM; ++i) {
    405    cfg->stage_range_row[i] =
    406        (range_mult2_col[stage_num_col - 1] + range_mult2_row[i] + 1) >> 1;
    407  }
    408 }
    409 
    410 void av1_get_fwd_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
    411                          TXFM_2D_FLIP_CFG *cfg) {
    412  assert(cfg != NULL);
    413  cfg->tx_size = tx_size;
    414  set_flip_cfg(tx_type, cfg);
    415  const TX_TYPE_1D tx_type_1d_col = vtx_tab[tx_type];
    416  const TX_TYPE_1D tx_type_1d_row = htx_tab[tx_type];
    417  const int txw_idx = get_txw_idx(tx_size);
    418  const int txh_idx = get_txh_idx(tx_size);
    419  cfg->shift = av1_fwd_txfm_shift_ls[tx_size];
    420  cfg->cos_bit_col = av1_fwd_cos_bit_col[txw_idx][txh_idx];
    421  cfg->cos_bit_row = av1_fwd_cos_bit_row[txw_idx][txh_idx];
    422  cfg->txfm_type_col = av1_txfm_type_ls[txh_idx][tx_type_1d_col];
    423  assert(cfg->txfm_type_col != TXFM_TYPE_INVALID);
    424  cfg->txfm_type_row = av1_txfm_type_ls[txw_idx][tx_type_1d_row];
    425  assert(cfg->txfm_type_row != TXFM_TYPE_INVALID);
    426  cfg->stage_num_col = av1_txfm_stage_num_list[cfg->txfm_type_col];
    427  cfg->stage_num_row = av1_txfm_stage_num_list[cfg->txfm_type_row];
    428  set_fwd_txfm_non_scale_range(cfg);
    429 }