Directory: | ../../../ffmpeg/ |
---|---|
File: | src/libavcodec/dct.c |
Date: | 2022-07-04 19:11:22 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 111 | 114 | 97.4% |
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/error.h" | ||
34 | #include "libavutil/mathematics.h" | ||
35 | #include "libavutil/mem.h" | ||
36 | #include "dct.h" | ||
37 | #include "dct32.h" | ||
38 | |||
39 | /* sin((M_PI * x / (2 * n)) */ | ||
40 | #define SIN(s, n, x) (s->costab[(n) - (x)]) | ||
41 | |||
42 | /* cos((M_PI * x / (2 * n)) */ | ||
43 | #define COS(s, n, x) (s->costab[x]) | ||
44 | |||
45 | 5614 | static void dst_calc_I_c(DCTContext *ctx, FFTSample *data) | |
46 | { | ||
47 | 5614 | int n = 1 << ctx->nbits; | |
48 | int i; | ||
49 | |||
50 | 5614 | data[0] = 0; | |
51 |
2/2✓ Branch 0 taken 174034 times.
✓ Branch 1 taken 5614 times.
|
179648 | for (i = 1; i < n / 2; i++) { |
52 | 174034 | float tmp1 = data[i ]; | |
53 | 174034 | float tmp2 = data[n - i]; | |
54 | 174034 | float s = SIN(ctx, n, 2 * i); | |
55 | |||
56 | 174034 | s *= tmp1 + tmp2; | |
57 | 174034 | tmp1 = (tmp1 - tmp2) * 0.5f; | |
58 | 174034 | data[i] = s + tmp1; | |
59 | 174034 | data[n - i] = s - tmp1; | |
60 | } | ||
61 | |||
62 | 5614 | data[n / 2] *= 2; | |
63 | 5614 | ctx->rdft.rdft_calc(&ctx->rdft, data); | |
64 | |||
65 | 5614 | data[0] *= 0.5f; | |
66 | |||
67 |
2/2✓ Branch 0 taken 174034 times.
✓ Branch 1 taken 5614 times.
|
179648 | for (i = 1; i < n - 2; i += 2) { |
68 | 174034 | data[i + 1] += data[i - 1]; | |
69 | 174034 | data[i] = -data[i + 2]; | |
70 | } | ||
71 | |||
72 | 5614 | data[n - 1] = 0; | |
73 | 5614 | } | |
74 | |||
75 | 5614 | static void dct_calc_I_c(DCTContext *ctx, FFTSample *data) | |
76 | { | ||
77 | 5614 | int n = 1 << ctx->nbits; | |
78 | int i; | ||
79 | 5614 | float next = -0.5f * (data[0] - data[n]); | |
80 | |||
81 |
2/2✓ Branch 0 taken 179648 times.
✓ Branch 1 taken 5614 times.
|
185262 | for (i = 0; i < n / 2; i++) { |
82 | 179648 | float tmp1 = data[i]; | |
83 | 179648 | float tmp2 = data[n - i]; | |
84 | 179648 | float s = SIN(ctx, n, 2 * i); | |
85 | 179648 | float c = COS(ctx, n, 2 * i); | |
86 | |||
87 | 179648 | c *= tmp1 - tmp2; | |
88 | 179648 | s *= tmp1 - tmp2; | |
89 | |||
90 | 179648 | next += c; | |
91 | |||
92 | 179648 | tmp1 = (tmp1 + tmp2) * 0.5f; | |
93 | 179648 | data[i] = tmp1 - s; | |
94 | 179648 | data[n - i] = tmp1 + s; | |
95 | } | ||
96 | |||
97 | 5614 | ctx->rdft.rdft_calc(&ctx->rdft, data); | |
98 | 5614 | data[n] = data[1]; | |
99 | 5614 | data[1] = next; | |
100 | |||
101 |
2/2✓ Branch 0 taken 174034 times.
✓ Branch 1 taken 5614 times.
|
179648 | for (i = 3; i <= n; i += 2) |
102 | 174034 | data[i] = data[i - 2] - data[i]; | |
103 | 5614 | } | |
104 | |||
105 | 256 | static void dct_calc_III_c(DCTContext *ctx, FFTSample *data) | |
106 | { | ||
107 | 256 | int n = 1 << ctx->nbits; | |
108 | int i; | ||
109 | |||
110 | 256 | float next = data[n - 1]; | |
111 | 256 | float inv_n = 1.0f / n; | |
112 | |||
113 |
2/2✓ Branch 0 taken 129776 times.
✓ Branch 1 taken 256 times.
|
130032 | for (i = n - 2; i >= 2; i -= 2) { |
114 | 129776 | float val1 = data[i]; | |
115 | 129776 | float val2 = data[i - 1] - data[i + 1]; | |
116 | 129776 | float c = COS(ctx, n, i); | |
117 | 129776 | float s = SIN(ctx, n, i); | |
118 | |||
119 | 129776 | data[i] = c * val1 + s * val2; | |
120 | 129776 | data[i + 1] = s * val1 - c * val2; | |
121 | } | ||
122 | |||
123 | 256 | data[1] = 2 * next; | |
124 | |||
125 | 256 | ctx->rdft.rdft_calc(&ctx->rdft, data); | |
126 | |||
127 |
2/2✓ Branch 0 taken 130032 times.
✓ Branch 1 taken 256 times.
|
130288 | for (i = 0; i < n / 2; i++) { |
128 | 130032 | float tmp1 = data[i] * inv_n; | |
129 | 130032 | float tmp2 = data[n - i - 1] * inv_n; | |
130 | 130032 | float csc = ctx->csc2[i] * (tmp1 - tmp2); | |
131 | |||
132 | 130032 | tmp1 += tmp2; | |
133 | 130032 | data[i] = tmp1 + csc; | |
134 | 130032 | data[n - i - 1] = tmp1 - csc; | |
135 | } | ||
136 | 256 | } | |
137 | |||
138 | 16 | static void dct_calc_II_c(DCTContext *ctx, FFTSample *data) | |
139 | { | ||
140 | 16 | int n = 1 << ctx->nbits; | |
141 | int i; | ||
142 | float next; | ||
143 | |||
144 |
2/2✓ Branch 0 taken 8144 times.
✓ Branch 1 taken 16 times.
|
8160 | for (i = 0; i < n / 2; i++) { |
145 | 8144 | float tmp1 = data[i]; | |
146 | 8144 | float tmp2 = data[n - i - 1]; | |
147 | 8144 | float s = SIN(ctx, n, 2 * i + 1); | |
148 | |||
149 | 8144 | s *= tmp1 - tmp2; | |
150 | 8144 | tmp1 = (tmp1 + tmp2) * 0.5f; | |
151 | |||
152 | 8144 | data[i] = tmp1 + s; | |
153 | 8144 | data[n-i-1] = tmp1 - s; | |
154 | } | ||
155 | |||
156 | 16 | ctx->rdft.rdft_calc(&ctx->rdft, data); | |
157 | |||
158 | 16 | next = data[1] * 0.5; | |
159 | 16 | data[1] *= -1; | |
160 | |||
161 |
2/2✓ Branch 0 taken 8144 times.
✓ Branch 1 taken 16 times.
|
8160 | for (i = n - 2; i >= 0; i -= 2) { |
162 | 8144 | float inr = data[i ]; | |
163 | 8144 | float ini = data[i + 1]; | |
164 | 8144 | float c = COS(ctx, n, i); | |
165 | 8144 | float s = SIN(ctx, n, i); | |
166 | |||
167 | 8144 | data[i] = c * inr + s * ini; | |
168 | 8144 | data[i + 1] = next; | |
169 | |||
170 | 8144 | next += s * inr - c * ini; | |
171 | } | ||
172 | 16 | } | |
173 | |||
174 | 2 | static void dct32_func(DCTContext *ctx, FFTSample *data) | |
175 | { | ||
176 | 2 | ctx->dct32(data, data); | |
177 | 2 | } | |
178 | |||
179 | 215 | av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse) | |
180 | { | ||
181 | 215 | int n = 1 << nbits; | |
182 | int i; | ||
183 | int ret; | ||
184 | |||
185 | 215 | memset(s, 0, sizeof(*s)); | |
186 | |||
187 | 215 | s->nbits = nbits; | |
188 | 215 | s->inverse = inverse; | |
189 | |||
190 |
4/4✓ Branch 0 taken 177 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 161 times.
✓ Branch 3 taken 16 times.
|
215 | if (inverse == DCT_II && nbits == 5) { |
191 | 161 | s->dct_calc = dct32_func; | |
192 | } else { | ||
193 | 54 | ff_init_ff_cos_tabs(nbits + 2); | |
194 | |||
195 | 54 | s->costab = ff_cos_tabs[nbits + 2]; | |
196 | 54 | s->csc2 = av_malloc_array(n / 2, sizeof(FFTSample)); | |
197 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
|
54 | if (!s->csc2) |
198 | ✗ | return AVERROR(ENOMEM); | |
199 | |||
200 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
|
54 | if ((ret = ff_rdft_init(&s->rdft, nbits, inverse == DCT_III)) < 0) { |
201 | ✗ | av_freep(&s->csc2); | |
202 | ✗ | return ret; | |
203 | } | ||
204 | |||
205 |
2/2✓ Branch 0 taken 19904 times.
✓ Branch 1 taken 54 times.
|
19958 | for (i = 0; i < n / 2; i++) |
206 | 19904 | s->csc2[i] = 0.5 / sin((M_PI / (2 * n) * (2 * i + 1))); | |
207 | |||
208 |
4/5✓ Branch 0 taken 8 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
54 | switch (inverse) { |
209 | 8 | case DCT_I : s->dct_calc = dct_calc_I_c; break; | |
210 | 16 | case DCT_II : s->dct_calc = dct_calc_II_c; break; | |
211 | 22 | case DCT_III: s->dct_calc = dct_calc_III_c; break; | |
212 | 8 | case DST_I : s->dct_calc = dst_calc_I_c; break; | |
213 | } | ||
214 | } | ||
215 | |||
216 | 215 | s->dct32 = ff_dct32_float; | |
217 | #if ARCH_X86 | ||
218 | 215 | ff_dct_init_x86(s); | |
219 | #endif | ||
220 | |||
221 | 215 | return 0; | |
222 | } | ||
223 | |||
224 | 56 | av_cold void ff_dct_end(DCTContext *s) | |
225 | { | ||
226 | 56 | ff_rdft_end(&s->rdft); | |
227 | 56 | av_freep(&s->csc2); | |
228 | 56 | } | |
229 |