idct.c 78.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 65 66

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

78
// For use in lieu of ADST
79 80 81 82 83 84 85 86 87 88 89
#if CONFIG_DAALA_DCT32
static void ihalfright32_c(const tran_low_t *input, tran_low_t *output) {
  int i;
  tran_low_t inputhalf[16];
  // No scaling within; Daala transforms are all orthonormal
  for (i = 0; i < 16; ++i) {
    inputhalf[i] = input[i];
  }
  for (i = 0; i < 16; ++i) {
    output[i] = input[16 + i];
  }
90
  daala_idct16(inputhalf, output + 16);
91 92
}
#else
93 94 95 96 97 98 99
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);
  }
100 101 102
  for (i = 0; i < 16; ++i) {
    output[i] = input[16 + i] * 4;
  }
Luca Barbato's avatar
Luca Barbato committed
103
  aom_idct16_c(inputhalf, output + 16);
104 105
  // Note overall scaling factor is 4 times orthogonal
}
106
#endif
107

108
#if CONFIG_TX64X64
109 110 111 112 113 114 115 116 117 118 119
#if CONFIG_DAALA_DCT64
static void ihalfright64_c(const tran_low_t *input, tran_low_t *output) {
  int i;
  tran_low_t inputhalf[32];
  // No scaling within; Daala transforms are all orthonormal
  for (i = 0; i < 32; ++i) {
    inputhalf[i] = input[i];
  }
  for (i = 0; i < 32; ++i) {
    output[i] = input[32 + i];
  }
120
  daala_idct32(inputhalf, output + 32);
121 122
}
#else
123 124 125 126
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];
127
  av1_idct64_new(in, out, inv_cos_bit_col_dct_64, inv_stage_range_col_dct_64);
128 129 130 131 132 133 134
  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];
135
  av1_idct64_new(in, out, inv_cos_bit_row_dct_64, inv_stage_range_row_dct_64);
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
  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
}
153
#endif  // CONFIG_DAALA_DCT64
154 155
#endif  // CONFIG_TX64X64

Jingning Han's avatar
Jingning Han committed
156
// Inverse identity transform and add.
157
#if CONFIG_EXT_TX
158
static void inv_idtx_add_c(const tran_low_t *input, uint8_t *dest, int stride,
Jingning Han's avatar
Jingning Han committed
159
                           int bs, int tx_type) {
160
  int r, c;
161
  const int shift = bs < 32 ? 3 : (bs < 64 ? 2 : 1);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
162
  if (tx_type == IDTX) {
Jingning Han's avatar
Jingning Han committed
163 164
    for (r = 0; r < bs; ++r) {
      for (c = 0; c < bs; ++c)
Debargha Mukherjee's avatar
Debargha Mukherjee committed
165 166 167
        dest[c] = clip_pixel_add(dest[c], input[c] >> shift);
      dest += stride;
      input += bs;
Jingning Han's avatar
Jingning Han committed
168
    }
169 170
  }
}
171
#endif  // CONFIG_EXT_TX
172

clang-format's avatar
clang-format committed
173 174 175 176 177
#define FLIPUD_PTR(dest, stride, size)       \
  do {                                       \
    (dest) = (dest) + ((size)-1) * (stride); \
    (stride) = -(stride);                    \
  } while (0)
178

179
#if CONFIG_EXT_TX
clang-format's avatar
clang-format committed
180 181 182
static void maybe_flip_strides(uint8_t **dst, int *dstride, tran_low_t **src,
                               int *sstride, int tx_type, int sizey,
                               int sizex) {
183 184 185 186 187 188 189 190
  // 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
191
    case IDTX:
Jingning Han's avatar
Jingning Han committed
192 193
    case V_DCT:
    case H_DCT:
194
    case V_ADST:
clang-format's avatar
clang-format committed
195
    case H_ADST: break;
196 197
    case FLIPADST_DCT:
    case FLIPADST_ADST:
198
    case V_FLIPADST:
199
      // flip UD
200
      FLIPUD_PTR(*dst, *dstride, sizey);
201 202 203
      break;
    case DCT_FLIPADST:
    case ADST_FLIPADST:
204
    case H_FLIPADST:
205
      // flip LR
206
      FLIPUD_PTR(*src, *sstride, sizex);
207 208 209
      break;
    case FLIPADST_FLIPADST:
      // flip UD
210
      FLIPUD_PTR(*dst, *dstride, sizey);
211
      // flip LR
212
      FLIPUD_PTR(*src, *sstride, sizex);
213
      break;
clang-format's avatar
clang-format committed
214
    default: assert(0); break;
215 216
  }
}
217
#endif  // CONFIG_EXT_TX
218

219
#if CONFIG_HIGHBITDEPTH
220
#if CONFIG_EXT_TX && CONFIG_TX64X64
221
static void highbd_inv_idtx_add_c(const tran_low_t *input, uint8_t *dest8,
222
                                  int stride, int bs, int tx_type, int bd) {
223 224 225
  int r, c;
  const int shift = bs < 32 ? 3 : 2;
  uint16_t *dest = CONVERT_TO_SHORTPTR(dest8);
226

Debargha Mukherjee's avatar
Debargha Mukherjee committed
227
  if (tx_type == IDTX) {
228 229
    for (r = 0; r < bs; ++r) {
      for (c = 0; c < bs; ++c)
Debargha Mukherjee's avatar
Debargha Mukherjee committed
230 231 232
        dest[c] = highbd_clip_pixel_add(dest[c], input[c] >> shift, bd);
      dest += stride;
      input += bs;
233
    }
234 235
  }
}
236
#endif  // CONFIG_EXT_TX && CONFIG_TX64X64
237
#endif  // CONFIG_HIGHBITDEPTH
238

Lester Lu's avatar
Lester Lu committed
239 240 241
#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
242 243
  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
244 245 246 247 248 249 250 251 252
  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
253 254
  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
255 256 257 258 259 260 261
  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
262 263 264 265 266 267 268 269 270 271 272
// 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
273 274
    return 1;
  }
Lester Lu's avatar
Lester Lu committed
275
  lgtmtx[0] = NULL;
Lester Lu's avatar
Lester Lu committed
276 277 278
  return 0;
}

Lester Lu's avatar
Lester Lu committed
279 280 281 282 283 284 285 286 287
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
288 289
    return 1;
  }
Lester Lu's avatar
Lester Lu committed
290
  lgtmtx[0] = NULL;
Lester Lu's avatar
Lester Lu committed
291 292 293 294
  return 0;
}
#endif  // CONFIG_LGT

Yaowu Xu's avatar
Yaowu Xu committed
295
void av1_iht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride,
296 297
                         const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
298 299 300
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
301
#if !CONFIG_DAALA_DCT4
302 303 304 305
  if (tx_type == DCT_DCT) {
    aom_idct4x4_16_add(input, dest, stride);
    return;
  }
306
#endif
307
  static const transform_2d IHT_4[] = {
308
#if CONFIG_DAALA_DCT4
309 310 311 312
    { 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
313
#if CONFIG_EXT_TX
314 315 316 317 318
    { 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
319 320 321 322 323 324 325
    { 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
326 327
#endif
#else
Luca Barbato's avatar
Luca Barbato committed
328 329 330 331
    { 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
332
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
333 334 335 336 337 338 339 340 341 342 343 344
    { 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
345
#endif
346
#endif
347 348 349
  };

  int i, j;
350
  tran_low_t tmp[4][4];
351 352 353
  tran_low_t out[4][4];
  tran_low_t *outp = &out[0][0];
  int outstride = 4;
354

355 356 357 358
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif

Lester Lu's avatar
Lester Lu committed
359
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
360 361 362 363
  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
364 365
#endif

366 367
  // inverse transform row vectors
  for (i = 0; i < 4; ++i) {
368 369
#if CONFIG_DAALA_DCT4
    tran_low_t temp_in[4];
370
    for (j = 0; j < 4; j++) temp_in[j] = input[j] * 2;
371 372
    IHT_4[tx_type].rows(temp_in, out[i]);
#else
Lester Lu's avatar
Lester Lu committed
373 374
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
375
      ilgt4(input, out[i], lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
376 377 378
    else
#endif
      IHT_4[tx_type].rows(input, out[i]);
379
#endif
clang-format's avatar
clang-format committed
380
    input += 4;
381 382 383
  }

  // transpose
384 385 386
  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
      tmp[j][i] = out[i][j];
387
    }
388 389 390 391
  }

  // inverse transform column vectors
  for (i = 0; i < 4; ++i) {
Lester Lu's avatar
Lester Lu committed
392 393
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
394
      ilgt4(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
395 396 397
    else
#endif
      IHT_4[tx_type].cols(tmp[i], out[i]);
398 399 400
  }

#if CONFIG_EXT_TX
401
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, 4, 4);
402 403 404 405
#endif

  // Sum with the destination
  for (i = 0; i < 4; ++i) {
406
    for (j = 0; j < 4; ++j) {
407 408
      int d = i * stride + j;
      int s = j * outstride + i;
409
#if CONFIG_DAALA_DCT4
410
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 4));
411 412 413
#else
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 4));
#endif
414 415 416 417
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
418
void av1_iht4x8_32_add_c(const tran_low_t *input, uint8_t *dest, int stride,
419 420
                         const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
421 422 423
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
424 425 426
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
427
  static const transform_2d IHT_4x8[] = {
Luca Barbato's avatar
Luca Barbato committed
428 429 430 431
    { 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
432
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
433 434 435 436 437 438 439 440 441 442 443 444
    { 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
445
#endif
446 447
  };

448 449
  const int n = 4;
  const int n2 = 8;
450
  int i, j;
451
  tran_low_t out[4][8], tmp[4][8], outtmp[4];
452
  tran_low_t *outp = &out[0][0];
453
  int outstride = n2;
454

Lester Lu's avatar
Lester Lu committed
455
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
456 457 458 459
  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
460 461
#endif

462
  // inverse transform row vectors and transpose
463
  for (i = 0; i < n2; ++i) {
Lester Lu's avatar
Lester Lu committed
464 465
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
466
      ilgt4(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
467 468 469
    else
#endif
      IHT_4x8[tx_type].rows(input, outtmp);
470
    for (j = 0; j < n; ++j)
471
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
472
    input += n;
473 474 475
  }

  // inverse transform column vectors
476
  for (i = 0; i < n; ++i) {
Lester Lu's avatar
Lester Lu committed
477 478
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
479
      ilgt8(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
480 481 482
    else
#endif
      IHT_4x8[tx_type].cols(tmp[i], out[i]);
483 484
  }

485
#if CONFIG_EXT_TX
486
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n2, n);
487
#endif
488 489

  // Sum with the destination
490 491
  for (i = 0; i < n2; ++i) {
    for (j = 0; j < n; ++j) {
492 493 494 495 496 497 498
      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
499
void av1_iht8x4_32_add_c(const tran_low_t *input, uint8_t *dest, int stride,
500 501
                         const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
502 503 504
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
505 506 507
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
508
  static const transform_2d IHT_8x4[] = {
Luca Barbato's avatar
Luca Barbato committed
509 510 511 512
    { 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
513
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
514 515 516 517 518 519 520 521 522 523 524 525
    { 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
526
#endif
527
  };
528

529 530
  const int n = 4;
  const int n2 = 8;
531 532

  int i, j;
533
  tran_low_t out[8][4], tmp[8][4], outtmp[8];
534
  tran_low_t *outp = &out[0][0];
535
  int outstride = n;
536

Lester Lu's avatar
Lester Lu committed
537
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
538 539 540 541
  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
542 543
#endif

544
  // inverse transform row vectors and transpose
545
  for (i = 0; i < n; ++i) {
Lester Lu's avatar
Lester Lu committed
546 547
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
548
      ilgt8(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
549 550 551
    else
#endif
      IHT_8x4[tx_type].rows(input, outtmp);
552
    for (j = 0; j < n2; ++j)
553
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
554
    input += n2;
555 556 557
  }

  // inverse transform column vectors
558
  for (i = 0; i < n2; ++i) {
Lester Lu's avatar
Lester Lu committed
559 560
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
561
      ilgt4(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
562 563 564
    else
#endif
      IHT_8x4[tx_type].cols(tmp[i], out[i]);
565 566
  }

567
#if CONFIG_EXT_TX
568
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n2);
569
#endif
570 571

  // Sum with the destination
572 573
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n2; ++j) {
574 575 576 577 578 579 580
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 5));
    }
  }
}

581
void av1_iht4x16_64_add_c(const tran_low_t *input, uint8_t *dest, int stride,
582 583
                          const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
584 585 586
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
587 588 589
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
  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;
614
  tran_low_t out[4][16], tmp[4][16], outtmp[4];
615 616 617
  tran_low_t *outp = &out[0][0];
  int outstride = n4;

Lester Lu's avatar
Lester Lu committed
618
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
619 620
  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
621 622
#endif

623 624
  // inverse transform row vectors and transpose
  for (i = 0; i < n4; ++i) {
Lester Lu's avatar
Lester Lu committed
625 626
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
627
      ilgt4(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
628 629 630
    else
#endif
      IHT_4x16[tx_type].rows(input, outtmp);
631
    for (j = 0; j < n; ++j) tmp[j][i] = outtmp[j];
632 633 634 635
    input += n;
  }

  // inverse transform column vectors
Lester Lu's avatar
Lester Lu committed
636 637 638
  for (i = 0; i < n; ++i) {
    IHT_4x16[tx_type].cols(tmp[i], out[i]);
  }
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654

#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,
655 656
                          const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
657 658 659
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
660 661 662
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
  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
  };
683

684 685 686 687
  const int n = 4;
  const int n4 = 16;

  int i, j;
688
  tran_low_t out[16][4], tmp[16][4], outtmp[16];
689 690 691
  tran_low_t *outp = &out[0][0];
  int outstride = n;

Lester Lu's avatar
Lester Lu committed
692
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
693 694
  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
695 696
#endif

697 698 699
  // inverse transform row vectors and transpose
  for (i = 0; i < n; ++i) {
    IHT_16x4[tx_type].rows(input, outtmp);
700
    for (j = 0; j < n4; ++j) tmp[j][i] = outtmp[j];
701 702 703 704
    input += n4;
  }

  // inverse transform column vectors
Lester Lu's avatar
Lester Lu committed
705 706 707
  for (i = 0; i < n4; ++i) {
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
708
      ilgt4(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
709 710 711 712
    else
#endif
      IHT_16x4[tx_type].cols(tmp[i], out[i]);
  }
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727

#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
728
void av1_iht8x16_128_add_c(const tran_low_t *input, uint8_t *dest, int stride,
729 730
                           const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
731 732 733
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
734 735 736
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
737
  static const transform_2d IHT_8x16[] = {
Luca Barbato's avatar
Luca Barbato committed
738 739 740 741
    { 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
742
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
743 744 745 746 747 748 749 750 751 752 753 754
    { 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
755
#endif
756 757 758 759 760
  };

  const int n = 8;
  const int n2 = 16;
  int i, j;
761
  tran_low_t out[8][16], tmp[8][16], outtmp[8];
762 763 764
  tran_low_t *outp = &out[0][0];
  int outstride = n2;

Lester Lu's avatar
Lester Lu committed
765
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
766 767
  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
768 769
#endif

770 771
  // inverse transform row vectors and transpose
  for (i = 0; i < n2; ++i) {
Lester Lu's avatar
Lester Lu committed
772 773
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
774
      ilgt8(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
775 776 777
    else
#endif
      IHT_8x16[tx_type].rows(input, outtmp);
778
    for (j = 0; j < n; ++j)
779
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
clang-format's avatar
clang-format committed
780
    input += n;
781 782 783 784
  }

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

788
#if CONFIG_EXT_TX
789
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n2, n);
790
#endif
791 792 793 794 795 796 797 798 799 800 801

  // 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
802
void av1_iht16x8_128_add_c(const tran_low_t *input, uint8_t *dest, int stride,
803 804
                           const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
805 806 807
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
808 809 810
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
811
  static const transform_2d IHT_16x8[] = {
Luca Barbato's avatar
Luca Barbato committed
812 813 814 815
    { 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
816
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
817 818 819 820 821 822 823 824 825 826 827 828
    { 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
829
#endif
830
  };
831

832 833 834 835
  const int n = 8;
  const int n2 = 16;

  int i, j;
836
  tran_low_t out[16][8], tmp[16][8], outtmp[16];
837 838 839
  tran_low_t *outp = &out[0][0];
  int outstride = n;

Lester Lu's avatar
Lester Lu committed
840
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
841 842
  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
843 844
#endif

845 846 847 848
  // 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)
849
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
clang-format's avatar
clang-format committed
850
    input += n2;
851 852 853 854
  }

  // inverse transform column vectors
  for (i = 0; i < n2; ++i) {
Lester Lu's avatar
Lester Lu committed
855 856
#if CONFIG_LGT
    if (use_lgt_col)
Lester Lu's avatar
Lester Lu committed
857
      ilgt8(tmp[i], out[i], lgtmtx_col[0]);
Lester Lu's avatar
Lester Lu committed
858 859 860
    else
#endif
      IHT_16x8[tx_type].cols(tmp[i], out[i]);
861 862
  }

863
#if CONFIG_EXT_TX
864
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n2);
865
#endif
866 867 868 869 870 871 872 873 874 875 876

  // 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));
    }
  }
}

877
void av1_iht8x32_256_add_c(const tran_low_t *input, uint8_t *dest, int stride,
878 879
                           const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
880 881 882
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
883 884 885
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
  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;
910
  tran_low_t out[8][32], tmp[8][32], outtmp[8];
911 912 913
  tran_low_t *outp = &out[0][0];
  int outstride = n4;

Lester Lu's avatar
Lester Lu committed
914
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
915 916
  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
917 918