idct.c 67.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"
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 39 40 41 42 43 44
static void iidtx4_c(const tran_low_t *input, tran_low_t *output) {
  int i;
  for (i = 0; i < 4; ++i)
    output[i] = (tran_low_t)dct_const_round_shift(input[i] * Sqrt2);
}

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

static void iidtx16_c(const tran_low_t *input, tran_low_t *output) {
  int i;
  for (i = 0; i < 16; ++i)
    output[i] = (tran_low_t)dct_const_round_shift(input[i] * 2 * Sqrt2);
}

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

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

68
// For use in lieu of ADST
69 70 71 72 73 74 75
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);
  }
76 77 78
  for (i = 0; i < 16; ++i) {
    output[i] = input[16 + i] * 4;
  }
Luca Barbato's avatar
Luca Barbato committed
79
  aom_idct16_c(inputhalf, output + 16);
80 81 82
  // Note overall scaling factor is 4 times orthogonal
}

83 84 85 86 87
#if CONFIG_TX64X64
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];
88
  av1_idct64_new(in, out, inv_cos_bit_col_dct_64, inv_stage_range_col_dct_64);
89 90 91 92 93 94 95
  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];
96
  av1_idct64_new(in, out, inv_cos_bit_row_dct_64, inv_stage_range_row_dct_64);
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
  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
116
// Inverse identity transform and add.
117
#if CONFIG_EXT_TX
118
static void inv_idtx_add_c(const tran_low_t *input, uint8_t *dest, int stride,
Jingning Han's avatar
Jingning Han committed
119
                           int bs, int tx_type) {
120
  int r, c;
121
  const int shift = bs < 32 ? 3 : (bs < 64 ? 2 : 1);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
122
  if (tx_type == IDTX) {
Jingning Han's avatar
Jingning Han committed
123 124
    for (r = 0; r < bs; ++r) {
      for (c = 0; c < bs; ++c)
Debargha Mukherjee's avatar
Debargha Mukherjee committed
125 126 127
        dest[c] = clip_pixel_add(dest[c], input[c] >> shift);
      dest += stride;
      input += bs;
Jingning Han's avatar
Jingning Han committed
128
    }
129 130
  }
}
131
#endif  // CONFIG_EXT_TX
132

clang-format's avatar
clang-format committed
133 134 135 136 137
#define FLIPUD_PTR(dest, stride, size)       \
  do {                                       \
    (dest) = (dest) + ((size)-1) * (stride); \
    (stride) = -(stride);                    \
  } while (0)
138

139
#if CONFIG_EXT_TX
clang-format's avatar
clang-format committed
140 141 142
static void maybe_flip_strides(uint8_t **dst, int *dstride, tran_low_t **src,
                               int *sstride, int tx_type, int sizey,
                               int sizex) {
143 144 145 146 147 148 149 150
  // 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
151
    case IDTX:
Jingning Han's avatar
Jingning Han committed
152 153
    case V_DCT:
    case H_DCT:
154
    case V_ADST:
clang-format's avatar
clang-format committed
155
    case H_ADST: break;
156 157
    case FLIPADST_DCT:
    case FLIPADST_ADST:
158
    case V_FLIPADST:
159
      // flip UD
160
      FLIPUD_PTR(*dst, *dstride, sizey);
161 162 163
      break;
    case DCT_FLIPADST:
    case ADST_FLIPADST:
164
    case H_FLIPADST:
165
      // flip LR
166
      FLIPUD_PTR(*src, *sstride, sizex);
167 168 169
      break;
    case FLIPADST_FLIPADST:
      // flip UD
170
      FLIPUD_PTR(*dst, *dstride, sizey);
171
      // flip LR
172
      FLIPUD_PTR(*src, *sstride, sizex);
173
      break;
clang-format's avatar
clang-format committed
174
    default: assert(0); break;
175 176
  }
}
177
#endif  // CONFIG_EXT_TX
178

179
#if CONFIG_HIGHBITDEPTH
180
#if CONFIG_EXT_TX && CONFIG_TX64X64
181
static void highbd_inv_idtx_add_c(const tran_low_t *input, uint8_t *dest8,
182
                                  int stride, int bs, int tx_type, int bd) {
183 184 185
  int r, c;
  const int shift = bs < 32 ? 3 : 2;
  uint16_t *dest = CONVERT_TO_SHORTPTR(dest8);
186

Debargha Mukherjee's avatar
Debargha Mukherjee committed
187
  if (tx_type == IDTX) {
188 189
    for (r = 0; r < bs; ++r) {
      for (c = 0; c < bs; ++c)
Debargha Mukherjee's avatar
Debargha Mukherjee committed
190 191 192
        dest[c] = highbd_clip_pixel_add(dest[c], input[c] >> shift, bd);
      dest += stride;
      input += bs;
193
    }
194 195
  }
}
196
#endif  // CONFIG_EXT_TX && CONFIG_TX64X64
197
#endif  // CONFIG_HIGHBITDEPTH
198

Yaowu Xu's avatar
Yaowu Xu committed
199
void av1_iht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride,
200 201
                         const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
202
  static const transform_2d IHT_4[] = {
Luca Barbato's avatar
Luca Barbato committed
203 204 205 206
    { 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
207
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
208 209 210 211 212 213 214 215 216 217 218 219
    { 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
220
#endif
221 222 223
  };

  int i, j;
224
  tran_low_t tmp[4][4];
225 226 227
  tran_low_t out[4][4];
  tran_low_t *outp = &out[0][0];
  int outstride = 4;
228 229 230

  // inverse transform row vectors
  for (i = 0; i < 4; ++i) {
231
    IHT_4[tx_type].rows(input, out[i]);
clang-format's avatar
clang-format committed
232
    input += 4;
233 234 235
  }

  // transpose
236 237 238
  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
      tmp[j][i] = out[i][j];
239
    }
240 241 242 243
  }

  // inverse transform column vectors
  for (i = 0; i < 4; ++i) {
244
    IHT_4[tx_type].cols(tmp[i], out[i]);
245 246 247
  }

#if CONFIG_EXT_TX
248
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, 4, 4);
249 250 251 252
#endif

  // Sum with the destination
  for (i = 0; i < 4; ++i) {
253
    for (j = 0; j < 4; ++j) {
254 255 256
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 4));
257 258 259 260
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
261
void av1_iht4x8_32_add_c(const tran_low_t *input, uint8_t *dest, int stride,
262 263
                         const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
264
  static const transform_2d IHT_4x8[] = {
Luca Barbato's avatar
Luca Barbato committed
265 266 267 268
    { 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
269
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
270 271 272 273 274 275 276 277 278 279 280 281
    { 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
282
#endif
283 284
  };

285 286
  const int n = 4;
  const int n2 = 8;
287
  int i, j;
288
  tran_low_t out[4][8], tmp[4][8], outtmp[4];
289
  tran_low_t *outp = &out[0][0];
290
  int outstride = n2;
291 292

  // inverse transform row vectors and transpose
293
  for (i = 0; i < n2; ++i) {
294
    IHT_4x8[tx_type].rows(input, outtmp);
295
    for (j = 0; j < n; ++j)
296
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
297
    input += n;
298 299 300
  }

  // inverse transform column vectors
301
  for (i = 0; i < n; ++i) {
302
    IHT_4x8[tx_type].cols(tmp[i], out[i]);
303 304
  }

305
#if CONFIG_EXT_TX
306
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n2, n);
307
#endif
308 309

  // Sum with the destination
310 311
  for (i = 0; i < n2; ++i) {
    for (j = 0; j < n; ++j) {
312 313 314 315 316 317 318
      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
319
void av1_iht8x4_32_add_c(const tran_low_t *input, uint8_t *dest, int stride,
320 321
                         const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
322
  static const transform_2d IHT_8x4[] = {
Luca Barbato's avatar
Luca Barbato committed
323 324 325 326
    { 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
327
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
328 329 330 331 332 333 334 335 336 337 338 339
    { 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
340
#endif
341
  };
342

343 344
  const int n = 4;
  const int n2 = 8;
345 346

  int i, j;
347
  tran_low_t out[8][4], tmp[8][4], outtmp[8];
348
  tran_low_t *outp = &out[0][0];
349
  int outstride = n;
350 351

  // inverse transform row vectors and transpose
352
  for (i = 0; i < n; ++i) {
353
    IHT_8x4[tx_type].rows(input, outtmp);
354
    for (j = 0; j < n2; ++j)
355
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
356
    input += n2;
357 358 359
  }

  // inverse transform column vectors
360
  for (i = 0; i < n2; ++i) {
361
    IHT_8x4[tx_type].cols(tmp[i], out[i]);
362 363
  }

364
#if CONFIG_EXT_TX
365
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n2);
366
#endif
367 368

  // Sum with the destination
369 370
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n2; ++j) {
371 372 373 374 375 376 377
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 5));
    }
  }
}

378
void av1_iht4x16_64_add_c(const tran_low_t *input, uint8_t *dest, int stride,
379 380
                          const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
  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;
405
  tran_low_t out[4][16], tmp[4][16], outtmp[4];
406 407 408 409 410 411
  tran_low_t *outp = &out[0][0];
  int outstride = n4;

  // inverse transform row vectors and transpose
  for (i = 0; i < n4; ++i) {
    IHT_4x16[tx_type].rows(input, outtmp);
412
    for (j = 0; j < n; ++j) tmp[j][i] = outtmp[j];
413 414 415 416
    input += n;
  }

  // inverse transform column vectors
417
  for (i = 0; i < n; ++i) IHT_4x16[tx_type].cols(tmp[i], out[i]);
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433

#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,
434 435
                          const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
  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
  };
456

457 458 459 460
  const int n = 4;
  const int n4 = 16;

  int i, j;
461
  tran_low_t out[16][4], tmp[16][4], outtmp[16];
462 463 464 465 466 467
  tran_low_t *outp = &out[0][0];
  int outstride = n;

  // inverse transform row vectors and transpose
  for (i = 0; i < n; ++i) {
    IHT_16x4[tx_type].rows(input, outtmp);
468
    for (j = 0; j < n4; ++j) tmp[j][i] = outtmp[j];
469 470 471 472
    input += n4;
  }

  // inverse transform column vectors
473
  for (i = 0; i < n4; ++i) IHT_16x4[tx_type].cols(tmp[i], out[i]);
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488

#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
489
void av1_iht8x16_128_add_c(const tran_low_t *input, uint8_t *dest, int stride,
490 491
                           const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
492
  static const transform_2d IHT_8x16[] = {
Luca Barbato's avatar
Luca Barbato committed
493 494 495 496
    { 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
497
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
498 499 500 501 502 503 504 505 506 507 508 509
    { 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
510
#endif
511 512 513 514 515
  };

  const int n = 8;
  const int n2 = 16;
  int i, j;
516
  tran_low_t out[8][16], tmp[8][16], outtmp[8];
517 518 519 520 521 522 523
  tran_low_t *outp = &out[0][0];
  int outstride = n2;

  // inverse transform row vectors and transpose
  for (i = 0; i < n2; ++i) {
    IHT_8x16[tx_type].rows(input, outtmp);
    for (j = 0; j < n; ++j)
524
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
clang-format's avatar
clang-format committed
525
    input += n;
526 527 528 529
  }

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

533
#if CONFIG_EXT_TX
534
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n2, n);
535
#endif
536 537 538 539 540 541 542 543 544 545 546

  // 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
547
void av1_iht16x8_128_add_c(const tran_low_t *input, uint8_t *dest, int stride,
548 549
                           const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
550
  static const transform_2d IHT_16x8[] = {
Luca Barbato's avatar
Luca Barbato committed
551 552 553 554
    { 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
555
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
556 557 558 559 560 561 562 563 564 565 566 567
    { 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
568
#endif
569
  };
570

571 572 573 574
  const int n = 8;
  const int n2 = 16;

  int i, j;
575
  tran_low_t out[16][8], tmp[16][8], outtmp[16];
576 577 578 579 580 581 582
  tran_low_t *outp = &out[0][0];
  int outstride = n;

  // 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)
583
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
clang-format's avatar
clang-format committed
584
    input += n2;
585 586 587 588
  }

  // inverse transform column vectors
  for (i = 0; i < n2; ++i) {
589
    IHT_16x8[tx_type].cols(tmp[i], out[i]);
590 591
  }

592
#if CONFIG_EXT_TX
593
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n2);
594
#endif
595 596 597 598 599 600 601 602 603 604 605

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

606
void av1_iht8x32_256_add_c(const tran_low_t *input, uint8_t *dest, int stride,
607 608
                           const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
  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;
633
  tran_low_t out[8][32], tmp[8][32], outtmp[8];
634 635 636 637 638 639
  tran_low_t *outp = &out[0][0];
  int outstride = n4;

  // inverse transform row vectors and transpose
  for (i = 0; i < n4; ++i) {
    IHT_8x32[tx_type].rows(input, outtmp);
640
    for (j = 0; j < n; ++j) tmp[j][i] = outtmp[j];
641 642 643 644
    input += n;
  }

  // inverse transform column vectors
645
  for (i = 0; i < n; ++i) IHT_8x32[tx_type].cols(tmp[i], out[i]);
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661

#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], 6));
    }
  }
}

void av1_iht32x8_256_add_c(const tran_low_t *input, uint8_t *dest, int stride,
662 663
                           const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
  static const transform_2d IHT_32x8[] = {
    { aom_idct8_c, aom_idct32_c },     // DCT_DCT
    { aom_iadst8_c, aom_idct32_c },    // ADST_DCT
    { aom_idct8_c, ihalfright32_c },   // DCT_ADST
    { aom_iadst8_c, ihalfright32_c },  // ADST_ADST
#if CONFIG_EXT_TX
    { aom_iadst8_c, aom_idct32_c },    // FLIPADST_DCT
    { aom_idct8_c, ihalfright32_c },   // DCT_FLIPADST
    { aom_iadst8_c, ihalfright32_c },  // FLIPADST_FLIPADST
    { aom_iadst8_c, ihalfright32_c },  // ADST_FLIPADST
    { aom_iadst8_c, ihalfright32_c },  // FLIPADST_ADST
    { iidtx8_c, iidtx32_c },           // IDTX
    { aom_idct8_c, iidtx32_c },        // V_DCT
    { iidtx8_c, aom_idct32_c },        // H_DCT
    { aom_iadst8_c, iidtx32_c },       // V_ADST
    { iidtx8_c, ihalfright32_c },      // H_ADST
    { aom_iadst8_c, iidtx32_c },       // V_FLIPADST
    { iidtx8_c, ihalfright32_c },      // H_FLIPADST
#endif
  };
684

685 686 687 688
  const int n = 8;
  const int n4 = 32;

  int i, j;
689
  tran_low_t out[32][8], tmp[32][8], outtmp[32];
690 691 692 693 694 695
  tran_low_t *outp = &out[0][0];
  int outstride = n;

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

  // inverse transform column vectors
701
  for (i = 0; i < n4; ++i) IHT_32x8[tx_type].cols(tmp[i], out[i]);
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716

#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], 6));
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
717
void av1_iht16x32_512_add_c(const tran_low_t *input, uint8_t *dest, int stride,
718 719
                            const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
720
  static const transform_2d IHT_16x32[] = {
Luca Barbato's avatar
Luca Barbato committed
721 722 723 724
    { aom_idct32_c, aom_idct16_c },     // DCT_DCT
    { ihalfright32_c, aom_idct16_c },   // ADST_DCT
    { aom_idct32_c, aom_iadst16_c },    // DCT_ADST
    { ihalfright32_c, aom_iadst16_c },  // ADST_ADST
725
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
726 727 728 729 730 731 732 733 734 735 736 737
    { ihalfright32_c, aom_idct16_c },   // FLIPADST_DCT
    { aom_idct32_c, aom_iadst16_c },    // DCT_FLIPADST
    { ihalfright32_c, aom_iadst16_c },  // FLIPADST_FLIPADST
    { ihalfright32_c, aom_iadst16_c },  // ADST_FLIPADST
    { ihalfright32_c, aom_iadst16_c },  // FLIPADST_ADST
    { iidtx32_c, iidtx16_c },           // IDTX
    { aom_idct32_c, iidtx16_c },        // V_DCT
    { iidtx32_c, aom_idct16_c },        // H_DCT
    { ihalfright32_c, iidtx16_c },      // V_ADST
    { iidtx32_c, aom_iadst16_c },       // H_ADST
    { ihalfright32_c, iidtx16_c },      // V_FLIPADST
    { iidtx32_c, aom_iadst16_c },       // H_FLIPADST
738
#endif
739 740 741 742 743
  };

  const int n = 16;
  const int n2 = 32;
  int i, j;
744
  tran_low_t out[16][32], tmp[16][32], outtmp[16];
745 746 747 748 749 750 751
  tran_low_t *outp = &out[0][0];
  int outstride = n2;

  // inverse transform row vectors and transpose
  for (i = 0; i < n2; ++i) {
    IHT_16x32[tx_type].rows(input, outtmp);
    for (j = 0; j < n; ++j)
752
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
clang-format's avatar
clang-format committed
753
    input += n;
754 755 756 757
  }

  // inverse transform column vectors
  for (i = 0; i < n; ++i) {
758
    IHT_16x32[tx_type].cols(tmp[i], out[i]);
759 760
  }

761
#if CONFIG_EXT_TX
762
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n2, n);
763
#endif
764 765 766 767 768 769 770 771 772 773 774

  // 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
775
void av1_iht32x16_512_add_c(const tran_low_t *input, uint8_t *dest, int stride,
776 777
                            const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
778
  static const transform_2d IHT_32x16[] = {
Luca Barbato's avatar
Luca Barbato committed
779 780 781 782
    { aom_idct16_c, aom_idct32_c },     // DCT_DCT
    { aom_iadst16_c, aom_idct32_c },    // ADST_DCT
    { aom_idct16_c, ihalfright32_c },   // DCT_ADST
    { aom_iadst16_c, ihalfright32_c },  // ADST_ADST
783
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
784 785 786 787 788 789 790 791 792 793 794 795
    { aom_iadst16_c, aom_idct32_c },    // FLIPADST_DCT
    { aom_idct16_c, ihalfright32_c },   // DCT_FLIPADST
    { aom_iadst16_c, ihalfright32_c },  // FLIPADST_FLIPADST
    { aom_iadst16_c, ihalfright32_c },  // ADST_FLIPADST
    { aom_iadst16_c, ihalfright32_c },  // FLIPADST_ADST
    { iidtx16_c, iidtx32_c },           // IDTX
    { aom_idct16_c, iidtx32_c },        // V_DCT
    { iidtx16_c, aom_idct32_c },        // H_DCT
    { aom_iadst16_c, iidtx32_c },       // V_ADST
    { iidtx16_c, ihalfright32_c },      // H_ADST
    { aom_iadst16_c, iidtx32_c },       // V_FLIPADST
    { iidtx16_c, ihalfright32_c },      // H_FLIPADST
796
#endif
797 798 799 800 801
  };
  const int n = 16;
  const int n2 = 32;

  int i, j;
802
  tran_low_t out[32][16], tmp[32][16], outtmp[32];
803 804 805 806 807 808 809
  tran_low_t *outp = &out[0][0];
  int outstride = n;

  // inverse transform row vectors and transpose
  for (i = 0; i < n; ++i) {
    IHT_32x16[tx_type].rows(input, outtmp);
    for (j = 0; j < n2; ++j)
810
      tmp[j][i] = (tran_low_t)dct_const_round_shift(outtmp[j] * Sqrt2);
clang-format's avatar
clang-format committed
811
    input += n2;
812 813 814 815
  }

  // inverse transform column vectors
  for (i = 0; i < n2; ++i) {
816
    IHT_32x16[tx_type].cols(tmp[i], out[i]);
817 818
  }

819
#if CONFIG_EXT_TX
820
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, n, n2);
821
#endif
822 823 824 825 826 827 828 829 830 831 832

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

Yaowu Xu's avatar
Yaowu Xu committed
833
void av1_iht8x8_64_add_c(const tran_low_t *input, uint8_t *dest, int stride,
834 835
                         const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
836
  static const transform_2d IHT_8[] = {
Luca Barbato's avatar
Luca Barbato committed
837 838 839 840
    { aom_idct8_c, aom_idct8_c },    // DCT_DCT  = 0
    { aom_iadst8_c, aom_idct8_c },   // ADST_DCT = 1
    { aom_idct8_c, aom_iadst8_c },   // DCT_ADST = 2
    { aom_iadst8_c, aom_iadst8_c },  // ADST_ADST = 3
841
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
842 843 844 845 846 847 848 849 850 851 852 853 854
    { aom_iadst8_c, aom_idct8_c },   // FLIPADST_DCT
    { aom_idct8_c, aom_iadst8_c },   // DCT_FLIPADST
    { aom_iadst8_c, aom_iadst8_c },  // FLIPADST_FLIPADST
    { aom_iadst8_c, aom_iadst8_c },  // ADST_FLIPADST
    { aom_iadst8_c, aom_iadst8_c },  // FLIPADST_ADST
    { iidtx8_c, iidtx8_c },          // IDTX
    { aom_idct8_c, iidtx8_c },       // V_DCT
    { iidtx8_c, aom_idct8_c },       // H_DCT
    { aom_iadst8_c, iidtx8_c },      // V_ADST
    { iidtx8_c, aom_iadst8_c },      // H_ADST
    { aom_iadst8_c, iidtx8_c },      // V_FLIPADST
    { iidtx8_c, aom_iadst8_c },      // H_FLIPADST
#endif                               // CONFIG_EXT_TX
855 856
  };

Jingning Han's avatar
Jingning Han committed
857
  int i, j;
858
  tran_low_t tmp[8][8];
859 860 861
  tran_low_t out[8][8];
  tran_low_t *outp = &out[0][0];
  int outstride = 8;
Jingning Han's avatar
Jingning Han committed
862 863 864

  // inverse transform row vectors
  for (i = 0; i < 8; ++i) {
865
    IHT_8[tx_type].rows(input, out[i]);
clang-format's avatar
clang-format committed
866
    input += 8;
867 868 869
  }

  // transpose
870 871 872
  for (i = 0; i < 8; i++) {
    for (j = 0; j < 8; j++) {
      tmp[j][i] = out[i][j];
873
    }
Jingning Han's avatar
Jingning Han committed
874 875 876 877
  }

  // inverse transform column vectors
  for (i = 0; i < 8; ++i) {
878
    IHT_8[tx_type].cols(tmp[i], out[i]);
879 880 881
  }

#if CONFIG_EXT_TX
882
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, 8, 8);
883 884 885 886
#endif

  // Sum with the destination
  for (i = 0; i < 8; ++i) {
Jingning Han's avatar
Jingning Han committed
887
    for (j = 0; j < 8; ++j) {
888 889 890
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 5));
Jingning Han's avatar
Jingning Han committed
891 892 893 894
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
895
void av1_iht16x16_256_add_c(const tran_low_t *input, uint8_t *dest, int stride,
896 897
                            const INV_TXFM_PARAM *param) {
  int tx_type = param->tx_type;
898
  static const transform_2d IHT_16[] = {
Luca Barbato's avatar
Luca Barbato committed
899 900 901 902
    { aom_idct16_c, aom_idct16_c },    // DCT_DCT  = 0
    { aom_iadst16_c, aom_idct16_c },   // ADST_DCT = 1
    { aom_idct16_c, aom_iadst16_c },   // DCT_ADST = 2
    { aom_iadst16_c, aom_iadst16_c },  // ADST_ADST = 3
903
#if CONFIG_EXT_TX
Luca Barbato's avatar
Luca Barbato committed
904 905 906 907 908 909 910 911 912 913 914 915 916
    { aom_iadst16_c, aom_idct16_c },   // FLIPADST_DCT
    { aom_idct16_c, aom_iadst16_c },   // DCT_FLIPADST
    { aom_iadst16_c, aom_iadst16_c },  // FLIPADST_FLIPADST
    { aom_iadst16_c, aom_iadst16_c },  // ADST_FLIPADST
    { aom_iadst16_c, aom_iadst16_c },  // FLIPADST_ADST
    { iidtx16_c, iidtx16_c },          // IDTX
    { aom_idct16_c, iidtx16_c },       // V_DCT
    { iidtx16_c, aom_idct16_c },       // H_DCT
    { aom_iadst16_c, iidtx16_c },      // V_ADST
    { iidtx16_c, aom_iadst16_c },      // H_ADST
    { aom_iadst16_c, iidtx16_c },      // V_FLIPADST
    { iidtx16_c, aom_iadst16_c },      // H_FLIPADST
#endif                                 // CONFIG_EXT_TX
917
  };
918

Jingning Han's avatar
Jingning Han committed
919
  int i, j;
920
  tran_low_t tmp[16][16];
921 922 923 924 925 926 927
  tran_low_t out[16][16];
  tran_low_t *outp = &out[0][0];
  int outstride = 16;

  // inverse transform row vectors
  for (i = 0; i < 16; ++i) {
    IHT_16[tx_type].rows(input, out[i]);
clang-format's avatar
clang-format committed
928
    input += 16;
929 930 931
  }

  // transpose
932 933 934
  for (i = 0; i < 16; i++) {
    for (j = 0; j < 16; j++) {
      tmp[j][i] = out[i][j];
935 936
    }
  }
Jingning Han's avatar
Jingning Han committed
937

938
  // inverse transform column vectors
Jingning Han's avatar
Jingning Han committed
939
  for (i = 0; i < 16; ++i) {
940
    IHT_16[tx_type].cols(tmp[i], out[i]);
Jingning Han's avatar
Jingning Han committed
941 942
  }

943
#if CONFIG_EXT_TX
944
  maybe_flip_strides(&dest, &stride, &outp, &outstride, tx_type, 16, 16);
945 946 947
#endif

  // Sum with the destination
Jingning Han's avatar
Jingning Han committed
948 949
  for (i = 0; i < 16; ++i) {
    for (j = 0; j < 16; ++j) {
950 951 952
      int d = i * stride + j;
      int s = j * outstride + i;
      dest[d] = clip_pixel_add(dest[d], ROUND_POWER_OF_TWO(outp[s], 6));
Jingning Han's avatar
Jingning Han committed
953