ffmpeg / libavcodec / simple_idct.c @ 63613fe6
History  View  Annotate  Download (15.8 KB)
1 
/*


2 
* Simple IDCT

3 
*

4 
* Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>

5 
*

6 
* This file is part of FFmpeg.

7 
*

8 
* FFmpeg is free software; you can redistribute it and/or

9 
* modify it under the terms of the GNU Lesser General Public

10 
* License as published by the Free Software Foundation; either

11 
* version 2.1 of the License, or (at your option) any later version.

12 
*

13 
* FFmpeg 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 GNU

16 
* Lesser General Public License for more details.

17 
*

18 
* You should have received a copy of the GNU Lesser General Public

19 
* License along with FFmpeg; if not, write to the Free Software

20 
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 021101301 USA

21 
*/

22  
23 
/**

24 
* @file libavcodec/simple_idct.c

25 
* simpleidct in C.

26 
*/

27  
28 
/*

29 
based upon some outcommented c code from mpeg2dec (idct_mmx.c

30 
written by Aaron Holtzman <aholtzma@ess.engr.uvic.ca>)

31 
*/

32 
#include "avcodec.h" 
33 
#include "dsputil.h" 
34 
#include "mathops.h" 
35 
#include "simple_idct.h" 
36  
37 
#if 0

38 
#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */

39 
#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */

40 
#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */

41 
#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */

42 
#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */

43 
#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */

44 
#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */

45 
#define ROW_SHIFT 8

46 
#define COL_SHIFT 17

47 
#else

48 
#define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 
49 
#define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 
50 
#define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 
51 
#define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 
52 
#define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 
53 
#define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 
54 
#define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 
55 
#define ROW_SHIFT 11 
56 
#define COL_SHIFT 20 // 6 
57 
#endif

58  
59 
static inline void idctRowCondDC (DCTELEM * row) 
60 
{ 
61 
int a0, a1, a2, a3, b0, b1, b2, b3;

62 
#if HAVE_FAST_64BIT

63 
uint64_t temp; 
64 
#else

65 
uint32_t temp; 
66 
#endif

67  
68 
#if HAVE_FAST_64BIT

69 
#if HAVE_BIGENDIAN

70 
#define ROW0_MASK 0xffff000000000000LL 
71 
#else

72 
#define ROW0_MASK 0xffffLL 
73 
#endif

74 
if(sizeof(DCTELEM)==2){ 
75 
if ( ((((uint64_t *)row)[0] & ~ROW0_MASK)  
76 
((uint64_t *)row)[1]) == 0) { 
77 
temp = (row[0] << 3) & 0xffff; 
78 
temp += temp << 16;

79 
temp += temp << 32;

80 
((uint64_t *)row)[0] = temp;

81 
((uint64_t *)row)[1] = temp;

82 
return;

83 
} 
84 
}else{

85 
if (!(row[1]row[2]row[3]row[4]row[5]row[6]row[7])) { 
86 
row[0]=row[1]=row[2]=row[3]=row[4]=row[5]=row[6]=row[7]= row[0] << 3; 
87 
return;

88 
} 
89 
} 
90 
#else

91 
if(sizeof(DCTELEM)==2){ 
92 
if (!(((uint32_t*)row)[1]  
93 
((uint32_t*)row)[2] 

94 
((uint32_t*)row)[3] 

95 
row[1])) {

96 
temp = (row[0] << 3) & 0xffff; 
97 
temp += temp << 16;

98 
((uint32_t*)row)[0]=((uint32_t*)row)[1] = 
99 
((uint32_t*)row)[2]=((uint32_t*)row)[3] = temp; 
100 
return;

101 
} 
102 
}else{

103 
if (!(row[1]row[2]row[3]row[4]row[5]row[6]row[7])) { 
104 
row[0]=row[1]=row[2]=row[3]=row[4]=row[5]=row[6]=row[7]= row[0] << 3; 
105 
return;

106 
} 
107 
} 
108 
#endif

109  
110 
a0 = (W4 * row[0]) + (1 << (ROW_SHIFT  1)); 
111 
a1 = a0; 
112 
a2 = a0; 
113 
a3 = a0; 
114  
115 
/* no need to optimize : gcc does it */

116 
a0 += W2 * row[2];

117 
a1 += W6 * row[2];

118 
a2 = W6 * row[2];

119 
a3 = W2 * row[2];

120  
121 
b0 = MUL16(W1, row[1]);

122 
MAC16(b0, W3, row[3]);

123 
b1 = MUL16(W3, row[1]);

124 
MAC16(b1, W7, row[3]);

125 
b2 = MUL16(W5, row[1]);

126 
MAC16(b2, W1, row[3]);

127 
b3 = MUL16(W7, row[1]);

128 
MAC16(b3, W5, row[3]);

129  
130 
#if HAVE_FAST_64BIT

131 
temp = ((uint64_t*)row)[1];

132 
#else

133 
temp = ((uint32_t*)row)[2]  ((uint32_t*)row)[3]; 
134 
#endif

135 
if (temp != 0) { 
136 
a0 += W4*row[4] + W6*row[6]; 
137 
a1 +=  W4*row[4]  W2*row[6]; 
138 
a2 +=  W4*row[4] + W2*row[6]; 
139 
a3 += W4*row[4]  W6*row[6]; 
140  
141 
MAC16(b0, W5, row[5]);

142 
MAC16(b0, W7, row[7]);

143  
144 
MAC16(b1, W1, row[5]);

145 
MAC16(b1, W5, row[7]);

146  
147 
MAC16(b2, W7, row[5]);

148 
MAC16(b2, W3, row[7]);

149  
150 
MAC16(b3, W3, row[5]);

151 
MAC16(b3, W1, row[7]);

152 
} 
153  
154 
row[0] = (a0 + b0) >> ROW_SHIFT;

155 
row[7] = (a0  b0) >> ROW_SHIFT;

156 
row[1] = (a1 + b1) >> ROW_SHIFT;

157 
row[6] = (a1  b1) >> ROW_SHIFT;

158 
row[2] = (a2 + b2) >> ROW_SHIFT;

159 
row[5] = (a2  b2) >> ROW_SHIFT;

160 
row[3] = (a3 + b3) >> ROW_SHIFT;

161 
row[4] = (a3  b3) >> ROW_SHIFT;

162 
} 
163  
164 
static inline void idctSparseColPut (uint8_t *dest, int line_size, 
165 
DCTELEM * col) 
166 
{ 
167 
int a0, a1, a2, a3, b0, b1, b2, b3;

168 
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; 
169  
170 
/* XXX: I did that only to give same values as previous code */

171 
a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT1))/W4)); 
172 
a1 = a0; 
173 
a2 = a0; 
174 
a3 = a0; 
175  
176 
a0 += + W2*col[8*2]; 
177 
a1 += + W6*col[8*2]; 
178 
a2 +=  W6*col[8*2]; 
179 
a3 +=  W2*col[8*2]; 
180  
181 
b0 = MUL16(W1, col[8*1]); 
182 
b1 = MUL16(W3, col[8*1]); 
183 
b2 = MUL16(W5, col[8*1]); 
184 
b3 = MUL16(W7, col[8*1]); 
185  
186 
MAC16(b0, + W3, col[8*3]); 
187 
MAC16(b1,  W7, col[8*3]); 
188 
MAC16(b2,  W1, col[8*3]); 
189 
MAC16(b3,  W5, col[8*3]); 
190  
191 
if(col[8*4]){ 
192 
a0 += + W4*col[8*4]; 
193 
a1 +=  W4*col[8*4]; 
194 
a2 +=  W4*col[8*4]; 
195 
a3 += + W4*col[8*4]; 
196 
} 
197  
198 
if (col[8*5]) { 
199 
MAC16(b0, + W5, col[8*5]); 
200 
MAC16(b1,  W1, col[8*5]); 
201 
MAC16(b2, + W7, col[8*5]); 
202 
MAC16(b3, + W3, col[8*5]); 
203 
} 
204  
205 
if(col[8*6]){ 
206 
a0 += + W6*col[8*6]; 
207 
a1 +=  W2*col[8*6]; 
208 
a2 += + W2*col[8*6]; 
209 
a3 +=  W6*col[8*6]; 
210 
} 
211  
212 
if (col[8*7]) { 
213 
MAC16(b0, + W7, col[8*7]); 
214 
MAC16(b1,  W5, col[8*7]); 
215 
MAC16(b2, + W3, col[8*7]); 
216 
MAC16(b3,  W1, col[8*7]); 
217 
} 
218  
219 
dest[0] = cm[(a0 + b0) >> COL_SHIFT];

220 
dest += line_size; 
221 
dest[0] = cm[(a1 + b1) >> COL_SHIFT];

222 
dest += line_size; 
223 
dest[0] = cm[(a2 + b2) >> COL_SHIFT];

224 
dest += line_size; 
225 
dest[0] = cm[(a3 + b3) >> COL_SHIFT];

226 
dest += line_size; 
227 
dest[0] = cm[(a3  b3) >> COL_SHIFT];

228 
dest += line_size; 
229 
dest[0] = cm[(a2  b2) >> COL_SHIFT];

230 
dest += line_size; 
231 
dest[0] = cm[(a1  b1) >> COL_SHIFT];

232 
dest += line_size; 
233 
dest[0] = cm[(a0  b0) >> COL_SHIFT];

234 
} 
235  
236 
static inline void idctSparseColAdd (uint8_t *dest, int line_size, 
237 
DCTELEM * col) 
238 
{ 
239 
int a0, a1, a2, a3, b0, b1, b2, b3;

240 
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; 
241  
242 
/* XXX: I did that only to give same values as previous code */

243 
a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT1))/W4)); 
244 
a1 = a0; 
245 
a2 = a0; 
246 
a3 = a0; 
247  
248 
a0 += + W2*col[8*2]; 
249 
a1 += + W6*col[8*2]; 
250 
a2 +=  W6*col[8*2]; 
251 
a3 +=  W2*col[8*2]; 
252  
253 
b0 = MUL16(W1, col[8*1]); 
254 
b1 = MUL16(W3, col[8*1]); 
255 
b2 = MUL16(W5, col[8*1]); 
256 
b3 = MUL16(W7, col[8*1]); 
257  
258 
MAC16(b0, + W3, col[8*3]); 
259 
MAC16(b1,  W7, col[8*3]); 
260 
MAC16(b2,  W1, col[8*3]); 
261 
MAC16(b3,  W5, col[8*3]); 
262  
263 
if(col[8*4]){ 
264 
a0 += + W4*col[8*4]; 
265 
a1 +=  W4*col[8*4]; 
266 
a2 +=  W4*col[8*4]; 
267 
a3 += + W4*col[8*4]; 
268 
} 
269  
270 
if (col[8*5]) { 
271 
MAC16(b0, + W5, col[8*5]); 
272 
MAC16(b1,  W1, col[8*5]); 
273 
MAC16(b2, + W7, col[8*5]); 
274 
MAC16(b3, + W3, col[8*5]); 
275 
} 
276  
277 
if(col[8*6]){ 
278 
a0 += + W6*col[8*6]; 
279 
a1 +=  W2*col[8*6]; 
280 
a2 += + W2*col[8*6]; 
281 
a3 +=  W6*col[8*6]; 
282 
} 
283  
284 
if (col[8*7]) { 
285 
MAC16(b0, + W7, col[8*7]); 
286 
MAC16(b1,  W5, col[8*7]); 
287 
MAC16(b2, + W3, col[8*7]); 
288 
MAC16(b3,  W1, col[8*7]); 
289 
} 
290  
291 
dest[0] = cm[dest[0] + ((a0 + b0) >> COL_SHIFT)]; 
292 
dest += line_size; 
293 
dest[0] = cm[dest[0] + ((a1 + b1) >> COL_SHIFT)]; 
294 
dest += line_size; 
295 
dest[0] = cm[dest[0] + ((a2 + b2) >> COL_SHIFT)]; 
296 
dest += line_size; 
297 
dest[0] = cm[dest[0] + ((a3 + b3) >> COL_SHIFT)]; 
298 
dest += line_size; 
299 
dest[0] = cm[dest[0] + ((a3  b3) >> COL_SHIFT)]; 
300 
dest += line_size; 
301 
dest[0] = cm[dest[0] + ((a2  b2) >> COL_SHIFT)]; 
302 
dest += line_size; 
303 
dest[0] = cm[dest[0] + ((a1  b1) >> COL_SHIFT)]; 
304 
dest += line_size; 
305 
dest[0] = cm[dest[0] + ((a0  b0) >> COL_SHIFT)]; 
306 
} 
307  
308 
static inline void idctSparseCol (DCTELEM * col) 
309 
{ 
310 
int a0, a1, a2, a3, b0, b1, b2, b3;

311  
312 
/* XXX: I did that only to give same values as previous code */

313 
a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT1))/W4)); 
314 
a1 = a0; 
315 
a2 = a0; 
316 
a3 = a0; 
317  
318 
a0 += + W2*col[8*2]; 
319 
a1 += + W6*col[8*2]; 
320 
a2 +=  W6*col[8*2]; 
321 
a3 +=  W2*col[8*2]; 
322  
323 
b0 = MUL16(W1, col[8*1]); 
324 
b1 = MUL16(W3, col[8*1]); 
325 
b2 = MUL16(W5, col[8*1]); 
326 
b3 = MUL16(W7, col[8*1]); 
327  
328 
MAC16(b0, + W3, col[8*3]); 
329 
MAC16(b1,  W7, col[8*3]); 
330 
MAC16(b2,  W1, col[8*3]); 
331 
MAC16(b3,  W5, col[8*3]); 
332  
333 
if(col[8*4]){ 
334 
a0 += + W4*col[8*4]; 
335 
a1 +=  W4*col[8*4]; 
336 
a2 +=  W4*col[8*4]; 
337 
a3 += + W4*col[8*4]; 
338 
} 
339  
340 
if (col[8*5]) { 
341 
MAC16(b0, + W5, col[8*5]); 
342 
MAC16(b1,  W1, col[8*5]); 
343 
MAC16(b2, + W7, col[8*5]); 
344 
MAC16(b3, + W3, col[8*5]); 
345 
} 
346  
347 
if(col[8*6]){ 
348 
a0 += + W6*col[8*6]; 
349 
a1 +=  W2*col[8*6]; 
350 
a2 += + W2*col[8*6]; 
351 
a3 +=  W6*col[8*6]; 
352 
} 
353  
354 
if (col[8*7]) { 
355 
MAC16(b0, + W7, col[8*7]); 
356 
MAC16(b1,  W5, col[8*7]); 
357 
MAC16(b2, + W3, col[8*7]); 
358 
MAC16(b3,  W1, col[8*7]); 
359 
} 
360  
361 
col[0 ] = ((a0 + b0) >> COL_SHIFT);

362 
col[8 ] = ((a1 + b1) >> COL_SHIFT);

363 
col[16] = ((a2 + b2) >> COL_SHIFT);

364 
col[24] = ((a3 + b3) >> COL_SHIFT);

365 
col[32] = ((a3  b3) >> COL_SHIFT);

366 
col[40] = ((a2  b2) >> COL_SHIFT);

367 
col[48] = ((a1  b1) >> COL_SHIFT);

368 
col[56] = ((a0  b0) >> COL_SHIFT);

369 
} 
370  
371 
void ff_simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block) 
372 
{ 
373 
int i;

374 
for(i=0; i<8; i++) 
375 
idctRowCondDC(block + i*8);

376  
377 
for(i=0; i<8; i++) 
378 
idctSparseColPut(dest + i, line_size, block + i); 
379 
} 
380  
381 
void ff_simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block) 
382 
{ 
383 
int i;

384 
for(i=0; i<8; i++) 
385 
idctRowCondDC(block + i*8);

386  
387 
for(i=0; i<8; i++) 
388 
idctSparseColAdd(dest + i, line_size, block + i); 
389 
} 
390  
391 
void ff_simple_idct(DCTELEM *block)

392 
{ 
393 
int i;

394 
for(i=0; i<8; i++) 
395 
idctRowCondDC(block + i*8);

396  
397 
for(i=0; i<8; i++) 
398 
idctSparseCol(block + i); 
399 
} 
400  
401 
/* 2x4x8 idct */

402  
403 
#define CN_SHIFT 12 
404 
#define C_FIX(x) ((int)((x) * (1 << CN_SHIFT) + 0.5)) 
405 
#define C1 C_FIX(0.6532814824) 
406 
#define C2 C_FIX(0.2705980501) 
407  
408 
/* row idct is multiple by 16 * sqrt(2.0), col idct4 is normalized,

409 
and the butterfly must be multiplied by 0.5 * sqrt(2.0) */

410 
#define C_SHIFT (4+1+12) 
411  
412 
static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col) 
413 
{ 
414 
int c0, c1, c2, c3, a0, a1, a2, a3;

415 
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;

416  
417 
a0 = col[8*0]; 
418 
a1 = col[8*2]; 
419 
a2 = col[8*4]; 
420 
a3 = col[8*6]; 
421 
c0 = ((a0 + a2) << (CN_SHIFT  1)) + (1 << (C_SHIFT  1)); 
422 
c2 = ((a0  a2) << (CN_SHIFT  1)) + (1 << (C_SHIFT  1)); 
423 
c1 = a1 * C1 + a3 * C2; 
424 
c3 = a1 * C2  a3 * C1; 
425 
dest[0] = cm[(c0 + c1) >> C_SHIFT];

426 
dest += line_size; 
427 
dest[0] = cm[(c2 + c3) >> C_SHIFT];

428 
dest += line_size; 
429 
dest[0] = cm[(c2  c3) >> C_SHIFT];

430 
dest += line_size; 
431 
dest[0] = cm[(c0  c1) >> C_SHIFT];

432 
} 
433  
434 
#define BF(k) \

435 
{\ 
436 
int a0, a1;\

437 
a0 = ptr[k];\ 
438 
a1 = ptr[8 + k];\

439 
ptr[k] = a0 + a1;\ 
440 
ptr[8 + k] = a0  a1;\

441 
} 
442  
443 
/* only used by DV codec. The input must be interlaced. 128 is added

444 
to the pixels before clamping to avoid systematic error

445 
(1024*sqrt(2)) offset would be needed otherwise. */

446 
/* XXX: I think a 1.0/sqrt(2) normalization should be needed to

447 
compensate the extra butterfly stage  I don't have the full DV

448 
specification */

449 
void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block) 
450 
{ 
451 
int i;

452 
DCTELEM *ptr; 
453  
454 
/* butterfly */

455 
ptr = block; 
456 
for(i=0;i<4;i++) { 
457 
BF(0);

458 
BF(1);

459 
BF(2);

460 
BF(3);

461 
BF(4);

462 
BF(5);

463 
BF(6);

464 
BF(7);

465 
ptr += 2 * 8; 
466 
} 
467  
468 
/* IDCT8 on each line */

469 
for(i=0; i<8; i++) { 
470 
idctRowCondDC(block + i*8);

471 
} 
472  
473 
/* IDCT4 and store */

474 
for(i=0;i<8;i++) { 
475 
idct4col_put(dest + i, 2 * line_size, block + i);

476 
idct4col_put(dest + line_size + i, 2 * line_size, block + 8 + i); 
477 
} 
478 
} 
479  
480 
/* 8x4 & 4x8 WMV2 IDCT */

481 
#undef CN_SHIFT

482 
#undef C_SHIFT

483 
#undef C_FIX

484 
#undef C1

485 
#undef C2

486 
#define CN_SHIFT 12 
487 
#define C_FIX(x) ((int)((x) * 1.414213562 * (1 << CN_SHIFT) + 0.5)) 
488 
#define C1 C_FIX(0.6532814824) 
489 
#define C2 C_FIX(0.2705980501) 
490 
#define C3 C_FIX(0.5) 
491 
#define C_SHIFT (4+1+12) 
492 
static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col) 
493 
{ 
494 
int c0, c1, c2, c3, a0, a1, a2, a3;

495 
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;

496  
497 
a0 = col[8*0]; 
498 
a1 = col[8*1]; 
499 
a2 = col[8*2]; 
500 
a3 = col[8*3]; 
501 
c0 = (a0 + a2)*C3 + (1 << (C_SHIFT  1)); 
502 
c2 = (a0  a2)*C3 + (1 << (C_SHIFT  1)); 
503 
c1 = a1 * C1 + a3 * C2; 
504 
c3 = a1 * C2  a3 * C1; 
505 
dest[0] = cm[dest[0] + ((c0 + c1) >> C_SHIFT)]; 
506 
dest += line_size; 
507 
dest[0] = cm[dest[0] + ((c2 + c3) >> C_SHIFT)]; 
508 
dest += line_size; 
509 
dest[0] = cm[dest[0] + ((c2  c3) >> C_SHIFT)]; 
510 
dest += line_size; 
511 
dest[0] = cm[dest[0] + ((c0  c1) >> C_SHIFT)]; 
512 
} 
513  
514 
#define RN_SHIFT 15 
515 
#define R_FIX(x) ((int)((x) * 1.414213562 * (1 << RN_SHIFT) + 0.5)) 
516 
#define R1 R_FIX(0.6532814824) 
517 
#define R2 R_FIX(0.2705980501) 
518 
#define R3 R_FIX(0.5) 
519 
#define R_SHIFT 11 
520 
static inline void idct4row(DCTELEM *row) 
521 
{ 
522 
int c0, c1, c2, c3, a0, a1, a2, a3;

523 
//const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;

524  
525 
a0 = row[0];

526 
a1 = row[1];

527 
a2 = row[2];

528 
a3 = row[3];

529 
c0 = (a0 + a2)*R3 + (1 << (R_SHIFT  1)); 
530 
c2 = (a0  a2)*R3 + (1 << (R_SHIFT  1)); 
531 
c1 = a1 * R1 + a3 * R2; 
532 
c3 = a1 * R2  a3 * R1; 
533 
row[0]= (c0 + c1) >> R_SHIFT;

534 
row[1]= (c2 + c3) >> R_SHIFT;

535 
row[2]= (c2  c3) >> R_SHIFT;

536 
row[3]= (c0  c1) >> R_SHIFT;

537 
} 
538  
539 
void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block) 
540 
{ 
541 
int i;

542  
543 
/* IDCT8 on each line */

544 
for(i=0; i<4; i++) { 
545 
idctRowCondDC(block + i*8);

546 
} 
547  
548 
/* IDCT4 and store */

549 
for(i=0;i<8;i++) { 
550 
idct4col_add(dest + i, line_size, block + i); 
551 
} 
552 
} 
553  
554 
void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block) 
555 
{ 
556 
int i;

557  
558 
/* IDCT4 on each line */

559 
for(i=0; i<8; i++) { 
560 
idct4row(block + i*8);

561 
} 
562  
563 
/* IDCT8 and store */

564 
for(i=0; i<4; i++){ 
565 
idctSparseColAdd(dest + i, line_size, block + i); 
566 
} 
567 
} 
568  
569 
void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block) 
570 
{ 
571 
int i;

572  
573 
/* IDCT4 on each line */

574 
for(i=0; i<4; i++) { 
575 
idct4row(block + i*8);

576 
} 
577  
578 
/* IDCT4 and store */

579 
for(i=0; i<4; i++){ 
580 
idct4col_add(dest + i, line_size, block + i); 
581 
} 
582 
} 