1D IDCT的实施如何运作?

时间:2012-01-04 08:56:34

标签: c math fft dct

我有一个反向离散余弦变换的实现,我试图弄清楚他们是如何得到这个代码的。到目前为止,我已经发现这可能是DCT的Cooley-Tukey radix-2 Decimation-in-time的优化实现,而不是DFT(离散傅立叶变换)。

然而,我仍然对每个阶段发生的事情感到茫然。我认为Wx常数可能是旋转因素。

任何人都可以提供解释的参考,或者对此代码提供一些解释吗?

//Twiddle factors
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */

//Discrete Cosine Transform on a row of 8 DCT coefficients.
NJ_INLINE void njRowIDCT(int* blk) {
    int x0, x1, x2, x3, x4, x5, x6, x7, x8;
    int t;
    if (!((x1 = blk[4] << 11)
        | (x2 = blk[6])
        | (x3 = blk[2])
        | (x4 = blk[1])
        | (x5 = blk[7])
        | (x6 = blk[5])
        | (x7 = blk[3])))
    {
        blk[0] = blk[1] = blk[2] = blk[3] = blk[4] = blk[5] = blk[6] = blk[7] = blk[0] << 3;
        return;
    }
    x0 = (blk[0] << 11) + 128;  //For rounding at fourth stage

    //First stage
    /*What exactly are we doing here? Do the x values have a meaning?*/
    x8 = W7 * (x4 + x5);
    x4 = x8 + (W1 - W7) * x4;
    x5 = x8 - (W1 + W7) * x5;
    x8 = W3 * (x6 + x7);
    x6 = x8 - (W3 - W5) * x6;
    x7 = x8 - (W3 + W5) * x7;

    //Second stage
    x8 = x0 + x1;
    x0 -= x1;
    x1 = W6 * (x3 + x2);
    x2 = x1 - (W2 + W6) * x2;
    x3 = x1 + (W2 - W6) * x3;
    x1 = x4 + x6;
    x4 -= x6;
    x6 = x5 + x7;
    x5 -= x7;

    //Third stage
    x7 = x8 + x3;
    x8 -= x3;
    x3 = x0 + x2;
    x0 -= x2;
    x2 = (181 * (x4 + x5) + 128) >> 8;
    x4 = (181 * (x4 - x5) + 128) >> 8;

    //Fourth stage
    blk[0] = (x7 + x1) >> 8;  //bit shift is to emulate 8 bit fixed point precision
    blk[1] = (x3 + x2) >> 8;
    blk[2] = (x0 + x4) >> 8;
    blk[3] = (x8 + x6) >> 8;
    blk[4] = (x8 - x6) >> 8;
    blk[5] = (x0 - x4) >> 8;
    blk[6] = (x3 - x2) >> 8;
    blk[7] = (x7 - x1) >> 8;

}

2 个答案:

答案 0 :(得分:4)

我不是DCT的专家,但我已经写了一些FFT implementations,所以我会采取措施来回答这个问题。请少量盐摄取以下内容。

void njRowIDCT(int* blk)

您正确地说该算法似乎是一个8长度的Radix-2 DCT,它使用24:8精度的定点算法。我猜测精度是因为最后一个阶段右移8来得到所需的(那个和告诉故事评论;)

因为其长度为8,其功率为3(2 ^ 3 = 8),这意味着DCT中有3个阶段。到目前为止,这与FFT非常相似。 “第四阶段”似乎只是在定点算术后恢复原始精度的缩放。

据我所知,输入阶段是从输入数组blk到局部变量x0-x7的bit-reversal。 x8似乎是一个临时变量。对不起,我不能比这更具描述性。

比特反转阶段

Bit Reversal of input

<强>更新

看看DSP For Scientists and Engineers。它为信号处理主题提供了清晰准确的解释。本章是关于DCT的(请跳到第497页)。

Wn(旋转因子)对应于本章的基本功能,但请注意这是描述8x8(2D)DCT。

关于我提到的3个阶段,与8点FFT的描述相比:

8ptFFTGraph

FFT在位反转输入数组上执行蝶形运算(基本上是复数乘法相加),沿途将一条路径乘以Wn或旋转因子。 FFT分阶段执行。我还没有弄清楚你的DCT代码在做什么,但是把它分解成这样的图表可能会有所帮助。

那个或者知道他们正在谈论什么的人会加强; - )

我将重新访问此页面并在我解读更多代码时进行编辑

答案 1 :(得分:1)

DFT和DCT都只是线性变换,可以表示为单个复数矩阵乘法(有时修剪为严格实数输入)。所以你可以结合上面的方程来得到每个最终项的公式,它最终应该相当于线性变换矩阵的一行(忽略舍入问题)。然后看看上面的代码序列是如何在行计算之间和/或行计算中手动执行公共子表达式优化或重构的。