idct.c 83.7 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10 11 12 13
 */

#include <math.h>

Yaowu Xu's avatar
Yaowu Xu committed
14
#include "./aom_dsp_rtcd.h"
Geza Lore's avatar
Geza Lore committed
15 16 17
#include "./av1_rtcd.h"
#include "aom_dsp/inv_txfm.h"
#include "aom_ports/mem.h"
18
#include "av1/common/av1_inv_txfm1d_cfg.h"
19 20 21
#include "av1/common/blockd.h"
#include "av1/common/enums.h"
#include "av1/common/idct.h"
22 23 24 25
#if CONFIG_DAALA_DCT4 || CONFIG_DAALA_DCT8 || CONFIG_DAALA_DCT16 || \
    CONFIG_DAALA_DCT32 || CONFIG_DAALA_DCT64
#include "av1/common/daala_tx.h"
#endif
Jingning Han's avatar
Jingning Han committed
26

27
int av1_get_tx_scale(const TX_SIZE tx_size) {
28 29
  const int pels = tx_size_2d[tx_size];
  return (pels > 256) + (pels > 1024) + (pels > 4096);
30 31
}

32 33 34
// NOTE: The implementation of all inverses need to be aware of the fact
// that input and output could be the same buffer.

35
#if CONFIG_EXT_TX
Debargha Mukherjee's avatar
Debargha Mukherjee committed
36 37
static void iidtx4_c(const tran_low_t *input, tran_low_t *output) {
  int i;
38
  for (i = 0; i < 4; ++i) {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
39
    output[i] = (tran_low_t)dct_const_round_shift(input[i] * Sqrt2);
40
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
41 42 43 44
}

static void iidtx8_c(const tran_low_t *input, tran_low_t *output) {
  int i;
45 46 47
  for (i = 0; i < 8; ++i) {
    output[i] = input[i] * 2;
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
48 49 50 51
}

static void iidtx16_c(const tran_low_t *input, tran_low_t *output) {
  int i;
52
  for (i = 0; i < 16; ++i) {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
53
    output[i] = (tran_low_t)dct_const_round_shift(input[i] * 2 * Sqrt2);
54
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
55 56 57 58
}

static void iidtx32_c(const tran_low_t *input, tran_low_t *output) {
  int i;
59 60 61
  for (i = 0; i < 32; ++i) {
    output[i] = input[i] * 4;
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
62
}
63

64
#if CONFIG_TX64X64 && !CONFIG_DAALA_DCT64
65 66
static void iidtx64_c(const tran_low_t *input, tran_low_t *output) {
  int i;
67
  for (i = 0; i < 64; ++i) {
68
    output[i] = (tran_low_t)dct_const_round_shift(input[i] * 4 * Sqrt2);
69
  }
70 71
}
#endif  // CONFIG_TX64X64
72
#endif  // CONFIG_EXT_TX
Debargha Mukherjee's avatar
Debargha Mukherjee committed
73

74
// For use in lieu of ADST
75 76 77 78 79 80 81
static void ihalfright32_c(const tran_low_t *input, tran_low_t *output) {
  int i;
  tran_low_t inputhalf[16];
  // Multiply input by sqrt(2)
  for (i = 0; i < 16; ++i) {
    inputhalf[i] = (tran_low_t)dct_const_round_shift(input[i] * Sqrt2);
  }
82 83 84
  for (i = 0; i < 16; ++i) {
    output[i] = input[16 + i] * 4;
  }
Luca Barbato's avatar
Luca Barbato committed
85
  aom_idct16_c(inputhalf, output + 16);
86 87 88
  // Note overall scaling factor is 4 times orthogonal
}

89
#if CONFIG_TX64X64 && !CONFIG_DAALA_DCT64
90 91 92 93
static void idct64_col_c(const tran_low_t *input, tran_low_t *output) {
  int32_t in[64], out[64];
  int i;
  for (i = 0; i < 64; ++i) in[i] = (int32_t)input[i];
94
  av1_idct64_new(in, out, inv_cos_bit_col_dct_64, inv_stage_range_col_dct_64);
95 96 97 98 99 100 101
  for (i = 0; i < 64; ++i) output[i] = (tran_low_t)out[i];
}

static void idct64_row_c(const tran_low_t *input, tran_low_t *output) {
  int32_t in[64], out[64];
  int i;
  for (i = 0; i < 64; ++i) in[i] = (int32_t)input[i];
102
  av1_idct64_new(in, out, inv_cos_bit_row_dct_64, inv_stage_range_row_dct_64);
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
  for (i = 0; i < 64; ++i) output[i] = (tran_low_t)out[i];
}

// For use in lieu of ADST
static void ihalfright64_c(const tran_low_t *input, tran_low_t *output) {
  int i;
  tran_low_t inputhalf[32];
  // Multiply input by sqrt(2)
  for (i = 0; i < 32; ++i) {
    inputhalf[i] = (tran_low_t)dct_const_round_shift(input[i] * Sqrt2);
  }
  for (i = 0; i < 32; ++i) {
    output[i] = (tran_low_t)dct_const_round_shift(input[32 + i] * 4 * Sqrt2);
  }
  aom_idct32_c(inputhalf, output + 32);
  // Note overall scaling factor is 4 * sqrt(2)  times orthogonal
}
#endif  // CONFIG_TX64X64

Jingning Han's avatar
Jingning Han committed
122
// Inverse identity transform and add.
123
#if CONFIG_EXT_TX
124
static void inv_idtx_add_c(const tran_low_t *input, uint8_t *dest, int stride,
125
                           int bsx, int bsy, int tx_type) {
126
  int r, c;
127 128
  const int pels = bsx * bsy;
  const int shift = 3 - ((pels > 256) + (pels > 1024));
Debargha Mukherjee's avatar
Debargha Mukherjee committed
129
  if (tx_type == IDTX) {
130 131
    for (r = 0; r < bsy; ++r) {
      for (c = 0; c < bsx; ++c)
Debargha Mukherjee's avatar
Debargha Mukherjee committed
132 133
        dest[c] = clip_pixel_add(dest[c], input[c] >> shift);
      dest += stride;
134
      input += bsx;
Jingning Han's avatar
Jingning Han committed
135
    }
136 137
  }
}
138
#endif  // CONFIG_EXT_TX
139

clang-format's avatar
clang-format committed
140 141 142 143 144
#define FLIPUD_PTR(dest, stride, size)       \
  do {                                       \
    (dest) = (dest) + ((size)-1) * (stride); \
    (stride) = -(stride);                    \
  } while (0)
145

146
#if CONFIG_EXT_TX
clang-format's avatar
clang-format committed
147 148 149
static void maybe_flip_strides(uint8_t **dst, int *dstride, tran_low_t **src,
                               int *sstride, int tx_type, int sizey,
                               int sizex) {
150 151 152 153 154 155 156 157
  // Note that the transpose of src will be added to dst. In order to LR
  // flip the addends (in dst coordinates), we UD flip the src. To UD flip
  // the addends, we UD flip the dst.
  switch (tx_type) {
    case DCT_DCT:
    case ADST_DCT:
    case DCT_ADST:
    case ADST_ADST:
Debargha Mukherjee's avatar
Debargha Mukherjee committed
158
    case IDTX:
Jingning Han's avatar
Jingning Han committed
159 160
    case V_DCT:
    case H_DCT:
161
    case V_ADST:
clang-format's avatar
clang-format committed
162
    case H_ADST: break;
163 164
    case FLIPADST_DCT:
    case FLIPADST_ADST:
165
    case V_FLIPADST:
166
      // flip UD
167
      FLIPUD_PTR(*dst, *dstride, sizey);
168 169 170
      break;
    case DCT_FLIPADST:
    case ADST_FLIPADST:
171
    case H_FLIPADST:
172
      // flip LR
173
      FLIPUD_PTR(*src, *sstride, sizex);
174 175 176
      break;
    case FLIPADST_FLIPADST:
      // flip UD
177
      FLIPUD_PTR(*dst, *dstride, sizey);
178
      // flip LR
179
      FLIPUD_PTR(*src, *sstride, sizex);
180
      break;
clang-format's avatar
clang-format committed
181
    default: assert(0); break;
182 183
  }
}
184
#endif  // CONFIG_EXT_TX
185

186
#if CONFIG_HIGHBITDEPTH
187
#if CONFIG_EXT_TX && CONFIG_TX64X64
188
static void highbd_inv_idtx_add_c(const tran_low_t *input, uint8_t *dest8,
189 190
                                  int stride, int bsx, int bsy, int tx_type,
                                  int bd) {
191
  int r, c;
192 193
  const int pels = bsx * bsy;
  const int shift = 3 - ((pels > 256) + (pels > 1024));
194
  uint16_t *dest = CONVERT_TO_SHORTPTR(dest8);
195

Debargha Mukherjee's avatar
Debargha Mukherjee committed
196
  if (tx_type == IDTX) {
197 198
    for (r = 0; r < bsy; ++r) {
      for (c = 0; c < bsx; ++c)
Debargha Mukherjee's avatar
Debargha Mukherjee committed
199 200
        dest[c] = highbd_clip_pixel_add(dest[c], input[c] >> shift, bd);
      dest += stride;
201
      input += bsx;
202
    }
203 204
  }
}
205
#endif  // CONFIG_EXT_TX && CONFIG_TX64X64
206
#endif  // CONFIG_HIGHBITDEPTH
207

Lester Lu's avatar
Lester Lu committed
208 209 210
#if CONFIG_LGT
void ilgt4(const tran_low_t *input, tran_low_t *output,
           const tran_high_t *lgtmtx) {
Lester Lu's avatar
Lester Lu committed
211 212
  if (!lgtmtx) assert(0);
  // evaluate s[j] = sum of all lgtmtx[j]*input[i] over i=1,...,4
Lester Lu's avatar
Lester Lu committed
213 214 215 216 217 218 219 220 221
  tran_high_t s[4] = { 0 };
  for (int i = 0; i < 4; ++i)
    for (int j = 0; j < 4; ++j) s[j] += lgtmtx[i * 4 + j] * input[i];

  for (int i = 0; i < 4; ++i) output[i] = WRAPLOW(dct_const_round_shift(s[i]));
}

void ilgt8(const tran_low_t *input, tran_low_t *output,
           const tran_high_t *lgtmtx) {
Lester Lu's avatar
Lester Lu committed
222 223
  if (!lgtmtx) assert(0);
  // evaluate s[j] = sum of all lgtmtx[j]*input[i] over i=1,...,8
Lester Lu's avatar
Lester Lu committed
224 225 226 227 228 229 230
  tran_high_t s[8] = { 0 };
  for (int i = 0; i < 8; ++i)
    for (int j = 0; j < 8; ++j) s[j] += lgtmtx[i * 8 + j] * input[i];

  for (int i = 0; i < 8; ++i) output[i] = WRAPLOW(dct_const_round_shift(s[i]));
}

Lester Lu's avatar
Lester Lu committed
231 232 233 234 235 236 237 238 239 240 241
// get_lgt4 and get_lgt8 return 1 and pick a lgt matrix if LGT is chosen to
// apply. Otherwise they return 0
int get_lgt4(const TxfmParam *txfm_param, int is_col,
             const tran_high_t **lgtmtx) {
  if (is_col && (vtx_tab[txfm_param->tx_type] == ADST_1D ||
                 vtx_tab[txfm_param->tx_type] == FLIPADST_1D)) {
    lgtmtx[0] = txfm_param->is_inter ? &lgt4_170[0][0] : &lgt4_140[0][0];
    return 1;
  } else if (!is_col && (htx_tab[txfm_param->tx_type] == ADST_1D ||
                         htx_tab[txfm_param->tx_type] == FLIPADST_1D)) {
    lgtmtx[0] = txfm_param->is_inter ? &lgt4_170[0][0] : &lgt4_140[0][0];
Lester Lu's avatar
Lester Lu committed
242 243
    return 1;
  }
Lester Lu's avatar
Lester Lu committed
244
  lgtmtx[0] = NULL;
Lester Lu's avatar
Lester Lu committed
245 246 247
  return 0;
}

Lester Lu's avatar
Lester Lu committed
248 249 250 251 252 253 254 255 256
int get_lgt8(const TxfmParam *txfm_param, int is_col,
             const tran_high_t **lgtmtx) {
  if (is_col && (vtx_tab[txfm_param->tx_type] == ADST_1D ||
                 vtx_tab[txfm_param->tx_type] == FLIPADST_1D)) {
    lgtmtx[0] = txfm_param->is_inter ? &lgt8_170[0][0] : &lgt8_150[0][0];
    return 1;
  } else if (!is_col && (htx_tab[txfm_param->tx_type] == ADST_1D ||
                         htx_tab[txfm_param->tx_type] == FLIPADST_1D)) {
    lgtmtx[0] = txfm_param->is_inter ? &lgt8_170[0][0] : &lgt8_150[0][0];
Lester Lu's avatar
Lester Lu committed
257 258
    return 1;
  }
Lester Lu's avatar
Lester Lu committed
259
  lgtmtx[0] = NULL;
Lester Lu's avatar
Lester Lu committed
260 261 262 263
  return 0;
}
#endif  // CONFIG_LGT

Yaowu Xu's avatar
Yaowu Xu committed
264
void av1_iht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride,
265 266
                         const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
267 268 269
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
270
#if !CONFIG_DAALA_DCT4
271 272 273 274
  if (tx_type == DCT_DCT) {
    aom_idct4x4_16_add(input, dest, stride);
    return;
  }
275
#endif
276
  static const transform_2d IHT_4[] = {
277
#if CONFIG_DAALA_DCT4
278 279 280 281
    { daala_idct4, daala_idct4 },  // DCT_DCT  = 0
    { daala_idst4, daala_idct4 },  // ADST_DCT = 1
    { daala_idct4, daala_idst4 },  // DCT_ADST = 2
    { daala_idst4, daala_idst4 },  // ADST_ADST = 3
282
#if CONFIG_EXT_TX
283 284 285 286 287
    { daala_idst4, daala_idct4 },  // FLIPADST_DCT
    { daala_idct4, daala_idst4 },  // DCT_FLIPADST
    { daala_idst4, daala_idst4 },  // FLIPADST_FLIPADST
    { daala_idst4, daala_idst4 },  // ADST_FLIPADST
    { daala_idst4, daala_idst4 },  // FLIPADST_ADST
288 289 290 291 292 293 294
    { daala_idtx4, daala_idtx4 },  // IDTX
    { daala_idct4, daala_idtx4 },  // V_DCT
    { daala_idtx4, daala_idct4 },  // H_DCT
    { daala_idst4, daala_idtx4 },  // V_ADST
    { daala_idtx4, daala_idst4 },  // H_ADST
    { daala_idst4, daala_idtx4 },  // V_FLIPADST
    { daala_idtx4, daala_idst4 },  // H_FLIPADST
295 296
#endif
#else
Luca Barbato's avatar
Luca Barbato committed
297 298 299 300
    { aom_idct4_c, aom_idct4_c },    // DCT_DCT  = 0
    { aom_iadst4_c, aom_idct4_c },   // ADST_DCT = 1
    { aom_idct4_c, aom_iadst4_c },   // DCT_ADST = 2
    { aom_iadst4_c, aom_iadst4_c },  // ADST_ADST = 3
301
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
302 303 304 305 306 307 308 309 310 311 312 313
    { aom_iadst4_c, aom_idct4_c },   // FLIPADST_DCT
    { aom_idct4_c, aom_iadst4_c },   // DCT_FLIPADST
    { aom_iadst4_c, aom_iadst4_c },  // FLIPADST_FLIPADST
    { aom_iadst4_c, aom_iadst4_c },  // ADST_FLIPADST
    { aom_iadst4_c, aom_iadst4_c },  // FLIPADST_ADST
    { iidtx4_c, iidtx4_c },          // IDTX
    { aom_idct4_c, iidtx4_c },       // V_DCT
    { iidtx4_c, aom_idct4_c },       // H_DCT
    { aom_iadst4_c, iidtx4_c },      // V_ADST
    { iidtx4_c, aom_iadst4_c },      // H_ADST
    { aom_iadst4_c, iidtx4_c },      // V_FLIPADST
    { iidtx4_c, aom_iadst4_c },      // H_FLIPADST
314
#endif
315
#endif
316 317 318
  };

  int i, j;
319
  tran_low_t tmp[4][4];
320 321 322
  tran_low_t out[4][4];
  tran_low_t *outp = &out[0][0];
  int outstride = 4;
323

324 325 326 327
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif

Lester Lu's avatar
Lester Lu committed
328
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
329 330 331 332
  const tran_high_t *lgtmtx_col[1];
  const tran_high_t *lgtmtx_row[1];
  int use_lgt_col = get_lgt4(txfm_param, 1, lgtmtx_col);
  int use_lgt_row = get_lgt4(txfm_param, 0, lgtmtx_row);
Lester Lu's avatar
Lester Lu committed
333 334
#endif

335 336
  // inverse transform row vectors
  for (i = 0; i < 4; ++i) {
337 338
#if CONFIG_DAALA_DCT4
    tran_low_t temp_in[4];
339
    for (j = 0; j < 4; j++) temp_in[j] = input[j] * 2;
340 341
    IHT_4[tx_type].rows(temp_in, out[i]);
#else
Lester Lu's avatar
Lester Lu committed
342 343
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
344
      ilgt4(input, out[i], lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
345 346 347
    else
#endif
      IHT_4[tx_type].rows(input, out[i]);
348
#endif
clang-format's avatar
clang-format committed
349
    input += 4;
350 351 352
  }

  // transpose
353 354 355
  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
      tmp[j][i] = out[i][j];
356
    }
357 358 359 360
  }

  // inverse transform column vectors
  for (i = 0; i < 4; ++i) {
Lester Lu's avatar
Lester Lu committed
361 362
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
363
      ilgt4(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
364 365 366
    else
#endif
      IHT_4[tx_type].cols(tmp[i], out[i]);
367 368 369
  }

#if CONFIG_EXT_TX
370
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, 4, 4);
371 372 373 374
#endif

  // Sum with the destination
  for (i = 0; i < 4; ++i) {
375
    for (j = 0; j < 4; ++j) {
376 377
      int d = i * stride + j;
      int s = j * outstride + i;
378
#if CONFIG_DAALA_DCT4
379
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 4));
380 381 382
#else
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 4));
#endif
383 384 385 386
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
387
void av1_iht4x8_32_add_c(const tran_low_t *input, uint8_t *dest, int stride,
388 389
                         const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
390 391 392
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
393 394 395
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
396
  static const transform_2d IHT_4x8[] = {
Luca Barbato's avatar
Luca Barbato committed
397 398 399 400
    { aom_idct8_c, aom_idct4_c },    // DCT_DCT
    { aom_iadst8_c, aom_idct4_c },   // ADST_DCT
    { aom_idct8_c, aom_iadst4_c },   // DCT_ADST
    { aom_iadst8_c, aom_iadst4_c },  // ADST_ADST
401
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
402 403 404 405 406 407 408 409 410 411 412 413
    { aom_iadst8_c, aom_idct4_c },   // FLIPADST_DCT
    { aom_idct8_c, aom_iadst4_c },   // DCT_FLIPADST
    { aom_iadst8_c, aom_iadst4_c },  // FLIPADST_FLIPADST
    { aom_iadst8_c, aom_iadst4_c },  // ADST_FLIPADST
    { aom_iadst8_c, aom_iadst4_c },  // FLIPADST_ADST
    { iidtx8_c, iidtx4_c },          // IDTX
    { aom_idct8_c, iidtx4_c },       // V_DCT
    { iidtx8_c, aom_idct4_c },       // H_DCT
    { aom_iadst8_c, iidtx4_c },      // V_ADST
    { iidtx8_c, aom_iadst4_c },      // H_ADST
    { aom_iadst8_c, iidtx4_c },      // V_FLIPADST
    { iidtx8_c, aom_iadst4_c },      // H_FLIPADST
414
#endif
415 416
  };

417 418
  const int n = 4;
  const int n2 = 8;
419
  int i, j;
420
  tran_low_t out[4][8], tmp[4][8], outtmp[4];
421
  tran_low_t *outp = &out[0][0];
422
  int outstride = n2;
423

Lester Lu's avatar
Lester Lu committed
424
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
425 426 427 428
  const tran_high_t *lgtmtx_col[1];
  const tran_high_t *lgtmtx_row[1];
  int use_lgt_col = get_lgt8(txfm_param, 1, lgtmtx_col);
  int use_lgt_row = get_lgt4(txfm_param, 0, lgtmtx_row);
Lester Lu's avatar
Lester Lu committed
429 430
#endif

431
  // inverse transform row vectors and transpose
432
  for (i = 0; i < n2; ++i) {
Lester Lu's avatar
Lester Lu committed
433 434
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
435
      ilgt4(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
436 437 438
    else
#endif
      IHT_4x8[tx_type].rows(input, outtmp);
439
    for (j = 0; j < n; ++j)
440
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
441
    input += n;
442 443 444
  }

  // inverse transform column vectors
445
  for (i = 0; i < n; ++i) {
Lester Lu's avatar
Lester Lu committed
446 447
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
448
      ilgt8(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
449 450 451
    else
#endif
      IHT_4x8[tx_type].cols(tmp[i], out[i]);
452 453
  }

454
#if CONFIG_EXT_TX
455
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n2, n);
456
#endif
457 458

  // Sum with the destination
459 460
  for (i = 0; i < n2; ++i) {
    for (j = 0; j < n; ++j) {
461 462 463 464 465 466 467
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 5));
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
468
void av1_iht8x4_32_add_c(const tran_low_t *input, uint8_t *dest, int stride,
469 470
                         const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
471 472 473
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
474 475 476
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
477
  static const transform_2d IHT_8x4[] = {
Luca Barbato's avatar
Luca Barbato committed
478 479 480 481
    { aom_idct4_c, aom_idct8_c },    // DCT_DCT
    { aom_iadst4_c, aom_idct8_c },   // ADST_DCT
    { aom_idct4_c, aom_iadst8_c },   // DCT_ADST
    { aom_iadst4_c, aom_iadst8_c },  // ADST_ADST
482
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
483 484 485 486 487 488 489 490 491 492 493 494
    { aom_iadst4_c, aom_idct8_c },   // FLIPADST_DCT
    { aom_idct4_c, aom_iadst8_c },   // DCT_FLIPADST
    { aom_iadst4_c, aom_iadst8_c },  // FLIPADST_FLIPADST
    { aom_iadst4_c, aom_iadst8_c },  // ADST_FLIPADST
    { aom_iadst4_c, aom_iadst8_c },  // FLIPADST_ADST
    { iidtx4_c, iidtx8_c },          // IDTX
    { aom_idct4_c, iidtx8_c },       // V_DCT
    { iidtx4_c, aom_idct8_c },       // H_DCT
    { aom_iadst4_c, iidtx8_c },      // V_ADST
    { iidtx4_c, aom_iadst8_c },      // H_ADST
    { aom_iadst4_c, iidtx8_c },      // V_FLIPADST
    { iidtx4_c, aom_iadst8_c },      // H_FLIPADST
495
#endif
496
  };
497

498 499
  const int n = 4;
  const int n2 = 8;
500 501

  int i, j;
502
  tran_low_t out[8][4], tmp[8][4], outtmp[8];
503
  tran_low_t *outp = &out[0][0];
504
  int outstride = n;
505

Lester Lu's avatar
Lester Lu committed
506
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
507 508 509 510
  const tran_high_t *lgtmtx_col[1];
  const tran_high_t *lgtmtx_row[1];
  int use_lgt_col = get_lgt4(txfm_param, 1, lgtmtx_col);
  int use_lgt_row = get_lgt8(txfm_param, 0, lgtmtx_row);
Lester Lu's avatar
Lester Lu committed
511 512
#endif

513
  // inverse transform row vectors and transpose
514
  for (i = 0; i < n; ++i) {
Lester Lu's avatar
Lester Lu committed
515 516
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
517
      ilgt8(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
518 519 520
    else
#endif
      IHT_8x4[tx_type].rows(input, outtmp);
521
    for (j = 0; j < n2; ++j)
522
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
523
    input += n2;
524 525 526
  }

  // inverse transform column vectors
527
  for (i = 0; i < n2; ++i) {
Lester Lu's avatar
Lester Lu committed
528 529
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
530
      ilgt4(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
531 532 533
    else
#endif
      IHT_8x4[tx_type].cols(tmp[i], out[i]);
534 535
  }

536
#if CONFIG_EXT_TX
537
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n2);
538
#endif
539 540

  // Sum with the destination
541 542
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n2; ++j) {
543 544 545 546 547 548 549
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 5));
    }
  }
}

550
void av1_iht4x16_64_add_c(const tran_low_t *input, uint8_t *dest, int stride,
551 552
                          const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
553 554 555
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
556 557 558
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
  static const transform_2d IHT_4x16[] = {
    { aom_idct16_c, aom_idct4_c },    // DCT_DCT
    { aom_iadst16_c, aom_idct4_c },   // ADST_DCT
    { aom_idct16_c, aom_iadst4_c },   // DCT_ADST
    { aom_iadst16_c, aom_iadst4_c },  // ADST_ADST
#if CONFIG_EXT_TX
    { aom_iadst16_c, aom_idct4_c },   // FLIPADST_DCT
    { aom_idct16_c, aom_iadst4_c },   // DCT_FLIPADST
    { aom_iadst16_c, aom_iadst4_c },  // FLIPADST_FLIPADST
    { aom_iadst16_c, aom_iadst4_c },  // ADST_FLIPADST
    { aom_iadst16_c, aom_iadst4_c },  // FLIPADST_ADST
    { iidtx16_c, iidtx4_c },          // IDTX
    { aom_idct16_c, iidtx4_c },       // V_DCT
    { iidtx16_c, aom_idct4_c },       // H_DCT
    { aom_iadst16_c, iidtx4_c },      // V_ADST
    { iidtx16_c, aom_iadst4_c },      // H_ADST
    { aom_iadst16_c, iidtx4_c },      // V_FLIPADST
    { iidtx16_c, aom_iadst4_c },      // H_FLIPADST
#endif
  };

  const int n = 4;
  const int n4 = 16;
  int i, j;
583
  tran_low_t out[4][16], tmp[4][16], outtmp[4];
584 585 586
  tran_low_t *outp = &out[0][0];
  int outstride = n4;

Lester Lu's avatar
Lester Lu committed
587
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
588 589
  const tran_high_t *lgtmtx_row[1];
  int use_lgt_row = get_lgt4(txfm_param, 0, lgtmtx_row);
Lester Lu's avatar
Lester Lu committed
590 591
#endif

592 593
  // inverse transform row vectors and transpose
  for (i = 0; i < n4; ++i) {
Lester Lu's avatar
Lester Lu committed
594 595
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
596
      ilgt4(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
597 598 599
    else
#endif
      IHT_4x16[tx_type].rows(input, outtmp);
600
    for (j = 0; j < n; ++j) tmp[j][i] = outtmp[j];
601 602 603 604
    input += n;
  }

  // inverse transform column vectors
Lester Lu's avatar
Lester Lu committed
605 606 607
  for (i = 0; i < n; ++i) {
    IHT_4x16[tx_type].cols(tmp[i], out[i]);
  }
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623

#if CONFIG_EXT_TX
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n4, n);
#endif

  // Sum with the destination
  for (i = 0; i < n4; ++i) {
    for (j = 0; j < n; ++j) {
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 5));
    }
  }
}

void av1_iht16x4_64_add_c(const tran_low_t *input, uint8_t *dest, int stride,
624 625
                          const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
626 627 628
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
629 630 631
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
  static const transform_2d IHT_16x4[] = {
    { aom_idct4_c, aom_idct16_c },    // DCT_DCT
    { aom_iadst4_c, aom_idct16_c },   // ADST_DCT
    { aom_idct4_c, aom_iadst16_c },   // DCT_ADST
    { aom_iadst4_c, aom_iadst16_c },  // ADST_ADST
#if CONFIG_EXT_TX
    { aom_iadst4_c, aom_idct16_c },   // FLIPADST_DCT
    { aom_idct4_c, aom_iadst16_c },   // DCT_FLIPADST
    { aom_iadst4_c, aom_iadst16_c },  // FLIPADST_FLIPADST
    { aom_iadst4_c, aom_iadst16_c },  // ADST_FLIPADST
    { aom_iadst4_c, aom_iadst16_c },  // FLIPADST_ADST
    { iidtx4_c, iidtx16_c },          // IDTX
    { aom_idct4_c, iidtx16_c },       // V_DCT
    { iidtx4_c, aom_idct16_c },       // H_DCT
    { aom_iadst4_c, iidtx16_c },      // V_ADST
    { iidtx4_c, aom_iadst16_c },      // H_ADST
    { aom_iadst4_c, iidtx16_c },      // V_FLIPADST
    { iidtx4_c, aom_iadst16_c },      // H_FLIPADST
#endif
  };
652

653 654 655 656
  const int n = 4;
  const int n4 = 16;

  int i, j;
657
  tran_low_t out[16][4], tmp[16][4], outtmp[16];
658 659 660
  tran_low_t *outp = &out[0][0];
  int outstride = n;

Lester Lu's avatar
Lester Lu committed
661
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
662 663
  const tran_high_t *lgtmtx_col[1];
  int use_lgt_col = get_lgt4(txfm_param, 1, lgtmtx_col);
Lester Lu's avatar
Lester Lu committed
664 665
#endif

666 667 668
  // inverse transform row vectors and transpose
  for (i = 0; i < n; ++i) {
    IHT_16x4[tx_type].rows(input, outtmp);
669
    for (j = 0; j < n4; ++j) tmp[j][i] = outtmp[j];
670 671 672 673
    input += n4;
  }

  // inverse transform column vectors
Lester Lu's avatar
Lester Lu committed
674 675 676
  for (i = 0; i < n4; ++i) {
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
677
      ilgt4(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
678 679 680 681
    else
#endif
      IHT_16x4[tx_type].cols(tmp[i], out[i]);
  }
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696

#if CONFIG_EXT_TX
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n4);
#endif

  // Sum with the destination
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n4; ++j) {
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 5));
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
697
void av1_iht8x16_128_add_c(const tran_low_t *input, uint8_t *dest, int stride,
698 699
                           const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
700 701 702
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
703 704 705
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
706
  static const transform_2d IHT_8x16[] = {
Luca Barbato's avatar
Luca Barbato committed
707 708 709 710
    { aom_idct16_c, aom_idct8_c },    // DCT_DCT
    { aom_iadst16_c, aom_idct8_c },   // ADST_DCT
    { aom_idct16_c, aom_iadst8_c },   // DCT_ADST
    { aom_iadst16_c, aom_iadst8_c },  // ADST_ADST
711
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
712 713 714 715 716 717 718 719 720 721 722 723
    { aom_iadst16_c, aom_idct8_c },   // FLIPADST_DCT
    { aom_idct16_c, aom_iadst8_c },   // DCT_FLIPADST
    { aom_iadst16_c, aom_iadst8_c },  // FLIPADST_FLIPADST
    { aom_iadst16_c, aom_iadst8_c },  // ADST_FLIPADST
    { aom_iadst16_c, aom_iadst8_c },  // FLIPADST_ADST
    { iidtx16_c, iidtx8_c },          // IDTX
    { aom_idct16_c, iidtx8_c },       // V_DCT
    { iidtx16_c, aom_idct8_c },       // H_DCT
    { aom_iadst16_c, iidtx8_c },      // V_ADST
    { iidtx16_c, aom_iadst8_c },      // H_ADST
    { aom_iadst16_c, iidtx8_c },      // V_FLIPADST
    { iidtx16_c, aom_iadst8_c },      // H_FLIPADST
724
#endif
725 726 727 728 729
  };

  const int n = 8;
  const int n2 = 16;
  int i, j;
730
  tran_low_t out[8][16], tmp[8][16], outtmp[8];
731 732 733
  tran_low_t *outp = &out[0][0];
  int outstride = n2;

Lester Lu's avatar
Lester Lu committed
734
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
735 736
  const tran_high_t *lgtmtx_row[1];
  int use_lgt_row = get_lgt8(txfm_param, 0, lgtmtx_row);
Lester Lu's avatar
Lester Lu committed
737 738
#endif

739 740
  // inverse transform row vectors and transpose
  for (i = 0; i < n2; ++i) {
Lester Lu's avatar
Lester Lu committed
741 742
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
743
      ilgt8(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
744 745 746
    else
#endif
      IHT_8x16[tx_type].rows(input, outtmp);
747
    for (j = 0; j < n; ++j)
748
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
clang-format's avatar
clang-format committed
749
    input += n;
750 751 752 753
  }

  // inverse transform column vectors
  for (i = 0; i < n; ++i) {
754
    IHT_8x16[tx_type].cols(tmp[i], out[i]);
755 756
  }

757
#if CONFIG_EXT_TX
758
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n2, n);
759
#endif
760 761 762 763 764 765 766 767 768 769 770

  // Sum with the destination
  for (i = 0; i < n2; ++i) {
    for (j = 0; j < n; ++j) {
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 6));
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
771
void av1_iht16x8_128_add_c(const tran_low_t *input, uint8_t *dest, int stride,
772 773
                           const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
774 775 776
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
777 778 779
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
780
  static const transform_2d IHT_16x8[] = {
Luca Barbato's avatar
Luca Barbato committed
781 782 783 784
    { aom_idct8_c, aom_idct16_c },    // DCT_DCT
    { aom_iadst8_c, aom_idct16_c },   // ADST_DCT
    { aom_idct8_c, aom_iadst16_c },   // DCT_ADST
    { aom_iadst8_c, aom_iadst16_c },  // ADST_ADST
785
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
786 787 788 789 790 791 792 793 794 795 796 797
    { aom_iadst8_c, aom_idct16_c },   // FLIPADST_DCT
    { aom_idct8_c, aom_iadst16_c },   // DCT_FLIPADST
    { aom_iadst8_c, aom_iadst16_c },  // FLIPADST_FLIPADST
    { aom_iadst8_c, aom_iadst16_c },  // ADST_FLIPADST
    { aom_iadst8_c, aom_iadst16_c },  // FLIPADST_ADST
    { iidtx8_c, iidtx16_c },          // IDTX
    { aom_idct8_c, iidtx16_c },       // V_DCT
    { iidtx8_c, aom_idct16_c },       // H_DCT
    { aom_iadst8_c, iidtx16_c },      // V_ADST
    { iidtx8_c, aom_iadst16_c },      // H_ADST
    { aom_iadst8_c, iidtx16_c },      // V_FLIPADST
    { iidtx8_c, aom_iadst16_c },      // H_FLIPADST
798
#endif
799
  };
800

801 802 803 804
  const int n = 8;
  const int n2 = 16;

  int i, j;
805
  tran_low_t out[16][8], tmp[16][8], outtmp[16];
806 807 808
  tran_low_t *outp = &out[0][0];
  int outstride = n;

Lester Lu's avatar
Lester Lu committed
809
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
810 811
  const tran_high_t *lgtmtx_col[1];
  int use_lgt_col = get_lgt8(txfm_param, 1, lgtmtx_col);
Lester Lu's avatar
Lester Lu committed
812 813
#endif

814 815 816 817
  // inverse transform row vectors and transpose
  for (i = 0; i < n; ++i) {
    IHT_16x8[tx_type].rows(input, outtmp);
    for (j = 0; j < n2; ++j)
818
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
clang-format's avatar
clang-format committed
819
    input += n2;
820 821 822 823
  }

  // inverse transform column vectors
  for (i = 0; i < n2; ++i) {
Lester Lu's avatar
Lester Lu committed
824 825
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
826
      ilgt8(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
827 828 829
    else
#endif
      IHT_16x8[tx_type].cols(tmp[i], out[i]);
830 831
  }

832
#if CONFIG_EXT_TX
833
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n2);
834
#endif
835 836 837 838 839 840 841 842 843 844 845

  // Sum with the destination
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n2; ++j) {
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 6));
    }
  }
}

846
void av1_iht8x32_256_add_c(const tran_low_t *input, uint8_t *dest, int stride,
847 848
                           const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
849 850 851
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
852 853 854
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
  static const transform_2d IHT_8x32[] = {
    { aom_idct32_c, aom_idct8_c },     // DCT_DCT
    { ihalfright32_c, aom_idct8_c },   // ADST_DCT
    { aom_idct32_c, aom_iadst8_c },    // DCT_ADST
    { ihalfright32_c, aom_iadst8_c },  // ADST_ADST
#if CONFIG_EXT_TX
    { ihalfright32_c, aom_idct8_c },   // FLIPADST_DCT
    { aom_idct32_c, aom_iadst8_c },    // DCT_FLIPADST
    { ihalfright32_c, aom_iadst8_c },  // FLIPADST_FLIPADST
    { ihalfright32_c, aom_iadst8_c },  // ADST_FLIPADST
    { ihalfright32_c, aom_iadst8_c },  // FLIPADST_ADST
    { iidtx32_c, iidtx8_c },           // IDTX
    { aom_idct32_c, iidtx8_c },        // V_DCT
    { iidtx32_c, aom_idct8_c },        // H_DCT
    { ihalfright32_c, iidtx8_c },      // V_ADST
    { iidtx32_c, aom_iadst8_c },       // H_ADST
    { ihalfright32_c, iidtx8_c },      // V_FLIPADST
    { iidtx32_c, aom_iadst8_c },       // H_FLIPADST
#endif
  };

  const int n = 8;
  const int n4 = 32;
  int i, j;
879
  tran_low_t out[8][32], tmp[8][32], outtmp[8];
880 881 882
  tran_low_t *outp = &out[0][0];
  int outstride = n4;

Lester Lu's avatar
Lester Lu committed
883
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
884 885
  const tran_high_t *lgtmtx_row[1];
  int use_lgt_row = get_lgt8(txfm_param, 0, lgtmtx_row);
Lester Lu's avatar
Lester Lu committed
886 887
#endif

888 889
  // inverse transform row vectors and transpose
  for (i = 0; i < n4; ++i) {
Lester Lu's avatar
Lester Lu committed
890 891
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
892
      ilgt8(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
893 894 895
    else
#endif
      IHT_8x32[tx_type].rows(input, outtmp);
896
    for (j = 0; j < n; ++j) tmp[j][i] = outtmp[j];
897 898 899 900
    input += n;
  }

  // inverse transform column vectors
Lester Lu's avatar
Lester Lu committed
901 902 903
  for (i = 0; i < n; ++i) {
    IHT_8x32[tx_type].cols(tmp[i], out[i]);
  }
904 905 906 907 908 909 910 911