这个 2D DCT 代码实际上是如何工作的?
How does this 2D DCT code actually work?
代码如下:
void dct(const tga_image *tga, double data[8][8],
const int xpos, const int ypos)
{
int i,j;
double in[8], out[8], rows[8][8];
/* transform rows */
for (j=0; j<8; j++)
{
for (i=0; i<8; i++)
in[i] = (double) pixel(tga, xpos+i, ypos+j);
dct_1d(in, out, 8);
for (i=0; i<8; i++) rows[j][i] = out[i];
}
/* transform columns */
for (j=0; j<8; j++)
{
for (i=0; i<8; i++)
in[i] = rows[i][j];
dct_1d(in, out, 8);
for (i=0; i<8; i++) data[i][j] = out[i];
}
}
取自listing2.c https://unix4lyfe.org/dct/
我只有 1 个问题,我们将行填写为 rows[j][i],然后读出 rows[i][j]。根据 2D DCT 公式,我们转置 DCT 矩阵而不是实际数据。为什么要转置实际数据?
如果我假设 xpos
为水平索引,ypos
为垂直索引,则以下内容为真。
函数 dct_1d(*,*,*);
仅适用于 一维数组 (此处为 in
和 out
)。您被带走的是由于 indexing
此处 C 中 2d 数组 的杂耍(特别是 rows
这里)。
通过在第一个 for
块中简单地交换变量 i
和 j
,相同的代码可以重写如下,这在您尝试时具有物理意义(看评论):
void dct(const tga_image *tga, double data[8][8],
const int xpos, const int ypos)
{
int i,j; /* as in matrix[i][j] */
double in[8], out[8], rows[8][8];
/* transform rows (each is running horizontally with j) */
for (i=0; i<8; i++)
{
for (j=0; j<8; j++)
in[j] = (double) pixel(tga, xpos+j, ypos+i); /* fill current row i */
/* Note above xpos in an image is horizontal as j is in a matrix[i][j] in c and
vice versa. (The fallacy that you will make is the following: You will think that
xpos corresponds to i and ypos corresponds to j, which is incorrect.) */
dct_1d(in, out, 8); /* transform current row i */
for (j=0; j<8; j++) rows[i][j] = out[j]; /* copy back current row i */
}
/* transform columns (each is running vertically with i) */
for (j=0; j<8; j++)
{
for (i=0; i<8; i++)
in[i] = rows[i][j]; /* fill current column j */
dct_1d(in, out, 8); /* transform current column j */
for (i=0; i<8; i++) data[i][j] = out[i]; /* copy back current column j */
}
}
代码如下:
void dct(const tga_image *tga, double data[8][8],
const int xpos, const int ypos)
{
int i,j;
double in[8], out[8], rows[8][8];
/* transform rows */
for (j=0; j<8; j++)
{
for (i=0; i<8; i++)
in[i] = (double) pixel(tga, xpos+i, ypos+j);
dct_1d(in, out, 8);
for (i=0; i<8; i++) rows[j][i] = out[i];
}
/* transform columns */
for (j=0; j<8; j++)
{
for (i=0; i<8; i++)
in[i] = rows[i][j];
dct_1d(in, out, 8);
for (i=0; i<8; i++) data[i][j] = out[i];
}
}
取自listing2.c https://unix4lyfe.org/dct/
我只有 1 个问题,我们将行填写为 rows[j][i],然后读出 rows[i][j]。根据 2D DCT 公式,我们转置 DCT 矩阵而不是实际数据。为什么要转置实际数据?
如果我假设 xpos
为水平索引,ypos
为垂直索引,则以下内容为真。
函数 dct_1d(*,*,*);
仅适用于 一维数组 (此处为 in
和 out
)。您被带走的是由于 indexing
此处 C 中 2d 数组 的杂耍(特别是 rows
这里)。
通过在第一个 for
块中简单地交换变量 i
和 j
,相同的代码可以重写如下,这在您尝试时具有物理意义(看评论):
void dct(const tga_image *tga, double data[8][8],
const int xpos, const int ypos)
{
int i,j; /* as in matrix[i][j] */
double in[8], out[8], rows[8][8];
/* transform rows (each is running horizontally with j) */
for (i=0; i<8; i++)
{
for (j=0; j<8; j++)
in[j] = (double) pixel(tga, xpos+j, ypos+i); /* fill current row i */
/* Note above xpos in an image is horizontal as j is in a matrix[i][j] in c and
vice versa. (The fallacy that you will make is the following: You will think that
xpos corresponds to i and ypos corresponds to j, which is incorrect.) */
dct_1d(in, out, 8); /* transform current row i */
for (j=0; j<8; j++) rows[i][j] = out[j]; /* copy back current row i */
}
/* transform columns (each is running vertically with i) */
for (j=0; j<8; j++)
{
for (i=0; i<8; i++)
in[i] = rows[i][j]; /* fill current column j */
dct_1d(in, out, 8); /* transform current column j */
for (i=0; i<8; i++) data[i][j] = out[i]; /* copy back current column j */
}
}