user427641 - 1 year ago 64
C Question

Trying to implement The inverse of a dct 8*8 matrix

I have managed to calculate the dct of an 8*8 matrix and I am having trouble doing the inverse. Can anyone have a look at this code and tell me what I am doing now. I should be getting the exact same values as before but im getting different values. I am reading in the input from a csv file and out putting it to anther csv file. Its programmed in c

``````void idct_func(float inMatrix[8][8]){

double idct,
Cu,
sum,
Cv;

int i,
j,
u,
v;

float idctMatrix[8][8],
greyLevel;

FILE * fp = fopen("mydata.csv", "r");
FILE * wp = fopen("idct.csv", "w");
fprintf(fp, "\n Inverse DCT");

for (i = 0; i < 8; ++i) {
for (j = 0; j < 8; ++j) {
sum = 0.0;
for (u = 0; u < 8; u++) {
for (v = 0; v < 8; v++) {
if (u == 0)
Cu = 1.0 / sqrt(2.0);
else
Cu = 1.0;
if (v == 0)
Cv = 1.0 / sqrt(2.0);
else
Cv = (1.0);
// Level around 0
greyLevel = idctMatrix[u][v];
idct = (greyLevel * cos((2 * i + 1) * u * M_PI / 16.0) *
cos((2 * j + 1) * v * M_PI / 16.0));
sum += idct;
}
}

idctMatrix[i][j] = 0.25 * Cu * Cv * sum;
fprintf(wp, "\n %f", idctMatrix[i][j]);
}
fprintf(wp, "\n");
}
``````

the original matrix is:

``````{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255}};
``````

the dct is :

``````2040   0  -0   0   0   0  -0  -0
0   0   0   0  -0   0  -0   0
-0   0  -0   0   0   0   0   0
0  -0  -0  -0   0  -0  -0   0
0   0  -0   0  -0  -0  -0   0
0  -0  -0  -0  -0   0  -0  -0
-0  -0  -0   0   0   0   0  -0
-0   0   0   0  -0   0  -0   0
``````

the idct calculated should be the same as the original

You're trying to calculate the IDCT in-place, using `idctMatrix[][]` as both input and output and hence the input is being modified in the process. That's wrong. You need to have a separate 2-dimensional array for input (or output).

It also appears that the u- and v-dependent scaling factors `Cu` and `Cv` are applied outside of the u- and v- loops. That would be wrong too.

EDIT: Here's the code if you can't understand the words:

``````#include <stdio.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265358979324
#endif

void Compute8x8Dct(const double in[8][8], double out[8][8])
{
int i, j, u, v;
double s;

for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
s = 0;

for (u = 0; u < 8; u++)
for (v = 0; v < 8; v++)
s += in[u][v] * cos((2 * u + 1) * i * M_PI / 16) *
cos((2 * v + 1) * j * M_PI / 16) *
((i == 0) ? 1 / sqrt(2) : 1) *
((j == 0) ? 1 / sqrt(2) : 1);

out[i][j] = s / 4;
}
}

void Compute8x8Idct(const double in[8][8], double out[8][8])
{
int i, j, u, v;
double s;

for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
s = 0;

for (u = 0; u < 8; u++)
for (v = 0; v < 8; v++)
s += in[u][v] * cos((2 * i + 1) * u * M_PI / 16) *
cos((2 * j + 1) * v * M_PI / 16) *
((u == 0) ? 1 / sqrt(2) : 1.) *
((v == 0) ? 1 / sqrt(2) : 1.);

out[i][j] = s / 4;
}
}

void Print8x8(const char* title, const double in[8][8])
{
int i, j;

printf("%s\n", title);

for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
printf("%8.3f ", in[i][j]);
printf("\n");
}
}

int main(void)
{
double pic1[8][8], dct[8][8], pic2[8][8];
int i, j;

for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
#if 01
pic1[i][j] = 255;
#else
pic1[i][j] = (i ^ j) & 1;
#endif
Print8x8("pic1:", pic1);
Compute8x8Dct(pic1, dct);
Print8x8("dct:", dct);
Compute8x8Idct(dct, pic2);
Print8x8("pic2:", pic2);

return 0;
}
``````

Here's its output:

``````pic1:
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
dct:
2040.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000
0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000
0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000
0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000
0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000
0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000
0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000
0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000
pic2:
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download