Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

Transform8.cc

Go to the documentation of this file.
00001 /*
00002 
00003     DFT, DCT and DST routines
00004     Copyright (C) 1996-1999 Takuya OOURA
00005     Copyright (C) 1999-2003 Jussi Laako
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     Version 1.0 : Converted T.OOURA's functions to C++ class
00022     Version 1.1 : Updated to match T.OOURA's Oct/99 code and all versions
00023     Version 1.2 : Some conversion and precision updates
00024 
00025 */
00026 
00027 
00028 /* This is decimation-in-frequency radix-2/4/8 transform */
00029 
00030 
00031 /*
00032 Fast Fourier/Cosine/Sine Transform
00033     dimension   :one
00034     data length :power of 2
00035     decimation  :frequency
00036     radix       :8, 4, 2
00037     data        :inplace
00038     table       :use
00039 functions
00040     cdft: Complex Discrete Fourier Transform
00041     rdft: Real Discrete Fourier Transform
00042     ddct: Discrete Cosine Transform
00043     ddst: Discrete Sine Transform
00044     dfct: Cosine Transform of RDFT (Real Symmetric DFT)
00045     dfst: Sine Transform of RDFT (Real Anti-symmetric DFT)
00046 function prototypes
00047     void cdft(int, int, double *, int *, double *);
00048     void rdft(int, int, double *, int *, double *);
00049     void ddct(int, int, double *, int *, double *);
00050     void ddst(int, int, double *, int *, double *);
00051     void dfct(int, double *, double *, int *, double *);
00052     void dfst(int, double *, double *, int *, double *);
00053 
00054 
00055 -------- Complex DFT (Discrete Fourier Transform) --------
00056     [definition]
00057         <case1>
00058             X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n
00059         <case2>
00060             X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n
00061         (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
00062     [usage]
00063         <case1>
00064             ip[0] = 0; // first time only
00065             cdft(2*n, 1, a, ip, w);
00066         <case2>
00067             ip[0] = 0; // first time only
00068             cdft(2*n, -1, a, ip, w);
00069     [parameters]
00070         2*n            :data length (int)
00071                         n >= 1, n = power of 2
00072         a[0...2*n-1]   :input/output data (double *)
00073                         input data
00074                             a[2*j] = Re(x[j]), 
00075                             a[2*j+1] = Im(x[j]), 0<=j<n
00076                         output data
00077                             a[2*k] = Re(X[k]), 
00078                             a[2*k+1] = Im(X[k]), 0<=k<n
00079         ip[0...*]      :work area for bit reversal (int *)
00080                         length of ip >= 2+sqrt(n)
00081                         strictly, 
00082                         length of ip >= 
00083                             2+(1<<(int)(log(n+0.5)/log(2))/2).
00084                         ip[0],ip[1] are pointers of the cos/sin table.
00085         w[0...n/2-1]   :cos/sin table (double *)
00086                         w[],ip[] are initialized if ip[0] == 0.
00087     [remark]
00088         Inverse of 
00089             cdft(2*n, -1, a, ip, w);
00090         is 
00091             cdft(2*n, 1, a, ip, w);
00092             for (j = 0; j <= 2 * n - 1; j++) {
00093                 a[j] *= 1.0 / n;
00094             }
00095         .
00096 
00097 
00098 -------- Real DFT / Inverse of Real DFT --------
00099     [definition]
00100         <case1> RDFT
00101             R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2
00102             I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2
00103         <case2> IRDFT (excluding scale)
00104             a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + 
00105                    sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + 
00106                    sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n
00107     [usage]
00108         <case1>
00109             ip[0] = 0; // first time only
00110             rdft(n, 1, a, ip, w);
00111         <case2>
00112             ip[0] = 0; // first time only
00113             rdft(n, -1, a, ip, w);
00114     [parameters]
00115         n              :data length (int)
00116                         n >= 2, n = power of 2
00117         a[0...n-1]     :input/output data (double *)
00118                         <case1>
00119                             output data
00120                                 a[2*k] = R[k], 0<=k<n/2
00121                                 a[2*k+1] = I[k], 0<k<n/2
00122                                 a[1] = R[n/2]
00123                         <case2>
00124                             input data
00125                                 a[2*j] = R[j], 0<=j<n/2
00126                                 a[2*j+1] = I[j], 0<j<n/2
00127                                 a[1] = R[n/2]
00128         ip[0...*]      :work area for bit reversal (int *)
00129                         length of ip >= 2+sqrt(n/2)
00130                         strictly, 
00131                         length of ip >= 
00132                             2+(1<<(int)(log(n/2+0.5)/log(2))/2).
00133                         ip[0],ip[1] are pointers of the cos/sin table.
00134         w[0...n/2-1]   :cos/sin table (double *)
00135                         w[],ip[] are initialized if ip[0] == 0.
00136     [remark]
00137         Inverse of 
00138             rdft(n, 1, a, ip, w);
00139         is 
00140             rdft(n, -1, a, ip, w);
00141             for (j = 0; j <= n - 1; j++) {
00142                 a[j] *= 2.0 / n;
00143             }
00144         .
00145 
00146 
00147 -------- DCT (Discrete Cosine Transform) / Inverse of DCT --------
00148     [definition]
00149         <case1> IDCT (excluding scale)
00150             C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n
00151         <case2> DCT
00152             C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n
00153     [usage]
00154         <case1>
00155             ip[0] = 0; // first time only
00156             ddct(n, 1, a, ip, w);
00157         <case2>
00158             ip[0] = 0; // first time only
00159             ddct(n, -1, a, ip, w);
00160     [parameters]
00161         n              :data length (int)
00162                         n >= 2, n = power of 2
00163         a[0...n-1]     :input/output data (double *)
00164                         output data
00165                             a[k] = C[k], 0<=k<n
00166         ip[0...*]      :work area for bit reversal (int *)
00167                         length of ip >= 2+sqrt(n/2)
00168                         strictly, 
00169                         length of ip >= 
00170                             2+(1<<(int)(log(n/2+0.5)/log(2))/2).
00171                         ip[0],ip[1] are pointers of the cos/sin table.
00172         w[0...n*5/4-1] :cos/sin table (double *)
00173                         w[],ip[] are initialized if ip[0] == 0.
00174     [remark]
00175         Inverse of 
00176             ddct(n, -1, a, ip, w);
00177         is 
00178             a[0] *= 0.5;
00179             ddct(n, 1, a, ip, w);
00180             for (j = 0; j <= n - 1; j++) {
00181                 a[j] *= 2.0 / n;
00182             }
00183         .
00184 
00185 
00186 -------- DST (Discrete Sine Transform) / Inverse of DST --------
00187     [definition]
00188         <case1> IDST (excluding scale)
00189             S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n
00190         <case2> DST
00191             S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n
00192     [usage]
00193         <case1>
00194             ip[0] = 0; // first time only
00195             ddst(n, 1, a, ip, w);
00196         <case2>
00197             ip[0] = 0; // first time only
00198             ddst(n, -1, a, ip, w);
00199     [parameters]
00200         n              :data length (int)
00201                         n >= 2, n = power of 2
00202         a[0...n-1]     :input/output data (double *)
00203                         <case1>
00204                             input data
00205                                 a[j] = A[j], 0<j<n
00206                                 a[0] = A[n]
00207                             output data
00208                                 a[k] = S[k], 0<=k<n
00209                         <case2>
00210                             output data
00211                                 a[k] = S[k], 0<k<n
00212                                 a[0] = S[n]
00213         ip[0...*]      :work area for bit reversal (int *)
00214                         length of ip >= 2+sqrt(n/2)
00215                         strictly, 
00216                         length of ip >= 
00217                             2+(1<<(int)(log(n/2+0.5)/log(2))/2).
00218                         ip[0],ip[1] are pointers of the cos/sin table.
00219         w[0...n*5/4-1] :cos/sin table (double *)
00220                         w[],ip[] are initialized if ip[0] == 0.
00221     [remark]
00222         Inverse of 
00223             ddst(n, -1, a, ip, w);
00224         is 
00225             a[0] *= 0.5;
00226             ddst(n, 1, a, ip, w);
00227             for (j = 0; j <= n - 1; j++) {
00228                 a[j] *= 2.0 / n;
00229             }
00230         .
00231 
00232 
00233 -------- Cosine Transform of RDFT (Real Symmetric DFT) --------
00234     [definition]
00235         C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n
00236     [usage]
00237         ip[0] = 0; // first time only
00238         dfct(n, a, t, ip, w);
00239     [parameters]
00240         n              :data length - 1 (int)
00241                         n >= 2, n = power of 2
00242         a[0...n]       :input/output data (double *)
00243                         output data
00244                             a[k] = C[k], 0<=k<=n
00245         t[0...n/2]     :work area (double *)
00246         ip[0...*]      :work area for bit reversal (int *)
00247                         length of ip >= 2+sqrt(n/4)
00248                         strictly, 
00249                         length of ip >= 
00250                             2+(1<<(int)(log(n/4+0.5)/log(2))/2).
00251                         ip[0],ip[1] are pointers of the cos/sin table.
00252         w[0...n*5/8-1] :cos/sin table (double *)
00253                         w[],ip[] are initialized if ip[0] == 0.
00254     [remark]
00255         Inverse of 
00256             a[0] *= 0.5;
00257             a[n] *= 0.5;
00258             dfct(n, a, t, ip, w);
00259         is 
00260             a[0] *= 0.5;
00261             a[n] *= 0.5;
00262             dfct(n, a, t, ip, w);
00263             for (j = 0; j <= n; j++) {
00264                 a[j] *= 2.0 / n;
00265             }
00266         .
00267 
00268 
00269 -------- Sine Transform of RDFT (Real Anti-symmetric DFT) --------
00270     [definition]
00271         S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n
00272     [usage]
00273         ip[0] = 0; // first time only
00274         dfst(n, a, t, ip, w);
00275     [parameters]
00276         n              :data length + 1 (int)
00277                         n >= 2, n = power of 2
00278         a[0...n-1]     :input/output data (double *)
00279                         output data
00280                             a[k] = S[k], 0<k<n
00281                         (a[0] is used for work area)
00282         t[0...n/2-1]   :work area (double *)
00283         ip[0...*]      :work area for bit reversal (int *)
00284                         length of ip >= 2+sqrt(n/4)
00285                         strictly, 
00286                         length of ip >= 
00287                             2+(1<<(int)(log(n/4+0.5)/log(2))/2).
00288                         ip[0],ip[1] are pointers of the cos/sin table.
00289         w[0...n*5/8-1] :cos/sin table (double *)
00290                         w[],ip[] are initialized if ip[0] == 0.
00291     [remark]
00292         Inverse of 
00293             dfst(n, a, t, ip, w);
00294         is 
00295             dfst(n, a, t, ip, w);
00296             for (j = 1; j <= n - 1; j++) {
00297                 a[j] *= 2.0 / n;
00298             }
00299         .
00300 
00301 
00302 Appendix :
00303     The cos/sin table is recalculated when the larger table required.
00304     w[] and ip[] are compatible with all routines.
00305 */
00306 
00307 
00308 #ifdef USE_INTEL_MATH
00309     #include <mathimf.h>
00310 #else
00311     #include <math.h>
00312 #endif
00313 #include <float.h>
00314 
00315 #include "dsp/Transform8.hh"
00316 
00317 
00318 void clTransform8::cdft(long n, long isgn, float *a, long *ip, float *w)
00319 {
00320     if (n > (ip[0] << 2)) {
00321         makewt(n >> 2, ip, w);
00322     }
00323     if (n > 4) {
00324         if (isgn >= 0) {
00325             bitrv2(n, ip + 2, a);
00326             cftfsub(n, a, w);
00327         } else {
00328             bitrv2conj(n, ip + 2, a);
00329             cftbsub(n, a, w);
00330         }
00331     } else if (n == 4) {
00332         cftfsub(n, a, w);
00333     }
00334 }
00335 
00336 
00337 void clTransform8::rdft(long n, long isgn, float *a, long *ip, float *w)
00338 {
00339     long nw, nc;
00340     float xi;
00341     
00342     nw = ip[0];
00343     if (n > (nw << 2)) {
00344         nw = n >> 2;
00345         makewt(nw, ip, w);
00346     }
00347     nc = ip[1];
00348     if (n > (nc << 2)) {
00349         nc = n >> 2;
00350         makect(nc, ip, w + nw);
00351     }
00352     if (isgn >= 0) {
00353         if (n > 4) {
00354             bitrv2(n, ip + 2, a);
00355             cftfsub(n, a, w);
00356             rftfsub(n, a, nc, w + nw);
00357         } else if (n == 4) {
00358             cftfsub(n, a, w);
00359         }
00360         xi = a[0] - a[1];
00361         a[0] += a[1];
00362         a[1] = xi;
00363     } else {
00364         a[1] = 0.5f * (a[0] - a[1]);
00365         a[0] -= a[1];
00366         if (n > 4) {
00367             rftbsub(n, a, nc, w + nw);
00368             bitrv2(n, ip + 2, a);
00369             cftbsub(n, a, w);
00370         } else if (n == 4) {
00371             cftfsub(n, a, w);
00372         }
00373     }
00374 }
00375 
00376 
00377 void clTransform8::ddct(long n, long isgn, float *a, long *ip, float *w)
00378 {
00379     long j, nw, nc;
00380     float xr;
00381     
00382     nw = ip[0];
00383     if (n > (nw << 2)) {
00384         nw = n >> 2;
00385         makewt(nw, ip, w);
00386     }
00387     nc = ip[1];
00388     if (n > nc) {
00389         nc = n;
00390         makect(nc, ip, w + nw);
00391     }
00392     if (isgn < 0) {
00393         xr = a[n - 1];
00394         for (j = n - 2; j >= 2; j -= 2) {
00395             a[j + 1] = a[j] - a[j - 1];
00396             a[j] += a[j - 1];
00397         }
00398         a[1] = a[0] - xr;
00399         a[0] += xr;
00400         if (n > 4) {
00401             rftbsub(n, a, nc, w + nw);
00402             bitrv2(n, ip + 2, a);
00403             cftbsub(n, a, w);
00404         } else if (n == 4) {
00405             cftfsub(n, a, w);
00406         }
00407     }
00408     dctsub(n, a, nc, w + nw);
00409     if (isgn >= 0) {
00410         if (n > 4) {
00411             bitrv2(n, ip + 2, a);
00412             cftfsub(n, a, w);
00413             rftfsub(n, a, nc, w + nw);
00414         } else if (n == 4) {
00415             cftfsub(n, a, w);
00416         }
00417         xr = a[0] - a[1];
00418         a[0] += a[1];
00419         for (j = 2; j < n; j += 2) {
00420             a[j - 1] = a[j] - a[j + 1];
00421             a[j] += a[j + 1];
00422         }
00423         a[n - 1] = xr;
00424     }
00425 }
00426 
00427 
00428 void clTransform8::ddst(long n, long isgn, float *a, long *ip, float *w)
00429 {
00430     long j, nw, nc;
00431     float xr;
00432     
00433     nw = ip[0];
00434     if (n > (nw << 2)) {
00435         nw = n >> 2;
00436         makewt(nw, ip, w);
00437     }
00438     nc = ip[1];
00439     if (n > nc) {
00440         nc = n;
00441         makect(nc, ip, w + nw);
00442     }
00443     if (isgn < 0) {
00444         xr = a[n - 1];
00445         for (j = n - 2; j >= 2; j -= 2) {
00446             a[j + 1] = -a[j] - a[j - 1];
00447             a[j] -= a[j - 1];
00448         }
00449         a[1] = a[0] + xr;
00450         a[0] -= xr;
00451         if (n > 4) {
00452             rftbsub(n, a, nc, w + nw);
00453             bitrv2(n, ip + 2, a);
00454             cftbsub(n, a, w);
00455         } else if (n == 4) {
00456             cftfsub(n, a, w);
00457         }
00458     }
00459     dstsub(n, a, nc, w + nw);
00460     if (isgn >= 0) {
00461         if (n > 4) {
00462             bitrv2(n, ip + 2, a);
00463             cftfsub(n, a, w);
00464             rftfsub(n, a, nc, w + nw);
00465         } else if (n == 4) {
00466             cftfsub(n, a, w);
00467         }
00468         xr = a[0] - a[1];
00469         a[0] += a[1];
00470         for (j = 2; j < n; j += 2) {
00471             a[j - 1] = -a[j] - a[j + 1];
00472             a[j] -= a[j + 1];
00473         }
00474         a[n - 1] = -xr;
00475     }
00476 }
00477 
00478 
00479 void clTransform8::dfct(long n, float *a, float *t, long *ip, float *w)
00480 {
00481     long j, k, l, m, mh, nw, nc;
00482     float xr, xi, yr, yi;
00483     
00484     nw = ip[0];
00485     if (n > (nw << 3)) {
00486         nw = n >> 3;
00487         makewt(nw, ip, w);
00488     }
00489     nc = ip[1];
00490     if (n > (nc << 1)) {
00491         nc = n >> 1;
00492         makect(nc, ip, w + nw);
00493     }
00494     m = n >> 1;
00495     yi = a[m];
00496     xi = a[0] + a[n];
00497     a[0] -= a[n];
00498     t[0] = xi - yi;
00499     t[m] = xi + yi;
00500     if (n > 2) {
00501         mh = m >> 1;
00502         for (j = 1; j < mh; j++) {
00503             k = m - j;
00504             xr = a[j] - a[n - j];
00505             xi = a[j] + a[n - j];
00506             yr = a[k] - a[n - k];
00507             yi = a[k] + a[n - k];
00508             a[j] = xr;
00509             a[k] = yr;
00510             t[j] = xi - yi;
00511             t[k] = xi + yi;
00512         }
00513         t[mh] = a[mh] + a[n - mh];
00514         a[mh] -= a[n - mh];
00515         dctsub(m, a, nc, w + nw);
00516         if (m > 4) {
00517             bitrv2(m, ip + 2, a);
00518             cftfsub(m, a, w);
00519             rftfsub(m, a, nc, w + nw);
00520         } else if (m == 4) {
00521             cftfsub(m, a, w);
00522         }
00523         a[n - 1] = a[0] - a[1];
00524         a[1] = a[0] + a[1];
00525         for (j = m - 2; j >= 2; j -= 2) {
00526             a[2 * j + 1] = a[j] + a[j + 1];
00527             a[2 * j - 1] = a[j] - a[j + 1];
00528         }
00529         l = 2;
00530         m = mh;
00531         while (m >= 2) {
00532             dctsub(m, t, nc, w + nw);
00533             if (m > 4) {
00534                 bitrv2(m, ip + 2, t);
00535                 cftfsub(m, t, w);
00536                 rftfsub(m, t, nc, w + nw);
00537             } else if (m == 4) {
00538                 cftfsub(m, t, w);
00539             }
00540             a[n - l] = t[0] - t[1];
00541             a[l] = t[0] + t[1];
00542             k = 0;
00543             for (j = 2; j < m; j += 2) {
00544                 k += l << 2;
00545                 a[k - l] = t[j] - t[j + 1];
00546                 a[k + l] = t[j] + t[j + 1];
00547             }
00548             l <<= 1;
00549             mh = m >> 1;
00550             for (j = 0; j < mh; j++) {
00551                 k = m - j;
00552                 t[j] = t[m + k] - t[m + j];
00553                 t[k] = t[m + k] + t[m + j];
00554             }
00555             t[mh] = t[m + mh];
00556             m = mh;
00557         }
00558         a[l] = t[0];
00559         a[n] = t[2] - t[1];
00560         a[0] = t[2] + t[1];
00561     } else {
00562         a[1] = a[0];
00563         a[2] = t[0];
00564         a[0] = t[1];
00565     }
00566 }
00567 
00568 
00569 void clTransform8::dfst(long n, float *a, float *t, long *ip, float *w)
00570 {
00571     long j, k, l, m, mh, nw, nc;
00572     float xr, xi, yr, yi;
00573     
00574     nw = ip[0];
00575     if (n > (nw << 3)) {
00576         nw = n >> 3;
00577         makewt(nw, ip, w);
00578     }
00579     nc = ip[1];
00580     if (n > (nc << 1)) {
00581         nc = n >> 1;
00582         makect(nc, ip, w + nw);
00583     }
00584     if (n > 2) {
00585         m = n >> 1;
00586         mh = m >> 1;
00587         for (j = 1; j < mh; j++) {
00588             k = m - j;
00589             xr = a[j] + a[n - j];
00590             xi = a[j] - a[n - j];
00591             yr = a[k] + a[n - k];
00592             yi = a[k] - a[n - k];
00593             a[j] = xr;
00594             a[k] = yr;
00595             t[j] = xi + yi;
00596             t[k] = xi - yi;
00597         }
00598         t[0] = a[mh] - a[n - mh];
00599         a[mh] += a[n - mh];
00600         a[0] = a[m];
00601         dstsub(m, a, nc, w + nw);
00602         if (m > 4) {
00603             bitrv2(m, ip + 2, a);
00604             cftfsub(m, a, w);
00605             rftfsub(m, a, nc, w + nw);
00606         } else if (m == 4) {
00607             cftfsub(m, a, w);
00608         }
00609         a[n - 1] = a[1] - a[0];
00610         a[1] = a[0] + a[1];
00611         for (j = m - 2; j >= 2; j -= 2) {
00612             a[2 * j + 1] = a[j] - a[j + 1];
00613             a[2 * j - 1] = -a[j] - a[j + 1];
00614         }
00615         l = 2;
00616         m = mh;
00617         while (m >= 2) {
00618             dstsub(m, t, nc, w + nw);
00619             if (m > 4) {
00620                 bitrv2(m, ip + 2, t);
00621                 cftfsub(m, t, w);
00622                 rftfsub(m, t, nc, w + nw);
00623             } else if (m == 4) {
00624                 cftfsub(m, t, w);
00625             }
00626             a[n - l] = t[1] - t[0];
00627             a[l] = t[0] + t[1];
00628             k = 0;
00629             for (j = 2; j < m; j += 2) {
00630                 k += l << 2;
00631                 a[k - l] = -t[j] - t[j + 1];
00632                 a[k + l] = t[j] - t[j + 1];
00633             }
00634             l <<= 1;
00635             mh = m >> 1;
00636             for (j = 1; j < mh; j++) {
00637                 k = m - j;
00638                 t[j] = t[m + k] + t[m + j];
00639                 t[k] = t[m + k] - t[m + j];
00640             }
00641             t[0] = t[m + mh];
00642             m = mh;
00643         }
00644         a[l] = t[0];
00645     }
00646     a[0] = 0;
00647 }
00648 
00649 
00650 /* -------- initializing routines -------- */
00651 
00652 
00653 void clTransform8::makewt(long nw, long *ip, float *w)
00654 {
00655     long j, nwh;
00656     float delta, x, y;
00657     
00658     ip[0] = nw;
00659     ip[1] = 1;
00660     if (nw > 2) {
00661         nwh = nw >> 1;
00662 #       ifndef TRANSFORM_EXT_PREC
00663         delta = atanf(1.0f) / nwh;
00664 #       else
00665         delta = (float) (atan(1.0) / nwh);
00666 #       endif
00667         w[0] = 1;
00668         w[1] = 0;
00669 #       ifndef TRANSFORM_EXT_PREC
00670         w[nwh] = cosf(delta * nwh);
00671 #       else
00672         w[nwh] = (float) cos(delta * nwh);
00673 #       endif
00674         w[nwh + 1] = w[nwh];
00675         if (nwh > 2) {
00676             for (j = 2; j < nwh; j += 2) {
00677 #               ifndef TRANSFORM_EXT_PREC
00678                 x = cosf(delta * j);
00679                 y = sinf(delta * j);
00680 #               else
00681                 x = (float) cos(delta * j);
00682                 y = (float) sin(delta * j);
00683 #               endif
00684                 w[j] = x;
00685                 w[j + 1] = y;
00686                 w[nw - j] = y;
00687                 w[nw - j + 1] = x;
00688             }
00689             for (j = nwh - 2; j >= 2; j -= 2) {
00690                 x = w[2 * j];
00691                 y = w[2 * j + 1];
00692                 w[nwh + j] = x;
00693                 w[nwh + j + 1] = y;
00694             }
00695             bitrv2(nw, ip + 2, w);
00696         }
00697     }
00698 }
00699 
00700 
00701 void clTransform8::makect(long nc, long *ip, float *c)
00702 {
00703     long j, nch;
00704     float delta;
00705     
00706     ip[1] = nc;
00707     if (nc > 1) {
00708         nch = nc >> 1;
00709 #       ifndef TRANSFORM_EXT_PREC
00710         delta = atanf(1.0f) / nch;
00711         c[0] = cosf(delta * nch);
00712 #       else
00713         delta = (float) (atan(1.0) / nch);
00714         c[0] = (float) cos(delta * nch);
00715 #       endif
00716         c[nch] = 0.5f * c[0];
00717         for (j = 1; j < nch; j++) {
00718 #           ifndef TRANSFORM_EXT_PREC
00719             c[j] = 0.5f * cosf(delta * j);
00720             c[nc - j] = 0.5f * sinf(delta * j);
00721 #           else
00722             c[j] = (float) (0.5 * cos(delta * j));
00723             c[nc - j] = (float) (0.5 * sin(delta * j));
00724 #           endif
00725         }
00726     }
00727 }
00728 
00729 
00730 /* -------- child routines -------- */
00731 
00732 
00733 T8_INLINE void clTransform8::bitrv2(long n, long *ip, float *a)
00734 {
00735     long j, j1, k, k1, l, m, m2;
00736     float xr, xi, yr, yi;
00737     
00738     ip[0] = 0;
00739     l = n;
00740     m = 1;
00741     while ((m << 3) < l) {
00742         l >>= 1;
00743         for (j = 0; j < m; j++) {
00744             ip[m + j] = ip[j] + l;
00745         }
00746         m <<= 1;
00747     }
00748     m2 = 2 * m;
00749     if ((m << 3) == l) {
00750         for (k = 0; k < m; k++) {
00751             for (j = 0; j < k; j++) {
00752                 j1 = 2 * j + ip[k];
00753                 k1 = 2 * k + ip[j];
00754                 xr = a[j1];
00755                 xi = a[j1 + 1];
00756                 yr = a[k1];
00757                 yi = a[k1 + 1];
00758                 a[j1] = yr;
00759                 a[j1 + 1] = yi;
00760                 a[k1] = xr;
00761                 a[k1 + 1] = xi;
00762                 j1 += m2;
00763                 k1 += 2 * m2;
00764                 xr = a[j1];
00765                 xi = a[j1 + 1];
00766                 yr = a[k1];
00767                 yi = a[k1 + 1];
00768                 a[j1] = yr;
00769                 a[j1 + 1] = yi;
00770                 a[k1] = xr;
00771                 a[k1 + 1] = xi;
00772                 j1 += m2;
00773                 k1 -= m2;
00774                 xr = a[j1];
00775                 xi = a[j1 + 1];
00776                 yr = a[k1];
00777                 yi = a[k1 + 1];
00778                 a[j1] = yr;
00779                 a[j1 + 1] = yi;
00780                 a[k1] = xr;
00781                 a[k1 + 1] = xi;
00782                 j1 += m2;
00783                 k1 += 2 * m2;
00784                 xr = a[j1];
00785                 xi = a[j1 + 1];
00786                 yr = a[k1];
00787                 yi = a[k1 + 1];
00788                 a[j1] = yr;
00789                 a[j1 + 1] = yi;
00790                 a[k1] = xr;
00791                 a[k1 + 1] = xi;
00792             }
00793             j1 = 2 * k + m2 + ip[k];
00794             k1 = j1 + m2;
00795             xr = a[j1];
00796             xi = a[j1 + 1];
00797             yr = a[k1];
00798             yi = a[k1 + 1];
00799             a[j1] = yr;
00800             a[j1 + 1] = yi;
00801             a[k1] = xr;
00802             a[k1 + 1] = xi;
00803         }
00804     } else {
00805         for (k = 1; k < m; k++) {
00806             for (j = 0; j < k; j++) {
00807                 j1 = 2 * j + ip[k];
00808                 k1 = 2 * k + ip[j];
00809                 xr = a[j1];
00810                 xi = a[j1 + 1];
00811                 yr = a[k1];
00812                 yi = a[k1 + 1];
00813                 a[j1] = yr;
00814                 a[j1 + 1] = yi;
00815                 a[k1] = xr;
00816                 a[k1 + 1] = xi;
00817                 j1 += m2;
00818                 k1 += m2;
00819                 xr = a[j1];
00820                 xi = a[j1 + 1];
00821                 yr = a[k1];
00822                 yi = a[k1 + 1];
00823                 a[j1] = yr;
00824                 a[j1 + 1] = yi;
00825                 a[k1] = xr;
00826                 a[k1 + 1] = xi;
00827             }
00828         }
00829     }
00830 }
00831 
00832 
00833 T8_INLINE void clTransform8::bitrv2conj(long n, long *ip, float *a)
00834 {
00835     long j, j1, k, k1, l, m, m2;
00836     float xr, xi, yr, yi;
00837     
00838     ip[0] = 0;
00839     l = n;
00840     m = 1;
00841     while ((m << 3) < l) {
00842         l >>= 1;
00843         for (j = 0; j < m; j++) {
00844             ip[m + j] = ip[j] + l;
00845         }
00846         m <<= 1;
00847     }
00848     m2 = 2 * m;
00849     if ((m << 3) == l) {
00850         for (k = 0; k < m; k++) {
00851             for (j = 0; j < k; j++) {
00852                 j1 = 2 * j + ip[k];
00853                 k1 = 2 * k + ip[j];
00854                 xr = a[j1];
00855                 xi = -a[j1 + 1];
00856                 yr = a[k1];
00857                 yi = -a[k1 + 1];
00858                 a[j1] = yr;
00859                 a[j1 + 1] = yi;
00860                 a[k1] = xr;
00861                 a[k1 + 1] = xi;
00862                 j1 += m2;
00863                 k1 += 2 * m2;
00864                 xr = a[j1];
00865                 xi = -a[j1 + 1];
00866                 yr = a[k1];
00867                 yi = -a[k1 + 1];
00868                 a[j1] = yr;
00869                 a[j1 + 1] = yi;
00870                 a[k1] = xr;
00871                 a[k1 + 1] = xi;
00872                 j1 += m2;
00873                 k1 -= m2;
00874                 xr = a[j1];
00875                 xi = -a[j1 + 1];
00876                 yr = a[k1];
00877                 yi = -a[k1 + 1];
00878                 a[j1] = yr;
00879                 a[j1 + 1] = yi;
00880                 a[k1] = xr;
00881                 a[k1 + 1] = xi;
00882                 j1 += m2;
00883                 k1 += 2 * m2;
00884                 xr = a[j1];
00885                 xi = -a[j1 + 1];
00886                 yr = a[k1];
00887                 yi = -a[k1 + 1];
00888                 a[j1] = yr;
00889                 a[j1 + 1] = yi;
00890                 a[k1] = xr;
00891                 a[k1 + 1] = xi;
00892             }
00893             k1 = 2 * k + ip[k];
00894             a[k1 + 1] = -a[k1 + 1];
00895             j1 = k1 + m2;
00896             k1 = j1 + m2;
00897             xr = a[j1];
00898             xi = -a[j1 + 1];
00899             yr = a[k1];
00900             yi = -a[k1 + 1];
00901             a[j1] = yr;
00902             a[j1 + 1] = yi;
00903             a[k1] = xr;
00904             a[k1 + 1] = xi;
00905             k1 += m2;
00906             a[k1 + 1] = -a[k1 + 1];
00907         }
00908     } else {
00909         a[1] = -a[1];
00910         a[m2 + 1] = -a[m2 + 1];
00911         for (k = 1; k < m; k++) {
00912             for (j = 0; j < k; j++) {
00913                 j1 = 2 * j + ip[k];
00914                 k1 = 2 * k + ip[j];
00915                 xr = a[j1];
00916                 xi = -a[j1 + 1];
00917                 yr = a[k1];
00918                 yi = -a[k1 + 1];
00919                 a[j1] = yr;
00920                 a[j1 + 1] = yi;
00921                 a[k1] = xr;
00922                 a[k1 + 1] = xi;
00923                 j1 += m2;
00924                 k1 += m2;
00925                 xr = a[j1];
00926                 xi = -a[j1 + 1];
00927                 yr = a[k1];
00928                 yi = -a[k1 + 1];
00929                 a[j1] = yr;
00930                 a[j1 + 1] = yi;
00931                 a[k1] = xr;
00932                 a[k1 + 1] = xi;
00933             }
00934             k1 = 2 * k + ip[k];
00935             a[k1 + 1] = -a[k1 + 1];
00936             a[k1 + m2 + 1] = -a[k1 + m2 + 1];
00937         }
00938     }
00939 }
00940 
00941 
00942 T8_INLINE void clTransform8::cftfsub(long n, float *a, float *w)
00943 {
00944     long j, j1, j2, j3, l;
00945     float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
00946     
00947     l = 2;
00948     if (n >= 16) {
00949         cft1st(n, a, w);
00950         l = 16;
00951         while ((l << 3) <= n) {
00952             cftmdl(n, l, a, w);
00953             l <<= 3;
00954         }
00955     }
00956     if ((l << 1) < n) {
00957         for (j = 0; j < l; j += 2) {
00958             j1 = j + l;
00959             j2 = j1 + l;
00960             j3 = j2 + l;
00961             x0r = a[j] + a[j1];
00962             x0i = a[j + 1] + a[j1 + 1];
00963             x1r = a[j] - a[j1];
00964             x1i = a[j + 1] - a[j1 + 1];
00965             x2r = a[j2] + a[j3];
00966             x2i = a[j2 + 1] + a[j3 + 1];
00967             x3r = a[j2] - a[j3];
00968             x3i = a[j2 + 1] - a[j3 + 1];
00969             a[j] = x0r + x2r;
00970             a[j + 1] = x0i + x2i;
00971             a[j2] = x0r - x2r;
00972             a[j2 + 1] = x0i - x2i;
00973             a[j1] = x1r - x3i;
00974             a[j1 + 1] = x1i + x3r;
00975             a[j3] = x1r + x3i;
00976             a[j3 + 1] = x1i - x3r;
00977         }
00978     } else if ((l << 1) == n) {
00979         for (j = 0; j < l; j += 2) {
00980             j1 = j + l;
00981             x0r = a[j] - a[j1];
00982             x0i = a[j + 1] - a[j1 + 1];
00983             a[j] += a[j1];
00984             a[j + 1] += a[j1 + 1];
00985             a[j1] = x0r;
00986             a[j1 + 1] = x0i;
00987         }
00988     }
00989 }
00990 
00991 
00992 T8_INLINE void clTransform8::cftbsub(long n, float *a, float *w)
00993 {
00994     long j, j1, j2, j3, j4, j5, j6, j7, l;
00995     float wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, 
00996         y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, 
00997         y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
00998     
00999     l = 2;
01000     if (n > 16) {
01001         cft1st(n, a, w);
01002         l = 16;
01003         while ((l << 3) < n) {
01004             cftmdl(n, l, a, w);
01005             l <<= 3;
01006         }
01007     }
01008     if ((l << 2) < n) {
01009         wn4r = w[2];
01010         for (j = 0; j < l; j += 2) {
01011             j1 = j + l;
01012             j2 = j1 + l;
01013             j3 = j2 + l;
01014             j4 = j3 + l;
01015             j5 = j4 + l;
01016             j6 = j5 + l;
01017             j7 = j6 + l;
01018             x0r = a[j] + a[j1];
01019             x0i = -a[j + 1] - a[j1 + 1];
01020             x1r = a[j] - a[j1];
01021             x1i = -a[j + 1] + a[j1 + 1];
01022             x2r = a[j2] + a[j3];
01023             x2i = a[j2 + 1] + a[j3 + 1];
01024             x3r = a[j2] - a[j3];
01025             x3i = a[j2 + 1] - a[j3 + 1];
01026             y0r = x0r + x2r;
01027             y0i = x0i - x2i;
01028             y2r = x0r - x2r;
01029             y2i = x0i + x2i;
01030             y1r = x1r - x3i;
01031             y1i = x1i - x3r;
01032             y3r = x1r + x3i;
01033             y3i = x1i + x3r;
01034             x0r = a[j4] + a[j5];
01035             x0i = a[j4 + 1] + a[j5 + 1];
01036             x1r = a[j4] - a[j5];
01037             x1i = a[j4 + 1] - a[j5 + 1];
01038             x2r = a[j6] + a[j7];
01039             x2i = a[j6 + 1] + a[j7 + 1];
01040             x3r = a[j6] - a[j7];
01041             x3i = a[j6 + 1] - a[j7 + 1];
01042             y4r = x0r + x2r;
01043             y4i = x0i + x2i;
01044             y6r = x0r - x2r;
01045             y6i = x0i - x2i;
01046             x0r = x1r - x3i;
01047             x0i = x1i + x3r;
01048             x2r = x1r + x3i;
01049             x2i = x1i - x3r;
01050             y5r = wn4r * (x0r - x0i);
01051             y5i = wn4r * (x0r + x0i);
01052             y7r = wn4r * (x2r - x2i);
01053             y7i = wn4r * (x2r + x2i);
01054             a[j1] = y1r + y5r;
01055             a[j1 + 1] = y1i - y5i;
01056             a[j5] = y1r - y5r;
01057             a[j5 + 1] = y1i + y5i;
01058             a[j3] = y3r - y7i;
01059             a[j3 + 1] = y3i - y7r;
01060             a[j7] = y3r + y7i;
01061             a[j7 + 1] = y3i + y7r;
01062             a[j] = y0r + y4r;
01063             a[j + 1] = y0i - y4i;
01064             a[j4] = y0r - y4r;
01065             a[j4 + 1] = y0i + y4i;
01066             a[j2] = y2r - y6i;
01067             a[j2 + 1] = y2i - y6r;
01068             a[j6] = y2r + y6i;
01069             a[j6 + 1] = y2i + y6r;
01070         }
01071     } else if ((l << 2) == n) {
01072         for (j = 0; j < l; j += 2) {
01073             j1 = j + l;
01074             j2 = j1 + l;
01075             j3 = j2 + l;
01076             x0r = a[j] + a[j1];
01077             x0i = -a[j + 1] - a[j1 + 1];
01078             x1r = a[j] - a[j1];
01079             x1i = -a[j + 1] + a[j1 + 1];
01080             x2r = a[j2] + a[j3];
01081             x2i = a[j2 + 1] + a[j3 + 1];
01082             x3r = a[j2] - a[j3];
01083             x3i = a[j2 + 1] - a[j3 + 1];
01084             a[j] = x0r + x2r;
01085             a[j + 1] = x0i - x2i;
01086             a[j2] = x0r - x2r;
01087             a[j2 + 1] = x0i + x2i;
01088             a[j1] = x1r - x3i;
01089             a[j1 + 1] = x1i - x3r;
01090             a[j3] = x1r + x3i;
01091             a[j3 + 1] = x1i + x3r;
01092         }
01093     } else {
01094         for (j = 0; j < l; j += 2) {
01095             j1 = j + l;
01096             x0r = a[j] - a[j1];
01097             x0i = -a[j + 1] + a[j1 + 1];
01098             a[j] += a[j1];
01099             a[j + 1] = -a[j + 1] - a[j1 + 1];
01100             a[j1] = x0r;
01101             a[j1 + 1] = x0i;
01102         }
01103     }
01104 }
01105 
01106 
01107 T8_INLINE void clTransform8::cft1st(long n, float *a, float *w)
01108 {
01109     long j, k1;
01110     float wn4r, wtmp, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, 
01111         wk4r, wk4i, wk5r, wk5i, wk6r, wk6i, wk7r, wk7i;
01112     float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, 
01113         y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, 
01114         y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
01115     
01116     wn4r = w[2];
01117     x0r = a[0] + a[2];
01118     x0i = a[1] + a[3];
01119     x1r = a[0] - a[2];
01120     x1i = a[1] - a[3];
01121     x2r = a[4] + a[6];
01122     x2i = a[5] + a[7];
01123     x3r = a[4] - a[6];
01124     x3i = a[5] - a[7];
01125     y0r = x0r + x2r;
01126     y0i = x0i + x2i;
01127     y2r = x0r - x2r;
01128     y2i = x0i - x2i;
01129     y1r = x1r - x3i;
01130     y1i = x1i + x3r;
01131     y3r = x1r + x3i;
01132     y3i = x1i - x3r;
01133     x0r = a[8] + a[10];
01134     x0i = a[9] + a[11];
01135     x1r = a[8] - a[10];
01136     x1i = a[9] - a[11];
01137     x2r = a[12] + a[14];
01138     x2i = a[13] + a[15];
01139     x3r = a[12] - a[14];
01140     x3i = a[13] - a[15];
01141     y4r = x0r + x2r;
01142     y4i = x0i + x2i;
01143     y6r = x0r - x2r;
01144     y6i = x0i - x2i;
01145     x0r = x1r - x3i;
01146     x0i = x1i + x3r;
01147     x2r = x1r + x3i;
01148     x2i = x1i - x3r;
01149     y5r = wn4r * (x0r - x0i);
01150     y5i = wn4r * (x0r + x0i);
01151     y7r = wn4r * (x2r - x2i);
01152     y7i = wn4r * (x2r + x2i);
01153     a[2] = y1r + y5r;
01154     a[3] = y1i + y5i;
01155     a[10] = y1r - y5r;
01156     a[11] = y1i - y5i;
01157     a[6] = y3r - y7i;
01158     a[7] = y3i + y7r;
01159     a[14] = y3r + y7i;
01160     a[15] = y3i - y7r;
01161     a[0] = y0r + y4r;
01162     a[1] = y0i + y4i;
01163     a[8] = y0r - y4r;
01164     a[9] = y0i - y4i;
01165     a[4] = y2r - y6i;
01166     a[5] = y2i + y6r;
01167     a[12] = y2r + y6i;
01168     a[13] = y2i - y6r;
01169     if (n > 16) {
01170         wk1r = w[4];
01171         wk1i = w[5];
01172         x0r = a[16] + a[18];
01173         x0i = a[17] + a[19];
01174         x1r = a[16] - a[18];
01175         x1i = a[17] - a[19];
01176         x2r = a[20] + a[22];
01177         x2i = a[21] + a[23];
01178         x3r = a[20] - a[22];
01179         x3i = a[21] - a[23];
01180         y0r = x0r + x2r;
01181         y0i = x0i + x2i;
01182         y2r = x0r - x2r;
01183         y2i = x0i - x2i;
01184         y1r = x1r - x3i;
01185         y1i = x1i + x3r;
01186         y3r = x1r + x3i;
01187         y3i = x1i - x3r;
01188         x0r = a[24] + a[26];
01189         x0i = a[25] + a[27];
01190         x1r = a[24] - a[26];
01191         x1i = a[25] - a[27];
01192         x2r = a[28] + a[30];
01193         x2i = a[29] + a[31];
01194         x3r = a[28] - a[30];
01195         x3i = a[29] - a[31];
01196         y4r = x0r + x2r;
01197         y4i = x0i + x2i;
01198         y6r = x0r - x2r;
01199         y6i = x0i - x2i;
01200         x0r = x1r - x3i;
01201         x0i = x1i + x3r;
01202         x2r = x1r + x3i;
01203         x2i = x3r - x1i;
01204         y5r = wk1i * x0r - wk1r * x0i;
01205         y5i = wk1i * x0i + wk1r * x0r;
01206         y7r = wk1r * x2r + wk1i * x2i;
01207         y7i = wk1r * x2i - wk1i * x2r;
01208         x0r = wk1r * y1r - wk1i * y1i;
01209         x0i = wk1r * y1i + wk1i * y1r;
01210         a[18] = x0r + y5r;
01211         a[19] = x0i + y5i;
01212         a[26] = y5i - x0i;
01213         a[27] = x0r - y5r;
01214         x0r = wk1i * y3r - wk1r * y3i;
01215         x0i = wk1i * y3i + wk1r * y3r;
01216         a[22] = x0r - y7r;
01217         a[23] = x0i + y7i;
01218         a[30] = y7i - x0i;
01219         a[31] = x0r + y7r;
01220         a[16] = y0r + y4r;
01221         a[17] = y0i + y4i;
01222         a[24] = y4i - y0i;
01223         a[25] = y0r - y4r;
01224         x0r = y2r - y6i;
01225         x0i = y2i + y6r;
01226         a[20] = wn4r * (x0r - x0i);
01227         a[21] = wn4r * (x0i + x0r);
01228         x0r = y6r - y2i;
01229         x0i = y2r + y6i;
01230         a[28] = wn4r * (x0r - x0i);
01231         a[29] = wn4r * (x0i + x0r);
01232         k1 = 4;
01233         for (j = 32; j < n; j += 16) {
01234             k1 += 4;
01235             wk1r = w[k1];
01236             wk1i = w[k1 + 1];
01237             wk2r = w[k1 + 2];
01238             wk2i = w[k1 + 3];
01239             wtmp = 2 * wk2i;
01240             wk3r = wk1r - wtmp * wk1i;
01241             wk3i = wtmp * wk1r - wk1i;
01242             wk4r = 1 - wtmp * wk2i;
01243             wk4i = wtmp * wk2r;
01244             wtmp = 2 * wk4i;
01245             wk5r = wk3r - wtmp * wk1i;
01246             wk5i = wtmp * wk1r - wk3i;
01247             wk6r = wk2r - wtmp * wk2i;
01248             wk6i = wtmp * wk2r - wk2i;
01249             wk7r = wk1r - wtmp * wk3i;
01250             wk7i = wtmp * wk3r - wk1i;
01251             x0r = a[j] + a[j + 2];
01252             x0i = a[j + 1] + a[j + 3];
01253             x1r = a[j] - a[j + 2];
01254             x1i = a[j + 1] - a[j + 3];
01255             x2r = a[j + 4] + a[j + 6];
01256             x2i = a[j + 5] + a[j + 7];
01257             x3r = a[j + 4] - a[j + 6];
01258             x3i = a[j + 5] - a[j + 7];
01259             y0r = x0r + x2r;
01260             y0i = x0i + x2i;
01261             y2r = x0r - x2r;
01262             y2i = x0i - x2i;
01263             y1r = x1r - x3i;
01264             y1i = x1i + x3r;
01265             y3r = x1r + x3i;
01266             y3i = x1i - x3r;
01267             x0r = a[j + 8] + a[j + 10];
01268             x0i = a[j + 9] + a[j + 11];
01269             x1r = a[j + 8] - a[j + 10];
01270             x1i = a[j + 9] - a[j + 11];
01271             x2r = a[j + 12] + a[j + 14];
01272             x2i = a[j + 13] + a[j + 15];
01273             x3r = a[j + 12] - a[j + 14];
01274             x3i = a[j + 13] - a[j + 15];
01275             y4r = x0r + x2r;
01276             y4i = x0i + x2i;
01277             y6r = x0r - x2r;
01278             y6i = x0i - x2i;
01279             x0r = x1r - x3i;
01280             x0i = x1i + x3r;
01281             x2r = x1r + x3i;
01282             x2i = x1i - x3r;
01283             y5r = wn4r * (x0r - x0i);
01284             y5i = wn4r * (x0r + x0i);
01285             y7r = wn4r * (x2r - x2i);
01286             y7i = wn4r * (x2r + x2i);
01287             x0r = y1r + y5r;
01288             x0i = y1i + y5i;
01289             a[j + 2] = wk1r * x0r - wk1i * x0i;
01290             a[j + 3] = wk1r * x0i + wk1i * x0r;
01291             x0r = y1r - y5r;
01292             x0i = y1i - y5i;
01293             a[j + 10] = wk5r * x0r - wk5i * x0i;
01294             a[j + 11] = wk5r * x0i + wk5i * x0r;
01295             x0r = y3r - y7i;
01296             x0i = y3i + y7r;
01297             a[j + 6] = wk3r * x0r - wk3i * x0i;
01298             a[j + 7] = wk3r * x0i + wk3i * x0r;
01299             x0r = y3r + y7i;
01300             x0i = y3i - y7r;
01301             a[j + 14] = wk7r * x0r - wk7i * x0i;
01302             a[j + 15] = wk7r * x0i + wk7i * x0r;
01303             a[j] = y0r + y4r;
01304             a[j + 1] = y0i + y4i;
01305             x0r = y0r - y4r;
01306             x0i = y0i - y4i;
01307             a[j + 8] = wk4r * x0r - wk4i * x0i;
01308             a[j + 9] = wk4r * x0i + wk4i * x0r;
01309             x0r = y2r - y6i;
01310             x0i = y2i + y6r;
01311             a[j + 4] = wk2r * x0r - wk2i * x0i;
01312             a[j + 5] = wk2r * x0i + wk2i * x0r;
01313             x0r = y2r + y6i;
01314             x0i = y2i - y6r;
01315             a[j + 12] = wk6r * x0r - wk6i * x0i;
01316             a[j + 13] = wk6r * x0i + wk6i * x0r;
01317         }
01318     }
01319 }
01320 
01321 
01322 T8_INLINE void clTransform8::cftmdl(long n, long l, float *a, float *w)
01323 {
01324     long j, j1, j2, j3, j4, j5, j6, j7, k, k1, m;
01325     float wn4r, wtmp, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, 
01326         wk4r, wk4i, wk5r, wk5i, wk6r, wk6i, wk7r, wk7i;
01327     float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, 
01328         y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, 
01329         y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
01330     
01331     m = l << 3;
01332     wn4r = w[2];
01333     for (j = 0; j < l; j += 2) {
01334         j1 = j + l;
01335         j2 = j1 + l;
01336         j3 = j2 + l;
01337         j4 = j3 + l;
01338         j5 = j4 + l;
01339         j6 = j5 + l;
01340         j7 = j6 + l;
01341         x0r = a[j] + a[j1];
01342         x0i = a[j + 1] + a[j1 + 1];
01343         x1r = a[j] - a[j1];
01344         x1i = a[j + 1] - a[j1 + 1];
01345         x2r = a[j2] + a[j3];
01346         x2i = a[j2 + 1] + a[j3 + 1];
01347         x3r = a[j2] - a[j3];
01348         x3i = a[j2 + 1] - a[j3 + 1];
01349         y0r = x0r + x2r;
01350         y0i = x0i + x2i;
01351         y2r = x0r - x2r;
01352         y2i = x0i - x2i;
01353         y1r = x1r - x3i;
01354         y1i = x1i + x3r;
01355         y3r = x1r + x3i;
01356         y3i = x1i - x3r;
01357         x0r = a[j4] + a[j5];
01358         x0i = a[j4 + 1] + a[j5 + 1];
01359         x1r = a[j4] - a[j5];
01360         x1i = a[j4 + 1] - a[j5 + 1];
01361         x2r = a[j6] + a[j7];
01362         x2i = a[j6 + 1] + a[j7 + 1];
01363         x3r = a[j6] - a[j7];
01364         x3i = a[j6 + 1] - a[j7 + 1];
01365         y4r = x0r + x2r;
01366         y4i = x0i + x2i;
01367         y6r = x0r - x2r;
01368         y6i = x0i - x2i;
01369         x0r = x1r - x3i;
01370         x0i = x1i + x3r;
01371         x2r = x1r + x3i;
01372         x2i = x1i - x3r;
01373         y5r = wn4r * (x0r - x0i);
01374         y5i = wn4r * (x0r + x0i);
01375         y7r = wn4r * (x2r - x2i);
01376         y7i = wn4r * (x2r + x2i);
01377         a[j1] = y1r + y5r;
01378         a[j1 + 1] = y1i + y5i;
01379         a[j5] = y1r - y5r;
01380         a[j5 + 1] = y1i - y5i;
01381         a[j3] = y3r - y7i;
01382         a[j3 + 1] = y3i + y7r;
01383         a[j7] = y3r + y7i;
01384         a[j7 + 1] = y3i - y7r;
01385         a[j] = y0r + y4r;
01386         a[j + 1] = y0i + y4i;
01387         a[j4] = y0r - y4r;
01388         a[j4 + 1] = y0i - y4i;
01389         a[j2] = y2r - y6i;
01390         a[j2 + 1] = y2i + y6r;
01391         a[j6] = y2r + y6i;
01392         a[j6 + 1] = y2i - y6r;
01393     }
01394     if (m < n) {
01395         wk1r = w[4];
01396         wk1i = w[5];
01397         for (j = m; j < l + m; j += 2) {
01398             j1 = j + l;
01399             j2 = j1 + l;
01400             j3 = j2 + l;
01401             j4 = j3 + l;
01402             j5 = j4 + l;
01403             j6 = j5 + l;
01404             j7 = j6 + l;
01405             x0r = a[j] + a[j1];
01406             x0i = a[j + 1] + a[j1 + 1];
01407             x1r = a[j] - a[j1];
01408             x1i = a[j + 1] - a[j1 + 1];
01409             x2r = a[j2] + a[j3];
01410             x2i = a[j2 + 1] + a[j3 + 1];
01411             x3r = a[j2] - a[j3];
01412             x3i = a[j2 + 1] - a[j3 + 1];
01413             y0r = x0r + x2r;
01414             y0i = x0i + x2i;
01415             y2r = x0r - x2r;
01416             y2i = x0i - x2i;
01417             y1r = x1r - x3i;
01418             y1i = x1i + x3r;
01419             y3r = x1r + x3i;
01420             y3i = x1i - x3r;
01421             x0r = a[j4] + a[j5];
01422             x0i = a[j4 + 1] + a[j5 + 1];
01423             x1r = a[j4] - a[j5];
01424             x1i = a[j4 + 1] - a[j5 + 1];
01425             x2r = a[j6] + a[j7];
01426             x2i = a[j6 + 1] + a[j7 + 1];
01427             x3r = a[j6] - a[j7];
01428             x3i = a[j6 + 1] - a[j7 + 1];
01429             y4r = x0r + x2r;
01430             y4i = x0i + x2i;
01431             y6r = x0r - x2r;
01432             y6i = x0i - x2i;
01433             x0r = x1r - x3i;
01434             x0i = x1i + x3r;
01435             x2r = x1r + x3i;
01436             x2i = x3r - x1i;
01437             y5r = wk1i * x0r - wk1r * x0i;
01438             y5i = wk1i * x0i + wk1r * x0r;
01439             y7r = wk1r * x2r + wk1i * x2i;
01440             y7i = wk1r * x2i - wk1i * x2r;
01441             x0r = wk1r * y1r - wk1i * y1i;
01442             x0i = wk1r * y1i + wk1i * y1r;
01443             a[j1] = x0r + y5r;
01444             a[j1 + 1] = x0i + y5i;
01445             a[j5] = y5i - x0i;
01446             a[j5 + 1] = x0r - y5r;
01447             x0r = wk1i * y3r - wk1r * y3i;
01448             x0i = wk1i * y3i + wk1r * y3r;
01449             a[j3] = x0r - y7r;
01450             a[j3 + 1] = x0i + y7i;
01451             a[j7] = y7i - x0i;
01452             a[j7 + 1] = x0r + y7r;
01453             a[j] = y0r + y4r;
01454             a[j + 1] = y0i + y4i;
01455             a[j4] = y4i - y0i;
01456             a[j4 + 1] = y0r - y4r;
01457             x0r = y2r - y6i;
01458             x0i = y2i + y6r;
01459             a[j2] = wn4r * (x0r - x0i);
01460             a[j2 + 1] = wn4r * (x0i + x0r);
01461             x0r = y6r - y2i;
01462             x0i = y2r + y6i;
01463             a[j6] = wn4r * (x0r - x0i);
01464             a[j6 + 1] = wn4r * (x0i + x0r);
01465         }
01466         k1 = 4;
01467         for (k = 2 * m; k < n; k += m) {
01468             k1 += 4;
01469             wk1r = w[k1];
01470             wk1i = w[k1 + 1];
01471             wk2r = w[k1 + 2];
01472             wk2i = w[k1 + 3];
01473             wtmp = 2 * wk2i;
01474             wk3r = wk1r - wtmp * wk1i;
01475             wk3i = wtmp * wk1r - wk1i;
01476             wk4r = 1 - wtmp * wk2i;
01477             wk4i = wtmp * wk2r;
01478             wtmp = 2 * wk4i;
01479             wk5r = wk3r - wtmp * wk1i;
01480             wk5i = wtmp * wk1r - wk3i;
01481             wk6r = wk2r - wtmp * wk2i;
01482             wk6i = wtmp * wk2r - wk2i;
01483             wk7r = wk1r - wtmp * wk3i;
01484             wk7i = wtmp * wk3r - wk1i;
01485             for (j = k; j < l + k; j += 2) {
01486                 j1 = j + l;
01487                 j2 = j1 + l;
01488                 j3 = j2 + l;
01489                 j4 = j3 + l;
01490                 j5 = j4 + l;
01491                 j6 = j5 + l;
01492                 j7 = j6 + l;
01493                 x0r = a[j] + a[j1];
01494                 x0i = a[j + 1] + a[j1 + 1];
01495                 x1r = a[j] - a[j1];
01496                 x1i = a[j + 1] - a[j1 + 1];
01497                 x2r = a[j2] + a[j3];
01498                 x2i = a[j2 + 1] + a[j3 + 1];
01499                 x3r = a[j2] - a[j3];
01500                 x3i = a[j2 + 1] - a[j3 + 1];
01501                 y0r = x0r + x2r;
01502                 y0i = x0i + x2i;
01503                 y2r = x0r - x2r;
01504                 y2i = x0i - x2i;
01505                 y1r = x1r - x3i;
01506                 y1i = x1i + x3r;
01507                 y3r = x1r + x3i;
01508                 y3i = x1i - x3r;
01509                 x0r = a[j4] + a[j5];
01510                 x0i = a[j4 + 1] + a[j5 + 1];
01511                 x1r = a[j4] - a[j5];
01512                 x1i = a[j4 + 1] - a[j5 + 1];
01513                 x2r = a[j6] + a[j7];
01514                 x2i = a[j6 + 1] + a[j7 + 1];
01515                 x3r = a[j6] - a[j7];
01516                 x3i = a[j6 + 1] - a[j7 + 1];
01517                 y4r = x0r + x2r;
01518                 y4i = x0i + x2i;
01519                 y6r = x0r - x2r;
01520                 y6i = x0i - x2i;
01521                 x0r = x1r - x3i;
01522                 x0i = x1i + x3r;
01523                 x2r = x1r + x3i;
01524                 x2i = x1i - x3r;
01525                 y5r = wn4r * (x0r - x0i);
01526                 y5i = wn4r * (x0r + x0i);
01527                 y7r = wn4r * (x2r - x2i);
01528                 y7i = wn4r * (x2r + x2i);
01529                 x0r = y1r + y5r;
01530                 x0i = y1i + y5i;
01531                 a[j1] = wk1r * x0r - wk1i * x0i;
01532                 a[j1 + 1] = wk1r * x0i + wk1i * x0r;
01533                 x0r = y1r - y5r;
01534                 x0i = y1i - y5i;
01535                 a[j5] = wk5r * x0r - wk5i * x0i;
01536                 a[j5 + 1] = wk5r * x0i + wk5i * x0r;
01537                 x0r = y3r - y7i;
01538                 x0i = y3i + y7r;
01539                 a[j3] = wk3r * x0r - wk3i * x0i;
01540                 a[j3 + 1] = wk3r * x0i + wk3i * x0r;
01541                 x0r = y3r + y7i;
01542                 x0i = y3i - y7r;
01543                 a[j7] = wk7r * x0r - wk7i * x0i;
01544                 a[j7 + 1] = wk7r * x0i + wk7i * x0r;
01545                 a[j] = y0r + y4r;
01546                 a[j + 1] = y0i + y4i;
01547                 x0r = y0r - y4r;
01548                 x0i = y0i - y4i;
01549                 a[j4] = wk4r * x0r - wk4i * x0i;
01550                 a[j4 + 1] = wk4r * x0i + wk4i * x0r;
01551                 x0r = y2r - y6i;
01552                 x0i = y2i + y6r;
01553                 a[j2] = wk2r * x0r - wk2i * x0i;
01554                 a[j2 + 1] = wk2r * x0i + wk2i * x0r;
01555                 x0r = y2r + y6i;
01556                 x0i = y2i - y6r;
01557                 a[j6] = wk6r * x0r - wk6i * x0i;
01558                 a[j6 + 1] = wk6r * x0i + wk6i * x0r;
01559             }
01560         }
01561     }
01562 }
01563 
01564 
01565 T8_INLINE void clTransform8::rftfsub(long n, float *a, long nc, float *c)
01566 {
01567     long j, k, kk, ks, m;
01568     float wkr, wki, xr, xi, yr, yi;
01569     
01570     m = n >> 1;
01571     ks = 2 * nc / m;
01572     kk = 0;
01573     for (j = 2; j < m; j += 2) {
01574         k = n - j;
01575         kk += ks;
01576         wkr = 0.5f - c[nc - kk];
01577         wki = c[kk];
01578         xr = a[j] - a[k];
01579         xi = a[j + 1] + a[k + 1];
01580         yr = wkr * xr - wki * xi;
01581         yi = wkr * xi + wki * xr;
01582         a[j] -= yr;
01583         a[j + 1] -= yi;
01584         a[k] += yr;
01585         a[k + 1] -= yi;
01586     }
01587 }
01588 
01589 
01590 T8_INLINE void clTransform8::rftbsub(long n, float *a, long nc, float *c)
01591 {
01592     long j, k, kk, ks, m;
01593     float wkr, wki, xr, xi, yr, yi;
01594     
01595     a[1] = -a[1];
01596     m = n >> 1;
01597     ks = 2 * nc / m;
01598     kk = 0;
01599     for (j = 2; j < m; j += 2) {
01600         k = n - j;
01601         kk += ks;
01602         wkr = 0.5f - c[nc - kk];
01603         wki = c[kk];
01604         xr = a[j] - a[k];
01605         xi = a[j + 1] + a[k + 1];
01606         yr = wkr * xr + wki * xi;
01607         yi = wkr * xi - wki * xr;
01608         a[j] -= yr;
01609         a[j + 1] = yi - a[j + 1];
01610         a[k] += yr;
01611         a[k + 1] = yi - a[k + 1];
01612     }
01613     a[m + 1] = -a[m + 1];
01614 }
01615 
01616 
01617 T8_INLINE void clTransform8::dctsub(long n, float *a, long nc, float *c)
01618 {
01619     long j, k, kk, ks, m;
01620     float wkr, wki, xr;
01621     
01622     m = n >> 1;
01623     ks = nc / n;
01624     kk = 0;
01625     for (j = 1; j < m; j++) {
01626         k = n - j;
01627         kk += ks;
01628         wkr = c[kk] - c[nc - kk];
01629         wki = c[kk] + c[nc - kk];
01630         xr = wki * a[j] - wkr * a[k];
01631         a[j] = wkr * a[j] + wki * a[k];
01632         a[k] = xr;
01633     }
01634     a[m] *= c[0];
01635 }
01636 
01637 
01638 T8_INLINE void clTransform8::dstsub(long n, float *a, long nc, float *c)
01639 {
01640     long j, k, kk, ks, m;
01641     float wkr, wki, xr;
01642     
01643     m = n >> 1;
01644     ks = nc / n;
01645     kk = 0;
01646     for (j = 1; j < m; j++) {
01647         k = n - j;
01648         kk += ks;
01649         wkr = c[kk] - c[nc - kk];
01650         wki = c[kk] + c[nc - kk];
01651         xr = wki * a[k] - wkr * a[j];
01652         a[k] = wkr * a[k] + wki * a[j];
01653         a[j] = xr;
01654     }
01655     a[m] *= c[0];
01656 }
01657 
01658 
01659 // ----- double precision version starts here
01660 
01661 
01662 void clTransform8::cdft(long n, long isgn, double *a, long *ip, double *w)
01663 {
01664     if (n > (ip[0] << 2)) {
01665         makewt(n >> 2, ip, w);
01666     }
01667     if (n > 4) {
01668         if (isgn >= 0) {
01669             bitrv2(n, ip + 2, a);
01670             cftfsub(n, a, w);
01671         } else {
01672             bitrv2conj(n, ip + 2, a);
01673             cftbsub(n, a, w);
01674         }
01675     } else if (n == 4) {
01676         cftfsub(n, a, w);
01677     }
01678 }
01679 
01680 
01681 void clTransform8::rdft(long n, long isgn, double *a, long *ip, double *w)
01682 {
01683     long nw, nc;
01684     double xi;
01685     
01686     nw = ip[0];
01687     if (n > (nw << 2)) {
01688         nw = n >> 2;
01689         makewt(nw, ip, w);
01690     }
01691     nc = ip[1];
01692     if (n > (nc << 2)) {
01693         nc = n >> 2;
01694         makect(nc, ip, w + nw);
01695     }
01696     if (isgn >= 0) {
01697         if (n > 4) {
01698             bitrv2(n, ip + 2, a);
01699             cftfsub(n, a, w);
01700             rftfsub(n, a, nc, w + nw);
01701         } else if (n == 4) {
01702             cftfsub(n, a, w);
01703         }
01704         xi = a[0] - a[1];
01705         a[0] += a[1];
01706         a[1] = xi;
01707     } else {
01708         a[1] = 0.5 * (a[0] - a[1]);
01709         a[0] -= a[1];
01710         if (n > 4) {
01711             rftbsub(n, a, nc, w + nw);
01712             bitrv2(n, ip + 2, a);
01713             cftbsub(n, a, w);
01714         } else if (n == 4) {
01715             cftfsub(n, a, w);
01716         }
01717     }
01718 }
01719 
01720 
01721 void clTransform8::ddct(long n, long isgn, double *a, long *ip, double *w)
01722 {
01723     long j, nw, nc;
01724     double xr;
01725     
01726     nw = ip[0];
01727     if (n > (nw << 2)) {
01728         nw = n >> 2;
01729         makewt(nw, ip, w);
01730     }
01731     nc = ip[1];
01732     if (n > nc) {
01733         nc = n;
01734         makect(nc, ip, w + nw);
01735     }
01736     if (isgn < 0) {
01737         xr = a[n - 1];
01738         for (j = n - 2; j >= 2; j -= 2) {
01739             a[j + 1] = a[j] - a[j - 1];
01740             a[j] += a[j - 1];
01741         }
01742         a[1] = a[0] - xr;
01743         a[0] += xr;
01744         if (n > 4) {
01745             rftbsub(n, a, nc, w + nw);
01746             bitrv2(n, ip + 2, a);
01747             cftbsub(n, a, w);
01748         } else if (n == 4) {
01749             cftfsub(n, a, w);
01750         }
01751     }
01752     dctsub(n, a, nc, w + nw);
01753     if (isgn >= 0) {
01754         if (n > 4) {
01755             bitrv2(n, ip + 2, a);
01756             cftfsub(n, a, w);
01757             rftfsub(n, a, nc, w + nw);
01758         } else if (n == 4) {
01759             cftfsub(n, a, w);
01760         }
01761         xr = a[0] - a[1];
01762         a[0] += a[1];
01763         for (j = 2; j < n; j += 2) {
01764             a[j - 1] = a[j] - a[j + 1];
01765             a[j] += a[j + 1];
01766         }
01767         a[n - 1] = xr;
01768     }
01769 }
01770 
01771 
01772 void clTransform8::ddst(long n, long isgn, double *a, long *ip, double *w)
01773 {
01774     long j, nw, nc;
01775     double xr;
01776     
01777     nw = ip[0];
01778     if (n > (nw << 2)) {
01779         nw = n >> 2;
01780         makewt(nw, ip, w);
01781     }
01782     nc = ip[1];
01783     if (n > nc) {
01784         nc = n;
01785         makect(nc, ip, w + nw);
01786     }
01787     if (isgn < 0) {
01788         xr = a[n - 1];
01789         for (j = n - 2; j >= 2; j -= 2) {
01790             a[j + 1] = -a[j] - a[j - 1];
01791             a[j] -= a[j - 1];
01792         }
01793         a[1] = a[0] + xr;
01794         a[0] -= xr;
01795         if (n > 4) {
01796             rftbsub(n, a, nc, w + nw);
01797             bitrv2(n, ip + 2, a);
01798             cftbsub(n, a, w);
01799         } else if (n == 4) {
01800             cftfsub(n, a, w);
01801         }
01802     }
01803     dstsub(n, a, nc, w + nw);
01804     if (isgn >= 0) {
01805         if (n > 4) {
01806             bitrv2(n, ip + 2, a);
01807             cftfsub(n, a, w);
01808             rftfsub(n, a, nc, w + nw);
01809         } else if (n == 4) {
01810             cftfsub(n, a, w);
01811         }
01812         xr = a[0] - a[1];
01813         a[0] += a[1];
01814         for (j = 2; j < n; j += 2) {
01815             a[j - 1] = -a[j] - a[j + 1];
01816             a[j] -= a[j + 1];
01817         }
01818         a[n - 1] = -xr;
01819     }
01820 }
01821 
01822 
01823 void clTransform8::dfct(long n, double *a, double *t, long *ip, double *w)
01824 {
01825     long j, k, l, m, mh, nw, nc;
01826     double xr, xi, yr, yi;
01827     
01828     nw = ip[0];
01829     if (n > (nw << 3)) {
01830         nw = n >> 3;
01831         makewt(nw, ip, w);
01832     }
01833     nc = ip[1];
01834     if (n > (nc << 1)) {
01835         nc = n >> 1;
01836         makect(nc, ip, w + nw);
01837     }
01838     m = n >> 1;
01839     yi = a[m];
01840     xi = a[0] + a[n];
01841     a[0] -= a[n];
01842     t[0] = xi - yi;
01843     t[m] = xi + yi;
01844     if (n > 2) {
01845         mh = m >> 1;
01846         for (j = 1; j < mh; j++) {
01847             k = m - j;
01848             xr = a[j] - a[n - j];
01849             xi = a[j] + a[n - j];
01850             yr = a[k] - a[n - k];
01851             yi = a[k] + a[n - k];
01852             a[j] = xr;
01853             a[k] = yr;
01854             t[j] = xi - yi;
01855             t[k] = xi + yi;
01856         }
01857         t[mh] = a[mh] + a[n - mh];
01858         a[mh] -= a[n - mh];
01859         dctsub(m, a, nc, w + nw);
01860         if (m > 4) {
01861             bitrv2(m, ip + 2, a);
01862             cftfsub(m, a, w);
01863             rftfsub(m, a, nc, w + nw);
01864         } else if (m == 4) {
01865             cftfsub(m, a, w);
01866         }
01867         a[n - 1] = a[0] - a[1];
01868         a[1] = a[0] + a[1];
01869         for (j = m - 2; j >= 2; j -= 2) {
01870             a[2 * j + 1] = a[j] + a[j + 1];
01871             a[2 * j - 1] = a[j] - a[j + 1];
01872         }
01873         l = 2;
01874         m = mh;
01875         while (m >= 2) {
01876             dctsub(m, t, nc, w + nw);
01877             if (m > 4) {
01878                 bitrv2(m, ip + 2, t);
01879                 cftfsub(m, t, w);
01880                 rftfsub(m, t, nc, w + nw);
01881             } else if (m == 4) {
01882                 cftfsub(m, t, w);
01883             }
01884             a[n - l] = t[0] - t[1];
01885             a[l] = t[0] + t[1];
01886             k = 0;
01887             for (j = 2; j < m; j += 2) {
01888                 k += l << 2;
01889                 a[k - l] = t[j] - t[j + 1];
01890                 a[k + l] = t[j] + t[j + 1];
01891             }
01892             l <<= 1;
01893             mh = m >> 1;
01894             for (j = 0; j < mh; j++) {
01895                 k = m - j;
01896                 t[j] = t[m + k] - t[m + j];
01897                 t[k] = t[m + k] + t[m + j];
01898             }
01899             t[mh] = t[m + mh];
01900             m = mh;
01901         }
01902         a[l] = t[0];
01903         a[n] = t[2] - t[1];
01904         a[0] = t[2] + t[1];
01905     } else {
01906         a[1] = a[0];
01907         a[2] = t[0];
01908         a[0] = t[1];
01909     }
01910 }
01911 
01912 
01913 void clTransform8::dfst(long n, double *a, double *t, long *ip, double *w)
01914 {
01915     long j, k, l, m, mh, nw, nc;
01916     double xr, xi, yr, yi;
01917     
01918     nw = ip[0];
01919     if (n > (nw << 3)) {
01920         nw = n >> 3;
01921         makewt(nw, ip, w);
01922     }
01923     nc = ip[1];
01924     if (n > (nc << 1)) {
01925         nc = n >> 1;
01926         makect(nc, ip, w + nw);
01927     }
01928     if (n > 2) {
01929         m = n >> 1;
01930         mh = m >> 1;
01931         for (j = 1; j < mh; j++) {
01932             k = m - j;
01933             xr = a[j] + a[n - j];
01934             xi = a[j] - a[n - j];
01935             yr = a[k] + a[n - k];
01936             yi = a[k] - a[n - k];
01937             a[j] = xr;
01938             a[k] = yr;
01939             t[j] = xi + yi;
01940             t[k] = xi - yi;
01941         }
01942         t[0] = a[mh] - a[n - mh];
01943         a[mh] += a[n - mh];
01944         a[0] = a[m];
01945         dstsub(m, a, nc, w + nw);
01946         if (m > 4) {
01947             bitrv2(m, ip + 2, a);
01948             cftfsub(m, a, w);
01949             rftfsub(m, a, nc, w + nw);
01950         } else if (m == 4) {
01951             cftfsub(m, a, w);
01952         }
01953         a[n - 1] = a[1] - a[0];
01954         a[1] = a[0] + a[1];
01955         for (j = m - 2; j >= 2; j -= 2) {
01956             a[2 * j + 1] = a[j] - a[j + 1];
01957             a[2 * j - 1] = -a[j] - a[j + 1];
01958         }
01959         l = 2;
01960         m = mh;
01961         while (m >= 2) {
01962             dstsub(m, t, nc, w + nw);
01963             if (m > 4) {
01964                 bitrv2(m, ip + 2, t);
01965                 cftfsub(m, t, w);
01966                 rftfsub(m, t, nc, w + nw);
01967             } else if (m == 4) {
01968                 cftfsub(m, t, w);
01969             }
01970             a[n - l] = t[1] - t[0];
01971             a[l] = t[0] + t[1];
01972             k = 0;
01973             for (j = 2; j < m; j += 2) {
01974                 k += l << 2;
01975                 a[k - l] = -t[j] - t[j + 1];
01976                 a[k + l] = t[j] - t[j + 1];
01977             }
01978             l <<= 1;
01979             mh = m >> 1;
01980             for (j = 1; j < mh; j++) {
01981                 k = m - j;
01982                 t[j] = t[m + k] + t[m + j];
01983                 t[k] = t[m + k] - t[m + j];
01984             }
01985             t[0] = t[m + mh];
01986             m = mh;
01987         }
01988         a[l] = t[0];
01989     }
01990     a[0] = 0;
01991 }
01992 
01993 
01994 /* -------- initializing routines -------- */
01995 
01996 
01997 void clTransform8::makewt(long nw, long *ip, double *w)
01998 {
01999     long j, nwh;
02000     double delta, x, y;
02001     
02002     ip[0] = nw;
02003     ip[1] = 1;
02004     if (nw > 2) {
02005         nwh = nw >> 1;
02006 #       ifndef TRANSFORM_EXT_PREC
02007         delta = atan(1.0) / nwh;
02008 #       else
02009         delta = (double) (atanl(1.0l) / nwh);
02010 #       endif
02011         w[0] = 1;
02012         w[1] = 0;
02013 #       ifndef TRANSFORM_EXT_PREC
02014         w[nwh] = cos(delta * nwh);
02015 #       else
02016         w[nwh] = (double) cosl(delta * nwh);
02017 #       endif
02018         w[nwh + 1] = w[nwh];
02019         if (nwh > 2) {
02020             for (j = 2; j < nwh; j += 2) {
02021 #               ifndef TRANSFORM_EXT_PREC
02022                 x = cos(delta * j);
02023                 y = sin(delta * j);
02024 #               else
02025                 x = (double) cosl(delta * j);
02026                 y = (double) sinl(delta * j);
02027 #               endif
02028                 w[j] = x;
02029                 w[j + 1] = y;
02030                 w[nw - j] = y;
02031                 w[nw - j + 1] = x;
02032             }
02033             for (j = nwh - 2; j >= 2; j -= 2) {
02034                 x = w[2 * j];
02035                 y = w[2 * j + 1];
02036                 w[nwh + j] = x;
02037                 w[nwh + j + 1] = y;
02038             }
02039             bitrv2(nw, ip + 2, w);
02040         }
02041     }
02042 }
02043 
02044 
02045 void clTransform8::makect(long nc, long *ip, double *c)
02046 {
02047     long j, nch;
02048     double delta;
02049     
02050     ip[1] = nc;
02051     if (nc > 1) {
02052         nch = nc >> 1;
02053 #       ifndef TRANSFORM_EXT_PREC
02054         delta = atan(1.0) / nch;
02055         c[0] = cos(delta * nch);
02056 #       else
02057         delta = (double) (atanl(1.0l) / nch);
02058         c[0] = (double) (cosl(delta * nch));
02059 #       endif
02060         c[nch] = 0.5 * c[0];
02061         for (j = 1; j < nch; j++) {
02062 #           ifndef TRANSFORM_EXT_PREC
02063             c[j] = 0.5 * cos(delta * j);
02064             c[nc - j] = 0.5 * sin(delta * j);
02065 #           else
02066             c[j] = (double) (0.5l * cosl(delta * j));
02067             c[nc - j] = (double) (0.5l * sinl(delta * j));
02068 #           endif
02069         }
02070     }
02071 }
02072 
02073 
02074 /* -------- child routines -------- */
02075 
02076 
02077 T8_INLINE void clTransform8::bitrv2(long n, long *ip, double *a)
02078 {
02079     long j, j1, k, k1, l, m, m2;
02080     double xr, xi, yr, yi;
02081     
02082     ip[0] = 0;
02083     l = n;
02084     m = 1;
02085     while ((m << 3) < l) {
02086         l >>= 1;
02087         for (j = 0; j < m; j++) {
02088             ip[m + j] = ip[j] + l;
02089         }
02090         m <<= 1;
02091     }
02092     m2 = 2 * m;
02093     if ((m << 3) == l) {
02094         for (k = 0; k < m; k++) {
02095             for (j = 0; j < k; j++) {
02096                 j1 = 2 * j + ip[k];
02097                 k1 = 2 * k + ip[j];
02098                 xr = a[j1];
02099                 xi = a[j1 + 1];
02100                 yr = a[k1];
02101                 yi = a[k1 + 1];
02102                 a[j1] = yr;
02103                 a[j1 + 1] = yi;
02104                 a[k1] = xr;
02105                 a[k1 + 1] = xi;
02106                 j1 += m2;
02107                 k1 += 2 * m2;
02108                 xr = a[j1];
02109                 xi = a[j1 + 1];
02110                 yr = a[k1];
02111                 yi = a[k1 + 1];
02112                 a[j1] = yr;
02113                 a[j1 + 1] = yi;
02114                 a[k1] = xr;
02115                 a[k1 + 1] = xi;
02116                 j1 += m2;
02117                 k1 -= m2;
02118                 xr = a[j1];
02119                 xi = a[j1 + 1];
02120                 yr = a[k1];
02121                 yi = a[k1 + 1];
02122                 a[j1] = yr;
02123                 a[j1 + 1] = yi;
02124                 a[k1] = xr;
02125                 a[k1 + 1] = xi;
02126                 j1 += m2;
02127                 k1 += 2 * m2;
02128                 xr = a[j1];
02129                 xi = a[j1 + 1];
02130                 yr = a[k1];
02131                 yi = a[k1 + 1];
02132                 a[j1] = yr;
02133                 a[j1 + 1] = yi;
02134                 a[k1] = xr;
02135                 a[k1 + 1] = xi;
02136             }
02137             j1 = 2 * k + m2 + ip[k];
02138             k1 = j1 + m2;
02139             xr = a[j1];
02140             xi = a[j1 + 1];
02141             yr = a[k1];
02142             yi = a[k1 + 1];
02143             a[j1] = yr;
02144             a[j1 + 1] = yi;
02145             a[k1] = xr;
02146             a[k1 + 1] = xi;
02147         }
02148     } else {
02149         for (k = 1; k < m; k++) {
02150             for (j = 0; j < k; j++) {
02151                 j1 = 2 * j + ip[k];
02152                 k1 = 2 * k + ip[j];
02153                 xr = a[j1];
02154                 xi = a[j1 + 1];
02155                 yr = a[k1];
02156                 yi = a[k1 + 1];
02157                 a[j1] = yr;
02158                 a[j1 + 1] = yi;
02159                 a[k1] = xr;
02160                 a[k1 + 1] = xi;
02161                 j1 += m2;
02162                 k1 += m2;
02163                 xr = a[j1];
02164                 xi = a[j1 + 1];
02165                 yr = a[k1];
02166                 yi = a[k1 + 1];
02167                 a[j1] = yr;
02168                 a[j1 + 1] = yi;
02169                 a[k1] = xr;
02170                 a[k1 + 1] = xi;
02171             }
02172         }
02173     }
02174 }
02175 
02176 
02177 T8_INLINE void clTransform8::bitrv2conj(long n, long *ip, double *a)
02178 {
02179     long j, j1, k, k1, l, m, m2;
02180     double xr, xi, yr, yi;
02181     
02182     ip[0] = 0;
02183     l = n;
02184     m = 1;
02185     while ((m << 3) < l) {
02186         l >>= 1;
02187         for (j = 0; j < m; j++) {
02188             ip[m + j] = ip[j] + l;
02189         }
02190         m <<= 1;
02191     }
02192     m2 = 2 * m;
02193     if ((m << 3) == l) {
02194         for (k = 0; k < m; k++) {
02195             for (j = 0; j < k; j++) {
02196                 j1 = 2 * j + ip[k];
02197                 k1 = 2 * k + ip[j];
02198                 xr = a[j1];
02199                 xi = -a[j1 + 1];
02200                 yr = a[k1];
02201                 yi = -a[k1 + 1];
02202                 a[j1] = yr;
02203                 a[j1 + 1] = yi;
02204                 a[k1] = xr;
02205                 a[k1 + 1] = xi;
02206                 j1 += m2;
02207                 k1 += 2 * m2;
02208                 xr = a[j1];
02209                 xi = -a[j1 + 1];
02210                 yr = a[k1];
02211                 yi = -a[k1 + 1];
02212                 a[j1] = yr;
02213                 a[j1 + 1] = yi;
02214                 a[k1] = xr;
02215                 a[k1 + 1] = xi;
02216                 j1 += m2;
02217                 k1 -= m2;
02218                 xr = a[j1];
02219                 xi = -a[j1 + 1];
02220                 yr = a[k1];
02221                 yi = -a[k1 + 1];
02222                 a[j1] = yr;
02223                 a[j1 + 1] = yi;
02224                 a[k1] = xr;
02225                 a[k1 + 1] = xi;
02226                 j1 += m2;
02227                 k1 += 2 * m2;
02228                 xr = a[j1];
02229                 xi = -a[j1 + 1];
02230                 yr = a[k1];
02231                 yi = -a[k1 + 1];
02232                 a[j1] = yr;
02233                 a[j1 + 1] = yi;
02234                 a[k1] = xr;
02235                 a[k1 + 1] = xi;
02236             }
02237             k1 = 2 * k + ip[k];
02238             a[k1 + 1] = -a[k1 + 1];
02239             j1 = k1 + m2;
02240             k1 = j1 + m2;
02241             xr = a[j1];
02242             xi = -a[j1 + 1];
02243             yr = a[k1];
02244             yi = -a[k1 + 1];
02245             a[j1] = yr;
02246             a[j1 + 1] = yi;
02247             a[k1] = xr;
02248             a[k1 + 1] = xi;
02249             k1 += m2;
02250             a[k1 + 1] = -a[k1 + 1];
02251         }
02252     } else {
02253         a[1] = -a[1];
02254         a[m2 + 1] = -a[m2 + 1];
02255         for (k = 1; k < m; k++) {
02256             for (j = 0; j < k; j++) {
02257                 j1 = 2 * j + ip[k];
02258                 k1 = 2 * k + ip[j];
02259                 xr = a[j1];
02260                 xi = -a[j1 + 1];
02261                 yr = a[k1];
02262                 yi = -a[k1 + 1];
02263                 a[j1] = yr;
02264                 a[j1 + 1] = yi;
02265                 a[k1] = xr;
02266                 a[k1 + 1] = xi;
02267                 j1 += m2;
02268                 k1 += m2;
02269                 xr = a[j1];
02270                 xi = -a[j1 + 1];
02271                 yr = a[k1];
02272                 yi = -a[k1 + 1];
02273                 a[j1] = yr;
02274                 a[j1 + 1] = yi;
02275                 a[k1] = xr;
02276                 a[k1 + 1] = xi;
02277             }
02278             k1 = 2 * k + ip[k];
02279             a[k1 + 1] = -a[k1 + 1];
02280             a[k1 + m2 + 1] = -a[k1 + m2 + 1];
02281         }
02282     }
02283 }
02284 
02285 
02286 T8_INLINE void clTransform8::cftfsub(long n, double *a, double *w)
02287 {
02288     long j, j1, j2, j3, l;
02289     double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
02290     
02291     l = 2;
02292     if (n >= 16) {
02293         cft1st(n, a, w);
02294         l = 16;
02295         while ((l << 3) <= n) {
02296             cftmdl(n, l, a, w);
02297             l <<= 3;
02298         }
02299     }
02300     if ((l << 1) < n) {
02301         for (j = 0; j < l; j += 2) {
02302             j1 = j + l;
02303             j2 = j1 + l;
02304             j3 = j2 + l;
02305             x0r = a[j] + a[j1];
02306             x0i = a[j + 1] + a[j1 + 1];
02307             x1r = a[j] - a[j1];
02308             x1i = a[j + 1] - a[j1 + 1];
02309             x2r = a[j2] + a[j3];
02310             x2i = a[j2 + 1] + a[j3 + 1];
02311             x3r = a[j2] - a[j3];
02312             x3i = a[j2 + 1] - a[j3 + 1];
02313             a[j] = x0r + x2r;
02314             a[j + 1] = x0i + x2i;
02315             a[j2] = x0r - x2r;
02316             a[j2 + 1] = x0i - x2i;
02317             a[j1] = x1r - x3i;
02318             a[j1 + 1] = x1i + x3r;
02319             a[j3] = x1r + x3i;
02320             a[j3 + 1] = x1i - x3r;
02321         }
02322     } else if ((l << 1) == n) {
02323         for (j = 0; j < l; j += 2) {
02324             j1 = j + l;
02325             x0r = a[j] - a[j1];
02326             x0i = a[j + 1] - a[j1 + 1];
02327             a[j] += a[j1];
02328             a[j + 1] += a[j1 + 1];
02329             a[j1] = x0r;
02330             a[j1 + 1] = x0i;
02331         }
02332     }
02333 }
02334 
02335 
02336 T8_INLINE void clTransform8::cftbsub(long n, double *a, double *w)
02337 {
02338     long j, j1, j2, j3, j4, j5, j6, j7, l;
02339     double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, 
02340         y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, 
02341         y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
02342     
02343     l = 2;
02344     if (n > 16) {
02345         cft1st(n, a, w);
02346         l = 16;
02347         while ((l << 3) < n) {
02348             cftmdl(n, l, a, w);
02349             l <<= 3;
02350         }
02351     }
02352     if ((l << 2) < n) {
02353         wn4r = w[2];
02354         for (j = 0; j < l; j += 2) {
02355             j1 = j + l;
02356             j2 = j1 + l;
02357             j3 = j2 + l;
02358             j4 = j3 + l;
02359             j5 = j4 + l;
02360             j6 = j5 + l;
02361             j7 = j6 + l;
02362             x0r = a[j] + a[j1];
02363             x0i = -a[j + 1] - a[j1 + 1];
02364             x1r = a[j] - a[j1];
02365             x1i = -a[j + 1] + a[j1 + 1];
02366             x2r = a[j2] + a[j3];
02367             x2i = a[j2 + 1] + a[j3 + 1];
02368             x3r = a[j2] - a[j3];
02369             x3i = a[j2 + 1] - a[j3 + 1];
02370             y0r = x0r + x2r;
02371             y0i = x0i - x2i;
02372             y2r = x0r - x2r;
02373             y2i = x0i + x2i;
02374             y1r = x1r - x3i;
02375             y1i = x1i - x3r;
02376             y3r = x1r + x3i;
02377             y3i = x1i + x3r;
02378             x0r = a[j4] + a[j5];
02379             x0i = a[j4 + 1] + a[j5 + 1];
02380             x1r = a[j4] - a[j5];
02381             x1i = a[j4 + 1] - a[j5 + 1];
02382             x2r = a[j6] + a[j7];
02383             x2i = a[j6 + 1] + a[j7 + 1];
02384             x3r = a[j6] - a[j7];
02385             x3i = a[j6 + 1] - a[j7 + 1];
02386             y4r = x0r + x2r;
02387             y4i = x0i + x2i;
02388             y6r = x0r - x2r;
02389             y6i = x0i - x2i;
02390             x0r = x1r - x3i;
02391             x0i = x1i + x3r;
02392             x2r = x1r + x3i;
02393             x2i = x1i - x3r;
02394             y5r = wn4r * (x0r - x0i);
02395             y5i = wn4r * (x0r + x0i);
02396             y7r = wn4r * (x2r - x2i);
02397             y7i = wn4r * (x2r + x2i);
02398             a[j1] = y1r + y5r;
02399             a[j1 + 1] = y1i - y5i;
02400             a[j5] = y1r - y5r;
02401             a[j5 + 1] = y1i + y5i;
02402             a[j3] = y3r - y7i;
02403             a[j3 + 1] = y3i - y7r;
02404             a[j7] = y3r + y7i;
02405             a[j7 + 1] = y3i + y7r;
02406             a[j] = y0r + y4r;
02407             a[j + 1] = y0i - y4i;
02408             a[j4] = y0r - y4r;
02409             a[j4 + 1] = y0i + y4i;
02410             a[j2] = y2r - y6i;
02411             a[j2 + 1] = y2i - y6r;
02412             a[j6] = y2r + y6i;
02413             a[j6 + 1] = y2i + y6r;
02414         }
02415     } else if ((l << 2) == n) {
02416         for (j = 0; j < l; j += 2) {
02417             j1 = j + l;
02418             j2 = j1 + l;
02419             j3 = j2 + l;
02420             x0r = a[j] + a[j1];
02421             x0i = -a[j + 1] - a[j1 + 1];
02422             x1r = a[j] - a[j1];
02423             x1i = -a[j + 1] + a[j1 + 1];
02424             x2r = a[j2] + a[j3];
02425             x2i = a[j2 + 1] + a[j3 + 1];
02426             x3r = a[j2] - a[j3];
02427             x3i = a[j2 + 1] - a[j3 + 1];
02428             a[j] = x0r + x2r;
02429             a[j + 1] = x0i - x2i;
02430             a[j2] = x0r - x2r;
02431             a[j2 + 1] = x0i + x2i;
02432             a[j1] = x1r - x3i;
02433             a[j1 + 1] = x1i - x3r;
02434             a[j3] = x1r + x3i;
02435             a[j3 + 1] = x1i + x3r;
02436         }
02437     } else {
02438         for (j = 0; j < l; j += 2) {
02439             j1 = j + l;
02440             x0r = a[j] - a[j1];
02441             x0i = -a[j + 1] + a[j1 + 1];
02442             a[j] += a[j1];
02443             a[j + 1] = -a[j + 1] - a[j1 + 1];
02444             a[j1] = x0r;
02445             a[j1 + 1] = x0i;
02446         }
02447     }
02448 }
02449 
02450 
02451 T8_INLINE void clTransform8::cft1st(long n, double *a, double *w)
02452 {
02453     long j, k1;
02454     double wn4r, wtmp, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, 
02455         wk4r, wk4i, wk5r, wk5i, wk6r, wk6i, wk7r, wk7i;
02456     double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, 
02457         y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, 
02458         y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
02459     
02460     wn4r = w[2];
02461     x0r = a[0] + a[2];
02462     x0i = a[1] + a[3];
02463     x1r = a[0] - a[2];
02464     x1i = a[1] - a[3];
02465     x2r = a[4] + a[6];
02466     x2i = a[5] + a[7];
02467     x3r = a[4] - a[6];
02468     x3i = a[5] - a[7];
02469     y0r = x0r + x2r;
02470     y0i = x0i + x2i;
02471     y2r = x0r - x2r;
02472     y2i = x0i - x2i;
02473     y1r = x1r - x3i;
02474     y1i = x1i + x3r;
02475     y3r = x1r + x3i;
02476     y3i = x1i - x3r;
02477     x0r = a[8] + a[10];
02478     x0i = a[9] + a[11];
02479     x1r = a[8] - a[10];
02480     x1i = a[9] - a[11];
02481     x2r = a[12] + a[14];
02482     x2i = a[13] + a[15];
02483     x3r = a[12] - a[14];
02484     x3i = a[13] - a[15];
02485     y4r = x0r + x2r;
02486     y4i = x0i + x2i;
02487     y6r = x0r - x2r;
02488     y6i = x0i - x2i;
02489     x0r = x1r - x3i;
02490     x0i = x1i + x3r;
02491     x2r = x1r + x3i;
02492     x2i = x1i - x3r;
02493     y5r = wn4r * (x0r - x0i);
02494     y5i = wn4r * (x0r + x0i);
02495     y7r = wn4r * (x2r - x2i);
02496     y7i = wn4r * (x2r + x2i);
02497     a[2] = y1r + y5r;
02498     a[3] = y1i + y5i;
02499     a[10] = y1r - y5r;
02500     a[11] = y1i - y5i;
02501     a[6] = y3r - y7i;
02502     a[7] = y3i + y7r;
02503     a[14] = y3r + y7i;
02504     a[15] = y3i - y7r;
02505     a[0] = y0r + y4r;
02506     a[1] = y0i + y4i;
02507     a[8] = y0r - y4r;
02508     a[9] = y0i - y4i;
02509     a[4] = y2r - y6i;
02510     a[5] = y2i + y6r;
02511     a[12] = y2r + y6i;
02512     a[13] = y2i - y6r;
02513     if (n > 16) {
02514         wk1r = w[4];
02515         wk1i = w[5];
02516         x0r = a[16] + a[18];
02517         x0i = a[17] + a[19];
02518         x1r = a[16] - a[18];
02519         x1i = a[17] - a[19];
02520         x2r = a[20] + a[22];
02521         x2i = a[21] + a[23];
02522         x3r = a[20] - a[22];
02523         x3i = a[21] - a[23];
02524         y0r = x0r + x2r;
02525         y0i = x0i + x2i;
02526         y2r = x0r - x2r;
02527         y2i = x0i - x2i;
02528         y1r = x1r - x3i;
02529         y1i = x1i + x3r;
02530         y3r = x1r + x3i;
02531         y3i = x1i - x3r;
02532         x0r = a[24] + a[26];
02533         x0i = a[25] + a[27];
02534         x1r = a[24] - a[26];
02535         x1i = a[25] - a[27];
02536         x2r = a[28] + a[30];
02537         x2i = a[29] + a[31];
02538         x3r = a[28] - a[30];
02539         x3i = a[29] - a[31];
02540         y4r = x0r + x2r;
02541         y4i = x0i + x2i;
02542         y6r = x0r - x2r;
02543         y6i = x0i - x2i;
02544         x0r = x1r - x3i;
02545         x0i = x1i + x3r;
02546         x2r = x1r + x3i;
02547         x2i = x3r - x1i;
02548         y5r = wk1i * x0r - wk1r * x0i;
02549         y5i = wk1i * x0i + wk1r * x0r;
02550         y7r = wk1r * x2r + wk1i * x2i;
02551         y7i = wk1r * x2i - wk1i * x2r;
02552         x0r = wk1r * y1r - wk1i * y1i;
02553         x0i = wk1r * y1i + wk1i * y1r;
02554         a[18] = x0r + y5r;
02555         a[19] = x0i + y5i;
02556         a[26] = y5i - x0i;
02557         a[27] = x0r - y5r;
02558         x0r = wk1i * y3r - wk1r * y3i;
02559         x0i = wk1i * y3i + wk1r * y3r;
02560         a[22] = x0r - y7r;
02561         a[23] = x0i + y7i;
02562         a[30] = y7i - x0i;
02563         a[31] = x0r + y7r;
02564         a[16] = y0r + y4r;
02565         a[17] = y0i + y4i;
02566         a[24] = y4i - y0i;
02567         a[25] = y0r - y4r;
02568         x0r = y2r - y6i;
02569         x0i = y2i + y6r;
02570         a[20] = wn4r * (x0r - x0i);
02571         a[21] = wn4r * (x0i + x0r);
02572         x0r = y6r - y2i;
02573         x0i = y2r + y6i;
02574         a[28] = wn4r * (x0r - x0i);
02575         a[29] = wn4r * (x0i + x0r);
02576         k1 = 4;
02577         for (j = 32; j < n; j += 16) {
02578             k1 += 4;
02579             wk1r = w[k1];
02580             wk1i = w[k1 + 1];
02581             wk2r = w[k1 + 2];
02582             wk2i = w[k1 + 3];
02583             wtmp = 2 * wk2i;
02584             wk3r = wk1r - wtmp * wk1i;
02585             wk3i = wtmp * wk1r - wk1i;
02586             wk4r = 1 - wtmp * wk2i;
02587             wk4i = wtmp * wk2r;
02588             wtmp = 2 * wk4i;
02589             wk5r = wk3r - wtmp * wk1i;
02590             wk5i = wtmp * wk1r - wk3i;
02591             wk6r = wk2r - wtmp * wk2i;
02592             wk6i = wtmp * wk2r - wk2i;
02593             wk7r = wk1r - wtmp * wk3i;
02594             wk7i = wtmp * wk3r - wk1i;
02595             x0r = a[j] + a[j + 2];
02596             x0i = a[j + 1] + a[j + 3];
02597             x1r = a[j] - a[j + 2];
02598             x1i = a[j + 1] - a[j + 3];
02599             x2r = a[j + 4] + a[j + 6];
02600             x2i = a[j + 5] + a[j + 7];
02601             x3r = a[j + 4] - a[j + 6];
02602             x3i = a[j + 5] - a[j + 7];
02603             y0r = x0r + x2r;
02604             y0i = x0i + x2i;
02605             y2r = x0r - x2r;
02606             y2i = x0i - x2i;
02607             y1r = x1r - x3i;
02608             y1i = x1i + x3r;
02609             y3r = x1r + x3i;
02610             y3i = x1i - x3r;
02611             x0r = a[j + 8] + a[j + 10];
02612             x0i = a[j + 9] + a[j + 11];
02613             x1r = a[j + 8] - a[j + 10];
02614             x1i = a[j + 9] - a[j + 11];
02615             x2r = a[j + 12] + a[j + 14];
02616             x2i = a[j + 13] + a[j + 15];
02617             x3r = a[j + 12] - a[j + 14];
02618             x3i = a[j + 13] - a[j + 15];
02619             y4r = x0r + x2r;
02620             y4i = x0i + x2i;
02621             y6r = x0r - x2r;
02622             y6i = x0i - x2i;
02623             x0r = x1r - x3i;
02624             x0i = x1i + x3r;
02625             x2r = x1r + x3i;
02626             x2i = x1i - x3r;
02627             y5r = wn4r * (x0r - x0i);
02628             y5i = wn4r * (x0r + x0i);
02629             y7r = wn4r * (x2r - x2i);
02630             y7i = wn4r * (x2r + x2i);
02631             x0r = y1r + y5r;
02632             x0i = y1i + y5i;
02633             a[j + 2] = wk1r * x0r - wk1i * x0i;
02634             a[j + 3] = wk1r * x0i + wk1i * x0r;
02635             x0r = y1r - y5r;
02636             x0i = y1i - y5i;
02637             a[j + 10] = wk5r * x0r - wk5i * x0i;
02638             a[j + 11] = wk5r * x0i + wk5i * x0r;
02639             x0r = y3r - y7i;
02640             x0i = y3i + y7r;
02641             a[j + 6] = wk3r * x0r - wk3i * x0i;
02642             a[j + 7] = wk3r * x0i + wk3i * x0r;
02643             x0r = y3r + y7i;
02644             x0i = y3i - y7r;
02645             a[j + 14] = wk7r * x0r - wk7i * x0i;
02646             a[j + 15] = wk7r * x0i + wk7i * x0r;
02647             a[j] = y0r + y4r;
02648             a[j + 1] = y0i + y4i;
02649             x0r = y0r - y4r;
02650             x0i = y0i - y4i;
02651             a[j + 8] = wk4r * x0r - wk4i * x0i;
02652             a[j + 9] = wk4r * x0i + wk4i * x0r;
02653             x0r = y2r - y6i;
02654             x0i = y2i + y6r;
02655             a[j + 4] = wk2r * x0r - wk2i * x0i;
02656             a[j + 5] = wk2r * x0i + wk2i * x0r;
02657             x0r = y2r + y6i;
02658             x0i = y2i - y6r;
02659             a[j + 12] = wk6r * x0r - wk6i * x0i;
02660             a[j + 13] = wk6r * x0i + wk6i * x0r;
02661         }
02662     }
02663 }
02664 
02665 
02666 T8_INLINE void clTransform8::cftmdl(long n, long l, double *a, double *w)
02667 {
02668     long j, j1, j2, j3, j4, j5, j6, j7, k, k1, m;
02669     double wn4r, wtmp, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, 
02670         wk4r, wk4i, wk5r, wk5i, wk6r, wk6i, wk7r, wk7i;
02671     double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, 
02672         y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, 
02673         y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
02674     
02675     m = l << 3;
02676     wn4r = w[2];
02677     for (j = 0; j < l; j += 2) {
02678         j1 = j + l;
02679         j2 = j1 + l;
02680         j3 = j2 + l;
02681         j4 = j3 + l;
02682         j5 = j4 + l;
02683         j6 = j5 + l;
02684         j7 = j6 + l;
02685         x0r = a[j] + a[j1];
02686         x0i = a[j + 1] + a[j1 + 1];
02687         x1r = a[j] - a[j1];
02688         x1i = a[j + 1] - a[j1 + 1];
02689         x2r = a[j2] + a[j3];
02690         x2i = a[j2 + 1] + a[j3 + 1];
02691         x3r = a[j2] - a[j3];
02692         x3i = a[j2 + 1] - a[j3 + 1];
02693         y0r = x0r + x2r;
02694         y0i = x0i + x2i;
02695         y2r = x0r - x2r;
02696         y2i = x0i - x2i;
02697         y1r = x1r - x3i;
02698         y1i = x1i + x3r;
02699         y3r = x1r + x3i;
02700         y3i = x1i - x3r;
02701         x0r = a[j4] + a[j5];
02702         x0i = a[j4 + 1] + a[j5 + 1];
02703         x1r = a[j4] - a[j5];
02704         x1i = a[j4 + 1] - a[j5 + 1];
02705         x2r = a[j6] + a[j7];
02706         x2i = a[j6 + 1] + a[j7 + 1];
02707         x3r = a[j6] - a[j7];
02708         x3i = a[j6 + 1] - a[j7 + 1];
02709         y4r = x0r + x2r;
02710         y4i = x0i + x2i;
02711         y6r = x0r - x2r;
02712         y6i = x0i - x2i;
02713         x0r = x1r - x3i;
02714         x0i = x1i + x3r;
02715         x2r = x1r + x3i;
02716         x2i = x1i - x3r;
02717         y5r = wn4r * (x0r - x0i);
02718         y5i = wn4r * (x0r + x0i);
02719         y7r = wn4r * (x2r - x2i);
02720         y7i = wn4r * (x2r + x2i);
02721         a[j1] = y1r + y5r;
02722         a[j1 + 1] = y1i + y5i;
02723         a[j5] = y1r - y5r;
02724         a[j5 + 1] = y1i - y5i;
02725         a[j3] = y3r - y7i;
02726         a[j3 + 1] = y3i + y7r;
02727         a[j7] = y3r + y7i;
02728         a[j7 + 1] = y3i - y7r;
02729         a[j] = y0r + y4r;
02730         a[j + 1] = y0i + y4i;
02731         a[j4] = y0r - y4r;
02732         a[j4 + 1] = y0i - y4i;
02733         a[j2] = y2r - y6i;
02734         a[j2 + 1] = y2i + y6r;
02735         a[j6] = y2r + y6i;
02736         a[j6 + 1] = y2i - y6r;
02737     }
02738     if (m < n) {
02739         wk1r = w[4];
02740         wk1i = w[5];
02741         for (j = m; j < l + m; j += 2) {
02742             j1 = j + l;
02743             j2 = j1 + l;
02744             j3 = j2 + l;
02745             j4 = j3 + l;
02746             j5 = j4 + l;
02747             j6 = j5 + l;
02748             j7 = j6 + l;
02749             x0r = a[j] + a[j1];
02750             x0i = a[j + 1] + a[j1 + 1];
02751             x1r = a[j] - a[j1];
02752             x1i = a[j + 1] - a[j1 + 1];
02753             x2r = a[j2] + a[j3];
02754             x2i = a[j2 + 1] + a[j3 + 1];
02755             x3r = a[j2] - a[j3];
02756             x3i = a[j2 + 1] - a[j3 + 1];
02757             y0r = x0r + x2r;
02758             y0i = x0i + x2i;
02759             y2r = x0r - x2r;
02760             y2i = x0i - x2i;
02761             y1r = x1r - x3i;
02762             y1i = x1i + x3r;
02763             y3r = x1r + x3i;
02764             y3i = x1i - x3r;
02765             x0r = a[j4] + a[j5];
02766             x0i = a[j4 + 1] + a[j5 + 1];
02767             x1r = a[j4] - a[j5];
02768             x1i = a[j4 + 1] - a[j5 + 1];
02769             x2r = a[j6] + a[j7];
02770             x2i = a[j6 + 1] + a[j7 + 1];
02771             x3r = a[j6] - a[j7];
02772             x3i = a[j6 + 1] - a[j7 + 1];
02773             y4r = x0r + x2r;
02774             y4i = x0i + x2i;
02775             y6r = x0r - x2r;
02776             y6i = x0i - x2i;
02777             x0r = x1r - x3i;
02778             x0i = x1i + x3r;
02779             x2r = x1r + x3i;
02780             x2i = x3r - x1i;
02781             y5r = wk1i * x0r - wk1r * x0i;
02782             y5i = wk1i * x0i + wk1r * x0r;
02783             y7r = wk1r * x2r + wk1i * x2i;
02784             y7i = wk1r * x2i - wk1i * x2r;
02785             x0r = wk1r * y1r - wk1i * y1i;
02786             x0i = wk1r * y1i + wk1i * y1r;
02787             a[j1] = x0r + y5r;
02788             a[j1 + 1] = x0i + y5i;
02789             a[j5] = y5i - x0i;
02790             a[j5 + 1] = x0r - y5r;
02791             x0r = wk1i * y3r - wk1r * y3i;
02792             x0i = wk1i * y3i + wk1r * y3r;
02793             a[j3] = x0r - y7r;
02794             a[j3 + 1] = x0i + y7i;
02795             a[j7] = y7i - x0i;
02796             a[j7 + 1] = x0r + y7r;
02797             a[j] = y0r + y4r;
02798             a[j + 1] = y0i + y4i;
02799             a[j4] = y4i - y0i;
02800             a[j4 + 1] = y0r - y4r;
02801             x0r = y2r - y6i;
02802             x0i = y2i + y6r;
02803             a[j2] = wn4r * (x0r - x0i);
02804             a[j2 + 1] = wn4r * (x0i + x0r);
02805             x0r = y6r - y2i;
02806             x0i = y2r + y6i;
02807             a[j6] = wn4r * (x0r - x0i);
02808             a[j6 + 1] = wn4r * (x0i + x0r);
02809         }
02810         k1 = 4;
02811         for (k = 2 * m; k < n; k += m) {
02812             k1 += 4;
02813             wk1r = w[k1];
02814             wk1i = w[k1 + 1];
02815             wk2r = w[k1 + 2];
02816             wk2i = w[k1 + 3];
02817             wtmp = 2 * wk2i;
02818             wk3r = wk1r - wtmp * wk1i;
02819             wk3i = wtmp * wk1r - wk1i;
02820             wk4r = 1 - wtmp * wk2i;
02821             wk4i = wtmp * wk2r;
02822             wtmp = 2 * wk4i;
02823             wk5r = wk3r - wtmp * wk1i;
02824             wk5i = wtmp * wk1r - wk3i;
02825             wk6r = wk2r - wtmp * wk2i;
02826             wk6i = wtmp * wk2r - wk2i;
02827             wk7r = wk1r - wtmp * wk3i;
02828             wk7i = wtmp * wk3r - wk1i;
02829             for (j = k; j < l + k; j += 2) {
02830                 j1 = j + l;
02831                 j2 = j1 + l;
02832                 j3 = j2 + l;
02833                 j4 = j3 + l;
02834                 j5 = j4 + l;
02835                 j6 = j5 + l;
02836                 j7 = j6 + l;
02837                 x0r = a[j] + a[j1];
02838                 x0i = a[j + 1] + a[j1 + 1];
02839                 x1r = a[j] - a[j1];
02840                 x1i = a[j + 1] - a[j1 + 1];
02841                 x2r = a[j2] + a[j3];
02842                 x2i = a[j2 + 1] + a[j3 + 1];
02843                 x3r = a[j2] - a[j3];
02844                 x3i = a[j2 + 1] - a[j3 + 1];
02845                 y0r = x0r + x2r;
02846                 y0i = x0i + x2i;
02847                 y2r = x0r - x2r;
02848                 y2i = x0i - x2i;
02849                 y1r = x1r - x3i;
02850                 y1i = x1i + x3r;
02851                 y3r = x1r + x3i;
02852                 y3i = x1i - x3r;
02853                 x0r = a[j4] + a[j5];
02854                 x0i = a[j4 + 1] + a[j5 + 1];
02855                 x1r = a[j4] - a[j5];
02856                 x1i = a[j4 + 1] - a[j5 + 1];
02857                 x2r = a[j6] + a[j7];
02858                 x2i = a[j6 + 1] + a[j7 + 1];
02859                 x3r = a[j6] - a[j7];
02860                 x3i = a[j6 + 1] - a[j7 + 1];
02861                 y4r = x0r + x2r;
02862                 y4i = x0i + x2i;
02863                 y6r = x0r - x2r;
02864                 y6i = x0i - x2i;
02865                 x0r = x1r - x3i;
02866                 x0i = x1i + x3r;
02867                 x2r = x1r + x3i;
02868                 x2i = x1i - x3r;
02869                 y5r = wn4r * (x0r - x0i);
02870                 y5i = wn4r * (x0r + x0i);
02871                 y7r = wn4r * (x2r - x2i);
02872                 y7i = wn4r * (x2r + x2i);
02873                 x0r = y1r + y5r;
02874                 x0i = y1i + y5i;
02875                 a[j1] = wk1r * x0r - wk1i * x0i;
02876                 a[j1 + 1] = wk1r * x0i + wk1i * x0r;
02877                 x0r = y1r - y5r;
02878                 x0i = y1i - y5i;
02879                 a[j5] = wk5r * x0r - wk5i * x0i;
02880                 a[j5 + 1] = wk5r * x0i + wk5i * x0r;
02881                 x0r = y3r - y7i;
02882                 x0i = y3i + y7r;
02883                 a[j3] = wk3r * x0r - wk3i * x0i;
02884                 a[j3 + 1] = wk3r * x0i + wk3i * x0r;
02885                 x0r = y3r + y7i;
02886                 x0i = y3i - y7r;
02887                 a[j7] = wk7r * x0r - wk7i * x0i;
02888                 a[j7 + 1] = wk7r * x0i + wk7i * x0r;
02889                 a[j] = y0r + y4r;
02890                 a[j + 1] = y0i + y4i;
02891                 x0r = y0r - y4r;
02892                 x0i = y0i - y4i;
02893                 a[j4] = wk4r * x0r - wk4i * x0i;
02894                 a[j4 + 1] = wk4r * x0i + wk4i * x0r;
02895                 x0r = y2r - y6i;
02896                 x0i = y2i + y6r;
02897                 a[j2] = wk2r * x0r - wk2i * x0i;
02898                 a[j2 + 1] = wk2r * x0i + wk2i * x0r;
02899                 x0r = y2r + y6i;
02900                 x0i = y2i - y6r;
02901                 a[j6] = wk6r * x0r - wk6i * x0i;
02902                 a[j6 + 1] = wk6r * x0i + wk6i * x0r;
02903             }
02904         }
02905     }
02906 }
02907 
02908 
02909 T8_INLINE void clTransform8::rftfsub(long n, double *a, long nc, double *c)
02910 {
02911     long j, k, kk, ks, m;
02912     double wkr, wki, xr, xi, yr, yi;
02913     
02914     m = n >> 1;
02915     ks = 2 * nc / m;
02916     kk = 0;
02917     for (j = 2; j < m; j += 2) {
02918         k = n - j;
02919         kk += ks;
02920         wkr = 0.5 - c[nc - kk];
02921         wki = c[kk];
02922         xr = a[j] - a[k];
02923         xi = a[j + 1] + a[k + 1];
02924         yr = wkr * xr - wki * xi;
02925         yi = wkr * xi + wki * xr;
02926         a[j] -= yr;
02927         a[j + 1] -= yi;
02928         a[k] += yr;
02929         a[k + 1] -= yi;
02930     }
02931 }
02932 
02933 
02934 T8_INLINE void clTransform8::rftbsub(long n, double *a, long nc, double *c)
02935 {
02936     long j, k, kk, ks, m;
02937     double wkr, wki, xr, xi, yr, yi;
02938     
02939     a[1] = -a[1];
02940     m = n >> 1;
02941     ks = 2 * nc / m;
02942     kk = 0;
02943     for (j = 2; j < m; j += 2) {
02944         k = n - j;
02945         kk += ks;
02946         wkr = 0.5 - c[nc - kk];
02947         wki = c[kk];
02948         xr = a[j] - a[k];
02949         xi = a[j + 1] + a[k + 1];
02950         yr = wkr * xr + wki * xi;
02951         yi = wkr * xi - wki * xr;
02952         a[j] -= yr;
02953         a[j + 1] = yi - a[j + 1];
02954         a[k] += yr;
02955         a[k + 1] = yi - a[k + 1];
02956     }
02957     a[m + 1] = -a[m + 1];
02958 }
02959 
02960 
02961 T8_INLINE void clTransform8::dctsub(long n, double *a, long nc, double *c)
02962 {
02963     long j, k, kk, ks, m;
02964     double wkr, wki, xr;
02965     
02966     m = n >> 1;
02967     ks = nc / n;
02968     kk = 0;
02969     for (j = 1; j < m; j++) {
02970         k = n - j;
02971         kk += ks;
02972         wkr = c[kk] - c[nc - kk];
02973         wki = c[kk] + c[nc - kk];
02974         xr = wki * a[j] - wkr * a[k];
02975         a[j] = wkr * a[j] + wki * a[k];
02976         a[k] = xr;
02977     }
02978     a[m] *= c[0];
02979 }
02980 
02981 
02982 T8_INLINE void clTransform8::dstsub(long n, double *a, long nc, double *c)
02983 {
02984     long j, k, kk, ks, m;
02985     double wkr, wki, xr;
02986     
02987     m = n >> 1;
02988     ks = nc / n;
02989     kk = 0;
02990     for (j = 1; j < m; j++) {
02991         k = n - j;
02992         kk += ks;
02993         wkr = c[kk] - c[nc - kk];
02994         wki = c[kk] + c[nc - kk];
02995         xr = wki * a[k] - wkr * a[j];
02996         a[k] = wkr * a[k] + wki * a[j];
02997         a[j] = xr;
02998     }
02999     a[m] *= c[0];
03000 }
03001 

Generated on Tue Mar 2 19:46:45 2004 for libDSP by doxygen 1.3.6