r1019: Fix crash in Ogg file handling.
[cinelerra/simeon] / mpeg2enc / fdctref.c
1 /* fdctref.c, forward discrete cosine transform, double precision           */
2
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
4
5 /*
6  * Disclaimer of Warranty
7  *
8  * These software programs are available to the user without any license fee or
9  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
10  * any and all warranties, whether express, implied, or statuary, including any
11  * implied warranties or merchantability or of fitness for a particular
12  * purpose.  In no event shall the copyright-holder be liable for any
13  * incidental, punitive, or consequential damages of any kind whatsoever
14  * arising from the use of these programs.
15  *
16  * This disclaimer of warranty extends to the user of these programs and user's
17  * customers, employees, agents, transferees, successors, and assigns.
18  *
19  * The MPEG Software Simulation Group does not represent or warrant that the
20  * programs furnished hereunder are free of infringement of any third-party
21  * patents.
22  *
23  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24  * are subject to royalty fees to patent holders.  Many of these patents are
25  * general enough such that they are unavoidable regardless of implementation
26  * design.
27  *
28  */
29
30 #include <math.h>
31
32 #include "config.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 _ANSI_ARGS_((void));
44 void fdct _ANSI_ARGS_((short *block));
45
46 /* private data */
47 static double c[8][8]; /* transform coefficients */
48
49 void init_fdct()
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
109                 block[8 * i + j] = (int)floor(s + 0.499999);
110 /*
111  * reason for adding 0.499999 instead of 0.5:
112  * s is quite often x.5 (at least for i and/or j = 0 or 4)
113  * and setting the rounding threshold exactly to 0.5 leads to an
114  * extremely high arithmetic implementation dependency of the result;
115  * s being between x.5 and x.500001 (which is now incorrectly rounded
116  * downwards instead of upwards) is assumed to occur less often
117  * (if at all)
118  */
119       }
120 }