]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/fdctref.c
164883dcbc0715f3880c3e5f67168141d61d0633
[frescor/ffmpeg.git] / libavcodec / fdctref.c
1 /**
2  * @file libavcodec/fdctref.c
3  * forward discrete cosine transform, double precision.
4  */
5
6 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
7
8 /*
9  * Disclaimer of Warranty
10  *
11  * These software programs are available to the user without any license fee or
12  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
13  * any and all warranties, whether express, implied, or statuary, including any
14  * implied warranties or merchantability or of fitness for a particular
15  * purpose.  In no event shall the copyright-holder be liable for any
16  * incidental, punitive, or consequential damages of any kind whatsoever
17  * arising from the use of these programs.
18  *
19  * This disclaimer of warranty extends to the user of these programs and user's
20  * customers, employees, agents, transferees, successors, and assigns.
21  *
22  * The MPEG Software Simulation Group does not represent or warrant that the
23  * programs furnished hereunder are free of infringement of any third-party
24  * patents.
25  *
26  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
27  * are subject to royalty fees to patent holders.  Many of these patents are
28  * general enough such that they are unavoidable regardless of implementation
29  * design.
30  */
31
32 #include <math.h>
33
34 #ifndef PI
35 # ifdef M_PI
36 #  define PI M_PI
37 # else
38 #  define PI 3.14159265358979323846
39 # endif
40 #endif
41
42 /* global declarations */
43 void init_fdct (void);
44 void fdct (short *block);
45
46 /* private data */
47 static double c[8][8]; /* transform coefficients */
48
49 void init_fdct(void)
50 {
51   int i, j;
52   double s;
53
54   for (i=0; i<8; i++)
55   {
56     s = (i==0) ? sqrt(0.125) : 0.5;
57
58     for (j=0; j<8; j++)
59       c[i][j] = s * cos((PI/8.0)*i*(j+0.5));
60   }
61 }
62
63 void fdct(block)
64 short *block;
65 {
66         register int i, j;
67         double s;
68         double tmp[64];
69
70         for(i = 0; i < 8; i++)
71             for(j = 0; j < 8; j++)
72             {
73                     s = 0.0;
74
75 /*
76  *                     for(k = 0; k < 8; k++)
77  *                         s += c[j][k] * block[8 * i + k];
78  */
79                 s += c[j][0] * block[8 * i + 0];
80                 s += c[j][1] * block[8 * i + 1];
81                 s += c[j][2] * block[8 * i + 2];
82                 s += c[j][3] * block[8 * i + 3];
83                 s += c[j][4] * block[8 * i + 4];
84                 s += c[j][5] * block[8 * i + 5];
85                 s += c[j][6] * block[8 * i + 6];
86                 s += c[j][7] * block[8 * i + 7];
87
88                     tmp[8 * i + j] = s;
89             }
90
91         for(j = 0; j < 8; j++)
92             for(i = 0; i < 8; i++)
93             {
94                     s = 0.0;
95
96 /*
97  *                       for(k = 0; k < 8; k++)
98  *                    s += c[i][k] * tmp[8 * k + j];
99  */
100                 s += c[i][0] * tmp[8 * 0 + j];
101                 s += c[i][1] * tmp[8 * 1 + j];
102                 s += c[i][2] * tmp[8 * 2 + j];
103                 s += c[i][3] * tmp[8 * 3 + j];
104                 s += c[i][4] * tmp[8 * 4 + j];
105                 s += c[i][5] * tmp[8 * 5 + j];
106                 s += c[i][6] * tmp[8 * 6 + j];
107                 s += c[i][7] * tmp[8 * 7 + j];
108                 s*=8.0;
109
110                     block[8 * i + j] = (short)floor(s + 0.499999);
111 /*
112  * reason for adding 0.499999 instead of 0.5:
113  * s is quite often x.5 (at least for i and/or j = 0 or 4)
114  * and setting the rounding threshold exactly to 0.5 leads to an
115  * extremely high arithmetic implementation dependency of the result;
116  * s being between x.5 and x.500001 (which is now incorrectly rounded
117  * downwards instead of upwards) is assumed to occur less often
118  * (if at all)
119  */
120       }
121 }
122
123 /* perform IDCT matrix multiply for 8x8 coefficient block */
124
125 void idct(block)
126 short *block;
127 {
128   int i, j, k, v;
129   double partial_product;
130   double tmp[64];
131
132   for (i=0; i<8; i++)
133     for (j=0; j<8; j++)
134     {
135       partial_product = 0.0;
136
137       for (k=0; k<8; k++)
138         partial_product+= c[k][j]*block[8*i+k];
139
140       tmp[8*i+j] = partial_product;
141     }
142
143   /* Transpose operation is integrated into address mapping by switching
144      loop order of i and j */
145
146   for (j=0; j<8; j++)
147     for (i=0; i<8; i++)
148     {
149       partial_product = 0.0;
150
151       for (k=0; k<8; k++)
152         partial_product+= c[k][i]*tmp[8*k+j];
153
154       v = (int) floor(partial_product+0.5);
155       block[8*i+j] = v;
156     }
157 }