FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/simple_idct_template.c
Date: 2026-09-25 02:02:46
Exec Total Coverage
Lines: 121 121 100.0%
Functions: 22 28 78.6%
Branches: 44 44 100.0%

Line Branch Exec Source
1 /*
2 * Simple IDCT
3 *
4 * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file
25 * simpleidct in C.
26 */
27
28 /* Based upon some commented-out C code from mpeg2dec (idct_mmx.c
29 * written by Aaron Holtzman <aholtzma@ess.engr.uvic.ca>). */
30
31 #include "bit_depth_template.c"
32
33 #undef W1
34 #undef W2
35 #undef W3
36 #undef W4
37 #undef W5
38 #undef W6
39 #undef W7
40 #undef ROW_SHIFT
41 #undef COL_SHIFT
42 #undef DC_SHIFT
43 #undef MUL
44 #undef MAC
45
46 #if BIT_DEPTH == 8
47
48 #define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
49 #define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
50 #define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
51 #define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
52 #define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
53 #define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
54 #define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
55
56 #define ROW_SHIFT 11
57 #define COL_SHIFT 20
58 #define DC_SHIFT 3
59
60 #define MUL(a, b) MUL16(a, b)
61 #define MAC(a, b, c) MAC16(a, b, c)
62
63 #elif BIT_DEPTH == 10 || BIT_DEPTH == 12 || BIT_DEPTH == 16
64
65 # if BIT_DEPTH == 10 || BIT_DEPTH == 16
66 #define W1 22725 // 90901
67 #define W2 21407 // 85627
68 #define W3 19265 // 77062
69 #define W4 16384 // 65535
70 #define W5 12873 // 51491
71 #define W6 8867 // 35468
72 #define W7 4520 // 18081
73
74 # if BIT_DEPTH == 16
75 /* 16-bit output from 16-bit coefficients. The rows keep two more
76 * fractional bits than 16-bit intermediates could hold, and the columns
77 * are shifted by as little as the 32-bit sums of a 16-bit result allow */
78 # if IN_IDCT_DEPTH != 32
79 #error "The 16-bit iDCT needs 32-bit intermediates"
80 # endif
81 #define ROW_SHIFT 13
82 #define COL_SHIFT 15
83 #define DC_SHIFT 1
84 # elif defined(EXTRA_SHIFT)
85 #define ROW_SHIFT 13
86 #define COL_SHIFT 18
87 #define DC_SHIFT 1
88 # elif IN_IDCT_DEPTH == 32
89 #define ROW_SHIFT 13
90 #define COL_SHIFT 21
91 #define DC_SHIFT 2
92 # else
93 #define ROW_SHIFT 12
94 #define COL_SHIFT 19
95 #define DC_SHIFT 2
96 # endif
97
98 # else
99 #define W1 45451
100 #define W2 42813
101 #define W3 38531
102 #define W4 32767
103 #define W5 25746
104 #define W6 17734
105 #define W7 9041
106
107 #define ROW_SHIFT 16
108 #define COL_SHIFT 17
109 #define DC_SHIFT -1
110 # endif
111
112 #define MUL(a, b) ((int)((SUINT)(a) * (b)))
113 #define MAC(a, b, c) ((a) += (SUINT)(b) * (c))
114
115 #else
116
117 #error "Unsupported bitdepth"
118
119 #endif
120
121 #ifdef EXTRA_SHIFT
122 17518080 static inline void FUNC(idctRowCondDC_extrashift)(int16_t *row, int extra_shift)
123 #else
124 1502737472 static inline void FUNC6(idctRowCondDC)(idctin *row, int extra_shift)
125 #endif
126 {
127 SUINT a0, a1, a2, a3, b0, b1, b2, b3;
128
129 // TODO: Add DC-only support for int32_t input
130 #if IN_IDCT_DEPTH == 16
131 #if HAVE_FAST_64BIT
132 #define ROW0_MASK (0xffffULL << 48 * HAVE_BIGENDIAN)
133
2/2
✓ Branch 0 taken 558437550 times.
✓ Branch 1 taken 210406586 times.
1520170176 if (((AV_RN64A(row) & ~ROW0_MASK) | AV_RN64A(row+4)) == 0) {
134 uint64_t temp;
135
2/2
✓ Branch 0 taken 540935880 times.
✓ Branch 1 taken 17501670 times.
1107935740 if (DC_SHIFT - extra_shift >= 0) {
136 1081871760 temp = (row[0] * (1 << (DC_SHIFT - extra_shift))) & 0xffff;
137 } else {
138 26063980 temp = ((row[0] + (1<<(extra_shift - DC_SHIFT-1))) >> (extra_shift - DC_SHIFT)) & 0xffff;
139 }
140 1107935740 temp += temp * (1 << 16);
141 1107935740 temp += temp * ((uint64_t) 1 << 32);
142 1107935740 AV_WN64A(row, temp);
143 1107935740 AV_WN64A(row + 4, temp);
144 1107935740 return;
145 }
146 #else
147 if (!(AV_RN32A(row+2) |
148 AV_RN32A(row+4) |
149 AV_RN32A(row+6) |
150 row[1])) {
151 uint32_t temp;
152 if (DC_SHIFT - extra_shift >= 0) {
153 temp = (row[0] * (1 << (DC_SHIFT - extra_shift))) & 0xffff;
154 } else {
155 temp = ((row[0] + (1<<(extra_shift - DC_SHIFT-1))) >> (extra_shift - DC_SHIFT)) & 0xffff;
156 }
157 temp += temp * (1 << 16);
158 AV_WN32A(row, temp);
159 AV_WN32A(row+2, temp);
160 AV_WN32A(row+4, temp);
161 AV_WN32A(row+6, temp);
162 return;
163 }
164 #endif
165 #endif
166
167 412319812 a0 = ((SUINT)W4 * row[0]) + (1 << (ROW_SHIFT + extra_shift - 1));
168 412319812 a1 = a0;
169 412319812 a2 = a0;
170 412319812 a3 = a0;
171
172 412319812 a0 += (SUINT)W2 * row[2];
173 412319812 a1 += (SUINT)W6 * row[2];
174 412319812 a2 -= (SUINT)W6 * row[2];
175 412319812 a3 -= (SUINT)W2 * row[2];
176
177 412319812 b0 = MUL(W1, row[1]);
178 412319812 MAC(b0, W3, row[3]);
179 412319812 b1 = MUL(W3, row[1]);
180 412319812 MAC(b1, -W7, row[3]);
181 412319812 b2 = MUL(W5, row[1]);
182 412319812 MAC(b2, -W1, row[3]);
183 412319812 b3 = MUL(W7, row[1]);
184 412319812 MAC(b3, -W5, row[3]);
185
186 #if IN_IDCT_DEPTH == 32
187
2/2
✓ Branch 0 taken 4223 times.
✓ Branch 1 taken 38465 times.
85376 if (AV_RN64A(row + 4) | AV_RN64A(row + 6)) {
188 #else
189
2/2
✓ Branch 0 taken 89309047 times.
✓ Branch 1 taken 121097539 times.
412234436 if (AV_RN64A(row + 4)) {
190 #endif
191 172070400 a0 += (SUINT) W4*row[4] + (SUINT)W6*row[6];
192 172070400 a1 += (SUINT)- W4*row[4] - (SUINT)W2*row[6];
193 172070400 a2 += (SUINT)- W4*row[4] + (SUINT)W2*row[6];
194 172070400 a3 += (SUINT) W4*row[4] - (SUINT)W6*row[6];
195
196 172070400 MAC(b0, W5, row[5]);
197 172070400 MAC(b0, W7, row[7]);
198
199 172070400 MAC(b1, -W1, row[5]);
200 172070400 MAC(b1, -W5, row[7]);
201
202 172070400 MAC(b2, W7, row[5]);
203 172070400 MAC(b2, W3, row[7]);
204
205 172070400 MAC(b3, W3, row[5]);
206 172070400 MAC(b3, -W1, row[7]);
207 }
208
209 412319812 row[0] = (int)(a0 + b0) >> (ROW_SHIFT + extra_shift);
210 412319812 row[7] = (int)(a0 - b0) >> (ROW_SHIFT + extra_shift);
211 412319812 row[1] = (int)(a1 + b1) >> (ROW_SHIFT + extra_shift);
212 412319812 row[6] = (int)(a1 - b1) >> (ROW_SHIFT + extra_shift);
213 412319812 row[2] = (int)(a2 + b2) >> (ROW_SHIFT + extra_shift);
214 412319812 row[5] = (int)(a2 - b2) >> (ROW_SHIFT + extra_shift);
215 412319812 row[3] = (int)(a3 + b3) >> (ROW_SHIFT + extra_shift);
216 412319812 row[4] = (int)(a3 - b3) >> (ROW_SHIFT + extra_shift);
217 85376 }
218
219 #define IDCT_COLS do { \
220 a0 = (SUINT)W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4)); \
221 a1 = a0; \
222 a2 = a0; \
223 a3 = a0; \
224 \
225 a0 += (SUINT) W2*col[8*2]; \
226 a1 += (SUINT) W6*col[8*2]; \
227 a2 += (SUINT)-W6*col[8*2]; \
228 a3 += (SUINT)-W2*col[8*2]; \
229 \
230 b0 = MUL(W1, col[8*1]); \
231 b1 = MUL(W3, col[8*1]); \
232 b2 = MUL(W5, col[8*1]); \
233 b3 = MUL(W7, col[8*1]); \
234 \
235 MAC(b0, W3, col[8*3]); \
236 MAC(b1, -W7, col[8*3]); \
237 MAC(b2, -W1, col[8*3]); \
238 MAC(b3, -W5, col[8*3]); \
239 \
240 if (col[8*4]) { \
241 a0 += (SUINT) W4*col[8*4]; \
242 a1 += (SUINT)-W4*col[8*4]; \
243 a2 += (SUINT)-W4*col[8*4]; \
244 a3 += (SUINT) W4*col[8*4]; \
245 } \
246 \
247 if (col[8*5]) { \
248 MAC(b0, W5, col[8*5]); \
249 MAC(b1, -W1, col[8*5]); \
250 MAC(b2, W7, col[8*5]); \
251 MAC(b3, W3, col[8*5]); \
252 } \
253 \
254 if (col[8*6]) { \
255 a0 += (SUINT) W6*col[8*6]; \
256 a1 += (SUINT)-W2*col[8*6]; \
257 a2 += (SUINT) W2*col[8*6]; \
258 a3 += (SUINT)-W6*col[8*6]; \
259 } \
260 \
261 if (col[8*7]) { \
262 MAC(b0, W7, col[8*7]); \
263 MAC(b1, -W5, col[8*7]); \
264 MAC(b2, W3, col[8*7]); \
265 MAC(b3, -W1, col[8*7]); \
266 } \
267 } while (0)
268
269 #ifdef EXTRA_SHIFT
270 17518080 static inline void FUNC(idctSparseCol_extrashift)(int16_t *col)
271 #else
272 97764976 static inline void FUNC6(idctSparseCol)(idctin *col)
273 #endif
274 {
275 unsigned a0, a1, a2, a3, b0, b1, b2, b3;
276
277
8/8
✓ Branch 0 taken 25348607 times.
✓ Branch 1 taken 41051969 times.
✓ Branch 2 taken 23422485 times.
✓ Branch 3 taken 42978091 times.
✓ Branch 4 taken 18648110 times.
✓ Branch 5 taken 47752466 times.
✓ Branch 6 taken 16376875 times.
✓ Branch 7 taken 50023701 times.
115283056 IDCT_COLS;
278
279 115283056 col[0 ] = ((int)(a0 + b0) >> COL_SHIFT);
280 115283056 col[8 ] = ((int)(a1 + b1) >> COL_SHIFT);
281 115283056 col[16] = ((int)(a2 + b2) >> COL_SHIFT);
282 115283056 col[24] = ((int)(a3 + b3) >> COL_SHIFT);
283 115283056 col[32] = ((int)(a3 - b3) >> COL_SHIFT);
284 115283056 col[40] = ((int)(a2 - b2) >> COL_SHIFT);
285 115283056 col[48] = ((int)(a1 - b1) >> COL_SHIFT);
286 115283056 col[56] = ((int)(a0 - b0) >> COL_SHIFT);
287 115283056 }
288
289 #ifndef PRORES_ONLY
290 #ifndef EXTRA_SHIFT
291 1122067120 static inline void FUNC6(idctSparseColPut)(pixel *dest, ptrdiff_t line_size,
292 idctin *col)
293 {
294 SUINT a0, a1, a2, a3, b0, b1, b2, b3;
295
296
8/8
✓ Branch 0 taken 119429396 times.
✓ Branch 1 taken 441604164 times.
✓ Branch 2 taken 113049730 times.
✓ Branch 3 taken 447983830 times.
✓ Branch 4 taken 64621274 times.
✓ Branch 5 taken 496412286 times.
✓ Branch 6 taken 75478822 times.
✓ Branch 7 taken 485554738 times.
1122067120 IDCT_COLS;
297
298 1122067120 dest[0] = av_clip_pixel((int)(a0 + b0) >> COL_SHIFT);
299 1122067120 dest += line_size;
300 1122067120 dest[0] = av_clip_pixel((int)(a1 + b1) >> COL_SHIFT);
301 1122067120 dest += line_size;
302 1122067120 dest[0] = av_clip_pixel((int)(a2 + b2) >> COL_SHIFT);
303 1122067120 dest += line_size;
304 1122067120 dest[0] = av_clip_pixel((int)(a3 + b3) >> COL_SHIFT);
305 1122067120 dest += line_size;
306 1122067120 dest[0] = av_clip_pixel((int)(a3 - b3) >> COL_SHIFT);
307 1122067120 dest += line_size;
308 1122067120 dest[0] = av_clip_pixel((int)(a2 - b2) >> COL_SHIFT);
309 1122067120 dest += line_size;
310 1122067120 dest[0] = av_clip_pixel((int)(a1 - b1) >> COL_SHIFT);
311 1122067120 dest += line_size;
312 1122067120 dest[0] = av_clip_pixel((int)(a0 - b0) >> COL_SHIFT);
313 1122067120 }
314
315 282440304 static inline void FUNC6(idctSparseColAdd)(pixel *dest, ptrdiff_t line_size,
316 idctin *col)
317 {
318 unsigned a0, a1, a2, a3, b0, b1, b2, b3;
319
320
8/8
✓ Branch 0 taken 40562093 times.
✓ Branch 1 taken 100658059 times.
✓ Branch 2 taken 34007617 times.
✓ Branch 3 taken 107212535 times.
✓ Branch 4 taken 28115279 times.
✓ Branch 5 taken 113104873 times.
✓ Branch 6 taken 64730202 times.
✓ Branch 7 taken 76489950 times.
282440304 IDCT_COLS;
321
322 282440304 dest[0] = av_clip_pixel(dest[0] + ((int)(a0 + b0) >> COL_SHIFT));
323 282440304 dest += line_size;
324 282440304 dest[0] = av_clip_pixel(dest[0] + ((int)(a1 + b1) >> COL_SHIFT));
325 282440304 dest += line_size;
326 282440304 dest[0] = av_clip_pixel(dest[0] + ((int)(a2 + b2) >> COL_SHIFT));
327 282440304 dest += line_size;
328 282440304 dest[0] = av_clip_pixel(dest[0] + ((int)(a3 + b3) >> COL_SHIFT));
329 282440304 dest += line_size;
330 282440304 dest[0] = av_clip_pixel(dest[0] + ((int)(a3 - b3) >> COL_SHIFT));
331 282440304 dest += line_size;
332 282440304 dest[0] = av_clip_pixel(dest[0] + ((int)(a2 - b2) >> COL_SHIFT));
333 282440304 dest += line_size;
334 282440304 dest[0] = av_clip_pixel(dest[0] + ((int)(a1 - b1) >> COL_SHIFT));
335 282440304 dest += line_size;
336 282440304 dest[0] = av_clip_pixel(dest[0] + ((int)(a0 - b0) >> COL_SHIFT));
337 282440304 }
338
339 140258390 void FUNC6(ff_simple_idct_put)(uint8_t *dest_, ptrdiff_t line_size, int16_t *block_)
340 {
341 140258390 idctin *block = (idctin *)block_;
342 140258390 pixel *dest = (pixel *)dest_;
343 int i;
344
345 140258390 line_size /= sizeof(pixel);
346
347
2/2
✓ Branch 0 taken 561033560 times.
✓ Branch 1 taken 70129195 times.
1262325510 for (i = 0; i < 8; i++)
348 1122067120 FUNC6(idctRowCondDC)(block + i*8, 0);
349
350
2/2
✓ Branch 0 taken 561033560 times.
✓ Branch 1 taken 70129195 times.
1262325510 for (i = 0; i < 8; i++)
351 1122067120 FUNC6(idctSparseColPut)(dest + i, line_size, block + i);
352 140258390 }
353
354 #if IN_IDCT_DEPTH == 16
355 35275082 void FUNC6(ff_simple_idct_add)(uint8_t *dest_, ptrdiff_t line_size, int16_t *block)
356 {
357 35275082 pixel *dest = (pixel *)dest_;
358 int i;
359
360 35275082 line_size /= sizeof(pixel);
361
362
2/2
✓ Branch 0 taken 141100328 times.
✓ Branch 1 taken 17637541 times.
317475738 for (i = 0; i < 8; i++)
363 282200656 FUNC6(idctRowCondDC)(block + i*8, 0);
364
365
2/2
✓ Branch 0 taken 141100328 times.
✓ Branch 1 taken 17637541 times.
317475738 for (i = 0; i < 8; i++)
366 282200656 FUNC6(idctSparseColAdd)(dest + i, line_size, block + i);
367 35275082 }
368
369 8169176 void FUNC6(ff_simple_idct)(int16_t *block)
370 {
371 int i;
372
373
2/2
✓ Branch 0 taken 32676704 times.
✓ Branch 1 taken 4084588 times.
73522584 for (i = 0; i < 8; i++)
374 65353408 FUNC6(idctRowCondDC)(block + i*8, 0);
375
376
2/2
✓ Branch 0 taken 32676704 times.
✓ Branch 1 taken 4084588 times.
73522584 for (i = 0; i < 8; i++)
377 65353408 FUNC6(idctSparseCol)(block + i);
378 8169176 }
379 #endif
380 #endif
381 #endif /* PRORES_ONLY */
382