idct.c 73.6 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"
Jingning Han's avatar
Jingning Han committed
22

23
int av1_get_tx_scale(const TX_SIZE tx_size) {
24 25 26 27 28 29 30
  if (txsize_sqr_up_map[tx_size] == TX_32X32) return 1;
#if CONFIG_TX64X64
  else if (txsize_sqr_up_map[tx_size] == TX_64X64)
    return 2;
#endif  // CONFIG_TX64X64
  else
    return 0;
31 32
}

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

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

static void iidtx8_c(const tran_low_t *input, tran_low_t *output) {
  int i;
50 51 52 53 54 55 56
  for (i = 0; i < 8; ++i) {
#if CONFIG_DAALA_DCT8
    output[i] = input[i];
#else
    output[i] = input[i] * 2;
#endif
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
57 58 59 60
}

static void iidtx16_c(const tran_low_t *input, tran_low_t *output) {
  int i;
61 62 63 64
  for (i = 0; i < 16; ++i) {
#if CONFIG_DAALA_DCT16
    output[i] = input[i];
#else
Debargha Mukherjee's avatar
Debargha Mukherjee committed
65
    output[i] = (tran_low_t)dct_const_round_shift(input[i] * 2 * Sqrt2);
66 67
#endif
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
68 69 70 71
}

static void iidtx32_c(const tran_low_t *input, tran_low_t *output) {
  int i;
72 73 74 75 76 77 78
  for (i = 0; i < 32; ++i) {
#if CONFIG_DAALA_DCT32
    output[i] = input[i];
#else
    output[i] = input[i] * 4;
#endif
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
79
}
80 81 82 83

#if CONFIG_TX64X64
static void iidtx64_c(const tran_low_t *input, tran_low_t *output) {
  int i;
84 85 86 87
  for (i = 0; i < 64; ++i) {
#if CONFIG_DAALA_DCT64
    output[i] = input[i];
#else
88
    output[i] = (tran_low_t)dct_const_round_shift(input[i] * 4 * Sqrt2);
89 90
#endif
  }
91 92
}
#endif  // CONFIG_TX64X64
93
#endif  // CONFIG_EXT_TX
Debargha Mukherjee's avatar
Debargha Mukherjee committed
94

95
// For use in lieu of ADST
96 97 98 99 100 101 102 103 104 105 106 107 108 109
#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];
  }
  aom_idct16_c(inputhalf, output + 16);
}
#else
110 111 112 113 114 115 116
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);
  }
117 118 119
  for (i = 0; i < 16; ++i) {
    output[i] = input[16 + i] * 4;
  }
Luca Barbato's avatar
Luca Barbato committed
120
  aom_idct16_c(inputhalf, output + 16);
121 122
  // Note overall scaling factor is 4 times orthogonal
}
123
#endif
124

125
#if CONFIG_TX64X64
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
#if CONFIG_DAALA_DCT64
static void idct64_col_c(const tran_low_t *input, tran_low_t *output) {
  aom_idct64_c(input, output);
}

static void idct64_row_c(const tran_low_t *input, tran_low_t *output) {
  aom_idct64_c(input, output);
}

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];
  }
  aom_idct32_c(inputhalf, output + 32);
}

#else
149 150 151 152
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];
153
  av1_idct64_new(in, out, inv_cos_bit_col_dct_64, inv_stage_range_col_dct_64);
154 155 156 157 158 159 160
  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];
161
  av1_idct64_new(in, out, inv_cos_bit_row_dct_64, inv_stage_range_row_dct_64);
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
  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
}
179
#endif  // CONFIG_DAALA_DCT64
180 181
#endif  // CONFIG_TX64X64

Jingning Han's avatar
Jingning Han committed
182
// Inverse identity transform and add.
183
#if CONFIG_EXT_TX
184
static void inv_idtx_add_c(const tran_low_t *input, uint8_t *dest, int stride,
Jingning Han's avatar
Jingning Han committed
185
                           int bs, int tx_type) {
186
  int r, c;
187
  const int shift = bs < 32 ? 3 : (bs < 64 ? 2 : 1);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
188
  if (tx_type == IDTX) {
Jingning Han's avatar
Jingning Han committed
189 190
    for (r = 0; r < bs; ++r) {
      for (c = 0; c < bs; ++c)
Debargha Mukherjee's avatar
Debargha Mukherjee committed
191 192 193
        dest[c] = clip_pixel_add(dest[c], input[c] >> shift);
      dest += stride;
      input += bs;
Jingning Han's avatar
Jingning Han committed
194
    }
195 196
  }
}
197
#endif  // CONFIG_EXT_TX
198

clang-format's avatar
clang-format committed
199 200 201 202 203
#define FLIPUD_PTR(dest, stride, size)       \
  do {                                       \
    (dest) = (dest) + ((size)-1) * (stride); \
    (stride) = -(stride);                    \
  } while (0)
204

205
#if CONFIG_EXT_TX
clang-format's avatar
clang-format committed
206 207 208
static void maybe_flip_strides(uint8_t **dst, int *dstride, tran_low_t **src,
                               int *sstride, int tx_type, int sizey,
                               int sizex) {
209 210 211 212 213 214 215 216
  // 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
217
    case IDTX:
Jingning Han's avatar
Jingning Han committed
218 219
    case V_DCT:
    case H_DCT:
220
    case V_ADST:
clang-format's avatar
clang-format committed
221
    case H_ADST: break;
222 223
    case FLIPADST_DCT:
    case FLIPADST_ADST:
224
    case V_FLIPADST:
225
      // flip UD
226
      FLIPUD_PTR(*dst, *dstride, sizey);
227 228 229
      break;
    case DCT_FLIPADST:
    case ADST_FLIPADST:
230
    case H_FLIPADST:
231
      // flip LR
232
      FLIPUD_PTR(*src, *sstride, sizex);
233 234 235
      break;
    case FLIPADST_FLIPADST:
      // flip UD
236
      FLIPUD_PTR(*dst, *dstride, sizey);
237
      // flip LR
238
      FLIPUD_PTR(*src, *sstride, sizex);
239
      break;
clang-format's avatar
clang-format committed
240
    default: assert(0); break;
241 242
  }
}
243
#endif  // CONFIG_EXT_TX
244

245
#if CONFIG_HIGHBITDEPTH
246
#if CONFIG_EXT_TX && CONFIG_TX64X64
247
static void highbd_inv_idtx_add_c(const tran_low_t *input, uint8_t *dest8,
248
                                  int stride, int bs, int tx_type, int bd) {
249 250 251
  int r, c;
  const int shift = bs < 32 ? 3 : 2;
  uint16_t *dest = CONVERT_TO_SHORTPTR(dest8);
252

Debargha Mukherjee's avatar
Debargha Mukherjee committed
253
  if (tx_type == IDTX) {
254 255
    for (r = 0; r < bs; ++r) {
      for (c = 0; c < bs; ++c)
Debargha Mukherjee's avatar
Debargha Mukherjee committed
256 257 258
        dest[c] = highbd_clip_pixel_add(dest[c], input[c] >> shift, bd);
      dest += stride;
      input += bs;
259
    }
260 261
  }
}
262
#endif  // CONFIG_EXT_TX && CONFIG_TX64X64
263
#endif  // CONFIG_HIGHBITDEPTH
264

Lester Lu's avatar
Lester Lu committed
265 266 267
#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
268 269
  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
270 271 272 273 274 275 276 277 278
  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
279 280
  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
281 282 283 284 285 286 287
  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
288 289 290 291 292 293 294 295 296 297 298
// 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
299 300
    return 1;
  }
Lester Lu's avatar
Lester Lu committed
301
  lgtmtx[0] = NULL;
Lester Lu's avatar
Lester Lu committed
302 303 304
  return 0;
}

Lester Lu's avatar
Lester Lu committed
305 306 307 308 309 310 311 312 313
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
314 315
    return 1;
  }
Lester Lu's avatar
Lester Lu committed
316
  lgtmtx[0] = NULL;
Lester Lu's avatar
Lester Lu committed
317 318 319 320
  return 0;
}
#endif  // CONFIG_LGT

Yaowu Xu's avatar
Yaowu Xu committed
321
void av1_iht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride,
322 323
                         const TxfmParam *txfm_param) {
  int tx_type = txfm_param->tx_type;
Sarah Parker's avatar
Sarah Parker committed
324 325 326
#if CONFIG_MRC_TX
  assert(tx_type != MRC_DCT && "Invalid tx type for tx size");
#endif  // CONFIG_MRC_TX
327
#if !CONFIG_DAALA_DCT4
328 329 330 331
  if (tx_type == DCT_DCT) {
    aom_idct4x4_16_add(input, dest, stride);
    return;
  }
332
#endif
333
  static const transform_2d IHT_4[] = {
Luca Barbato's avatar
Luca Barbato committed
334 335 336 337
    { 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
338
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
339 340 341 342 343 344 345 346 347 348 349 350
    { 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
351
#endif
352 353 354
  };

  int i, j;
355
  tran_low_t tmp[4][4];
356 357 358
  tran_low_t out[4][4];
  tran_low_t *outp = &out[0][0];
  int outstride = 4;
359

360 361 362 363
#if CONFIG_DCT_ONLY
  assert(tx_type == DCT_DCT);
#endif

Lester Lu's avatar
Lester Lu committed
364
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
365 366 367 368
  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
369 370
#endif

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

  // transpose
389 390 391
  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
      tmp[j][i] = out[i][j];
392
    }
393 394 395 396
  }

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

#if CONFIG_EXT_TX
406
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, 4, 4);
407 408 409 410
#endif

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

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

453 454
  const int n = 4;
  const int n2 = 8;
455
  int i, j;
456
  tran_low_t out[4][8], tmp[4][8], outtmp[4];
457
  tran_low_t *outp = &out[0][0];
458
  int outstride = n2;
459

Lester Lu's avatar
Lester Lu committed
460
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
461 462 463 464
  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
465 466
#endif

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

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

490
#if CONFIG_EXT_TX
491
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n2, n);
492
#endif
493 494

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

534 535
  const int n = 4;
  const int n2 = 8;
536 537

  int i, j;
538
  tran_low_t out[8][4], tmp[8][4], outtmp[8];
539
  tran_low_t *outp = &out[0][0];
540
  int outstride = n;
541

Lester Lu's avatar
Lester Lu committed
542
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
543 544 545 546
  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
547 548
#endif

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

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

572
#if CONFIG_EXT_TX
573
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n2);
574
#endif
575 576

  // Sum with the destination
577 578
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n2; ++j) {
579 580 581 582 583 584 585
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 5));
    }
  }
}

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

Lester Lu's avatar
Lester Lu committed
623
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
624 625
  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
626 627
#endif

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

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

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

689 690 691 692
  const int n = 4;
  const int n4 = 16;

  int i, j;
693
  tran_low_t out[16][4], tmp[16][4], outtmp[16];
694 695 696
  tran_low_t *outp = &out[0][0];
  int outstride = n;

Lester Lu's avatar
Lester Lu committed
697
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
698 699
  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
700 701
#endif

702 703 704
  // inverse transform row vectors and transpose
  for (i = 0; i < n; ++i) {
    IHT_16x4[tx_type].rows(input, outtmp);
705
    for (j = 0; j < n4; ++j) tmp[j][i] = outtmp[j];
706 707 708 709
    input += n4;
  }

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

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

  const int n = 8;
  const int n2 = 16;
  int i, j;
766
  tran_low_t out[8][16], tmp[8][16], outtmp[8];
767 768 769
  tran_low_t *outp = &out[0][0];
  int outstride = n2;

Lester Lu's avatar
Lester Lu committed
770
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
771 772
  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
773 774
#endif

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

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

793
#if CONFIG_EXT_TX
794
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n2, n);
795
#endif
796 797 798 799 800 801 802 803 804 805 806

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

837 838 839 840
  const int n = 8;
  const int n2 = 16;

  int i, j;
841
  tran_low_t out[16][8], tmp[16][8], outtmp[16];
842 843 844
  tran_low_t *outp = &out[0][0];
  int outstride = n;

Lester Lu's avatar
Lester Lu committed
845
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
846 847
  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
848 849
#endif

850 851 852 853
  // 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)
854
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
clang-format's avatar
clang-format committed
855
    input += n2;
856 857 858 859
  }

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

868
#if CONFIG_EXT_TX
869
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n2);
870
#endif
871 872 873 874 875 876 877 878 879 880 881

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

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

Lester Lu's avatar
Lester Lu committed
919
#if CONFIG_LGT
Lester Lu's avatar
Lester Lu committed
920 921
  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
922 923
#endif

924 925
  // inverse transform row vectors and transpose
  for (i = 0; i < n4; ++i) {
Lester Lu's avatar
Lester Lu committed
926 927
#if CONFIG_LGT
    if (use_lgt_row)
Lester Lu's avatar
Lester Lu committed
928
      ilgt8(input, outtmp, lgtmtx_row[0]);
Lester Lu's avatar
Lester Lu committed
929 930 931
    else
#endif
      IHT_8x32[tx_type].rows(input, outtmp);
932
    for (j = 0; j < n; ++j) tmp[j][i] = outtmp[j];
933 934 935 936
    input += n;
  }

  // inverse transform column vectors
Lester Lu's avatar
Lester Lu committed
937