2 /**************************************************************************
4 * This code is developed by Adam Li. This software is an *
5 * implementation of a part of one or more MPEG-4 Video tools as *
6 * specified in ISO/IEC 14496-2 standard. Those intending to use this *
7 * software module in hardware or software products are advised that its *
8 * use may infringe existing patents or copyrights, and any such use *
9 * would be at such party's own risk. The original developer of this *
10 * software module and his/her company, and subsequent editors and their *
11 * companies (including Project Mayo), will have no liability for use of *
12 * this software or modifications or derivatives thereof. *
14 * Project Mayo gives users of the Codec a license to this software *
15 * module or modifications thereof for use in hardware or software *
16 * products claiming conformance to the MPEG-4 Video Standard as *
17 * described in the Open DivX license. *
19 * The complete Open DivX license can be found at *
20 * http://www.projectmayo.com/opendivx/license.php . *
22 **************************************************************************/
24 /**************************************************************************
28 * Copyright (C) 2001 Project Mayo
32 * DivX Advance Research Center <darc@projectmayo.com>
34 **************************************************************************/
36 /* This file contains some functions for fDCT/iDCT transformation. */
37 /* Some codes of this project come from SSG MPEG-2 implementation. */
38 /* Please see seperate acknowledgement file for a list of contributors. */
42 /* The first part of it is for the forward DCT */
48 # define PI 3.14159265358979323846
53 static double c
[8][8]; /* transform coefficients */
68 s
+= c
[j
][k
] * block
[8*i
+k
];
79 s
+= c
[i
][k
] * tmp
[8*k
+j
];
81 block
[8*i
+j
] = (int)floor(s
+0.499999);
83 * reason for adding 0.499999 instead of 0.5:
84 * s is quite often x.5 (at least for i and/or j = 0 or 4)
85 * and setting the rounding threshold exactly to 0.5 leads to an
86 * extremely high arithmetic implementation dependency of the result;
87 * s being between x.5 and x.500001 (which is now incorrectly rounded
88 * downwards instead of upwards) is assumed to occur less often
101 s
= (i
==0) ? sqrt(0.125) : 0.5;
104 c
[i
][j
] = s
* cos((PI
/8.0)*i
*(j
+0.5));
111 /* the second part of it is for the inverse DCT */
113 #define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
114 #define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
115 #define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
116 #define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
117 #define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
118 #define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
121 static short iclip
[1024]; /* clipping table */
124 /* private prototypes */
125 static void idctrow_enc (short *blk
);
126 static void idctcol_enc (short *blk
);
128 /* two dimensional inverse discrete cosine transform */
135 idctrow_enc(block
+8*i
);
138 idctcol_enc(block
+i
);
146 for (i
= -512; i
<512; i
++)
147 iclp
[i
] = (i
<-256) ? -256 : ((i
>255) ? 255 : i
);
150 /* row (horizontal) IDCT
153 * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l )
157 * c[1..7] = 128*sqrt(2)
160 static void idctrow_enc(blk
)
163 int x0
, x1
, x2
, x3
, x4
, x5
, x6
, x7
, x8
;
166 if (!((x1
= blk
[4]<<11) | (x2
= blk
[6]) | (x3
= blk
[2]) |
167 (x4
= blk
[1]) | (x5
= blk
[7]) | (x6
= blk
[5]) | (x7
= blk
[3])))
169 blk
[0]=blk
[1]=blk
[2]=blk
[3]=blk
[4]=blk
[5]=blk
[6]=blk
[7]=blk
[0]<<3;
173 x0
= (blk
[0]<<11) + 128; /* for proper rounding in the fourth stage */
177 x4
= x8
+ (W1
-W7
)*x4
;
178 x5
= x8
- (W1
+W7
)*x5
;
180 x6
= x8
- (W3
-W5
)*x6
;
181 x7
= x8
- (W3
+W5
)*x7
;
187 x2
= x1
- (W2
+W6
)*x2
;
188 x3
= x1
+ (W2
-W6
)*x3
;
199 x2
= (181*(x4
+x5
)+128)>>8;
200 x4
= (181*(x4
-x5
)+128)>>8;
213 /* column (vertical) IDCT
216 * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l )
219 * where: c[0] = 1/1024
220 * c[1..7] = (1/1024)*sqrt(2)
222 static void idctcol_enc(blk
)
225 int x0
, x1
, x2
, x3
, x4
, x5
, x6
, x7
, x8
;
228 if (!((x1
= (blk
[8*4]<<8)) | (x2
= blk
[8*6]) | (x3
= blk
[8*2]) |
229 (x4
= blk
[8*1]) | (x5
= blk
[8*7]) | (x6
= blk
[8*5]) | (x7
= blk
[8*3])))
231 blk
[8*0]=blk
[8*1]=blk
[8*2]=blk
[8*3]=blk
[8*4]=blk
[8*5]=blk
[8*6]=blk
[8*7]=
232 iclp
[(blk
[8*0]+32)>>6];
236 x0
= (blk
[8*0]<<8) + 8192;
240 x4
= (x8
+(W1
-W7
)*x4
)>>3;
241 x5
= (x8
-(W1
+W7
)*x5
)>>3;
243 x6
= (x8
-(W3
-W5
)*x6
)>>3;
244 x7
= (x8
-(W3
+W5
)*x7
)>>3;
250 x2
= (x1
-(W2
+W6
)*x2
)>>3;
251 x3
= (x1
+(W2
-W6
)*x3
)>>3;
262 x2
= (181*(x4
+x5
)+128)>>8;
263 x4
= (181*(x4
-x5
)+128)>>8;
266 blk
[8*0] = iclp
[(x7
+x1
)>>14];
267 blk
[8*1] = iclp
[(x3
+x2
)>>14];
268 blk
[8*2] = iclp
[(x0
+x4
)>>14];
269 blk
[8*3] = iclp
[(x8
+x6
)>>14];
270 blk
[8*4] = iclp
[(x8
-x6
)>>14];
271 blk
[8*5] = iclp
[(x0
-x4
)>>14];
272 blk
[8*6] = iclp
[(x3
-x2
)>>14];
273 blk
[8*7] = iclp
[(x7
-x1
)>>14];