fdctref.c

Go to the documentation of this file.
00001 /**
00002  * @file fdctref.c
00003  * forward discrete cosine transform, double precision.
00004  */
00005 
00006 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
00007 
00008 /*
00009  * Disclaimer of Warranty
00010  *
00011  * These software programs are available to the user without any license fee or
00012  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
00013  * any and all warranties, whether express, implied, or statuary, including any
00014  * implied warranties or merchantability or of fitness for a particular
00015  * purpose.  In no event shall the copyright-holder be liable for any
00016  * incidental, punitive, or consequential damages of any kind whatsoever
00017  * arising from the use of these programs.
00018  *
00019  * This disclaimer of warranty extends to the user of these programs and user's
00020  * customers, employees, agents, transferees, successors, and assigns.
00021  *
00022  * The MPEG Software Simulation Group does not represent or warrant that the
00023  * programs furnished hereunder are free of infringement of any third-party
00024  * patents.
00025  *
00026  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
00027  * are subject to royalty fees to patent holders.  Many of these patents are
00028  * general enough such that they are unavoidable regardless of implementation
00029  * design.
00030  */
00031 
00032 #include <math.h>
00033 
00034 #ifndef PI
00035 # ifdef M_PI
00036 #  define PI M_PI
00037 # else
00038 #  define PI 3.14159265358979323846
00039 # endif
00040 #endif
00041 
00042 /* global declarations */
00043 void init_fdct (void);
00044 void fdct (short *block);
00045 
00046 /* private data */
00047 static double c[8][8]; /* transform coefficients */
00048 
00049 void init_fdct()
00050 {
00051   int i, j;
00052   double s;
00053 
00054   for (i=0; i<8; i++)
00055   {
00056     s = (i==0) ? sqrt(0.125) : 0.5;
00057 
00058     for (j=0; j<8; j++)
00059       c[i][j] = s * cos((PI/8.0)*i*(j+0.5));
00060   }
00061 }
00062 
00063 void fdct(block)
00064 short *block;
00065 {
00066         register int i, j;
00067         double s;
00068         double tmp[64];
00069 
00070         for(i = 0; i < 8; i++)
00071             for(j = 0; j < 8; j++)
00072             {
00073                     s = 0.0;
00074 
00075 /*
00076  *                     for(k = 0; k < 8; k++)
00077  *                         s += c[j][k] * block[8 * i + k];
00078  */
00079                 s += c[j][0] * block[8 * i + 0];
00080                 s += c[j][1] * block[8 * i + 1];
00081                 s += c[j][2] * block[8 * i + 2];
00082                 s += c[j][3] * block[8 * i + 3];
00083                 s += c[j][4] * block[8 * i + 4];
00084                 s += c[j][5] * block[8 * i + 5];
00085                 s += c[j][6] * block[8 * i + 6];
00086                 s += c[j][7] * block[8 * i + 7];
00087 
00088                     tmp[8 * i + j] = s;
00089             }
00090 
00091         for(j = 0; j < 8; j++)
00092             for(i = 0; i < 8; i++)
00093             {
00094                     s = 0.0;
00095 
00096 /*
00097  *                       for(k = 0; k < 8; k++)
00098  *                    s += c[i][k] * tmp[8 * k + j];
00099  */
00100                 s += c[i][0] * tmp[8 * 0 + j];
00101                 s += c[i][1] * tmp[8 * 1 + j];
00102                 s += c[i][2] * tmp[8 * 2 + j];
00103                 s += c[i][3] * tmp[8 * 3 + j];
00104                 s += c[i][4] * tmp[8 * 4 + j];
00105                 s += c[i][5] * tmp[8 * 5 + j];
00106                 s += c[i][6] * tmp[8 * 6 + j];
00107                 s += c[i][7] * tmp[8 * 7 + j];
00108                 s*=8.0;
00109 
00110                     block[8 * i + j] = (short)floor(s + 0.499999);
00111 /*
00112  * reason for adding 0.499999 instead of 0.5:
00113  * s is quite often x.5 (at least for i and/or j = 0 or 4)
00114  * and setting the rounding threshold exactly to 0.5 leads to an
00115  * extremely high arithmetic implementation dependency of the result;
00116  * s being between x.5 and x.500001 (which is now incorrectly rounded
00117  * downwards instead of upwards) is assumed to occur less often
00118  * (if at all)
00119  */
00120       }
00121 }
00122 
00123 /* perform IDCT matrix multiply for 8x8 coefficient block */
00124 
00125 void idct(block)
00126 short *block;
00127 {
00128   int i, j, k, v;
00129   double partial_product;
00130   double tmp[64];
00131 
00132   for (i=0; i<8; i++)
00133     for (j=0; j<8; j++)
00134     {
00135       partial_product = 0.0;
00136 
00137       for (k=0; k<8; k++)
00138         partial_product+= c[k][j]*block[8*i+k];
00139 
00140       tmp[8*i+j] = partial_product;
00141     }
00142 
00143   /* Transpose operation is integrated into address mapping by switching
00144      loop order of i and j */
00145 
00146   for (j=0; j<8; j++)
00147     for (i=0; i<8; i++)
00148     {
00149       partial_product = 0.0;
00150 
00151       for (k=0; k<8; k++)
00152         partial_product+= c[k][i]*tmp[8*k+j];
00153 
00154       v = (int) floor(partial_product+0.5);
00155       block[8*i+j] = v;
00156     }
00157 }

Generated on Fri Jan 9 13:44:28 2009 for libextractor by  doxygen 1.5.1