xoreos  0.0.5
dct.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 /* Based on the (I)DCT code in FFmpeg (<https://ffmpeg.org/)>, which
26  * is released under the terms of version 2 or later of the GNU Lesser
27  * General Public License.
28  *
29  * The original copyright note in libavcodec/dct.c reads as follows:
30  *
31  * (I)DCT Transforms
32  * Copyright (c) 2009 Peter Ross <pross@xvid.org>
33  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
34  * Copyright (c) 2010 Vitor Sessak
35  *
36  * This file is part of FFmpeg.
37  *
38  * FFmpeg is free software; you can redistribute it and/or
39  * modify it under the terms of the GNU Lesser General Public
40  * License as published by the Free Software Foundation; either
41  * version 2.1 of the License, or (at your option) any later version.
42  *
43  * FFmpeg is distributed in the hope that it will be useful,
44  * but WITHOUT ANY WARRANTY; without even the implied warranty of
45  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
46  * Lesser General Public License for more details.
47  *
48  * You should have received a copy of the GNU Lesser General Public
49  * License along with FFmpeg; if not, write to the Free Software
50  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
51  */
52 
53 #include "src/common/maths.h"
55 #include "src/common/rdft.h"
56 #include "src/common/dct.h"
57 
58 namespace Common {
59 
60 DCT::DCT(int bits, TransformType trans) : _bits(bits), _trans(trans) {
61  int n = 1 << _bits;
62 
63  _tCos = getCosineTable(_bits + 2);
64 
65  _csc2.reset(new float[n / 2]);
66 
68 
69  for (int i = 0; i < (n / 2); i++)
70  _csc2[i] = 0.5 / sin((M_PI / (2 * n) * (2 * i + 1)));
71 }
72 
74 }
75 
76 void DCT::calc(float *data) {
77  switch (_trans) {
78  case DCT_I:
79  calcDCTI(data);
80  break;
81 
82  case DCT_II:
83  calcDCTII(data);
84  break;
85 
86  case DCT_III:
87  calcDCTIII(data);
88  break;
89 
90  case DST_I:
91  calcDSTI(data);
92  break;
93  }
94 }
95 
96 /* sin((M_PI * x / (2*n)) */
97 #define SIN(n,x) (_tCos[(n) - (x)])
98 /* cos((M_PI * x / (2*n)) */
99 #define COS(n,x) (_tCos[x])
100 
101 void DCT::calcDCTI(float *data) {
102  int n = 1 << _bits;
103 
104  float next = -0.5f * (data[0] - data[n]);
105 
106  for (int i = 0; i < (n / 2); i++) {
107  float tmp1 = data[i ];
108  float tmp2 = data[n - i];
109 
110  float s = SIN(n, 2 * i);
111  float c = COS(n, 2 * i);
112 
113  c *= tmp1 - tmp2;
114  s *= tmp1 - tmp2;
115 
116  next += c;
117 
118  tmp1 = (tmp1 + tmp2) * 0.5f;
119 
120  data[i ] = tmp1 - s;
121  data[n - i] = tmp1 + s;
122  }
123 
124  _rdft->calc(data);
125 
126  data[n] = data[1];
127  data[1] = next;
128 
129  for (int i = 3; i <= n; i += 2)
130  data[i] = data[i - 2] - data[i];
131 }
132 
133 void DCT::calcDCTII(float *data) {
134  int n = 1 << _bits;
135 
136  for (int i = 0; i < (n / 2); i++) {
137  float tmp1 = data[i ];
138  float tmp2 = data[n - i - 1];
139 
140  float s = SIN(n, 2 * i + 1);
141 
142  s *= tmp1 - tmp2;
143 
144  tmp1 = (tmp1 + tmp2) * 0.5f;
145 
146  data[i ] = tmp1 + s;
147  data[n-i-1] = tmp1 - s;
148  }
149 
150  _rdft->calc(data);
151 
152  float next = data[1] * 0.5f;
153 
154  data[1] *= -1;
155 
156  for (int i = n - 2; i >= 0; i -= 2) {
157  float inr = data[i ];
158  float ini = data[i + 1];
159 
160  float c = COS(n, i);
161  float s = SIN(n, i);
162 
163  data[i ] = c * inr + s * ini;
164  data[i+1] = next;
165 
166  next += s * inr - c * ini;
167  }
168 }
169 
170 void DCT::calcDCTIII(float *data) {
171  int n = 1 << _bits;
172 
173  float next = data[n - 1];
174  float inv_n = 1.0f / n;
175 
176  for (int i = n - 2; i >= 2; i -= 2) {
177  float val1 = data[i ];
178  float val2 = data[i - 1] - data[i + 1];
179 
180  float c = COS(n, i);
181  float s = SIN(n, i);
182 
183  data[i ] = c * val1 + s * val2;
184  data[i + 1] = s * val1 - c * val2;
185  }
186 
187  data[1] = 2 * next;
188 
189  _rdft->calc(data);
190 
191  for (int i = 0; i < (n / 2); i++) {
192  float tmp1 = data[i ] * inv_n;
193  float tmp2 = data[n - i - 1] * inv_n;
194 
195  float csc = _csc2[i] * (tmp1 - tmp2);
196 
197  tmp1 += tmp2;
198 
199  data[i ] = tmp1 + csc;
200  data[n - i - 1] = tmp1 - csc;
201  }
202 }
203 
204 void DCT::calcDSTI(float *data) {
205  int n = 1 << _bits;
206 
207  data[0] = 0;
208 
209  for (int i = 1; i < (n / 2); i++) {
210  float tmp1 = data[i ];
211  float tmp2 = data[n - i];
212  float s = SIN(n, 2 * i);
213 
214  s *= tmp1 + tmp2;
215  tmp1 = (tmp1 - tmp2) * 0.5f;
216 
217  data[i ] = s + tmp1;
218  data[n - i] = s - tmp1;
219  }
220 
221  data[n / 2] *= 2;
222 
223  _rdft->calc(data);
224 
225  data[0] *= 0.5f;
226 
227  for (int i = 1; i < (n - 2); i += 2) {
228  data[i + 1] += data[i - 1];
229  data[i ] = -data[i + 2];
230  }
231 
232  data[n - 1] = 0;
233 }
234 
235 } // End of namespace Common
Definition: 2dafile.h:39
~DCT()
Definition: dct.cpp:73
void reset(PointerType o=0)
Resets the pointer with the new value.
Definition: scopedptr.h:87
ScopedPtr< RDFT > _rdft
Definition: dct.h:86
Mathematical helpers.
ScopedArray< float > _csc2
Definition: dct.h:88
#define M_PI
Definition: maths.h:39
void calcDSTI(float *data)
Definition: dct.cpp:204
#define SIN(n, x)
Definition: dct.cpp:97
(Inverse) Discrete Cosine Transforms.
void calcDCTIII(float *data)
Definition: dct.cpp:170
TransformType
Definition: dct.h:68
DCT(int bits, TransformType trans)
Definition: dct.cpp:60
int _bits
Definition: dct.h:81
(Inverse) Real Discrete Fourier Transform.
TransformType _trans
Definition: dct.h:82
void calc(float *data)
Definition: dct.cpp:76
const float * getCosineTable(int bits)
void calcDCTI(float *data)
Definition: dct.cpp:101
const float * _tCos
Definition: dct.h:84
(Inverse) Real Discrete Fourier Transform.
Definition: rdft.h:64
#define COS(n, x)
Definition: dct.cpp:99
Static cosine tables.
void calcDCTII(float *data)
Definition: dct.cpp:133