Statistics
| Branch: | Revision:

ffmpeg / libavcodec / dct.c @ 89d7df7c

History | View | Annotate | Download (3.54 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_c(DCTContext *ctx, FFTSample *data)
41
{
42
    int n = 1 << ctx->nbits;
43
    int i;
44

    
45
    if (ctx->inverse) {
46
        float next = data[n - 1];
47
        float inv_n = 1.0f / n;
48

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

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

    
59
        data[1] = 2 * next;
60

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

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

    
68
            tmp1 += tmp2;
69
            data[i        ] = tmp1 + csc;
70
            data[n - i - 1] = tmp1 - csc;
71
        }
72
    } else {
73
        float next;
74
        for (i=0; i < n/2; i++) {
75
            float tmp1 = data[i        ];
76
            float tmp2 = data[n - i - 1];
77
            float s = SIN(ctx, n, 2*i + 1);
78

    
79
            s *= tmp1 - tmp2;
80
            tmp1 = (tmp1 + tmp2) * 0.5f;
81

    
82
            data[i    ] = tmp1 + s;
83
            data[n-i-1] = tmp1 - s;
84
        }
85

    
86
        ff_rdft_calc(&ctx->rdft, data);
87

    
88
        next = data[1] * 0.5;
89
        data[1] *= -1;
90

    
91
        for (i = n - 2; i >= 0; i -= 2) {
92
            float inr = data[i    ];
93
            float ini = data[i + 1];
94
            float c = COS(ctx, n, i);
95
            float s = SIN(ctx, n, i);
96

    
97
            data[i  ] = c * inr + s * ini;
98

    
99
            data[i+1] = next;
100

    
101
            next +=     s * inr - c * ini;
102
        }
103
    }
104
}
105

    
106
void ff_dct_calc(DCTContext *s, FFTSample *data)
107
{
108
    ff_dct_calc_c(s, data);
109
}
110

    
111
av_cold int ff_dct_init(DCTContext *s, int nbits, int inverse)
112
{
113
    int n = 1 << nbits;
114
    int i;
115

    
116
    s->nbits    = nbits;
117
    s->inverse  = inverse;
118

    
119
    ff_init_ff_cos_tabs(nbits+2);
120

    
121
    s->costab = ff_cos_tabs[nbits+2];
122

    
123
    s->csc2 = av_malloc(n/2 * sizeof(FFTSample));
124

    
125
    if (ff_rdft_init(&s->rdft, nbits, inverse) < 0) {
126
        av_free(s->csc2);
127
        return -1;
128
    }
129

    
130
    for (i = 0; i < n/2; i++)
131
        s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1)));
132

    
133
    return 0;
134
}
135

    
136
av_cold void ff_dct_end(DCTContext *s)
137
{
138
    ff_rdft_end(&s->rdft);
139
    av_free(s->csc2);
140
}