Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Copyright 2011 Stefano Sabatini <stefano.sabatini-lala poste it> | ||
3 | * Copyright 2012 Nicolas George <nicolas.george normalesup org> | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #include <string.h> | ||
23 | |||
24 | #include "libavutil/avassert.h" | ||
25 | #include "libavutil/avutil.h" | ||
26 | #include "libavutil/csp.h" | ||
27 | #include "libavutil/intreadwrite.h" | ||
28 | #include "libavutil/pixdesc.h" | ||
29 | #include "colorspace.h" | ||
30 | #include "drawutils.h" | ||
31 | #include "formats.h" | ||
32 | |||
33 | enum { RED = 0, GREEN, BLUE, ALPHA }; | ||
34 | |||
35 | 108 | int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt) | |
36 | { | ||
37 | 108 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); | |
38 |
2/2✓ Branch 0 taken 46 times.
✓ Branch 1 taken 62 times.
|
108 | if (!(desc->flags & AV_PIX_FMT_FLAG_RGB)) |
39 | 46 | return AVERROR(EINVAL); | |
40 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) |
41 | ✗ | return AVERROR(EINVAL); | |
42 |
3/4✓ Branch 0 taken 26 times.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 62 times.
|
62 | av_assert0(desc->nb_components == 3 + !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)); |
43 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 39 times.
|
62 | if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) { |
44 | 23 | rgba_map[RED] = desc->comp[0].plane; | |
45 | 23 | rgba_map[GREEN] = desc->comp[1].plane; | |
46 | 23 | rgba_map[BLUE] = desc->comp[2].plane; | |
47 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 11 times.
|
23 | rgba_map[ALPHA] = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? desc->comp[3].plane : 3; |
48 | } else { | ||
49 | 39 | int had0 = 0; | |
50 | 39 | unsigned depthb = 0; | |
51 | unsigned i; | ||
52 |
2/2✓ Branch 0 taken 131 times.
✓ Branch 1 taken 39 times.
|
170 | for (i = 0; i < desc->nb_components; i++) { |
53 | /* all components must have same depth in bytes */ | ||
54 | 131 | unsigned db = (desc->comp[i].depth + 7) / 8; | |
55 | 131 | unsigned pos = desc->comp[i].offset / db; | |
56 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 131 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
131 | if (depthb && (depthb != db)) |
57 | ✗ | return AVERROR(ENOSYS); | |
58 | |||
59 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 131 times.
|
131 | if (desc->comp[i].offset % db) |
60 | ✗ | return AVERROR(ENOSYS); | |
61 | |||
62 | 131 | had0 |= pos == 0; | |
63 | 131 | rgba_map[i] = pos; | |
64 | } | ||
65 | |||
66 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 14 times.
|
39 | if (desc->nb_components == 3) |
67 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | rgba_map[ALPHA] = had0 ? 3 : 0; |
68 | } | ||
69 | |||
70 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | av_assert0(rgba_map[RED] != rgba_map[GREEN]); |
71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | av_assert0(rgba_map[GREEN] != rgba_map[BLUE]); |
72 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | av_assert0(rgba_map[BLUE] != rgba_map[RED]); |
73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | av_assert0(rgba_map[RED] != rgba_map[ALPHA]); |
74 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | av_assert0(rgba_map[GREEN] != rgba_map[ALPHA]); |
75 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | av_assert0(rgba_map[BLUE] != rgba_map[ALPHA]); |
76 | |||
77 | 62 | return 0; | |
78 | } | ||
79 | |||
80 | 36698 | int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp, | |
81 | enum AVColorRange range, unsigned flags) | ||
82 | { | ||
83 | 36698 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); | |
84 | 36698 | const AVLumaCoefficients *luma = NULL; | |
85 | const AVComponentDescriptor *c; | ||
86 | 36698 | unsigned i, nb_planes = 0; | |
87 | 36698 | int pixelstep[MAX_PLANES] = { 0 }; | |
88 | 36698 | int depthb = 0; | |
89 | |||
90 |
2/4✓ Branch 0 taken 36698 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36698 times.
|
36698 | if (!desc || !desc->name) |
91 | ✗ | return AVERROR(EINVAL); | |
92 |
2/2✓ Branch 0 taken 12960 times.
✓ Branch 1 taken 23738 times.
|
36698 | if (desc->flags & AV_PIX_FMT_FLAG_BE) |
93 | 12960 | return AVERROR(ENOSYS); | |
94 |
2/2✓ Branch 0 taken 5440 times.
✓ Branch 1 taken 18298 times.
|
23738 | if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA)) |
95 | 5440 | return AVERROR(ENOSYS); | |
96 |
2/2✓ Branch 0 taken 18252 times.
✓ Branch 1 taken 46 times.
|
18298 | if (csp == AVCOL_SPC_UNSPECIFIED) |
97 |
2/2✓ Branch 0 taken 5920 times.
✓ Branch 1 taken 12332 times.
|
18252 | csp = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? AVCOL_SPC_RGB : AVCOL_SPC_SMPTE170M; |
98 |
3/4✓ Branch 0 taken 12332 times.
✓ Branch 1 taken 5966 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12332 times.
|
18298 | if (!(desc->flags & AV_PIX_FMT_FLAG_RGB) && !(luma = av_csp_luma_coeffs_from_avcsp(csp))) |
99 | ✗ | return AVERROR(EINVAL); | |
100 |
2/2✓ Branch 0 taken 18127 times.
✓ Branch 1 taken 171 times.
|
18298 | if (range == AVCOL_RANGE_UNSPECIFIED) |
101 |
4/4✓ Branch 0 taken 17807 times.
✓ Branch 1 taken 160 times.
✓ Branch 2 taken 17647 times.
✓ Branch 3 taken 160 times.
|
36094 | range = (format == AV_PIX_FMT_YUVJ420P || format == AV_PIX_FMT_YUVJ422P || |
102 |
4/4✓ Branch 0 taken 17487 times.
✓ Branch 1 taken 160 times.
✓ Branch 2 taken 17327 times.
✓ Branch 3 taken 160 times.
|
17647 | format == AV_PIX_FMT_YUVJ444P || format == AV_PIX_FMT_YUVJ411P || |
103 |
2/2✓ Branch 0 taken 5920 times.
✓ Branch 1 taken 11407 times.
|
17327 | format == AV_PIX_FMT_YUVJ440P || csp == AVCOL_SPC_RGB) |
104 |
2/2✓ Branch 0 taken 17967 times.
✓ Branch 1 taken 160 times.
|
36094 | ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; |
105 |
3/4✓ Branch 0 taken 11511 times.
✓ Branch 1 taken 6787 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11511 times.
|
18298 | if (range != AVCOL_RANGE_JPEG && range != AVCOL_RANGE_MPEG) |
106 | ✗ | return AVERROR(EINVAL); | |
107 |
2/2✓ Branch 0 taken 50292 times.
✓ Branch 1 taken 14618 times.
|
64910 | for (i = 0; i < desc->nb_components; i++) { |
108 | int db; | ||
109 | 50292 | c = &desc->comp[i]; | |
110 | /* for now, only 8-16 bits formats */ | ||
111 |
3/4✓ Branch 0 taken 48692 times.
✓ Branch 1 taken 1600 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48692 times.
|
50292 | if (c->depth < 8 || c->depth > 16) |
112 | 1600 | return AVERROR(ENOSYS); | |
113 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48692 times.
|
48692 | if (c->plane >= MAX_PLANES) |
114 | ✗ | return AVERROR(ENOSYS); | |
115 | /* data must either be in the high or low bits, never middle */ | ||
116 |
4/4✓ Branch 0 taken 4178 times.
✓ Branch 1 taken 44514 times.
✓ Branch 2 taken 480 times.
✓ Branch 3 taken 3698 times.
|
48692 | if (c->shift && ((c->shift + c->depth) & 0x7)) |
117 | 480 | return AVERROR(ENOSYS); | |
118 | /* mixed >8 and <=8 depth */ | ||
119 | 48212 | db = (c->depth + 7) / 8; | |
120 |
3/4✓ Branch 0 taken 31834 times.
✓ Branch 1 taken 16378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31834 times.
|
48212 | if (depthb && (depthb != db)) |
121 | ✗ | return AVERROR(ENOSYS); | |
122 | 48212 | depthb = db; | |
123 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48212 times.
|
48212 | if (db * (c->offset + 1) > 16) |
124 | ✗ | return AVERROR(ENOSYS); | |
125 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48212 times.
|
48212 | if (c->offset % db) |
126 | ✗ | return AVERROR(ENOSYS); | |
127 | /* strange interleaving */ | ||
128 |
2/2✓ Branch 0 taken 9055 times.
✓ Branch 1 taken 39157 times.
|
48212 | if (pixelstep[c->plane] != 0 && |
129 |
2/2✓ Branch 0 taken 960 times.
✓ Branch 1 taken 8095 times.
|
9055 | pixelstep[c->plane] != c->step) |
130 | 960 | return AVERROR(ENOSYS); | |
131 | 47252 | pixelstep[c->plane] = c->step; | |
132 |
2/2✓ Branch 0 taken 640 times.
✓ Branch 1 taken 46612 times.
|
47252 | if (pixelstep[c->plane] >= 8) |
133 | 640 | return AVERROR(ENOSYS); | |
134 | 46612 | nb_planes = FFMAX(nb_planes, c->plane + 1); | |
135 | } | ||
136 | 14618 | memset(draw, 0, sizeof(*draw)); | |
137 | 14618 | draw->desc = desc; | |
138 | 14618 | draw->format = format; | |
139 | 14618 | draw->nb_planes = nb_planes; | |
140 | 14618 | draw->range = range; | |
141 | 14618 | draw->csp = csp; | |
142 | 14618 | draw->flags = flags; | |
143 |
2/2✓ Branch 0 taken 10892 times.
✓ Branch 1 taken 3726 times.
|
14618 | if (luma) |
144 | 10892 | ff_fill_rgb2yuv_table(luma, draw->rgb2yuv); | |
145 | 14618 | memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep)); | |
146 | 14618 | draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w; | |
147 | 14618 | draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h; | |
148 | 14618 | return 0; | |
149 | } | ||
150 | |||
151 | 36480 | int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) | |
152 | { | ||
153 | 36480 | return ff_draw_init2(draw, format, AVCOL_SPC_UNSPECIFIED, AVCOL_RANGE_UNSPECIFIED, flags); | |
154 | } | ||
155 | |||
156 | 207167 | void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4]) | |
157 | { | ||
158 | unsigned i; | ||
159 | double yuvad[4]; | ||
160 | double rgbad[4]; | ||
161 | 207167 | const AVPixFmtDescriptor *desc = draw->desc; | |
162 | |||
163 |
1/2✓ Branch 0 taken 207167 times.
✗ Branch 1 not taken.
|
207167 | if (rgba != color->rgba) |
164 | 207167 | memcpy(color->rgba, rgba, sizeof(color->rgba)); | |
165 | |||
166 | 207167 | memset(color->comp, 0, sizeof(color->comp)); | |
167 | |||
168 |
2/2✓ Branch 0 taken 828668 times.
✓ Branch 1 taken 207167 times.
|
1035835 | for (int i = 0; i < 4; i++) |
169 | 828668 | rgbad[i] = color->rgba[i] / 255.; | |
170 | |||
171 |
2/2✓ Branch 0 taken 53004 times.
✓ Branch 1 taken 154163 times.
|
207167 | if (draw->desc->flags & AV_PIX_FMT_FLAG_RGB) |
172 | 53004 | memcpy(yuvad, rgbad, sizeof(double) * 3); | |
173 | else | ||
174 | 154163 | ff_matrix_mul_3x3_vec(yuvad, rgbad, draw->rgb2yuv); | |
175 | |||
176 | 207167 | yuvad[3] = rgbad[3]; | |
177 | |||
178 |
2/2✓ Branch 0 taken 621501 times.
✓ Branch 1 taken 207167 times.
|
828668 | for (int i = 0; i < 3; i++) { |
179 |
4/4✓ Branch 0 taken 462489 times.
✓ Branch 1 taken 159012 times.
✓ Branch 2 taken 308326 times.
✓ Branch 3 taken 154163 times.
|
621501 | int chroma = (!(draw->desc->flags & AV_PIX_FMT_FLAG_RGB) && i > 0); |
180 |
2/2✓ Branch 0 taken 462426 times.
✓ Branch 1 taken 159075 times.
|
621501 | if (draw->range == AVCOL_RANGE_MPEG) { |
181 |
2/2✓ Branch 0 taken 308284 times.
✓ Branch 1 taken 154142 times.
|
462426 | yuvad[i] *= (chroma ? 224. : 219.) / 255.; |
182 |
2/2✓ Branch 0 taken 308284 times.
✓ Branch 1 taken 154142 times.
|
462426 | yuvad[i] += (chroma ? 128. : 16.) / 255.; |
183 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 159033 times.
|
159075 | } else if (chroma) { |
184 | 42 | yuvad[i] += 0.5; | |
185 | } | ||
186 | } | ||
187 | |||
188 | // Ensure we place the alpha appropriately for gray formats | ||
189 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 207157 times.
|
207167 | if (desc->nb_components <= 2) |
190 | 10 | yuvad[1] = yuvad[3]; | |
191 | |||
192 |
2/2✓ Branch 0 taken 647510 times.
✓ Branch 1 taken 207167 times.
|
854677 | for (i = 0; i < desc->nb_components; i++) { |
193 | 647510 | unsigned val = yuvad[i] * ((1 << (draw->desc->comp[i].depth + draw->desc->comp[i].shift)) - 1) + 0.5; | |
194 |
2/2✓ Branch 0 taken 59662 times.
✓ Branch 1 taken 587848 times.
|
647510 | if (desc->comp[i].depth > 8) |
195 | 59662 | color->comp[desc->comp[i].plane].u16[desc->comp[i].offset / 2] = val; | |
196 | else | ||
197 | 587848 | color->comp[desc->comp[i].plane].u8[desc->comp[i].offset] = val; | |
198 | } | ||
199 | 207167 | } | |
200 | |||
201 | 602756 | static uint8_t *pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[], | |
202 | int plane, int x, int y) | ||
203 | { | ||
204 | 602756 | return data[plane] + | |
205 | 1205512 | (y >> draw->vsub[plane]) * linesize[plane] + | |
206 | 602756 | (x >> draw->hsub[plane]) * draw->pixelstep[plane]; | |
207 | } | ||
208 | |||
209 | 37 | void ff_copy_rectangle2(FFDrawContext *draw, | |
210 | uint8_t *dst[], int dst_linesize[], | ||
211 | uint8_t *src[], int src_linesize[], | ||
212 | int dst_x, int dst_y, int src_x, int src_y, | ||
213 | int w, int h) | ||
214 | { | ||
215 | int plane, y, wp, hp; | ||
216 | uint8_t *p, *q; | ||
217 | |||
218 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 37 times.
|
148 | for (plane = 0; plane < draw->nb_planes; plane++) { |
219 | 111 | p = pointer_at(draw, src, src_linesize, plane, src_x, src_y); | |
220 | 111 | q = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y); | |
221 | 111 | wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]) * draw->pixelstep[plane]; | |
222 | 111 | hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]); | |
223 |
2/2✓ Branch 0 taken 21312 times.
✓ Branch 1 taken 111 times.
|
21423 | for (y = 0; y < hp; y++) { |
224 | 21312 | memcpy(q, p, wp); | |
225 | 21312 | p += src_linesize[plane]; | |
226 | 21312 | q += dst_linesize[plane]; | |
227 | } | ||
228 | } | ||
229 | 37 | } | |
230 | |||
231 | 208803 | void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, | |
232 | uint8_t *dst[], int dst_linesize[], | ||
233 | int dst_x, int dst_y, int w, int h) | ||
234 | { | ||
235 | int plane, x, y, wp, hp; | ||
236 | uint8_t *p0, *p; | ||
237 | 208803 | FFDrawColor color_tmp = *color; | |
238 | |||
239 |
2/2✓ Branch 0 taken 521234 times.
✓ Branch 1 taken 208803 times.
|
730037 | for (plane = 0; plane < draw->nb_planes; plane++) { |
240 | 521234 | p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y); | |
241 | 521234 | wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]); | |
242 | 521234 | hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]); | |
243 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 521234 times.
|
521234 | if (!hp) |
244 | ✗ | return; | |
245 | 521234 | p = p0; | |
246 | |||
247 | if (HAVE_BIGENDIAN && draw->desc->comp[0].depth > 8) { | ||
248 | for (x = 0; 2*x < draw->pixelstep[plane]; x++) | ||
249 | color_tmp.comp[plane].u16[x] = av_bswap16(color_tmp.comp[plane].u16[x]); | ||
250 | } | ||
251 | |||
252 | /* copy first line from color */ | ||
253 |
2/2✓ Branch 0 taken 1999453 times.
✓ Branch 1 taken 521234 times.
|
2520687 | for (x = 0; x < wp; x++) { |
254 | 1999453 | memcpy(p, color_tmp.comp[plane].u8, draw->pixelstep[plane]); | |
255 | 1999453 | p += draw->pixelstep[plane]; | |
256 | } | ||
257 | 521234 | wp *= draw->pixelstep[plane]; | |
258 | /* copy next lines from first line */ | ||
259 | 521234 | p = p0 + dst_linesize[plane]; | |
260 |
2/2✓ Branch 0 taken 8923835 times.
✓ Branch 1 taken 521234 times.
|
9445069 | for (y = 1; y < hp; y++) { |
261 | 8923835 | memcpy(p, p0, wp); | |
262 | 8923835 | p += dst_linesize[plane]; | |
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | /** | ||
268 | * Clip interval [x; x+w[ within [0; wmax[. | ||
269 | * The resulting w may be negative if the final interval is empty. | ||
270 | * dx, if not null, return the difference between in and out value of x. | ||
271 | */ | ||
272 | 60940 | static void clip_interval(int wmax, int *x, int *w, int *dx) | |
273 | { | ||
274 |
2/2✓ Branch 0 taken 59048 times.
✓ Branch 1 taken 1892 times.
|
60940 | if (dx) |
275 | 59048 | *dx = 0; | |
276 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 60940 times.
|
60940 | if (*x < 0) { |
277 | ✗ | if (dx) | |
278 | ✗ | *dx = -*x; | |
279 | ✗ | *w += *x; | |
280 | ✗ | *x = 0; | |
281 | } | ||
282 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 60940 times.
|
60940 | if (*x + *w > wmax) |
283 | ✗ | *w = wmax - *x; | |
284 | 60940 | } | |
285 | |||
286 | /** | ||
287 | * Decompose w pixels starting at x | ||
288 | * into start + (w starting at x) + end | ||
289 | * with x and w aligned on multiples of 1<<sub. | ||
290 | */ | ||
291 | 162600 | static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end) | |
292 | { | ||
293 | 162600 | int mask = (1 << sub) - 1; | |
294 | |||
295 | 162600 | *start = (-*x) & mask; | |
296 | 162600 | *x += *start; | |
297 | 162600 | *start = FFMIN(*start, *w); | |
298 | 162600 | *w -= *start; | |
299 | 162600 | *end = *w & mask; | |
300 | 162600 | *w >>= sub; | |
301 | 162600 | } | |
302 | |||
303 | /* If alpha is in the [ 0 ; 0x1010101 ] range, | ||
304 | then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range, | ||
305 | and >> 24 gives a correct rounding. */ | ||
306 | 68580 | static void blend_line(uint8_t *dst, unsigned src, unsigned alpha, | |
307 | int dx, int w, unsigned hsub, int left, int right) | ||
308 | { | ||
309 | 68580 | unsigned asrc = alpha * src; | |
310 | 68580 | unsigned tau = 0x1010101 - alpha; | |
311 | int x; | ||
312 | |||
313 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 68580 times.
|
68580 | if (left) { |
314 | ✗ | unsigned suba = (left * alpha) >> hsub; | |
315 | ✗ | *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24; | |
316 | ✗ | dst += dx; | |
317 | } | ||
318 |
2/2✓ Branch 0 taken 5729400 times.
✓ Branch 1 taken 68580 times.
|
5797980 | for (x = 0; x < w; x++) { |
319 | 5729400 | *dst = (*dst * tau + asrc) >> 24; | |
320 | 5729400 | dst += dx; | |
321 | } | ||
322 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 68580 times.
|
68580 | if (right) { |
323 | ✗ | unsigned suba = (right * alpha) >> hsub; | |
324 | ✗ | *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24; | |
325 | } | ||
326 | 68580 | } | |
327 | |||
328 | 11880 | static void blend_line16(uint8_t *dst, unsigned src, unsigned alpha, | |
329 | int dx, int w, unsigned hsub, int left, int right) | ||
330 | { | ||
331 | 11880 | unsigned asrc = alpha * src; | |
332 | 11880 | unsigned tau = 0x10001 - alpha; | |
333 | int x; | ||
334 | |||
335 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11880 times.
|
11880 | if (left) { |
336 | ✗ | unsigned suba = (left * alpha) >> hsub; | |
337 | ✗ | uint16_t value = AV_RL16(dst); | |
338 | ✗ | AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16); | |
339 | ✗ | dst += dx; | |
340 | } | ||
341 |
2/2✓ Branch 0 taken 792000 times.
✓ Branch 1 taken 11880 times.
|
803880 | for (x = 0; x < w; x++) { |
342 | 792000 | uint16_t value = AV_RL16(dst); | |
343 | 792000 | AV_WL16(dst, (value * tau + asrc) >> 16); | |
344 | 792000 | dst += dx; | |
345 | } | ||
346 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11880 times.
|
11880 | if (right) { |
347 | ✗ | unsigned suba = (right * alpha) >> hsub; | |
348 | ✗ | uint16_t value = AV_RL16(dst); | |
349 | ✗ | AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16); | |
350 | } | ||
351 | 11880 | } | |
352 | |||
353 | 946 | void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, | |
354 | uint8_t *dst[], int dst_linesize[], | ||
355 | int dst_w, int dst_h, | ||
356 | int x0, int y0, int w, int h) | ||
357 | { | ||
358 | unsigned alpha, nb_planes, nb_comp, plane, comp; | ||
359 | int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y; | ||
360 | uint8_t *p0, *p; | ||
361 | |||
362 | 1892 | nb_comp = draw->desc->nb_components - | |
363 |
3/4✓ Branch 0 taken 71 times.
✓ Branch 1 taken 875 times.
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
|
946 | !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
364 | |||
365 | /* TODO optimize if alpha = 0xFF */ | ||
366 | 946 | clip_interval(dst_w, &x0, &w, NULL); | |
367 | 946 | clip_interval(dst_h, &y0, &h, NULL); | |
368 |
3/6✓ Branch 0 taken 946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 946 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 946 times.
|
946 | if (w <= 0 || h <= 0 || !color->rgba[3]) |
369 | ✗ | return; | |
370 |
2/2✓ Branch 0 taken 836 times.
✓ Branch 1 taken 110 times.
|
946 | if (draw->desc->comp[0].depth <= 8) { |
371 | /* 0x10203 * alpha + 2 is in the [ 2 ; 0x1010101 - 2 ] range */ | ||
372 | 836 | alpha = 0x10203 * color->rgba[3] + 0x2; | |
373 | } else { | ||
374 | /* 0x101 * alpha is in the [ 2 ; 0x1001] range */ | ||
375 | 110 | alpha = 0x101 * color->rgba[3] + 0x2; | |
376 | } | ||
377 |
3/4✓ Branch 0 taken 71 times.
✓ Branch 1 taken 875 times.
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
|
946 | nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
378 | 946 | nb_planes += !nb_planes; | |
379 |
2/2✓ Branch 0 taken 2536 times.
✓ Branch 1 taken 946 times.
|
3482 | for (plane = 0; plane < nb_planes; plane++) { |
380 | 2536 | p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); | |
381 | 2536 | w_sub = w; | |
382 | 2536 | h_sub = h; | |
383 | 2536 | x_sub = x0; | |
384 | 2536 | y_sub = y0; | |
385 | 2536 | subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right); | |
386 | 2536 | subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); | |
387 |
2/2✓ Branch 0 taken 7608 times.
✓ Branch 1 taken 2536 times.
|
10144 | for (comp = 0; comp < nb_comp; comp++) { |
388 | 7608 | const int depth = draw->desc->comp[comp].depth; | |
389 | 7608 | const int offset = draw->desc->comp[comp].offset; | |
390 | 7608 | const int index = offset / ((depth + 7) / 8); | |
391 | |||
392 |
2/2✓ Branch 0 taken 4770 times.
✓ Branch 1 taken 2838 times.
|
7608 | if (draw->desc->comp[comp].plane != plane) |
393 | 4770 | continue; | |
394 | 2838 | p = p0 + offset; | |
395 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2838 times.
|
2838 | if (top) { |
396 | ✗ | if (depth <= 8) { | |
397 | ✗ | blend_line(p, color->comp[plane].u8[index], alpha >> 1, | |
398 | draw->pixelstep[plane], w_sub, | ||
399 | ✗ | draw->hsub[plane], left, right); | |
400 | } else { | ||
401 | ✗ | blend_line16(p, color->comp[plane].u16[index], alpha >> 1, | |
402 | draw->pixelstep[plane], w_sub, | ||
403 | ✗ | draw->hsub[plane], left, right); | |
404 | } | ||
405 | ✗ | p += dst_linesize[plane]; | |
406 | } | ||
407 |
2/2✓ Branch 0 taken 2508 times.
✓ Branch 1 taken 330 times.
|
2838 | if (depth <= 8) { |
408 |
2/2✓ Branch 0 taken 68580 times.
✓ Branch 1 taken 2508 times.
|
71088 | for (y = 0; y < h_sub; y++) { |
409 | 68580 | blend_line(p, color->comp[plane].u8[index], alpha, | |
410 | draw->pixelstep[plane], w_sub, | ||
411 | 68580 | draw->hsub[plane], left, right); | |
412 | 68580 | p += dst_linesize[plane]; | |
413 | } | ||
414 | } else { | ||
415 |
2/2✓ Branch 0 taken 11880 times.
✓ Branch 1 taken 330 times.
|
12210 | for (y = 0; y < h_sub; y++) { |
416 | 11880 | blend_line16(p, color->comp[plane].u16[index], alpha, | |
417 | draw->pixelstep[plane], w_sub, | ||
418 | 11880 | draw->hsub[plane], left, right); | |
419 | 11880 | p += dst_linesize[plane]; | |
420 | } | ||
421 | } | ||
422 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2838 times.
|
2838 | if (bottom) { |
423 | ✗ | if (depth <= 8) { | |
424 | ✗ | blend_line(p, color->comp[plane].u8[index], alpha >> 1, | |
425 | draw->pixelstep[plane], w_sub, | ||
426 | ✗ | draw->hsub[plane], left, right); | |
427 | } else { | ||
428 | ✗ | blend_line16(p, color->comp[plane].u16[index], alpha >> 1, | |
429 | draw->pixelstep[plane], w_sub, | ||
430 | ✗ | draw->hsub[plane], left, right); | |
431 | } | ||
432 | } | ||
433 | } | ||
434 | } | ||
435 | } | ||
436 | |||
437 | 1070080 | static void blend_pixel16(uint8_t *dst, unsigned src, unsigned alpha, | |
438 | const uint8_t *mask, int mask_linesize, int l2depth, | ||
439 | unsigned w, unsigned h, unsigned shift, unsigned xm0) | ||
440 | { | ||
441 | 1070080 | unsigned xm, x, y, t = 0; | |
442 | 1070080 | unsigned xmshf = 3 - l2depth; | |
443 | 1070080 | unsigned xmmod = 7 >> l2depth; | |
444 | 1070080 | unsigned mbits = (1 << (1 << l2depth)) - 1; | |
445 | 1070080 | unsigned mmult = 255 / mbits; | |
446 | 1070080 | uint16_t value = AV_RL16(dst); | |
447 | |||
448 |
2/2✓ Branch 0 taken 1070080 times.
✓ Branch 1 taken 1070080 times.
|
2140160 | for (y = 0; y < h; y++) { |
449 | 1070080 | xm = xm0; | |
450 |
2/2✓ Branch 0 taken 1605120 times.
✓ Branch 1 taken 1070080 times.
|
2675200 | for (x = 0; x < w; x++) { |
451 | 1605120 | t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits) | |
452 | 1605120 | * mmult; | |
453 | 1605120 | xm++; | |
454 | } | ||
455 | 1070080 | mask += mask_linesize; | |
456 | } | ||
457 | 1070080 | alpha = (t >> shift) * alpha; | |
458 | 1070080 | AV_WL16(dst, ((0x10001 - alpha) * value + alpha * src) >> 16); | |
459 | 1070080 | } | |
460 | |||
461 | 7902880 | static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha, | |
462 | const uint8_t *mask, int mask_linesize, int l2depth, | ||
463 | unsigned w, unsigned h, unsigned shift, unsigned xm0) | ||
464 | { | ||
465 | 7902880 | unsigned xm, x, y, t = 0; | |
466 | 7902880 | unsigned xmshf = 3 - l2depth; | |
467 | 7902880 | unsigned xmmod = 7 >> l2depth; | |
468 | 7902880 | unsigned mbits = (1 << (1 << l2depth)) - 1; | |
469 | 7902880 | unsigned mmult = 255 / mbits; | |
470 | |||
471 |
2/2✓ Branch 0 taken 9366016 times.
✓ Branch 1 taken 7902880 times.
|
17268896 | for (y = 0; y < h; y++) { |
472 | 9366016 | xm = xm0; | |
473 |
2/2✓ Branch 0 taken 12350976 times.
✓ Branch 1 taken 9366016 times.
|
21716992 | for (x = 0; x < w; x++) { |
474 | 12350976 | t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits) | |
475 | 12350976 | * mmult; | |
476 | 12350976 | xm++; | |
477 | } | ||
478 | 9366016 | mask += mask_linesize; | |
479 | } | ||
480 | 7902880 | alpha = (t >> shift) * alpha; | |
481 | 7902880 | *dst = ((0x1010101 - alpha) * *dst + alpha * src) >> 24; | |
482 | 7902880 | } | |
483 | |||
484 | 163680 | static void blend_line_hv16(uint8_t *dst, int dst_delta, | |
485 | unsigned src, unsigned alpha, | ||
486 | const uint8_t *mask, int mask_linesize, int l2depth, int w, | ||
487 | unsigned hsub, unsigned vsub, | ||
488 | int xm, int left, int right, int hband) | ||
489 | { | ||
490 | int x; | ||
491 | |||
492 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 163680 times.
|
163680 | if (left) { |
493 | ✗ | blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth, | |
494 | left, hband, hsub + vsub, xm); | ||
495 | ✗ | dst += dst_delta; | |
496 | ✗ | xm += left; | |
497 | } | ||
498 |
2/2✓ Branch 0 taken 1070080 times.
✓ Branch 1 taken 163680 times.
|
1233760 | for (x = 0; x < w; x++) { |
499 | 1070080 | blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth, | |
500 | 1070080 | 1 << hsub, hband, hsub + vsub, xm); | |
501 | 1070080 | dst += dst_delta; | |
502 | 1070080 | xm += 1 << hsub; | |
503 | } | ||
504 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 163680 times.
|
163680 | if (right) |
505 | ✗ | blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth, | |
506 | right, hband, hsub + vsub, xm); | ||
507 | 163680 | } | |
508 | |||
509 | 954804 | static void blend_line_hv(uint8_t *dst, int dst_delta, | |
510 | unsigned src, unsigned alpha, | ||
511 | const uint8_t *mask, int mask_linesize, int l2depth, int w, | ||
512 | unsigned hsub, unsigned vsub, | ||
513 | int xm, int left, int right, int hband) | ||
514 | { | ||
515 | int x; | ||
516 | |||
517 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 954804 times.
|
954804 | if (left) { |
518 | ✗ | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, | |
519 | left, hband, hsub + vsub, xm); | ||
520 | ✗ | dst += dst_delta; | |
521 | ✗ | xm += left; | |
522 | } | ||
523 |
2/2✓ Branch 0 taken 7902880 times.
✓ Branch 1 taken 954804 times.
|
8857684 | for (x = 0; x < w; x++) { |
524 | 7902880 | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, | |
525 | 7902880 | 1 << hsub, hband, hsub + vsub, xm); | |
526 | 7902880 | dst += dst_delta; | |
527 | 7902880 | xm += 1 << hsub; | |
528 | } | ||
529 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 954804 times.
|
954804 | if (right) |
530 | ✗ | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, | |
531 | right, hband, hsub + vsub, xm); | ||
532 | 954804 | } | |
533 | |||
534 | 29524 | void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, | |
535 | uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, | ||
536 | const uint8_t *mask, int mask_linesize, int mask_w, int mask_h, | ||
537 | int l2depth, unsigned endianness, int x0, int y0) | ||
538 | { | ||
539 | unsigned alpha, nb_planes, nb_comp, plane, comp; | ||
540 | int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y; | ||
541 | uint8_t *p0, *p; | ||
542 | const uint8_t *m; | ||
543 | |||
544 | 59048 | nb_comp = draw->desc->nb_components - | |
545 |
3/4✓ Branch 0 taken 2434 times.
✓ Branch 1 taken 27090 times.
✓ Branch 2 taken 2434 times.
✗ Branch 3 not taken.
|
29524 | !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
546 | |||
547 | 29524 | clip_interval(dst_w, &x0, &mask_w, &xm0); | |
548 | 29524 | clip_interval(dst_h, &y0, &mask_h, &ym0); | |
549 | 29524 | mask += ym0 * mask_linesize; | |
550 |
3/6✓ Branch 0 taken 29524 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29524 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29524 times.
|
29524 | if (mask_w <= 0 || mask_h <= 0 || !color->rgba[3]) |
551 | ✗ | return; | |
552 |
2/2✓ Branch 0 taken 26114 times.
✓ Branch 1 taken 3410 times.
|
29524 | if (draw->desc->comp[0].depth <= 8) { |
553 | /* alpha is in the [ 0 ; 0x10203 ] range, | ||
554 | alpha * mask is in the [ 0 ; 0x1010101 - 4 ] range */ | ||
555 | 26114 | alpha = (0x10307 * color->rgba[3] + 0x3) >> 8; | |
556 | } else { | ||
557 | 3410 | alpha = (0x101 * color->rgba[3] + 0x2) >> 8; | |
558 | } | ||
559 |
3/4✓ Branch 0 taken 2434 times.
✓ Branch 1 taken 27090 times.
✓ Branch 2 taken 2434 times.
✗ Branch 3 not taken.
|
29524 | nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
560 | 29524 | nb_planes += !nb_planes; | |
561 |
2/2✓ Branch 0 taken 78764 times.
✓ Branch 1 taken 29524 times.
|
108288 | for (plane = 0; plane < nb_planes; plane++) { |
562 | 78764 | p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); | |
563 | 78764 | w_sub = mask_w; | |
564 | 78764 | h_sub = mask_h; | |
565 | 78764 | x_sub = x0; | |
566 | 78764 | y_sub = y0; | |
567 | 78764 | subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right); | |
568 | 78764 | subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); | |
569 |
2/2✓ Branch 0 taken 236292 times.
✓ Branch 1 taken 78764 times.
|
315056 | for (comp = 0; comp < nb_comp; comp++) { |
570 | 236292 | const int depth = draw->desc->comp[comp].depth; | |
571 | 236292 | const int offset = draw->desc->comp[comp].offset; | |
572 | 236292 | const int index = offset / ((depth + 7) / 8); | |
573 | |||
574 |
2/2✓ Branch 0 taken 147720 times.
✓ Branch 1 taken 88572 times.
|
236292 | if (draw->desc->comp[comp].plane != plane) |
575 | 147720 | continue; | |
576 | 88572 | p = p0 + offset; | |
577 | 88572 | m = mask; | |
578 |
2/2✓ Branch 0 taken 180 times.
✓ Branch 1 taken 88392 times.
|
88572 | if (top) { |
579 |
1/2✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
|
180 | if (depth <= 8) { |
580 | 180 | blend_line_hv(p, draw->pixelstep[plane], | |
581 | 180 | color->comp[plane].u8[index], alpha, | |
582 | m, mask_linesize, l2depth, w_sub, | ||
583 | 180 | draw->hsub[plane], draw->vsub[plane], | |
584 | xm0, left, right, top); | ||
585 | } else { | ||
586 | ✗ | blend_line_hv16(p, draw->pixelstep[plane], | |
587 | ✗ | color->comp[plane].u16[index], alpha, | |
588 | m, mask_linesize, l2depth, w_sub, | ||
589 | ✗ | draw->hsub[plane], draw->vsub[plane], | |
590 | xm0, left, right, top); | ||
591 | } | ||
592 | 180 | p += dst_linesize[plane]; | |
593 | 180 | m += top * mask_linesize; | |
594 | } | ||
595 |
2/2✓ Branch 0 taken 78342 times.
✓ Branch 1 taken 10230 times.
|
88572 | if (depth <= 8) { |
596 |
2/2✓ Branch 0 taken 954444 times.
✓ Branch 1 taken 78342 times.
|
1032786 | for (y = 0; y < h_sub; y++) { |
597 | 954444 | blend_line_hv(p, draw->pixelstep[plane], | |
598 | 954444 | color->comp[plane].u8[index], alpha, | |
599 | m, mask_linesize, l2depth, w_sub, | ||
600 | 954444 | draw->hsub[plane], draw->vsub[plane], | |
601 | 954444 | xm0, left, right, 1 << draw->vsub[plane]); | |
602 | 954444 | p += dst_linesize[plane]; | |
603 | 954444 | m += mask_linesize << draw->vsub[plane]; | |
604 | } | ||
605 | } else { | ||
606 |
2/2✓ Branch 0 taken 163680 times.
✓ Branch 1 taken 10230 times.
|
173910 | for (y = 0; y < h_sub; y++) { |
607 | 163680 | blend_line_hv16(p, draw->pixelstep[plane], | |
608 | 163680 | color->comp[plane].u16[index], alpha, | |
609 | m, mask_linesize, l2depth, w_sub, | ||
610 | 163680 | draw->hsub[plane], draw->vsub[plane], | |
611 | 163680 | xm0, left, right, 1 << draw->vsub[plane]); | |
612 | 163680 | p += dst_linesize[plane]; | |
613 | 163680 | m += mask_linesize << draw->vsub[plane]; | |
614 | } | ||
615 | } | ||
616 |
2/2✓ Branch 0 taken 180 times.
✓ Branch 1 taken 88392 times.
|
88572 | if (bottom) { |
617 |
1/2✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
|
180 | if (depth <= 8) { |
618 | 180 | blend_line_hv(p, draw->pixelstep[plane], | |
619 | 180 | color->comp[plane].u8[index], alpha, | |
620 | m, mask_linesize, l2depth, w_sub, | ||
621 | 180 | draw->hsub[plane], draw->vsub[plane], | |
622 | xm0, left, right, bottom); | ||
623 | } else { | ||
624 | ✗ | blend_line_hv16(p, draw->pixelstep[plane], | |
625 | ✗ | color->comp[plane].u16[index], alpha, | |
626 | m, mask_linesize, l2depth, w_sub, | ||
627 | ✗ | draw->hsub[plane], draw->vsub[plane], | |
628 | xm0, left, right, bottom); | ||
629 | } | ||
630 | } | ||
631 | } | ||
632 | } | ||
633 | } | ||
634 | |||
635 | 227442 | int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, | |
636 | int value) | ||
637 | { | ||
638 |
2/2✓ Branch 0 taken 204345 times.
✓ Branch 1 taken 23097 times.
|
227442 | unsigned shift = sub_dir ? draw->vsub_max : draw->hsub_max; |
639 | |||
640 |
2/2✓ Branch 0 taken 103170 times.
✓ Branch 1 taken 124272 times.
|
227442 | if (!shift) |
641 | 103170 | return value; | |
642 |
2/2✓ Branch 0 taken 104061 times.
✓ Branch 1 taken 20211 times.
|
124272 | if (round_dir >= 0) |
643 |
2/2✓ Branch 0 taken 3381 times.
✓ Branch 1 taken 100680 times.
|
104061 | value += round_dir ? (1 << shift) - 1 : 1 << (shift - 1); |
644 | 124272 | return (value >> shift) << shift; | |
645 | } | ||
646 | |||
647 | 160 | AVFilterFormats *ff_draw_supported_pixel_formats(unsigned flags) | |
648 | { | ||
649 | enum AVPixelFormat i; | ||
650 | FFDrawContext draw; | ||
651 | 160 | AVFilterFormats *fmts = NULL; | |
652 | int ret; | ||
653 | |||
654 |
2/2✓ Branch 1 taken 36480 times.
✓ Branch 2 taken 160 times.
|
36640 | for (i = 0; av_pix_fmt_desc_get(i); i++) |
655 |
3/4✓ Branch 1 taken 14400 times.
✓ Branch 2 taken 22080 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14400 times.
|
50880 | if (ff_draw_init(&draw, i, flags) >= 0 && |
656 | 14400 | (ret = ff_add_format(&fmts, i)) < 0) | |
657 | ✗ | return NULL; | |
658 | 160 | return fmts; | |
659 | } | ||
660 |