Statistics
| Branch: | Revision:

ffmpeg / libavcodec / dct.c @ 8305c76b

History | View | Annotate | Download (3.71 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
        for (i=0; i < n/2; i++) {
79
            float tmp1 = data[i        ];
80
            float tmp2 = data[n - i - 1];
81
            float s = SIN(ctx, n, 2*i + 1);
82

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

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

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

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

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

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

    
103
            data[i+1] = next;
104

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

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

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

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

    
122
    ff_init_ff_cos_tabs(nbits+2);
123

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

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

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

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

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

    
141
    return 0;
142
}
143

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