FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/vf_colordetect.h
Date: 2025-08-19 23:55:23
Exec Total Coverage
Lines: 79 79 100.0%
Functions: 8 8 100.0%
Branches: 50 60 83.3%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #ifndef AVFILTER_COLORDETECT_H
20 #define AVFILTER_COLORDETECT_H
21
22 #include <stddef.h>
23 #include <stdint.h>
24
25 #include <libavutil/avassert.h>
26 #include <libavutil/macros.h>
27 #include <libavutil/pixfmt.h>
28
29 enum FFAlphaDetect {
30 FF_ALPHA_NONE = -1,
31 FF_ALPHA_UNDETERMINED = 0,
32 FF_ALPHA_TRANSPARENT = 1 << 0, ///< alpha < alpha_max
33 FF_ALPHA_STRAIGHT = (1 << 1) | FF_ALPHA_TRANSPARENT, ///< alpha < pixel
34 /* No way to positively identify premultiplied alpha */
35 };
36
37 typedef struct FFColorDetectDSPContext {
38 /* Returns 1 if an out-of-range value was detected, 0 otherwise */
39 int (*detect_range)(const uint8_t *data, ptrdiff_t stride,
40 ptrdiff_t width, ptrdiff_t height,
41 int mpeg_min, int mpeg_max);
42
43 /* Returns an FFAlphaDetect enum value */
44 int (*detect_alpha)(const uint8_t *color, ptrdiff_t color_stride,
45 const uint8_t *alpha, ptrdiff_t alpha_stride,
46 ptrdiff_t width, ptrdiff_t height,
47 int alpha_max, int mpeg_range, int offset);
48 } FFColorDetectDSPContext;
49
50 void ff_color_detect_dsp_init(FFColorDetectDSPContext *dsp, int depth,
51 enum AVColorRange color_range);
52
53 void ff_color_detect_dsp_init_x86(FFColorDetectDSPContext *dsp, int depth,
54 enum AVColorRange color_range);
55
56 58 static inline int ff_detect_range_impl_c(const uint8_t *data, ptrdiff_t stride,
57 ptrdiff_t width, ptrdiff_t height,
58 uint8_t mpeg_min, uint8_t mpeg_max)
59 {
60
2/2
✓ Branch 0 taken 436 times.
✓ Branch 1 taken 44 times.
480 while (height--) {
61 436 uint8_t cond = 0;
62
2/2
✓ Branch 0 taken 97536 times.
✓ Branch 1 taken 436 times.
97972 for (int x = 0; x < width; x++) {
63 97536 const uint8_t val = data[x];
64
3/4
✓ Branch 0 taken 97522 times.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 97522 times.
97536 cond |= val < mpeg_min || val > mpeg_max;
65 }
66
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 422 times.
436 if (cond)
67 14 return 1;
68 422 data += stride;
69 }
70
71 44 return 0;
72 }
73
74 58 static inline int ff_detect_range_c(const uint8_t *data, ptrdiff_t stride,
75 ptrdiff_t width, ptrdiff_t height,
76 int mpeg_min, int mpeg_max)
77 {
78
2/4
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 58 times.
58 av_assume(mpeg_min >= 0 && mpeg_min <= UINT8_MAX);
79
2/4
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 58 times.
58 av_assume(mpeg_max >= 0 && mpeg_max <= UINT8_MAX);
80 58 return ff_detect_range_impl_c(data, stride, width, height, mpeg_min, mpeg_max);
81 }
82
83 62 static inline int ff_detect_range16_impl_c(const uint8_t *data, ptrdiff_t stride,
84 ptrdiff_t width, ptrdiff_t height,
85 uint16_t mpeg_min, uint16_t mpeg_max)
86 {
87
2/2
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 52 times.
552 while (height--) {
88 500 const uint16_t *data16 = (const uint16_t *) data;
89 500 uint8_t cond = 0;
90
2/2
✓ Branch 0 taken 50560 times.
✓ Branch 1 taken 500 times.
51060 for (int x = 0; x < width; x++) {
91 50560 const uint16_t val = data16[x];
92
3/4
✓ Branch 0 taken 50550 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 50550 times.
50560 cond |= val < mpeg_min || val > mpeg_max;
93 }
94
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 490 times.
500 if (cond)
95 10 return 1;
96 490 data += stride;
97 }
98
99 52 return 0;
100 }
101
102 62 static inline int ff_detect_range16_c(const uint8_t *data, ptrdiff_t stride,
103 ptrdiff_t width, ptrdiff_t height,
104 int mpeg_min, int mpeg_max)
105 {
106
2/4
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 62 times.
62 av_assume(mpeg_min >= 0 && mpeg_min <= UINT16_MAX);
107
2/4
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 62 times.
62 av_assume(mpeg_max >= 0 && mpeg_max <= UINT16_MAX);
108 62 return ff_detect_range16_impl_c(data, stride, width, height, mpeg_min, mpeg_max);
109 }
110
111 static inline int
112 52 ff_detect_alpha_full_c(const uint8_t *color, ptrdiff_t color_stride,
113 const uint8_t *alpha, ptrdiff_t alpha_stride,
114 ptrdiff_t width, ptrdiff_t height,
115 int alpha_max, int mpeg_range, int offset)
116 {
117 52 uint8_t transparent = 0;
118
2/2
✓ Branch 0 taken 427 times.
✓ Branch 1 taken 34 times.
461 while (height--) {
119 427 uint8_t straight = 0;
120
2/2
✓ Branch 0 taken 105216 times.
✓ Branch 1 taken 427 times.
105643 for (int x = 0; x < width; x++) {
121 105216 straight |= color[x] > alpha[x];
122 105216 transparent |= alpha[x] != alpha_max;
123 }
124
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 409 times.
427 if (straight)
125 18 return FF_ALPHA_STRAIGHT;
126 409 color += color_stride;
127 409 alpha += alpha_stride;
128 }
129 34 return transparent ? FF_ALPHA_TRANSPARENT : 0;
130 }
131
132 static inline int
133 52 ff_detect_alpha_limited_c(const uint8_t *color, ptrdiff_t color_stride,
134 const uint8_t *alpha, ptrdiff_t alpha_stride,
135 ptrdiff_t width, ptrdiff_t height,
136 int alpha_max, int mpeg_range, int offset)
137 {
138 52 uint8_t transparent = 0;
139
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 4 times.
116 while (height--) {
140 112 uint8_t straight = 0;
141
2/2
✓ Branch 0 taken 24576 times.
✓ Branch 1 taken 112 times.
24688 for (int x = 0; x < width; x++) {
142 24576 straight |= alpha_max * color[x] - offset > mpeg_range * alpha[x];
143 24576 transparent |= alpha[x] != alpha_max;
144 }
145
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 64 times.
112 if (straight)
146 48 return FF_ALPHA_STRAIGHT;
147 64 color += color_stride;
148 64 alpha += alpha_stride;
149 }
150 4 return transparent ? FF_ALPHA_TRANSPARENT : 0;
151 }
152
153 static inline int
154 52 ff_detect_alpha16_full_c(const uint8_t *color, ptrdiff_t color_stride,
155 const uint8_t *alpha, ptrdiff_t alpha_stride,
156 ptrdiff_t width, ptrdiff_t height,
157 int alpha_max, int mpeg_range, int offset)
158 {
159 52 uint8_t transparent = 0;
160
2/2
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 39 times.
489 while (height--) {
161 450 const uint16_t *color16 = (const uint16_t *) color;
162 450 const uint16_t *alpha16 = (const uint16_t *) alpha;
163 450 uint8_t straight = 0;
164
2/2
✓ Branch 0 taken 55552 times.
✓ Branch 1 taken 450 times.
56002 for (int x = 0; x < width; x++) {
165 55552 straight |= color16[x] > alpha16[x];
166 55552 transparent |= alpha16[x] != alpha_max;
167 }
168
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 437 times.
450 if (straight)
169 13 return FF_ALPHA_STRAIGHT;
170 437 color += color_stride;
171 437 alpha += alpha_stride;
172 }
173 39 return transparent ? FF_ALPHA_TRANSPARENT : 0;
174 }
175
176 static inline int
177 52 ff_detect_alpha16_limited_c(const uint8_t *color, ptrdiff_t color_stride,
178 const uint8_t *alpha, ptrdiff_t alpha_stride,
179 ptrdiff_t width, ptrdiff_t height,
180 int alpha_max, int mpeg_range, int offset)
181 {
182 52 uint8_t transparent = 0;
183
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 4 times.
116 while (height--) {
184 112 const uint16_t *color16 = (const uint16_t *) color;
185 112 const uint16_t *alpha16 = (const uint16_t *) alpha;
186
2/2
✓ Branch 0 taken 6192 times.
✓ Branch 1 taken 64 times.
6256 for (int x = 0; x < width; x++) {
187
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 6144 times.
6192 if ((int64_t) alpha_max * color16[x] - offset > (int64_t) mpeg_range * alpha16[x])
188 48 return FF_ALPHA_STRAIGHT;
189 6144 transparent |= alpha16[x] != alpha_max;
190 }
191 64 color += color_stride;
192 64 alpha += alpha_stride;
193 }
194 4 return transparent ? FF_ALPHA_TRANSPARENT : 0;
195 }
196
197 #endif /* AVFILTER_COLORDETECT_H */
198