Mercurial > libavcodec.hg
comparison dct.c @ 11535:f468aac92300 libavcodec
Implement the discrete sine/cosine transforms DCT-I and DST-I
author | vitor |
---|---|
date | Tue, 23 Mar 2010 19:48:16 +0000 |
parents | a791382fd782 |
children | 7dd2a45249a9 |
comparison
equal
deleted
inserted
replaced
11534:baece61a55cf | 11535:f468aac92300 |
---|---|
35 #define SIN(s,n,x) (s->costab[(n) - (x)]) | 35 #define SIN(s,n,x) (s->costab[(n) - (x)]) |
36 | 36 |
37 /* cos((M_PI * x / (2*n)) */ | 37 /* cos((M_PI * x / (2*n)) */ |
38 #define COS(s,n,x) (s->costab[x]) | 38 #define COS(s,n,x) (s->costab[x]) |
39 | 39 |
40 static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data) | |
41 { | |
42 int n = 1 << ctx->nbits; | |
43 int i; | |
44 | |
45 data[0] = 0; | |
46 for(i = 1; i < n/2; i++) { | |
47 float tmp1 = data[i ]; | |
48 float tmp2 = data[n - i]; | |
49 float s = SIN(ctx, n, 2*i); | |
50 | |
51 s *= tmp1 + tmp2; | |
52 tmp1 = (tmp1 - tmp2) * 0.5f; | |
53 data[i ] = s + tmp1; | |
54 data[n - i] = s - tmp1; | |
55 } | |
56 | |
57 data[n/2] *= 2; | |
58 ff_rdft_calc(&ctx->rdft, data); | |
59 | |
60 data[0] *= 0.5f; | |
61 | |
62 for(i = 1; i < n-2; i += 2) { | |
63 data[i + 1] += data[i - 1]; | |
64 data[i ] = -data[i + 2]; | |
65 } | |
66 | |
67 data[n-1] = 0; | |
68 } | |
69 | |
70 static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data) | |
71 { | |
72 int n = 1 << ctx->nbits; | |
73 int i; | |
74 float next = -0.5f * (data[0] - data[n]); | |
75 | |
76 for(i = 0; i < n/2; i++) { | |
77 float tmp1 = data[i ]; | |
78 float tmp2 = data[n - i]; | |
79 float s = SIN(ctx, n, 2*i); | |
80 float c = COS(ctx, n, 2*i); | |
81 | |
82 c *= tmp1 - tmp2; | |
83 s *= tmp1 - tmp2; | |
84 | |
85 next += c; | |
86 | |
87 tmp1 = (tmp1 + tmp2) * 0.5f; | |
88 data[i ] = tmp1 - s; | |
89 data[n - i] = tmp1 + s; | |
90 } | |
91 | |
92 ff_rdft_calc(&ctx->rdft, data); | |
93 data[n] = data[1]; | |
94 data[1] = next; | |
95 | |
96 for(i = 3; i <= n; i += 2) | |
97 data[i] = data[i - 2] - data[i]; | |
98 } | |
99 | |
40 static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data) | 100 static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data) |
41 { | 101 { |
42 int n = 1 << ctx->nbits; | 102 int n = 1 << ctx->nbits; |
43 int i; | 103 int i; |
44 | 104 |
110 void ff_dct_calc(DCTContext *s, FFTSample *data) | 170 void ff_dct_calc(DCTContext *s, FFTSample *data) |
111 { | 171 { |
112 s->dct_calc(s, data); | 172 s->dct_calc(s, data); |
113 } | 173 } |
114 | 174 |
115 av_cold int ff_dct_init(DCTContext *s, int nbits, int inverse) | 175 av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse) |
116 { | 176 { |
117 int n = 1 << nbits; | 177 int n = 1 << nbits; |
118 int i; | 178 int i; |
119 | 179 |
120 s->nbits = nbits; | 180 s->nbits = nbits; |
124 | 184 |
125 s->costab = ff_cos_tabs[nbits+2]; | 185 s->costab = ff_cos_tabs[nbits+2]; |
126 | 186 |
127 s->csc2 = av_malloc(n/2 * sizeof(FFTSample)); | 187 s->csc2 = av_malloc(n/2 * sizeof(FFTSample)); |
128 | 188 |
129 if (ff_rdft_init(&s->rdft, nbits, inverse) < 0) { | 189 if (ff_rdft_init(&s->rdft, nbits, inverse == DCT_III) < 0) { |
130 av_free(s->csc2); | 190 av_free(s->csc2); |
131 return -1; | 191 return -1; |
132 } | 192 } |
133 | 193 |
134 for (i = 0; i < n/2; i++) | 194 for (i = 0; i < n/2; i++) |
135 s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1))); | 195 s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1))); |
136 | 196 |
137 if(inverse) { | 197 switch(inverse) { |
138 s->dct_calc = ff_dct_calc_III_c; | 198 case DCT_I : s->dct_calc = ff_dct_calc_I_c; break; |
139 } else | 199 case DCT_II : s->dct_calc = ff_dct_calc_II_c ; break; |
140 s->dct_calc = ff_dct_calc_II_c; | 200 case DCT_III: s->dct_calc = ff_dct_calc_III_c; break; |
141 | 201 case DST_I : s->dct_calc = ff_dst_calc_I_c; break; |
202 } | |
142 return 0; | 203 return 0; |
143 } | 204 } |
144 | 205 |
145 av_cold void ff_dct_end(DCTContext *s) | 206 av_cold void ff_dct_end(DCTContext *s) |
146 { | 207 { |