Statistics
| Branch: | Revision:

ffmpeg / libavcodec / dct.c @ b531e1ab

History | View | Annotate | Download (3.55 KB)

1
/*
2
 * (I)DCT Transforms
3
 * Copyright (c) 2009 Peter Ross <pross@xvid.org>
4
 * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
5
 * Copyright (c) 2010 Vitor Sessak
6
 *
7
 * This file is part of FFmpeg.
8
 *
9
 * FFmpeg is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * FFmpeg is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with FFmpeg; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22
 */
23

    
24
/**
25
 * @file libavcodec/dct.c
26
 * (Inverse) Discrete Cosine Transforms. These are also known as the
27
 * type II and type III DCTs respectively.
28
 */
29

    
30
#include <math.h>
31
#include "libavutil/mathematics.h"
32
#include "fft.h"
33

    
34
/* sin((M_PI * x / (2*n)) */
35
#define SIN(s,n,x) (s->costab[(n) - (x)])
36

    
37
/* cos((M_PI * x / (2*n)) */
38
#define COS(s,n,x) (s->costab[x])
39

    
40
static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data)
41
{
42
    int n = 1 << ctx->nbits;
43
    int i;
44

    
45
    float next = data[n - 1];
46
    float inv_n = 1.0f / n;
47

    
48
    for (i = n - 2; i >= 2; i -= 2) {
49
        float val1 = data[i    ];
50
        float val2 = data[i - 1] - data[i + 1];
51
        float c = COS(ctx, n, i);
52
        float s = SIN(ctx, n, i);
53

    
54
        data[i    ] = c * val1 + s * val2;
55
        data[i + 1] = s * val1 - c * val2;
56
    }
57

    
58
    data[1] = 2 * next;
59

    
60
    ff_rdft_calc(&ctx->rdft, data);
61

    
62
    for (i = 0; i < n / 2; i++) {
63
        float tmp1 = data[i        ] * inv_n;
64
        float tmp2 = data[n - i - 1] * inv_n;
65
        float csc = ctx->csc2[i] * (tmp1 - tmp2);
66

    
67
        tmp1 += tmp2;
68
        data[i        ] = tmp1 + csc;
69
        data[n - i - 1] = tmp1 - csc;
70
    }
71
}
72

    
73
static void ff_dct_calc_II_c(DCTContext *ctx, FFTSample *data)
74
{
75
    int n = 1 << ctx->nbits;
76
    int i;
77
    float next;
78

    
79
    for (i=0; i < n/2; i++) {
80
        float tmp1 = data[i        ];
81
        float tmp2 = data[n - i - 1];
82
        float s = SIN(ctx, n, 2*i + 1);
83

    
84
        s *= tmp1 - tmp2;
85
        tmp1 = (tmp1 + tmp2) * 0.5f;
86

    
87
        data[i    ] = tmp1 + s;
88
        data[n-i-1] = tmp1 - s;
89
    }
90

    
91
    ff_rdft_calc(&ctx->rdft, data);
92

    
93
    next = data[1] * 0.5;
94
    data[1] *= -1;
95

    
96
    for (i = n - 2; i >= 0; i -= 2) {
97
        float inr = data[i    ];
98
        float ini = data[i + 1];
99
        float c = COS(ctx, n, i);
100
        float s = SIN(ctx, n, i);
101

    
102
        data[i  ] = c * inr + s * ini;
103

    
104
        data[i+1] = next;
105

    
106
        next +=     s * inr - c * ini;
107
    }
108
}
109

    
110
void ff_dct_calc(DCTContext *s, FFTSample *data)
111
{
112
    s->dct_calc(s, data);
113
}
114

    
115
av_cold int ff_dct_init(DCTContext *s, int nbits, int inverse)
116
{
117
    int n = 1 << nbits;
118
    int i;
119

    
120
    s->nbits    = nbits;
121
    s->inverse  = inverse;
122

    
123
    ff_init_ff_cos_tabs(nbits+2);
124

    
125
    s->costab = ff_cos_tabs[nbits+2];
126

    
127
    s->csc2 = av_malloc(n/2 * sizeof(FFTSample));
128

    
129
    if (ff_rdft_init(&s->rdft, nbits, inverse) < 0) {
130
        av_free(s->csc2);
131
        return -1;
132
    }
133

    
134
    for (i = 0; i < n/2; i++)
135
        s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1)));
136

    
137
    if(inverse) {
138
        s->dct_calc = ff_dct_calc_III_c;
139
    } else
140
        s->dct_calc = ff_dct_calc_II_c;
141

    
142
    return 0;
143
}
144

    
145
av_cold void ff_dct_end(DCTContext *s)
146
{
147
    ff_rdft_end(&s->rdft);
148
    av_free(s->csc2);
149
}