author | viric@mandarina |
Mon, 15 Dec 2008 01:06:43 +0000 | |
changeset 253 | e3aa70211aee |
parent 227 | f2a4f54d3fc8 |
permissions | -rw-r--r-- |
225 | 1 |
#include <stdio.h> |
2 |
#include <math.h> |
|
3 |
#include "libjpegrest.h" |
|
4 |
||
5 |
#define PI 3.141592657 |
|
6 |
||
226 | 7 |
/* This opens a 8x8 PGM file from argv[1], and stores |
8 |
* a 64+7x64+7 PGM file with each DCT-IDCT result, considering |
|
9 |
* only the coefficients from top-left until the concerning |
|
10 |
* DCT-IDCT result. */ |
|
11 |
||
225 | 12 |
static void mydct(float *in, float *out) |
13 |
{ |
|
14 |
int x,y,u,v; |
|
15 |
||
16 |
float Cu, Cv; |
|
17 |
||
18 |
for (u=0; u < 8; ++u) |
|
19 |
for (v=0; v < 8; ++v) |
|
20 |
{ |
|
21 |
float *optr; |
|
22 |
float sum; |
|
227
f2a4f54d3fc8
Fixed an error, regarding x-y switched in the DCT.
viric@llimona
parents:
226
diff
changeset
|
23 |
optr = out+v*8+u; |
225 | 24 |
|
25 |
sum = 0.; |
|
26 |
for (x=0; x < 8; ++x) |
|
226 | 27 |
for (y=0; y < 8; ++y) { |
225 | 28 |
float *iptr; |
29 |
iptr = in+y*8+x; |
|
30 |
||
31 |
sum += *iptr |
|
32 |
* cos(((float) ((2*x+1)*u) )*PI/16.) |
|
33 |
* cos(((float) ((2*y+1)*v) )*PI/16.); |
|
34 |
} |
|
35 |
||
36 |
if (u == 0) Cu = 1. / sqrt(2); else Cu = 1.; |
|
37 |
if (v == 0) Cv = 1. / sqrt(2); else Cv = 1.; |
|
38 |
*optr = 0.25 * Cu * Cv * sum; |
|
39 |
} |
|
40 |
} |
|
41 |
||
42 |
static void myidct(float *in, float *out) |
|
43 |
{ |
|
44 |
int x,y,u,v; |
|
45 |
||
46 |
float Cu, Cv; |
|
47 |
||
48 |
for (x=0; x < 8; ++x) |
|
49 |
for (y=0; y < 8; ++y) |
|
50 |
{ |
|
51 |
float *optr; |
|
52 |
float sum; |
|
53 |
optr = out+y*8+x; |
|
54 |
||
55 |
sum = 0.; |
|
56 |
for (v=0; v < 8; ++v) |
|
57 |
for (u=0; u < 8; ++u) |
|
58 |
{ |
|
59 |
float *iptr; |
|
227
f2a4f54d3fc8
Fixed an error, regarding x-y switched in the DCT.
viric@llimona
parents:
226
diff
changeset
|
60 |
iptr = in+v*8+u; |
225 | 61 |
|
62 |
if (u == 0) Cu = 1. / sqrt(2); else Cu = 1.; |
|
63 |
if (v == 0) Cv = 1. / sqrt(2); else Cv = 1.; |
|
64 |
||
65 |
sum += Cu * Cv * *iptr |
|
66 |
* cos(((float) ((2*x+1)*u) )*PI/16.) |
|
67 |
* cos(((float) ((2*y+1)*v) )*PI/16.); |
|
68 |
} |
|
69 |
||
70 |
*optr = 0.25 * sum; |
|
71 |
} |
|
72 |
} |
|
73 |
||
74 |
void zero_block(float *block) |
|
75 |
{ |
|
76 |
int i; |
|
77 |
for (i=0; i < 64; ++i) |
|
78 |
block[i] = 0.; |
|
79 |
} |
|
80 |
||
81 |
void prepare_subblock(float *block, int x, int y, const float *input) |
|
82 |
{ |
|
83 |
/* Fill the subsquare from 0..x and 0..y */ |
|
84 |
int i,j; |
|
85 |
||
86 |
zero_block(block); |
|
87 |
||
88 |
for (j=0; j <= y; ++j) |
|
89 |
for (i=0; i <= x; ++i) |
|
90 |
{ |
|
91 |
block[j*8+i] = input[j*8+i]; |
|
92 |
} |
|
93 |
} |
|
94 |
||
95 |
void write_block_to_big(struct bitmap *bdest, const float *sub, int x, int y) |
|
96 |
{ |
|
97 |
int i,j; |
|
98 |
||
99 |
for (j=0; j < 8; ++j) |
|
100 |
for (i=0; i < 8; ++i) |
|
101 |
{ |
|
102 |
gsl_matrix *dest = bdest->m[0]; |
|
226 | 103 |
dest->data[(j+y*9)*dest->tda+x*9+i] = sub[j*8+i]; |
104 |
} |
|
105 |
||
106 |
if (x < 7) |
|
107 |
for (j=0; j < 8; ++j) |
|
108 |
{ |
|
109 |
gsl_matrix *dest = bdest->m[0]; |
|
110 |
dest->data[(j+y*9)*dest->tda+x*9+8] = 255; |
|
225 | 111 |
} |
226 | 112 |
if (y < 7) |
113 |
for (i=0; i < 8; ++i) |
|
114 |
{ |
|
115 |
gsl_matrix *dest = bdest->m[0]; |
|
116 |
dest->data[(8+y*9)*dest->tda+x*9+i] = 255; |
|
117 |
} |
|
118 |
||
119 |
if (y < 7 && x < 7) |
|
120 |
{ |
|
121 |
gsl_matrix *dest = bdest->m[0]; |
|
122 |
dest->data[(8+y*9)*dest->tda+x*9+8] = 255; |
|
123 |
} |
|
225 | 124 |
} |
125 |
||
126 |
int main(int argn, char **argv) |
|
127 |
{ |
|
128 |
struct bitmap bmap; |
|
129 |
float input[64]; |
|
130 |
float input_test[64]; |
|
131 |
float input_dct[64]; |
|
132 |
float output_dct[64]; |
|
133 |
float output[64]; |
|
253 | 134 |
float quantize[64] = { |
135 |
20, 14, 13, 20, 30, 50, 64, 76, |
|
136 |
15, 15, 18, 24, 33, 73, 75, 69, |
|
137 |
18, 16, 20, 30, 50, 71, 86, 70, |
|
138 |
18, 21, 28, 36, 64, 109, 100, 78, |
|
139 |
23, 28, 46, 70, 85, 136, 129, 96, |
|
140 |
30, 44, 69, 80, 101, 130, 141, 115, |
|
141 |
61, 80, 98, 109, 129, 151, 150, 126, |
|
142 |
90, 115, 119, 123, 140, 125, 129, 124 }; |
|
143 |
||
144 |
||
225 | 145 |
struct bitmap obmap; |
146 |
int i,j,k; |
|
147 |
||
148 |
bitmap_pam_init(&argn, argv); |
|
149 |
||
150 |
bitmap_filename_pam_get(argv[1], &bmap); |
|
151 |
||
152 |
if (bmap.nplanes != 1 || bmap.width != 8 || bmap.height != 8) |
|
153 |
{ |
|
154 |
fprintf(stderr, "Error: The file should be 8x8 PGM\n"); |
|
155 |
return -1; |
|
156 |
} |
|
157 |
||
158 |
k=0; |
|
159 |
for(j=0;j < 8; ++j) |
|
160 |
for(i=0;i < 8; ++i) |
|
161 |
{ |
|
162 |
gsl_matrix *mat = bmap.m[0]; |
|
163 |
input[k++] = mat->data[j*mat->tda + i]; |
|
164 |
} |
|
165 |
||
166 |
mydct(input, input_dct); |
|
253 | 167 |
|
168 |
{ |
|
169 |
FILE *odct, *ifile, *qtable, *qfile; |
|
170 |
odct = fopen("dct.txt", "wt"); |
|
171 |
ifile = fopen("ifile.txt", "wt"); |
|
172 |
qtable = fopen("qtable.txt", "wt"); |
|
173 |
qfile = fopen("qfile.txt", "wt"); |
|
174 |
for(j=0;j < 8; ++j) |
|
175 |
{ |
|
176 |
fprintf(odct, "<tr>\n"); |
|
177 |
fprintf(ifile, "<tr>\n"); |
|
178 |
fprintf(qtable, "<tr>\n"); |
|
179 |
fprintf(qfile, "<tr>\n"); |
|
180 |
for(i=0;i < 8; ++i) |
|
181 |
{ |
|
182 |
fprintf(odct, "<td>%.2f\n", input_dct[j*8+i]); |
|
183 |
fprintf(ifile, "<td>%.0f\n", input[j*8+i]); |
|
184 |
fprintf(qtable, "<td>%.0f\n", quantize[j*8+i]); |
|
185 |
fprintf(qfile, "<td>%i\n", lrint(input_dct[j*8+i]/quantize[j*8+i])); |
|
186 |
} |
|
187 |
} |
|
188 |
fclose(odct); |
|
189 |
fclose(ifile); |
|
190 |
fclose(qtable); |
|
191 |
fclose(qfile); |
|
192 |
} |
|
193 |
||
225 | 194 |
myidct(input_dct, input_test); |
195 |
||
226 | 196 |
obmap = bitmap_alloc(1, 64+7, 64+7); |
225 | 197 |
|
198 |
for(j=0;j < 8; ++j) |
|
199 |
for(i=0;i < 8; ++i) |
|
200 |
{ |
|
201 |
prepare_subblock(output_dct,i,j,input_dct); |
|
202 |
myidct(output_dct, output); |
|
203 |
write_block_to_big(&obmap, output, i, j); |
|
204 |
} |
|
205 |
||
206 |
bitmap_filename_pam_put(argv[2], &obmap); |
|
207 |
||
208 |
bitmap_free(obmap); |
|
209 |
return 0; |
|
210 |
} |