• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/dct.c

Go to the documentation of this file.
00001 /*
00002  * (I)DCT Transforms
00003  * Copyright (c) 2009 Peter Ross <pross@xvid.org>
00004  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
00005  * Copyright (c) 2010 Vitor Sessak
00006  *
00007  * This file is part of FFmpeg.
00008  *
00009  * FFmpeg is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  * FFmpeg is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with FFmpeg; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022  */
00023 
00030 #include <math.h>
00031 #include "libavutil/mathematics.h"
00032 #include "fft.h"
00033 
00034 /* sin((M_PI * x / (2*n)) */
00035 #define SIN(s,n,x) (s->costab[(n) - (x)])
00036 
00037 /* cos((M_PI * x / (2*n)) */
00038 #define COS(s,n,x) (s->costab[x])
00039 
00040 static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data)
00041 {
00042     int n = 1 << ctx->nbits;
00043     int i;
00044 
00045     data[0] = 0;
00046     for(i = 1; i < n/2; i++) {
00047         float tmp1 = data[i    ];
00048         float tmp2 = data[n - i];
00049         float s = SIN(ctx, n, 2*i);
00050 
00051         s *= tmp1 + tmp2;
00052         tmp1 = (tmp1 - tmp2) * 0.5f;
00053         data[i    ] = s + tmp1;
00054         data[n - i] = s - tmp1;
00055     }
00056 
00057     data[n/2] *= 2;
00058     ff_rdft_calc(&ctx->rdft, data);
00059 
00060     data[0] *= 0.5f;
00061 
00062     for(i = 1; i < n-2; i += 2) {
00063         data[i + 1] += data[i - 1];
00064         data[i    ] = -data[i + 2];
00065     }
00066 
00067     data[n-1] = 0;
00068 }
00069 
00070 static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data)
00071 {
00072     int n = 1 << ctx->nbits;
00073     int i;
00074     float next = -0.5f * (data[0] - data[n]);
00075 
00076     for(i = 0; i < n/2; i++) {
00077         float tmp1 = data[i    ];
00078         float tmp2 = data[n - i];
00079         float s = SIN(ctx, n, 2*i);
00080         float c = COS(ctx, n, 2*i);
00081 
00082         c *= tmp1 - tmp2;
00083         s *= tmp1 - tmp2;
00084 
00085         next += c;
00086 
00087         tmp1 = (tmp1 + tmp2) * 0.5f;
00088         data[i    ] = tmp1 - s;
00089         data[n - i] = tmp1 + s;
00090     }
00091 
00092     ff_rdft_calc(&ctx->rdft, data);
00093     data[n] = data[1];
00094     data[1] = next;
00095 
00096     for(i = 3; i <= n; i += 2)
00097         data[i] = data[i - 2] - data[i];
00098 }
00099 
00100 static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data)
00101 {
00102     int n = 1 << ctx->nbits;
00103     int i;
00104 
00105     float next = data[n - 1];
00106     float inv_n = 1.0f / n;
00107 
00108     for (i = n - 2; i >= 2; i -= 2) {
00109         float val1 = data[i    ];
00110         float val2 = data[i - 1] - data[i + 1];
00111         float c = COS(ctx, n, i);
00112         float s = SIN(ctx, n, i);
00113 
00114         data[i    ] = c * val1 + s * val2;
00115         data[i + 1] = s * val1 - c * val2;
00116     }
00117 
00118     data[1] = 2 * next;
00119 
00120     ff_rdft_calc(&ctx->rdft, data);
00121 
00122     for (i = 0; i < n / 2; i++) {
00123         float tmp1 = data[i        ] * inv_n;
00124         float tmp2 = data[n - i - 1] * inv_n;
00125         float csc = ctx->csc2[i] * (tmp1 - tmp2);
00126 
00127         tmp1 += tmp2;
00128         data[i        ] = tmp1 + csc;
00129         data[n - i - 1] = tmp1 - csc;
00130     }
00131 }
00132 
00133 static void ff_dct_calc_II_c(DCTContext *ctx, FFTSample *data)
00134 {
00135     int n = 1 << ctx->nbits;
00136     int i;
00137     float next;
00138 
00139     for (i=0; i < n/2; i++) {
00140         float tmp1 = data[i        ];
00141         float tmp2 = data[n - i - 1];
00142         float s = SIN(ctx, n, 2*i + 1);
00143 
00144         s *= tmp1 - tmp2;
00145         tmp1 = (tmp1 + tmp2) * 0.5f;
00146 
00147         data[i    ] = tmp1 + s;
00148         data[n-i-1] = tmp1 - s;
00149     }
00150 
00151     ff_rdft_calc(&ctx->rdft, data);
00152 
00153     next = data[1] * 0.5;
00154     data[1] *= -1;
00155 
00156     for (i = n - 2; i >= 0; i -= 2) {
00157         float inr = data[i    ];
00158         float ini = data[i + 1];
00159         float c = COS(ctx, n, i);
00160         float s = SIN(ctx, n, i);
00161 
00162         data[i  ] = c * inr + s * ini;
00163 
00164         data[i+1] = next;
00165 
00166         next +=     s * inr - c * ini;
00167     }
00168 }
00169 
00170 void ff_dct_calc(DCTContext *s, FFTSample *data)
00171 {
00172     s->dct_calc(s, data);
00173 }
00174 
00175 av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse)
00176 {
00177     int n = 1 << nbits;
00178     int i;
00179 
00180     s->nbits    = nbits;
00181     s->inverse  = inverse;
00182 
00183     ff_init_ff_cos_tabs(nbits+2);
00184 
00185     s->costab = ff_cos_tabs[nbits+2];
00186 
00187     s->csc2 = av_malloc(n/2 * sizeof(FFTSample));
00188 
00189     if (ff_rdft_init(&s->rdft, nbits, inverse == DCT_III) < 0) {
00190         av_free(s->csc2);
00191         return -1;
00192     }
00193 
00194     for (i = 0; i < n/2; i++)
00195         s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1)));
00196 
00197     switch(inverse) {
00198     case DCT_I  : s->dct_calc = ff_dct_calc_I_c; break;
00199     case DCT_II : s->dct_calc = ff_dct_calc_II_c ; break;
00200     case DCT_III: s->dct_calc = ff_dct_calc_III_c; break;
00201     case DST_I  : s->dct_calc = ff_dst_calc_I_c; break;
00202     }
00203     return 0;
00204 }
00205 
00206 av_cold void ff_dct_end(DCTContext *s)
00207 {
00208     ff_rdft_end(&s->rdft);
00209     av_free(s->csc2);
00210 }

Generated on Fri Sep 16 2011 17:17:35 for FFmpeg by  doxygen 1.7.1