GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/dct.c Lines: 112 115 97.4 %
Date: 2019-11-18 18:00:01 Branches: 28 31 90.3 %

Line Branch Exec Source
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
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 <string.h>
32
33
#include "libavutil/mathematics.h"
34
#include "dct.h"
35
#include "dct32.h"
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
5614
static void dst_calc_I_c(DCTContext *ctx, FFTSample *data)
44
{
45
5614
    int n = 1 << ctx->nbits;
46
    int i;
47
48
5614
    data[0] = 0;
49
179648
    for (i = 1; i < n / 2; i++) {
50
174034
        float tmp1   = data[i    ];
51
174034
        float tmp2   = data[n - i];
52
174034
        float s      = SIN(ctx, n, 2 * i);
53
54
174034
        s           *= tmp1 + tmp2;
55
174034
        tmp1         = (tmp1 - tmp2) * 0.5f;
56
174034
        data[i]      = s + tmp1;
57
174034
        data[n - i]  = s - tmp1;
58
    }
59
60
5614
    data[n / 2] *= 2;
61
5614
    ctx->rdft.rdft_calc(&ctx->rdft, data);
62
63
5614
    data[0] *= 0.5f;
64
65
179648
    for (i = 1; i < n - 2; i += 2) {
66
174034
        data[i + 1] +=  data[i - 1];
67
174034
        data[i]      = -data[i + 2];
68
    }
69
70
5614
    data[n - 1] = 0;
71
5614
}
72
73
5614
static void dct_calc_I_c(DCTContext *ctx, FFTSample *data)
74
{
75
5614
    int n = 1 << ctx->nbits;
76
    int i;
77
5614
    float next = -0.5f * (data[0] - data[n]);
78
79
185262
    for (i = 0; i < n / 2; i++) {
80
179648
        float tmp1 = data[i];
81
179648
        float tmp2 = data[n - i];
82
179648
        float s    = SIN(ctx, n, 2 * i);
83
179648
        float c    = COS(ctx, n, 2 * i);
84
85
179648
        c *= tmp1 - tmp2;
86
179648
        s *= tmp1 - tmp2;
87
88
179648
        next += c;
89
90
179648
        tmp1        = (tmp1 + tmp2) * 0.5f;
91
179648
        data[i]     = tmp1 - s;
92
179648
        data[n - i] = tmp1 + s;
93
    }
94
95
5614
    ctx->rdft.rdft_calc(&ctx->rdft, data);
96
5614
    data[n] = data[1];
97
5614
    data[1] = next;
98
99
179648
    for (i = 3; i <= n; i += 2)
100
174034
        data[i] = data[i - 2] - data[i];
101
5614
}
102
103
256
static void dct_calc_III_c(DCTContext *ctx, FFTSample *data)
104
{
105
256
    int n = 1 << ctx->nbits;
106
    int i;
107
108
256
    float next  = data[n - 1];
109
256
    float inv_n = 1.0f / n;
110
111
130032
    for (i = n - 2; i >= 2; i -= 2) {
112
129776
        float val1 = data[i];
113
129776
        float val2 = data[i - 1] - data[i + 1];
114
129776
        float c    = COS(ctx, n, i);
115
129776
        float s    = SIN(ctx, n, i);
116
117
129776
        data[i]     = c * val1 + s * val2;
118
129776
        data[i + 1] = s * val1 - c * val2;
119
    }
120
121
256
    data[1] = 2 * next;
122
123
256
    ctx->rdft.rdft_calc(&ctx->rdft, data);
124
125
130288
    for (i = 0; i < n / 2; i++) {
126
130032
        float tmp1 = data[i]         * inv_n;
127
130032
        float tmp2 = data[n - i - 1] * inv_n;
128
130032
        float csc  = ctx->csc2[i] * (tmp1 - tmp2);
129
130
130032
        tmp1            += tmp2;
131
130032
        data[i]          = tmp1 + csc;
132
130032
        data[n - i - 1]  = tmp1 - csc;
133
    }
134
256
}
135
136
16
static void dct_calc_II_c(DCTContext *ctx, FFTSample *data)
137
{
138
16
    int n = 1 << ctx->nbits;
139
    int i;
140
    float next;
141
142
8160
    for (i = 0; i < n / 2; i++) {
143
8144
        float tmp1 = data[i];
144
8144
        float tmp2 = data[n - i - 1];
145
8144
        float s    = SIN(ctx, n, 2 * i + 1);
146
147
8144
        s    *= tmp1 - tmp2;
148
8144
        tmp1  = (tmp1 + tmp2) * 0.5f;
149
150
8144
        data[i]     = tmp1 + s;
151
8144
        data[n-i-1] = tmp1 - s;
152
    }
153
154
16
    ctx->rdft.rdft_calc(&ctx->rdft, data);
155
156
16
    next     = data[1] * 0.5;
157
16
    data[1] *= -1;
158
159
8160
    for (i = n - 2; i >= 0; i -= 2) {
160
8144
        float inr = data[i    ];
161
8144
        float ini = data[i + 1];
162
8144
        float c   = COS(ctx, n, i);
163
8144
        float s   = SIN(ctx, n, i);
164
165
8144
        data[i]     = c * inr + s * ini;
166
8144
        data[i + 1] = next;
167
168
8144
        next += s * inr - c * ini;
169
    }
170
16
}
171
172
2
static void dct32_func(DCTContext *ctx, FFTSample *data)
173
{
174
2
    ctx->dct32(data, data);
175
2
}
176
177
193
av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse)
178
{
179
193
    int n = 1 << nbits;
180
    int i;
181
    int ret;
182
183
193
    memset(s, 0, sizeof(*s));
184
185
193
    s->nbits   = nbits;
186
193
    s->inverse = inverse;
187
188

193
    if (inverse == DCT_II && nbits == 5) {
189
139
        s->dct_calc = dct32_func;
190
    } else {
191
54
        ff_init_ff_cos_tabs(nbits + 2);
192
193
54
        s->costab = ff_cos_tabs[nbits + 2];
194
54
        s->csc2   = av_malloc_array(n / 2, sizeof(FFTSample));
195
54
        if (!s->csc2)
196
            return AVERROR(ENOMEM);
197
198
54
        if ((ret = ff_rdft_init(&s->rdft, nbits, inverse == DCT_III)) < 0) {
199
            av_freep(&s->csc2);
200
            return ret;
201
        }
202
203
19958
        for (i = 0; i < n / 2; i++)
204
19904
            s->csc2[i] = 0.5 / sin((M_PI / (2 * n) * (2 * i + 1)));
205
206

54
        switch (inverse) {
207
8
        case DCT_I  : s->dct_calc = dct_calc_I_c;   break;
208
16
        case DCT_II : s->dct_calc = dct_calc_II_c;  break;
209
22
        case DCT_III: s->dct_calc = dct_calc_III_c; break;
210
8
        case DST_I  : s->dct_calc = dst_calc_I_c;   break;
211
        }
212
193
    }
213
214
193
    s->dct32 = ff_dct32_float;
215
    if (ARCH_X86)
216
193
        ff_dct_init_x86(s);
217
218
193
    return 0;
219
}
220
221
56
av_cold void ff_dct_end(DCTContext *s)
222
{
223
56
    ff_rdft_end(&s->rdft);
224
56
    av_freep(&s->csc2);
225
56
}