Statistics
| Branch: | Revision:

ffmpeg / libavcodec / dct.c @ 8eec0027

History | View | Annotate | Download (5.15 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 Libav.
8
 *
9
 * Libav 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
 * Libav 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 Libav; 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
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 "dct.h"
33

    
34
#define DCT32_FLOAT
35
#include "dct32.c"
36

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

    
40
/* cos((M_PI * x / (2*n)) */
41
#define COS(s,n,x) (s->costab[x])
42

    
43
static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data)
44
{
45
    int n = 1 << ctx->nbits;
46
    int i;
47

    
48
    data[0] = 0;
49
    for(i = 1; i < n/2; i++) {
50
        float tmp1 = data[i    ];
51
        float tmp2 = data[n - i];
52
        float s = SIN(ctx, n, 2*i);
53

    
54
        s *= tmp1 + tmp2;
55
        tmp1 = (tmp1 - tmp2) * 0.5f;
56
        data[i    ] = s + tmp1;
57
        data[n - i] = s - tmp1;
58
    }
59

    
60
    data[n/2] *= 2;
61
    ctx->rdft.rdft_calc(&ctx->rdft, data);
62

    
63
    data[0] *= 0.5f;
64

    
65
    for(i = 1; i < n-2; i += 2) {
66
        data[i + 1] += data[i - 1];
67
        data[i    ] = -data[i + 2];
68
    }
69

    
70
    data[n-1] = 0;
71
}
72

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

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

    
85
        c *= tmp1 - tmp2;
86
        s *= tmp1 - tmp2;
87

    
88
        next += c;
89

    
90
        tmp1 = (tmp1 + tmp2) * 0.5f;
91
        data[i    ] = tmp1 - s;
92
        data[n - i] = tmp1 + s;
93
    }
94

    
95
    ctx->rdft.rdft_calc(&ctx->rdft, data);
96
    data[n] = data[1];
97
    data[1] = next;
98

    
99
    for(i = 3; i <= n; i += 2)
100
        data[i] = data[i - 2] - data[i];
101
}
102

    
103
static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data)
104
{
105
    int n = 1 << ctx->nbits;
106
    int i;
107

    
108
    float next = data[n - 1];
109
    float inv_n = 1.0f / n;
110

    
111
    for (i = n - 2; i >= 2; i -= 2) {
112
        float val1 = data[i    ];
113
        float val2 = data[i - 1] - data[i + 1];
114
        float c = COS(ctx, n, i);
115
        float s = SIN(ctx, n, i);
116

    
117
        data[i    ] = c * val1 + s * val2;
118
        data[i + 1] = s * val1 - c * val2;
119
    }
120

    
121
    data[1] = 2 * next;
122

    
123
    ctx->rdft.rdft_calc(&ctx->rdft, data);
124

    
125
    for (i = 0; i < n / 2; i++) {
126
        float tmp1 = data[i        ] * inv_n;
127
        float tmp2 = data[n - i - 1] * inv_n;
128
        float csc = ctx->csc2[i] * (tmp1 - tmp2);
129

    
130
        tmp1 += tmp2;
131
        data[i        ] = tmp1 + csc;
132
        data[n - i - 1] = tmp1 - csc;
133
    }
134
}
135

    
136
static void ff_dct_calc_II_c(DCTContext *ctx, FFTSample *data)
137
{
138
    int n = 1 << ctx->nbits;
139
    int i;
140
    float next;
141

    
142
    for (i=0; i < n/2; i++) {
143
        float tmp1 = data[i        ];
144
        float tmp2 = data[n - i - 1];
145
        float s = SIN(ctx, n, 2*i + 1);
146

    
147
        s *= tmp1 - tmp2;
148
        tmp1 = (tmp1 + tmp2) * 0.5f;
149

    
150
        data[i    ] = tmp1 + s;
151
        data[n-i-1] = tmp1 - s;
152
    }
153

    
154
    ctx->rdft.rdft_calc(&ctx->rdft, data);
155

    
156
    next = data[1] * 0.5;
157
    data[1] *= -1;
158

    
159
    for (i = n - 2; i >= 0; i -= 2) {
160
        float inr = data[i    ];
161
        float ini = data[i + 1];
162
        float c = COS(ctx, n, i);
163
        float s = SIN(ctx, n, i);
164

    
165
        data[i  ] = c * inr + s * ini;
166

    
167
        data[i+1] = next;
168

    
169
        next +=     s * inr - c * ini;
170
    }
171
}
172

    
173
static void dct32_func(DCTContext *ctx, FFTSample *data)
174
{
175
    ctx->dct32(data, data);
176
}
177

    
178
av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse)
179
{
180
    int n = 1 << nbits;
181
    int i;
182

    
183
    s->nbits    = nbits;
184
    s->inverse  = inverse;
185

    
186
    ff_init_ff_cos_tabs(nbits+2);
187

    
188
    s->costab = ff_cos_tabs[nbits+2];
189

    
190
    s->csc2 = av_malloc(n/2 * sizeof(FFTSample));
191

    
192
    if (ff_rdft_init(&s->rdft, nbits, inverse == DCT_III) < 0) {
193
        av_free(s->csc2);
194
        return -1;
195
    }
196

    
197
    for (i = 0; i < n/2; i++)
198
        s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1)));
199

    
200
    switch(inverse) {
201
    case DCT_I  : s->dct_calc = ff_dct_calc_I_c; break;
202
    case DCT_II : s->dct_calc = ff_dct_calc_II_c ; break;
203
    case DCT_III: s->dct_calc = ff_dct_calc_III_c; break;
204
    case DST_I  : s->dct_calc = ff_dst_calc_I_c; break;
205
    }
206

    
207
    if (inverse == DCT_II && nbits == 5)
208
        s->dct_calc = dct32_func;
209

    
210
    s->dct32 = dct32;
211
    if (HAVE_MMX)     ff_dct_init_mmx(s);
212

    
213
    return 0;
214
}
215

    
216
av_cold void ff_dct_end(DCTContext *s)
217
{
218
    ff_rdft_end(&s->rdft);
219
    av_free(s->csc2);
220
}