blob: 32ad568998be65708efbecb5a23baaec13b6971e [file] [log] [blame]
#include "av1/common/daala_tx.h"
#include "av1/common/odintrin.h"
/* clang-format off */
# define OD_DCT_RSHIFT(_a, _b) OD_UNBIASED_RSHIFT32(_a, _b)
/* TODO: Daala DCT overflow checks need to be ported as a later test */
# if defined(OD_DCT_CHECK_OVERFLOW)
# else
# define OD_DCT_OVERFLOW_CHECK(val, scale, offset, idx)
# endif
#define OD_FDCT_2_ASYM(p0, p1, p1h) \
/* Embedded 2-point asymmetric Type-II fDCT. */ \
do { \
p0 += p1h; \
p1 = p0 - p1; \
} \
while (0)
#define OD_IDCT_2_ASYM(p0, p1, p1h) \
/* Embedded 2-point asymmetric Type-II iDCT. */ \
do { \
p1 = p0 - p1; \
p1h = OD_DCT_RSHIFT(p1, 1); \
p0 -= p1h; \
} \
while (0)
#define OD_FDST_2_ASYM(p0, p1) \
/* Embedded 2-point asymmetric Type-IV fDST. */ \
do { \
/* 11507/16384 ~= 4*Sin[Pi/8] - 2*Tan[Pi/8] ~= 0.702306604714169 */ \
OD_DCT_OVERFLOW_CHECK(p1, 11507, 8192, 187); \
p0 -= (p1*11507 + 8192) >> 14; \
/* 669/1024 ~= Cos[Pi/8]/Sqrt[2] ~= 0.653281482438188 */ \
OD_DCT_OVERFLOW_CHECK(p0, 669, 512, 188); \
p1 += (p0*669 + 512) >> 10; \
/* 4573/4096 ~= 4*Sin[Pi/8] - Tan[Pi/8] ~= 1.11652016708726 */ \
OD_DCT_OVERFLOW_CHECK(p1, 4573, 2048, 189); \
p0 -= (p1*4573 + 2048) >> 12; \
} \
while (0)
#define OD_IDST_2_ASYM(p0, p1) \
/* Embedded 2-point asymmetric Type-IV iDST. */ \
do { \
/* 4573/4096 ~= 4*Sin[Pi/8] - Tan[Pi/8] ~= 1.11652016708726 */ \
p0 += (p1*4573 + 2048) >> 12; \
/* 669/1024 ~= Cos[Pi/8]/Sqrt[2] ~= 0.653281482438188 */ \
p1 -= (p0*669 + 512) >> 10; \
/* 11507/16384 ~= 4*Sin[Pi/8] - 2*Tan[Pi/8] ~= 0.702306604714169 */ \
p0 += (p1*11507 + 8192) >> 14; \
} \
while (0)
#define OD_FDCT_4(q0, q2, q1, q3) \
/* Embedded 4-point orthonormal Type-II fDCT. */ \
do { \
int q2h; \
int q3h; \
q3 = q0 - q3; \
q3h = OD_DCT_RSHIFT(q3, 1); \
q0 -= q3h; \
q2 += q1; \
q2h = OD_DCT_RSHIFT(q2, 1); \
q1 = q2h - q1; \
OD_FDCT_2_ASYM(q0, q2, q2h); \
OD_FDST_2_ASYM(q3, q1); \
} \
while (0)
#define OD_IDCT_4(q0, q2, q1, q3) \
/* Embedded 4-point orthonormal Type-II iDCT. */ \
do { \
int q1h; \
int q3h; \
OD_IDST_2_ASYM(q3, q2); \
OD_IDCT_2_ASYM(q0, q1, q1h); \
q3h = OD_DCT_RSHIFT(q3, 1); \
q0 += q3h; \
q3 = q0 - q3; \
q2 = q1h - q2; \
q1 -= q2; \
} \
while (0)
void od_bin_fdct4(od_coeff y[4], const od_coeff *x, int xstride) {
int q0;
int q1;
int q2;
int q3;
q0 = x[0*xstride];
q2 = x[1*xstride];
q1 = x[2*xstride];
q3 = x[3*xstride];
OD_FDCT_4(q0, q2, q1, q3);
y[0] = (od_coeff)q0;
y[1] = (od_coeff)q1;
y[2] = (od_coeff)q2;
y[3] = (od_coeff)q3;
}
void od_bin_idct4(od_coeff *x, int xstride, const od_coeff y[4]) {
int q0;
int q1;
int q2;
int q3;
q0 = y[0];
q2 = y[1];
q1 = y[2];
q3 = y[3];
OD_IDCT_4(q0, q2, q1, q3);
x[0*xstride] = q0;
x[1*xstride] = q1;
x[2*xstride] = q2;
x[3*xstride] = q3;
}