]> git.sesse.net Git - ffmpeg/blob - libavcodec/simple_idct.c
in fact IDCT248 needs to be normalized as I suspected
[ffmpeg] / libavcodec / simple_idct.c
1 /*
2  * Simple IDCT
3  *
4  * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 /*
21   based upon some outcommented c code from mpeg2dec (idct_mmx.c
22   written by Aaron Holtzman <aholtzma@ess.engr.uvic.ca>) 
23  */
24 #include "avcodec.h"
25 #include "dsputil.h"
26 #include "simple_idct.h"
27
28 //#define ARCH_ALPHA
29
30 #if 0
31 #define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
32 #define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
33 #define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
34 #define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
35 #define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
36 #define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
37 #define W7 565  /* 2048*sqrt (2)*cos (7*pi/16) */
38 #define ROW_SHIFT 8
39 #define COL_SHIFT 17
40 #else
41 #define W1  22725  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
42 #define W2  21407  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
43 #define W3  19266  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
44 #define W4  16383  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
45 #define W5  12873  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
46 #define W6  8867   //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
47 #define W7  4520   //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
48 #define ROW_SHIFT 11
49 #define COL_SHIFT 20 // 6
50 #endif
51
52 #ifdef ARCH_ALPHA
53 #define FAST_64BIT
54 #endif
55
56 #if defined(ARCH_POWERPC_405)
57
58 /* signed 16x16 -> 32 multiply add accumulate */
59 #define MAC16(rt, ra, rb) \
60     asm ("maclhw %0, %2, %3" : "=r" (rt) : "0" (rt), "r" (ra), "r" (rb));
61
62 /* signed 16x16 -> 32 multiply */
63 #define MUL16(rt, ra, rb) \
64     asm ("mullhw %0, %1, %2" : "=r" (rt) : "r" (ra), "r" (rb));
65
66 #else
67
68 /* signed 16x16 -> 32 multiply add accumulate */
69 #define MAC16(rt, ra, rb) rt += (ra) * (rb)
70
71 /* signed 16x16 -> 32 multiply */
72 #define MUL16(rt, ra, rb) rt = (ra) * (rb)
73
74 #endif
75
76 #ifdef ARCH_ALPHA
77 /* 0: all entries 0, 1: only first entry nonzero, 2: otherwise  */
78 static inline int idctRowCondDC(int16_t *row)
79 {
80         int_fast32_t a0, a1, a2, a3, b0, b1, b2, b3;
81         uint64_t *lrow = (uint64_t *) row;
82
83         if (lrow[1] == 0) {
84                 if (lrow[0] == 0)
85                         return 0;
86                 if ((lrow[0] & ~0xffffULL) == 0) {
87                         uint64_t v;
88 #if 1                   //is ok if |a0| < 1024 than theres an +-1 error (for the *W4 case for W4=16383 !!!)
89                         a0 = row[0]<<3;
90 #else
91                         a0 = W4 * row[0];
92                         a0 += 1 << (ROW_SHIFT - 1);
93                         a0 >>= ROW_SHIFT;
94 #endif
95                         v = (uint16_t) a0;
96                         v += v << 16;
97                         v += v << 32;
98                         lrow[0] = v;
99                         lrow[1] = v;
100
101                         return 1;
102                 }
103         }
104
105         a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1));
106         a1 = a0;
107         a2 = a0;
108         a3 = a0;
109
110         if (row[2]) {
111                 a0 += W2 * row[2];
112                 a1 += W6 * row[2];
113                 a2 -= W6 * row[2];
114                 a3 -= W2 * row[2];
115         }
116
117         if (row[4]) {
118                 a0 += W4 * row[4];
119                 a1 -= W4 * row[4];
120                 a2 -= W4 * row[4];
121                 a3 += W4 * row[4];
122         }
123
124         if (row[6]) {
125                 a0 += W6 * row[6];
126                 a1 -= W2 * row[6];
127                 a2 += W2 * row[6];
128                 a3 -= W6 * row[6];
129         }
130
131         if (row[1]) {
132                 b0 = W1 * row[1];
133                 b1 = W3 * row[1];
134                 b2 = W5 * row[1];
135                 b3 = W7 * row[1];
136         } else {
137                 b0 = 0;
138                 b1 = 0;
139                 b2 = 0;
140                 b3 = 0;
141         }
142
143         if (row[3]) {
144                 b0 += W3 * row[3];
145                 b1 -= W7 * row[3];
146                 b2 -= W1 * row[3];
147                 b3 -= W5 * row[3];
148         }
149
150         if (row[5]) {
151                 b0 += W5 * row[5];
152                 b1 -= W1 * row[5];
153                 b2 += W7 * row[5];
154                 b3 += W3 * row[5];
155         }
156
157         if (row[7]) {
158                 b0 += W7 * row[7];
159                 b1 -= W5 * row[7];
160                 b2 += W3 * row[7];
161                 b3 -= W1 * row[7];
162         }
163
164         row[0] = (a0 + b0) >> ROW_SHIFT;
165         row[1] = (a1 + b1) >> ROW_SHIFT;
166         row[2] = (a2 + b2) >> ROW_SHIFT;
167         row[3] = (a3 + b3) >> ROW_SHIFT;
168         row[4] = (a3 - b3) >> ROW_SHIFT;
169         row[5] = (a2 - b2) >> ROW_SHIFT;
170         row[6] = (a1 - b1) >> ROW_SHIFT;
171         row[7] = (a0 - b0) >> ROW_SHIFT;
172
173         return 2;
174 }
175
176 inline static void idctSparseCol2(int16_t *col)
177 {
178         int a0, a1, a2, a3, b0, b1, b2, b3;
179
180         col[0] += (1 << (COL_SHIFT - 1)) / W4;
181
182         a0 = W4 * col[8 * 0];
183         a1 = W4 * col[8 * 0];
184         a2 = W4 * col[8 * 0];
185         a3 = W4 * col[8 * 0];
186
187         if (col[8 * 2]) {
188                 a0 += W2 * col[8 * 2];
189                 a1 += W6 * col[8 * 2];
190                 a2 -= W6 * col[8 * 2];
191                 a3 -= W2 * col[8 * 2];
192         }
193
194         if (col[8 * 4]) {
195                 a0 += W4 * col[8 * 4];
196                 a1 -= W4 * col[8 * 4];
197                 a2 -= W4 * col[8 * 4];
198                 a3 += W4 * col[8 * 4];
199         }
200
201         if (col[8 * 6]) {
202                 a0 += W6 * col[8 * 6];
203                 a1 -= W2 * col[8 * 6];
204                 a2 += W2 * col[8 * 6];
205                 a3 -= W6 * col[8 * 6];
206         }
207
208         if (col[8 * 1]) {
209                 b0 = W1 * col[8 * 1];
210                 b1 = W3 * col[8 * 1];
211                 b2 = W5 * col[8 * 1];
212                 b3 = W7 * col[8 * 1];
213         } else {
214                 b0 = b1 = b2 = b3 = 0;
215         }
216
217         if (col[8 * 3]) {
218                 b0 += W3 * col[8 * 3];
219                 b1 -= W7 * col[8 * 3];
220                 b2 -= W1 * col[8 * 3];
221                 b3 -= W5 * col[8 * 3];
222         }
223
224         if (col[8 * 5]) {
225                 b0 += W5 * col[8 * 5];
226                 b1 -= W1 * col[8 * 5];
227                 b2 += W7 * col[8 * 5];
228                 b3 += W3 * col[8 * 5];
229         }
230
231         if (col[8 * 7]) {
232                 b0 += W7 * col[8 * 7];
233                 b1 -= W5 * col[8 * 7];
234                 b2 += W3 * col[8 * 7];
235                 b3 -= W1 * col[8 * 7];
236         }
237
238         col[8 * 0] = (a0 + b0) >> COL_SHIFT;
239         col[8 * 7] = (a0 - b0) >> COL_SHIFT;
240         col[8 * 1] = (a1 + b1) >> COL_SHIFT;
241         col[8 * 6] = (a1 - b1) >> COL_SHIFT;
242         col[8 * 2] = (a2 + b2) >> COL_SHIFT;
243         col[8 * 5] = (a2 - b2) >> COL_SHIFT;
244         col[8 * 3] = (a3 + b3) >> COL_SHIFT;
245         col[8 * 4] = (a3 - b3) >> COL_SHIFT;
246 }
247
248 #else  /* not ARCH_ALPHA */
249
250 static inline void idctRowCondDC (int16_t * row)
251 {
252         int a0, a1, a2, a3, b0, b1, b2, b3;
253 #ifdef FAST_64BIT
254         uint64_t temp;
255 #else
256         uint32_t temp;
257 #endif
258
259 #ifdef FAST_64BIT
260 #ifdef WORDS_BIGENDIAN
261 #define ROW0_MASK 0xffff000000000000LL
262 #else
263 #define ROW0_MASK 0xffffLL
264 #endif
265         if ( ((((uint64_t *)row)[0] & ~ROW0_MASK) | 
266               ((uint64_t *)row)[1]) == 0) {
267             temp = (row[0] << 3) & 0xffff;
268             temp += temp << 16;
269             temp += temp << 32;
270             ((uint64_t *)row)[0] = temp;
271             ((uint64_t *)row)[1] = temp;
272             return;
273         }
274 #else
275         if (!(((uint32_t*)row)[1] |
276               ((uint32_t*)row)[2] |
277               ((uint32_t*)row)[3] | 
278               row[1])) {
279             temp = (row[0] << 3) & 0xffff;
280             temp += temp << 16;
281             ((uint32_t*)row)[0]=((uint32_t*)row)[1] =
282                 ((uint32_t*)row)[2]=((uint32_t*)row)[3] = temp;
283                 return;
284         }
285 #endif
286
287         a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1));
288         a1 = a0;
289         a2 = a0;
290         a3 = a0;
291
292         /* no need to optimize : gcc does it */
293         a0 += W2 * row[2];
294         a1 += W6 * row[2];
295         a2 -= W6 * row[2];
296         a3 -= W2 * row[2];
297
298         MUL16(b0, W1, row[1]);
299         MAC16(b0, W3, row[3]);
300         MUL16(b1, W3, row[1]);
301         MAC16(b1, -W7, row[3]);
302         MUL16(b2, W5, row[1]);
303         MAC16(b2, -W1, row[3]);
304         MUL16(b3, W7, row[1]);
305         MAC16(b3, -W5, row[3]);
306
307 #ifdef FAST_64BIT
308         temp = ((uint64_t*)row)[1];
309 #else
310         temp = ((uint32_t*)row)[2] | ((uint32_t*)row)[3];
311 #endif
312         if (temp != 0) {
313             a0 += W4*row[4] + W6*row[6];
314             a1 += - W4*row[4] - W2*row[6];
315             a2 += - W4*row[4] + W2*row[6];
316             a3 += W4*row[4] - W6*row[6];
317
318             MAC16(b0, W5, row[5]);
319             MAC16(b0, W7, row[7]);
320             
321             MAC16(b1, -W1, row[5]);
322             MAC16(b1, -W5, row[7]);
323             
324             MAC16(b2, W7, row[5]);
325             MAC16(b2, W3, row[7]);
326             
327             MAC16(b3, W3, row[5]);
328             MAC16(b3, -W1, row[7]);
329         }
330
331         row[0] = (a0 + b0) >> ROW_SHIFT;
332         row[7] = (a0 - b0) >> ROW_SHIFT;
333         row[1] = (a1 + b1) >> ROW_SHIFT;
334         row[6] = (a1 - b1) >> ROW_SHIFT;
335         row[2] = (a2 + b2) >> ROW_SHIFT;
336         row[5] = (a2 - b2) >> ROW_SHIFT;
337         row[3] = (a3 + b3) >> ROW_SHIFT;
338         row[4] = (a3 - b3) >> ROW_SHIFT;
339 }
340 #endif /* not ARCH_ALPHA */
341
342 static inline void idctSparseColPut (UINT8 *dest, int line_size, 
343                                      int16_t * col)
344 {
345         int a0, a1, a2, a3, b0, b1, b2, b3;
346         UINT8 *cm = cropTbl + MAX_NEG_CROP;
347
348         /* XXX: I did that only to give same values as previous code */
349         a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
350         a1 = a0;
351         a2 = a0;
352         a3 = a0;
353
354         a0 +=  + W2*col[8*2];
355         a1 +=  + W6*col[8*2];
356         a2 +=  - W6*col[8*2];
357         a3 +=  - W2*col[8*2];
358
359         MUL16(b0, W1, col[8*1]);
360         MUL16(b1, W3, col[8*1]);
361         MUL16(b2, W5, col[8*1]);
362         MUL16(b3, W7, col[8*1]);
363
364         MAC16(b0, + W3, col[8*3]);
365         MAC16(b1, - W7, col[8*3]);
366         MAC16(b2, - W1, col[8*3]);
367         MAC16(b3, - W5, col[8*3]);
368
369         if(col[8*4]){
370             a0 += + W4*col[8*4];
371             a1 += - W4*col[8*4];
372             a2 += - W4*col[8*4];
373             a3 += + W4*col[8*4];
374         }
375
376         if (col[8*5]) {
377             MAC16(b0, + W5, col[8*5]);
378             MAC16(b1, - W1, col[8*5]);
379             MAC16(b2, + W7, col[8*5]);
380             MAC16(b3, + W3, col[8*5]);
381         }
382
383         if(col[8*6]){
384             a0 += + W6*col[8*6];
385             a1 += - W2*col[8*6];
386             a2 += + W2*col[8*6];
387             a3 += - W6*col[8*6];
388         }
389
390         if (col[8*7]) {
391             MAC16(b0, + W7, col[8*7]);
392             MAC16(b1, - W5, col[8*7]);
393             MAC16(b2, + W3, col[8*7]);
394             MAC16(b3, - W1, col[8*7]);
395         }
396
397         dest[0] = cm[(a0 + b0) >> COL_SHIFT];
398         dest += line_size;
399         dest[0] = cm[(a1 + b1) >> COL_SHIFT];
400         dest += line_size;
401         dest[0] = cm[(a2 + b2) >> COL_SHIFT];
402         dest += line_size;
403         dest[0] = cm[(a3 + b3) >> COL_SHIFT];
404         dest += line_size;
405         dest[0] = cm[(a3 - b3) >> COL_SHIFT];
406         dest += line_size;
407         dest[0] = cm[(a2 - b2) >> COL_SHIFT];
408         dest += line_size;
409         dest[0] = cm[(a1 - b1) >> COL_SHIFT];
410         dest += line_size;
411         dest[0] = cm[(a0 - b0) >> COL_SHIFT];
412 }
413
414 static inline void idctSparseColAdd (UINT8 *dest, int line_size, 
415                                      int16_t * col)
416 {
417         int a0, a1, a2, a3, b0, b1, b2, b3;
418         UINT8 *cm = cropTbl + MAX_NEG_CROP;
419
420         /* XXX: I did that only to give same values as previous code */
421         a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
422         a1 = a0;
423         a2 = a0;
424         a3 = a0;
425
426         a0 +=  + W2*col[8*2];
427         a1 +=  + W6*col[8*2];
428         a2 +=  - W6*col[8*2];
429         a3 +=  - W2*col[8*2];
430
431         MUL16(b0, W1, col[8*1]);
432         MUL16(b1, W3, col[8*1]);
433         MUL16(b2, W5, col[8*1]);
434         MUL16(b3, W7, col[8*1]);
435
436         MAC16(b0, + W3, col[8*3]);
437         MAC16(b1, - W7, col[8*3]);
438         MAC16(b2, - W1, col[8*3]);
439         MAC16(b3, - W5, col[8*3]);
440
441         if(col[8*4]){
442             a0 += + W4*col[8*4];
443             a1 += - W4*col[8*4];
444             a2 += - W4*col[8*4];
445             a3 += + W4*col[8*4];
446         }
447
448         if (col[8*5]) {
449             MAC16(b0, + W5, col[8*5]);
450             MAC16(b1, - W1, col[8*5]);
451             MAC16(b2, + W7, col[8*5]);
452             MAC16(b3, + W3, col[8*5]);
453         }
454
455         if(col[8*6]){
456             a0 += + W6*col[8*6];
457             a1 += - W2*col[8*6];
458             a2 += + W2*col[8*6];
459             a3 += - W6*col[8*6];
460         }
461
462         if (col[8*7]) {
463             MAC16(b0, + W7, col[8*7]);
464             MAC16(b1, - W5, col[8*7]);
465             MAC16(b2, + W3, col[8*7]);
466             MAC16(b3, - W1, col[8*7]);
467         }
468
469         dest[0] = cm[dest[0] + ((a0 + b0) >> COL_SHIFT)];
470         dest += line_size;
471         dest[0] = cm[dest[0] + ((a1 + b1) >> COL_SHIFT)];
472         dest += line_size;
473         dest[0] = cm[dest[0] + ((a2 + b2) >> COL_SHIFT)];
474         dest += line_size;
475         dest[0] = cm[dest[0] + ((a3 + b3) >> COL_SHIFT)];
476         dest += line_size;
477         dest[0] = cm[dest[0] + ((a3 - b3) >> COL_SHIFT)];
478         dest += line_size;
479         dest[0] = cm[dest[0] + ((a2 - b2) >> COL_SHIFT)];
480         dest += line_size;
481         dest[0] = cm[dest[0] + ((a1 - b1) >> COL_SHIFT)];
482         dest += line_size;
483         dest[0] = cm[dest[0] + ((a0 - b0) >> COL_SHIFT)];
484 }
485
486 static inline void idctSparseCol (int16_t * col)
487 {
488         int a0, a1, a2, a3, b0, b1, b2, b3;
489
490         /* XXX: I did that only to give same values as previous code */
491         a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
492         a1 = a0;
493         a2 = a0;
494         a3 = a0;
495
496         a0 +=  + W2*col[8*2];
497         a1 +=  + W6*col[8*2];
498         a2 +=  - W6*col[8*2];
499         a3 +=  - W2*col[8*2];
500
501         MUL16(b0, W1, col[8*1]);
502         MUL16(b1, W3, col[8*1]);
503         MUL16(b2, W5, col[8*1]);
504         MUL16(b3, W7, col[8*1]);
505
506         MAC16(b0, + W3, col[8*3]);
507         MAC16(b1, - W7, col[8*3]);
508         MAC16(b2, - W1, col[8*3]);
509         MAC16(b3, - W5, col[8*3]);
510
511         if(col[8*4]){
512             a0 += + W4*col[8*4];
513             a1 += - W4*col[8*4];
514             a2 += - W4*col[8*4];
515             a3 += + W4*col[8*4];
516         }
517
518         if (col[8*5]) {
519             MAC16(b0, + W5, col[8*5]);
520             MAC16(b1, - W1, col[8*5]);
521             MAC16(b2, + W7, col[8*5]);
522             MAC16(b3, + W3, col[8*5]);
523         }
524
525         if(col[8*6]){
526             a0 += + W6*col[8*6];
527             a1 += - W2*col[8*6];
528             a2 += + W2*col[8*6];
529             a3 += - W6*col[8*6];
530         }
531
532         if (col[8*7]) {
533             MAC16(b0, + W7, col[8*7]);
534             MAC16(b1, - W5, col[8*7]);
535             MAC16(b2, + W3, col[8*7]);
536             MAC16(b3, - W1, col[8*7]);
537         }
538
539         col[0 ] = ((a0 + b0) >> COL_SHIFT);
540         col[8 ] = ((a1 + b1) >> COL_SHIFT);
541         col[16] = ((a2 + b2) >> COL_SHIFT);
542         col[24] = ((a3 + b3) >> COL_SHIFT);
543         col[32] = ((a3 - b3) >> COL_SHIFT);
544         col[40] = ((a2 - b2) >> COL_SHIFT);
545         col[48] = ((a1 - b1) >> COL_SHIFT);
546         col[56] = ((a0 - b0) >> COL_SHIFT);
547 }
548
549
550 #ifdef ARCH_ALPHA
551 /* If all rows but the first one are zero after row transformation,
552    all rows will be identical after column transformation.  */
553 static inline void idctCol2(int16_t *col)
554 {
555         int i;
556         uint64_t l, r;
557         uint64_t *lcol = (uint64_t *) col;
558
559         for (i = 0; i < 8; ++i) {
560                 int a0 = col[0] + (1 << (COL_SHIFT - 1)) / W4;
561
562                 a0 *= W4;
563                 col[0] = a0 >> COL_SHIFT;
564                 ++col;
565         }
566
567         l = lcol[0];
568         r = lcol[1];
569         lcol[ 2] = l; lcol[ 3] = r;
570         lcol[ 4] = l; lcol[ 5] = r;
571         lcol[ 6] = l; lcol[ 7] = r;
572         lcol[ 8] = l; lcol[ 9] = r;
573         lcol[10] = l; lcol[11] = r;
574         lcol[12] = l; lcol[13] = r;
575         lcol[14] = l; lcol[15] = r;
576 }
577
578 void simple_idct (short *block)
579 {
580
581         int i;
582         int rowsZero = 1;       /* all rows except row 0 zero */
583         int rowsConstant = 1;   /* all rows consist of a constant value */
584
585         for (i = 0; i < 8; i++) {
586                 int sparseness = idctRowCondDC(block + 8 * i);
587
588                 if (i > 0 && sparseness > 0)
589                         rowsZero = 0;
590                 if (sparseness == 2)
591                         rowsConstant = 0;
592         }
593
594         if (rowsZero) {
595                 idctCol2(block);
596         } else if (rowsConstant) {
597                 uint64_t *lblock = (uint64_t *) block;
598
599                 idctSparseCol2(block);
600                 for (i = 0; i < 8; i++) {
601                         uint64_t v = (uint16_t) block[i * 8];
602
603                         v += v << 16;
604                         v += v << 32;
605                         lblock[0] = v;
606                         lblock[1] = v;
607                         lblock += 2;
608                 }
609         } else {
610                 for (i = 0; i < 8; i++)
611                         idctSparseCol2(block + i);
612         }
613 }
614
615 /* XXX: suppress this mess */
616 void simple_idct_put(UINT8 *dest, int line_size, DCTELEM *block)
617 {
618     simple_idct(block);
619     put_pixels_clamped(block, dest, line_size);
620 }
621
622 void simple_idct_add(UINT8 *dest, int line_size, DCTELEM *block)
623 {
624     simple_idct(block);
625     add_pixels_clamped(block, dest, line_size);
626 }
627
628 #else
629
630 void simple_idct_put(UINT8 *dest, int line_size, INT16 *block)
631 {
632     int i;
633     for(i=0; i<8; i++)
634         idctRowCondDC(block + i*8);
635     
636     for(i=0; i<8; i++)
637         idctSparseColPut(dest + i, line_size, block + i);
638 }
639
640 void simple_idct_add(UINT8 *dest, int line_size, INT16 *block)
641 {
642     int i;
643     for(i=0; i<8; i++)
644         idctRowCondDC(block + i*8);
645     
646     for(i=0; i<8; i++)
647         idctSparseColAdd(dest + i, line_size, block + i);
648 }
649
650 void simple_idct(INT16 *block)
651 {
652     int i;
653     for(i=0; i<8; i++)
654         idctRowCondDC(block + i*8);
655     
656     for(i=0; i<8; i++)
657         idctSparseCol(block + i);
658 }
659
660 #endif
661
662 /* 2x4x8 idct */
663
664 #define CN_SHIFT 12
665 #define C_FIX(x) ((int)((x) * (1 << CN_SHIFT) + 0.5))
666 #define C1 C_FIX(0.6532814824)
667 #define C2 C_FIX(0.2705980501)
668
669 /* row idct is multiple by 16 * sqrt(2.0), col idct4 is normalized,
670    and the butterfly must be multiplied by 0.5 * sqrt(2.0) */
671 #define C_SHIFT (4+1+12)
672
673 static inline void idct4col(UINT8 *dest, int line_size, const INT16 *col)
674 {
675     int c0, c1, c2, c3, a0, a1, a2, a3;
676     const UINT8 *cm = cropTbl + MAX_NEG_CROP;
677
678     a0 = col[8*0];
679     a1 = col[8*2];
680     a2 = col[8*4];
681     a3 = col[8*6];
682     c0 = ((a0 + a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));
683     c2 = ((a0 - a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1));
684     c1 = a1 * C1 + a3 * C2;
685     c3 = a1 * C2 - a3 * C1;
686     dest[0] = cm[(c0 + c1) >> C_SHIFT];
687     dest += line_size;
688     dest[0] = cm[(c2 + c3) >> C_SHIFT];
689     dest += line_size;
690     dest[0] = cm[(c2 - c3) >> C_SHIFT];
691     dest += line_size;
692     dest[0] = cm[(c0 - c1) >> C_SHIFT];
693 }
694
695 #define BF(k) \
696 {\
697     int a0, a1;\
698     a0 = ptr[k];\
699     a1 = ptr[8 + k];\
700     ptr[k] = a0 + a1;\
701     ptr[8 + k] = a0 - a1;\
702 }
703
704 /* only used by DV codec. The input must be interlaced. 128 is added
705    to the pixels before clamping to avoid systematic error
706    (1024*sqrt(2)) offset would be needed otherwise. */
707 /* XXX: I think a 1.0/sqrt(2) normalization should be needed to
708    compensate the extra butterfly stage - I don't have the full DV
709    specification */
710 void simple_idct248_put(UINT8 *dest, int line_size, INT16 *block)
711 {
712     int i;
713     INT16 *ptr;
714     
715     /* butterfly */
716     ptr = block;
717     for(i=0;i<4;i++) {
718         BF(0);
719         BF(1);
720         BF(2);
721         BF(3);
722         BF(4);
723         BF(5);
724         BF(6);
725         BF(7);
726         ptr += 2 * 8;
727     }
728
729     /* IDCT8 on each line */
730     for(i=0; i<8; i++) {
731         idctRowCondDC(block + i*8);
732     }
733
734     /* IDCT4 and store */
735     for(i=0;i<8;i++) {
736         idct4col(dest + i, 2 * line_size, block + i);
737         idct4col(dest + line_size + i, 2 * line_size, block + 8 + i);
738     }
739 }