[svn] / trunk / xvidcore / src / dct / idct.c Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/dct/idct.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1979 - (view) (download)

1 : edgomez 1382 /*****************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - Inverse DCT -
5 :     *
6 : Isibaar 1979 * Copyright (C) 2006-2011 Xvid Solutions GmbH
7 : edgomez 1382 *
8 :     * This program is free software ; you can redistribute it and/or modify
9 :     * it under the terms of the GNU General Public License as published by
10 :     * the Free Software Foundation ; either version 2 of the License, or
11 :     * (at your option) any later version.
12 :     *
13 :     * This program is distributed in the hope that it will be useful,
14 :     * but WITHOUT ANY WARRANTY ; without even the implied warranty of
15 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 :     * GNU General Public License for more details.
17 :     *
18 :     * You should have received a copy of the GNU General Public License
19 :     * along with this program ; if not, write to the Free Software
20 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 :     *
22 : suxen_drol 1653 * $Id: idct.c,v 1.9 2005-11-22 10:23:01 suxen_drol Exp $
23 : edgomez 1382 *
24 :     ****************************************************************************/
25 : Isibaar 1979
26 :     /*
27 :     * Authors: Skal
28 :     *
29 :     * Walken IDCT
30 :     * Alternative idct implementations for decoding compatibility
31 :     *
32 :     * NOTE: this "C" version is not the original one,
33 :     * but is modified to yield the same error profile
34 :     * than the MMX version.
35 :     *
36 :     ************************************************************************/
37 : edgomez 851
38 : Isibaar 3 #include "idct.h"
39 :    
40 : edgomez 1382 /* function pointer */
41 : Isibaar 3 idctFuncPtr idct;
42 :    
43 : Isibaar 1979 #define XVID_DSP_CLIP_255(x) ( ((x)&~255) ? ((-(x)) >> (8*sizeof((x))-1))&0xff : (x) )
44 : Isibaar 3
45 : Isibaar 1979 #define ROW_SHIFT 11
46 :     #define COL_SHIFT 6
47 :    
48 :     // #define FIX(x) (int)((x) * (1<<ROW_SHIFT))
49 :     #define Rnd0 65536 // 1<<(COL_SHIFT+ROW_SHIFT-1);
50 :     #define Rnd1 3597 // FIX (1.75683487303);
51 :     #define Rnd2 2260 // FIX (1.10355339059);
52 :     #define Rnd3 1203 // FIX (0.587788325588);
53 :     #define Rnd4 0
54 :     #define Rnd5 120 // FIX (0.058658283817);
55 :     #define Rnd6 512 // FIX (0.25);
56 :     #define Rnd7 512 // FIX (0.25);
57 :     #undef FIX
58 :    
59 :     static const int Tab04[] = { 22725, 21407, 19266, 16384, 12873, 8867, 4520 };
60 :     static const int Tab17[] = { 31521, 29692, 26722, 22725, 17855, 12299, 6270 };
61 :     static const int Tab26[] = { 29692, 27969, 25172, 21407, 16819, 11585, 5906 };
62 :     static const int Tab35[] = { 26722, 25172, 22654, 19266, 15137, 10426, 5315 };
63 :    
64 :     static int Idct_Row(short * In, const int * const Tab, int Rnd)
65 :     {
66 :     const int C1 = Tab[0];
67 :     const int C2 = Tab[1];
68 :     const int C3 = Tab[2];
69 :     const int C4 = Tab[3];
70 :     const int C5 = Tab[4];
71 :     const int C6 = Tab[5];
72 :     const int C7 = Tab[6];
73 :    
74 :     const int Right = In[5]|In[6]|In[7];
75 :     const int Left = In[1]|In[2]|In[3];
76 :     if (!(Right | In[4]))
77 :     {
78 :     const int K = C4*In[0] + Rnd;
79 :     if (Left)
80 :     {
81 :     const int a0 = K + C2*In[2];
82 :     const int a1 = K + C6*In[2];
83 :     const int a2 = K - C6*In[2];
84 :     const int a3 = K - C2*In[2];
85 :    
86 :     const int b0 = C1*In[1] + C3*In[3];
87 :     const int b1 = C3*In[1] - C7*In[3];
88 :     const int b2 = C5*In[1] - C1*In[3];
89 :     const int b3 = C7*In[1] - C5*In[3];
90 :    
91 :     In[0] = (a0 + b0) >> ROW_SHIFT;
92 :     In[1] = (a1 + b1) >> ROW_SHIFT;
93 :     In[2] = (a2 + b2) >> ROW_SHIFT;
94 :     In[3] = (a3 + b3) >> ROW_SHIFT;
95 :     In[4] = (a3 - b3) >> ROW_SHIFT;
96 :     In[5] = (a2 - b2) >> ROW_SHIFT;
97 :     In[6] = (a1 - b1) >> ROW_SHIFT;
98 :     In[7] = (a0 - b0) >> ROW_SHIFT;
99 :     }
100 :     else
101 :     {
102 :     const int a0 = K >> ROW_SHIFT;
103 :     if (a0) {
104 :     In[0] = In[1] = In[2] = In[3] =
105 :     In[4] = In[5] = In[6] = In[7] = a0;
106 :     }
107 :     else return 0;
108 :     }
109 :     }
110 :     else if (!(Left|Right))
111 :     {
112 :     const int a0 = (Rnd + C4*(In[0]+In[4])) >> ROW_SHIFT;
113 :     const int a1 = (Rnd + C4*(In[0]-In[4])) >> ROW_SHIFT;
114 :    
115 :     In[0] = a0;
116 :     In[3] = a0;
117 :     In[4] = a0;
118 :     In[7] = a0;
119 :     In[1] = a1;
120 :     In[2] = a1;
121 :     In[5] = a1;
122 :     In[6] = a1;
123 :     }
124 :     else
125 :     {
126 :     const int K = C4*In[0] + Rnd;
127 :     const int a0 = K + C2*In[2] + C4*In[4] + C6*In[6];
128 :     const int a1 = K + C6*In[2] - C4*In[4] - C2*In[6];
129 :     const int a2 = K - C6*In[2] - C4*In[4] + C2*In[6];
130 :     const int a3 = K - C2*In[2] + C4*In[4] - C6*In[6];
131 :    
132 :     const int b0 = C1*In[1] + C3*In[3] + C5*In[5] + C7*In[7];
133 :     const int b1 = C3*In[1] - C7*In[3] - C1*In[5] - C5*In[7];
134 :     const int b2 = C5*In[1] - C1*In[3] + C7*In[5] + C3*In[7];
135 :     const int b3 = C7*In[1] - C5*In[3] + C3*In[5] - C1*In[7];
136 :    
137 :     In[0] = (a0 + b0) >> ROW_SHIFT;
138 :     In[1] = (a1 + b1) >> ROW_SHIFT;
139 :     In[2] = (a2 + b2) >> ROW_SHIFT;
140 :     In[3] = (a3 + b3) >> ROW_SHIFT;
141 :     In[4] = (a3 - b3) >> ROW_SHIFT;
142 :     In[5] = (a2 - b2) >> ROW_SHIFT;
143 :     In[6] = (a1 - b1) >> ROW_SHIFT;
144 :     In[7] = (a0 - b0) >> ROW_SHIFT;
145 :     }
146 :     return 1;
147 :     }
148 :    
149 :     #define Tan1 0x32ec
150 :     #define Tan2 0x6a0a
151 :     #define Tan3 0xab0e
152 :     #define Sqrt2 0x5a82
153 :    
154 :     #define MULT(c,x, n) ( ((c) * (x)) >> (n) )
155 :     // 12b version => #define MULT(c,x, n) ( (((c)>>3) * (x)) >> ((n)-3) )
156 :     // 12b zero-testing version:
157 :    
158 :     #define BUTF(a, b, tmp) \
159 :     (tmp) = (a)+(b); \
160 :     (b) = (a)-(b); \
161 :     (a) = (tmp)
162 :    
163 :     #define LOAD_BUTF(m1, m2, a, b, tmp, S) \
164 :     (m1) = (S)[(a)] + (S)[(b)]; \
165 :     (m2) = (S)[(a)] - (S)[(b)]
166 :    
167 :     static void Idct_Col_8(short * const In)
168 :     {
169 :     int mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, Spill;
170 :    
171 :     // odd
172 :    
173 :     mm4 = (int)In[7*8];
174 :     mm5 = (int)In[5*8];
175 :     mm6 = (int)In[3*8];
176 :     mm7 = (int)In[1*8];
177 :    
178 :     mm0 = MULT(Tan1, mm4, 16) + mm7;
179 :     mm1 = MULT(Tan1, mm7, 16) - mm4;
180 :     mm2 = MULT(Tan3, mm5, 16) + mm6;
181 :     mm3 = MULT(Tan3, mm6, 16) - mm5;
182 :    
183 :     mm7 = mm0 + mm2;
184 :     mm4 = mm1 - mm3;
185 :     mm0 = mm0 - mm2;
186 :     mm1 = mm1 + mm3;
187 :     mm6 = mm0 + mm1;
188 :     mm5 = mm0 - mm1;
189 :     mm5 = 2*MULT(Sqrt2, mm5, 16); // 2*sqrt2
190 :     mm6 = 2*MULT(Sqrt2, mm6, 16); // Watch out: precision loss but done to match
191 :     // the pmulhw used in mmx/sse versions
192 :    
193 :     // even
194 :    
195 :     mm1 = (int)In[2*8];
196 :     mm2 = (int)In[6*8];
197 :     mm3 = MULT(Tan2,mm2, 16) + mm1;
198 :     mm2 = MULT(Tan2,mm1, 16) - mm2;
199 :    
200 :     LOAD_BUTF(mm0, mm1, 0*8, 4*8, Spill, In);
201 :    
202 :     BUTF(mm0, mm3, Spill);
203 :     BUTF(mm0, mm7, Spill);
204 :     In[8*0] = (int16_t) (mm0 >> COL_SHIFT);
205 :     In[8*7] = (int16_t) (mm7 >> COL_SHIFT);
206 :     BUTF(mm3, mm4, mm0);
207 :     In[8*3] = (int16_t) (mm3 >> COL_SHIFT);
208 :     In[8*4] = (int16_t) (mm4 >> COL_SHIFT);
209 :    
210 :     BUTF(mm1, mm2, mm0);
211 :     BUTF(mm1, mm6, mm0);
212 :     In[8*1] = (int16_t) (mm1 >> COL_SHIFT);
213 :     In[8*6] = (int16_t) (mm6 >> COL_SHIFT);
214 :     BUTF(mm2, mm5, mm0);
215 :     In[8*2] = (int16_t) (mm2 >> COL_SHIFT);
216 :     In[8*5] = (int16_t) (mm5 >> COL_SHIFT);
217 :     }
218 :    
219 :     static void Idct_Col_4(short * const In)
220 :     {
221 :     int mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, Spill;
222 :    
223 :     // odd
224 :    
225 :     mm0 = (int)In[1*8];
226 :     mm2 = (int)In[3*8];
227 :    
228 :     mm1 = MULT(Tan1, mm0, 16);
229 :     mm3 = MULT(Tan3, mm2, 16);
230 :    
231 :     mm7 = mm0 + mm2;
232 :     mm4 = mm1 - mm3;
233 :     mm0 = mm0 - mm2;
234 :     mm1 = mm1 + mm3;
235 :     mm6 = mm0 + mm1;
236 :     mm5 = mm0 - mm1;
237 :     mm6 = 2*MULT(Sqrt2, mm6, 16); // 2*sqrt2
238 :     mm5 = 2*MULT(Sqrt2, mm5, 16);
239 :    
240 :     // even
241 :    
242 :     mm0 = mm1 = (int)In[0*8];
243 :     mm3 = (int)In[2*8];
244 :     mm2 = MULT(Tan2,mm3, 16);
245 :    
246 :     BUTF(mm0, mm3, Spill);
247 :     BUTF(mm0, mm7, Spill);
248 :     In[8*0] = (int16_t) (mm0 >> COL_SHIFT);
249 :     In[8*7] = (int16_t) (mm7 >> COL_SHIFT);
250 :     BUTF(mm3, mm4, mm0);
251 :     In[8*3] = (int16_t) (mm3 >> COL_SHIFT);
252 :     In[8*4] = (int16_t) (mm4 >> COL_SHIFT);
253 :    
254 :     BUTF(mm1, mm2, mm0);
255 :     BUTF(mm1, mm6, mm0);
256 :     In[8*1] = (int16_t) (mm1 >> COL_SHIFT);
257 :     In[8*6] = (int16_t) (mm6 >> COL_SHIFT);
258 :     BUTF(mm2, mm5, mm0);
259 :     In[8*2] = (int16_t) (mm2 >> COL_SHIFT);
260 :     In[8*5] = (int16_t) (mm5 >> COL_SHIFT);
261 :     }
262 :    
263 :     static void Idct_Col_3(short * const In)
264 :     {
265 :     int mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, Spill;
266 :    
267 :     // odd
268 :    
269 :     mm7 = (int)In[1*8];
270 :     mm4 = MULT(Tan1, mm7, 16);
271 :    
272 :     mm6 = mm7 + mm4;
273 :     mm5 = mm7 - mm4;
274 :     mm6 = 2*MULT(Sqrt2, mm6, 16); // 2*sqrt2
275 :     mm5 = 2*MULT(Sqrt2, mm5, 16);
276 :    
277 :     // even
278 :    
279 :     mm0 = mm1 = (int)In[0*8];
280 :     mm3 = (int)In[2*8];
281 :     mm2 = MULT(Tan2,mm3, 16);
282 :    
283 :     BUTF(mm0, mm3, Spill);
284 :     BUTF(mm0, mm7, Spill);
285 :     In[8*0] = (int16_t) (mm0 >> COL_SHIFT);
286 :     In[8*7] = (int16_t) (mm7 >> COL_SHIFT);
287 :     BUTF(mm3, mm4, mm0);
288 :     In[8*3] = (int16_t) (mm3 >> COL_SHIFT);
289 :     In[8*4] = (int16_t) (mm4 >> COL_SHIFT);
290 :    
291 :     BUTF(mm1, mm2, mm0);
292 :     BUTF(mm1, mm6, mm0);
293 :     In[8*1] = (int16_t) (mm1 >> COL_SHIFT);
294 :     In[8*6] = (int16_t) (mm6 >> COL_SHIFT);
295 :     BUTF(mm2, mm5, mm0);
296 :     In[8*2] = (int16_t) (mm2 >> COL_SHIFT);
297 :     In[8*5] = (int16_t) (mm5 >> COL_SHIFT);
298 :     }
299 :    
300 :     #undef Tan1
301 :     #undef Tan2
302 :     #undef Tan3
303 :     #undef Sqrt2
304 :    
305 :     #undef ROW_SHIFT
306 :     #undef COL_SHIFT
307 :    
308 :     //////////////////////////////////////////////////////////
309 :    
310 :     void idct_int32(short *const In)
311 :     {
312 :     int i, Rows = 0x07;
313 :    
314 :     Idct_Row(In + 0*8, Tab04, Rnd0);
315 :     Idct_Row(In + 1*8, Tab17, Rnd1);
316 :     Idct_Row(In + 2*8, Tab26, Rnd2);
317 :     if (Idct_Row(In + 3*8, Tab35, Rnd3)) Rows |= 0x08;
318 :     if (Idct_Row(In + 4*8, Tab04, Rnd4)) Rows |= 0x10;
319 :     if (Idct_Row(In + 5*8, Tab35, Rnd5)) Rows |= 0x20;
320 :     if (Idct_Row(In + 6*8, Tab26, Rnd6)) Rows |= 0x40;
321 :     if (Idct_Row(In + 7*8, Tab17, Rnd7)) Rows |= 0x80;
322 :    
323 :     if (Rows&0xf0) {
324 :     for(i=0; i<8; i++)
325 :     Idct_Col_8(In + i);
326 :     }
327 :     else if (Rows&0x08) {
328 :     for(i=0; i<8; i++)
329 :     Idct_Col_4(In + i);
330 :     }
331 :     else {
332 :     for(i=0; i<8; i++)
333 :     Idct_Col_3(In + i);
334 :     }
335 :     }

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4