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