package org.jcodec.common.dct;
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* @author The JCodec project
*
*/
public class IDCT4x4 {
public static void idct(int[] blk, int off) {
int i;
for (i = 0; i < 4; i++) {
idct4row(blk, off + (i << 2));
}
for (i = 0; i < 4; i++) {
idct4col_add(blk, off + i);
}
}
public static final int CN_SHIFT = 12;
public static final int C_FIX(double x) {
return ((int) ((x) * 1.414213562 * (1 << CN_SHIFT) + 0.5));
}
public static final int C1 = C_FIX(0.6532814824);
public static final int C2 = C_FIX(0.2705980501);
public static final int C3 = C_FIX(0.5);
public static final int C_SHIFT = (4 + 2 + 12);
private static void idct4col_add(int[] blk, int off) {
int c0, c1, c2, c3, a0, a1, a2, a3;
a0 = blk[off];
a1 = blk[off + 4];
a2 = blk[off + 8];
a3 = blk[off + 12];
c0 = (a0 + a2) * C3 + (1 << (C_SHIFT - 1));
c2 = (a0 - a2) * C3 + (1 << (C_SHIFT - 1));
c1 = a1 * C1 + a3 * C2;
c3 = a1 * C2 - a3 * C1;
blk[off] = ((c0 + c1) >> C_SHIFT);
blk[off + 4] = ((c2 + c3) >> C_SHIFT);
blk[off + 8] = ((c2 - c3) >> C_SHIFT);
blk[off + 12] = ((c0 - c1) >> C_SHIFT);
}
public static final int RN_SHIFT = 15;
public static final int R_FIX(double x) {
return ((int) ((x) * 1.414213562 * (1 << RN_SHIFT) + 0.5));
}
public static final int R1 = R_FIX(0.6532814824);
public static final int R2 = R_FIX(0.2705980501);
public static final int R3 = R_FIX(0.5);
public static final int R_SHIFT = 11;
private static void idct4row(int[] blk, int off) {
int c0, c1, c2, c3, a0, a1, a2, a3;
a0 = blk[off];
a1 = blk[off + 1];
a2 = blk[off + 2];
a3 = blk[off + 3];
c0 = (a0 + a2) * R3 + (1 << (R_SHIFT - 1));
c2 = (a0 - a2) * R3 + (1 << (R_SHIFT - 1));
c1 = a1 * R1 + a3 * R2;
c3 = a1 * R2 - a3 * R1;
blk[off] = (c0 + c1) >> R_SHIFT;
blk[off + 1] = (c2 + c3) >> R_SHIFT;
blk[off + 2] = (c2 - c3) >> R_SHIFT;
blk[off + 3] = (c0 - c1) >> R_SHIFT;
}
}