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 | 1124 | static int fill_map(const AVPixFmtDescriptor *desc, uint8_t *map) | |
36 | { | ||
37 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1124 times.
|
1124 | if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL | |
38 | AV_PIX_FMT_FLAG_BAYER | AV_PIX_FMT_FLAG_XYZ | AV_PIX_FMT_FLAG_PAL)) | ||
39 | ✗ | return AVERROR(EINVAL); | |
40 |
3/4✓ Branch 0 taken 34 times.
✓ Branch 1 taken 1090 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1124 times.
|
1124 | av_assert0(desc->nb_components == 3 + !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)); |
41 |
2/2✓ Branch 0 taken 893 times.
✓ Branch 1 taken 231 times.
|
1124 | if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) { |
42 |
2/2✓ Branch 2 taken 295 times.
✓ Branch 3 taken 598 times.
|
893 | if (desc->nb_components != av_pix_fmt_count_planes(av_pix_fmt_desc_get_id(desc))) |
43 | 295 | return AVERROR(EINVAL); | |
44 | 598 | map[RED] = desc->comp[0].plane; | |
45 | 598 | map[GREEN] = desc->comp[1].plane; | |
46 | 598 | map[BLUE] = desc->comp[2].plane; | |
47 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 582 times.
|
598 | map[ALPHA] = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? desc->comp[3].plane : 3; |
48 | } else { | ||
49 | 231 | int had0 = 0; | |
50 | 231 | unsigned depthb = 0; | |
51 |
2/2✓ Branch 0 taken 706 times.
✓ Branch 1 taken 228 times.
|
934 | for (unsigned i = 0; i < desc->nb_components; i++) { |
52 | /* all components must have same depth in bytes */ | ||
53 | 706 | unsigned db = (desc->comp[i].depth + 7) / 8; | |
54 | 706 | unsigned pos = desc->comp[i].offset / db; | |
55 |
3/4✓ Branch 0 taken 475 times.
✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 475 times.
|
706 | if (depthb && (depthb != db)) |
56 | ✗ | return AVERROR(ENOSYS); | |
57 | |||
58 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 703 times.
|
706 | if (desc->comp[i].offset % db) |
59 | 3 | return AVERROR(ENOSYS); | |
60 | |||
61 | 703 | had0 |= pos == 0; | |
62 | 703 | map[i] = pos; | |
63 | 703 | depthb = db; | |
64 | } | ||
65 | |||
66 |
2/2✓ Branch 0 taken 210 times.
✓ Branch 1 taken 18 times.
|
228 | if (desc->nb_components == 3) |
67 |
1/2✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
|
210 | map[ALPHA] = had0 ? 3 : 0; |
68 | } | ||
69 | |||
70 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 826 times.
|
826 | av_assert0(map[RED] != map[GREEN]); |
71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 826 times.
|
826 | av_assert0(map[GREEN] != map[BLUE]); |
72 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 826 times.
|
826 | av_assert0(map[BLUE] != map[RED]); |
73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 826 times.
|
826 | av_assert0(map[RED] != map[ALPHA]); |
74 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 826 times.
|
826 | av_assert0(map[GREEN] != map[ALPHA]); |
75 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 826 times.
|
826 | av_assert0(map[BLUE] != map[ALPHA]); |
76 | |||
77 | 826 | return 0; | |
78 | } | ||
79 | |||
80 | 591 | int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt) | |
81 | { | ||
82 | 591 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); | |
83 |
2/2✓ Branch 0 taken 47 times.
✓ Branch 1 taken 544 times.
|
591 | if (!(desc->flags & AV_PIX_FMT_FLAG_RGB)) |
84 | 47 | return AVERROR(EINVAL); | |
85 | 544 | return fill_map(desc, rgba_map); | |
86 | } | ||
87 | |||
88 | 580 | int ff_fill_ayuv_map(uint8_t *ayuv_map, enum AVPixelFormat pix_fmt) | |
89 | { | ||
90 | 580 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); | |
91 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 580 times.
|
580 | if (desc->flags & AV_PIX_FMT_FLAG_RGB) |
92 | ✗ | return AVERROR(EINVAL); | |
93 | 580 | return fill_map(desc, ayuv_map); | |
94 | } | ||
95 | |||
96 | 43052 | int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp, | |
97 | enum AVColorRange range, unsigned flags) | ||
98 | { | ||
99 | 43052 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); | |
100 | 43052 | const AVLumaCoefficients *luma = NULL; | |
101 | const AVComponentDescriptor *c; | ||
102 | 43052 | unsigned nb_planes = 0; | |
103 | 43052 | int pixelstep[MAX_PLANES] = { 0 }; | |
104 | 43052 | int depthb = 0; | |
105 | |||
106 |
2/4✓ Branch 0 taken 43052 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 43052 times.
|
43052 | if (!desc || !desc->name) |
107 | ✗ | return AVERROR(EINVAL); | |
108 |
2/2✓ Branch 0 taken 15604 times.
✓ Branch 1 taken 27448 times.
|
43052 | if (desc->flags & AV_PIX_FMT_FLAG_BE) |
109 | 15604 | return AVERROR(ENOSYS); | |
110 |
2/2✓ Branch 0 taken 6806 times.
✓ Branch 1 taken 20642 times.
|
27448 | if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA)) |
111 | 6806 | return AVERROR(ENOSYS); | |
112 |
2/2✓ Branch 0 taken 20595 times.
✓ Branch 1 taken 47 times.
|
20642 | if (csp == AVCOL_SPC_UNSPECIFIED) |
113 |
2/2✓ Branch 0 taken 6640 times.
✓ Branch 1 taken 13955 times.
|
20595 | csp = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? AVCOL_SPC_RGB : AVCOL_SPC_SMPTE170M; |
114 |
3/4✓ Branch 0 taken 13955 times.
✓ Branch 1 taken 6687 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13955 times.
|
20642 | if (!(desc->flags & AV_PIX_FMT_FLAG_RGB) && !(luma = av_csp_luma_coeffs_from_avcsp(csp))) |
115 | ✗ | return AVERROR(EINVAL); | |
116 |
2/2✓ Branch 0 taken 20466 times.
✓ Branch 1 taken 176 times.
|
20642 | if (range == AVCOL_RANGE_UNSPECIFIED) |
117 |
4/4✓ Branch 0 taken 20134 times.
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 19968 times.
✓ Branch 3 taken 166 times.
|
40766 | range = (format == AV_PIX_FMT_YUVJ420P || format == AV_PIX_FMT_YUVJ422P || |
118 |
4/4✓ Branch 0 taken 19802 times.
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 19636 times.
✓ Branch 3 taken 166 times.
|
19968 | format == AV_PIX_FMT_YUVJ444P || format == AV_PIX_FMT_YUVJ411P || |
119 |
2/2✓ Branch 0 taken 6640 times.
✓ Branch 1 taken 12996 times.
|
19636 | format == AV_PIX_FMT_YUVJ440P || csp == AVCOL_SPC_RGB) |
120 |
2/2✓ Branch 0 taken 20300 times.
✓ Branch 1 taken 166 times.
|
40766 | ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; |
121 |
3/4✓ Branch 0 taken 13104 times.
✓ Branch 1 taken 7538 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13104 times.
|
20642 | if (range != AVCOL_RANGE_JPEG && range != AVCOL_RANGE_MPEG) |
122 | ✗ | return AVERROR(EINVAL); | |
123 |
2/2✓ Branch 0 taken 55326 times.
✓ Branch 1 taken 15662 times.
|
70988 | for (unsigned i = 0; i < desc->nb_components; i++) { |
124 | int db; | ||
125 | 55326 | c = &desc->comp[i]; | |
126 | /* for now, only 8-16 bits formats */ | ||
127 |
4/4✓ Branch 0 taken 53666 times.
✓ Branch 1 taken 1660 times.
✓ Branch 2 taken 664 times.
✓ Branch 3 taken 53002 times.
|
55326 | if (c->depth < 8 || c->depth > 16) |
128 | 2324 | return AVERROR(ENOSYS); | |
129 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 53002 times.
|
53002 | if (c->plane >= MAX_PLANES) |
130 | ✗ | return AVERROR(ENOSYS); | |
131 | /* data must either be in the high or low bits, never middle */ | ||
132 |
4/4✓ Branch 0 taken 4500 times.
✓ Branch 1 taken 48502 times.
✓ Branch 2 taken 664 times.
✓ Branch 3 taken 3836 times.
|
53002 | if (c->shift && ((c->shift + c->depth) & 0x7)) |
133 | 664 | return AVERROR(ENOSYS); | |
134 | /* mixed >8 and <=8 depth */ | ||
135 | 52338 | db = (c->depth + 7) / 8; | |
136 |
3/4✓ Branch 0 taken 34518 times.
✓ Branch 1 taken 17820 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 34518 times.
|
52338 | if (depthb && (depthb != db)) |
137 | ✗ | return AVERROR(ENOSYS); | |
138 | 52338 | depthb = db; | |
139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 52338 times.
|
52338 | if (db * (c->offset + 1) > 16) |
140 | ✗ | return AVERROR(ENOSYS); | |
141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 52338 times.
|
52338 | if (c->offset % db) |
142 | ✗ | return AVERROR(ENOSYS); | |
143 | /* strange interleaving */ | ||
144 |
2/2✓ Branch 0 taken 10896 times.
✓ Branch 1 taken 41442 times.
|
52338 | if (pixelstep[c->plane] != 0 && |
145 |
2/2✓ Branch 0 taken 1162 times.
✓ Branch 1 taken 9734 times.
|
10896 | pixelstep[c->plane] != c->step) |
146 | 1162 | return AVERROR(ENOSYS); | |
147 | 51176 | pixelstep[c->plane] = c->step; | |
148 |
2/2✓ Branch 0 taken 830 times.
✓ Branch 1 taken 50346 times.
|
51176 | if (pixelstep[c->plane] >= 8) |
149 | 830 | return AVERROR(ENOSYS); | |
150 | 50346 | nb_planes = FFMAX(nb_planes, c->plane + 1); | |
151 | } | ||
152 | 15662 | memset(draw, 0, sizeof(*draw)); | |
153 | 15662 | draw->desc = desc; | |
154 | 15662 | draw->format = format; | |
155 | 15662 | draw->nb_planes = nb_planes; | |
156 | 15662 | draw->range = range; | |
157 | 15662 | draw->csp = csp; | |
158 | 15662 | draw->flags = flags; | |
159 |
2/2✓ Branch 0 taken 11797 times.
✓ Branch 1 taken 3865 times.
|
15662 | if (luma) |
160 | 11797 | ff_fill_rgb2yuv_table(luma, draw->rgb2yuv); | |
161 | 15662 | memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep)); | |
162 | 15662 | draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w; | |
163 | 15662 | draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h; | |
164 | 15662 | return 0; | |
165 | } | ||
166 | |||
167 | 42828 | int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) | |
168 | { | ||
169 | 42828 | return ff_draw_init2(draw, format, AVCOL_SPC_UNSPECIFIED, AVCOL_RANGE_UNSPECIFIED, flags); | |
170 | } | ||
171 | |||
172 | 209611 | void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4]) | |
173 | { | ||
174 | double yuvad[4]; | ||
175 | double rgbad[4]; | ||
176 | 209611 | const AVPixFmtDescriptor *desc = draw->desc; | |
177 | |||
178 |
1/2✓ Branch 0 taken 209611 times.
✗ Branch 1 not taken.
|
209611 | if (rgba != color->rgba) |
179 | 209611 | memcpy(color->rgba, rgba, sizeof(color->rgba)); | |
180 | |||
181 | 209611 | memset(color->comp, 0, sizeof(color->comp)); | |
182 | |||
183 |
2/2✓ Branch 0 taken 838444 times.
✓ Branch 1 taken 209611 times.
|
1048055 | for (int i = 0; i < 4; i++) |
184 | 838444 | rgbad[i] = color->rgba[i] / 255.; | |
185 | |||
186 |
2/2✓ Branch 0 taken 54599 times.
✓ Branch 1 taken 155012 times.
|
209611 | if (draw->desc->flags & AV_PIX_FMT_FLAG_RGB) |
187 | 54599 | memcpy(yuvad, rgbad, sizeof(double) * 3); | |
188 | else | ||
189 | 155012 | ff_matrix_mul_3x3_vec(yuvad, rgbad, draw->rgb2yuv); | |
190 | |||
191 | 209611 | yuvad[3] = rgbad[3]; | |
192 | |||
193 |
2/2✓ Branch 0 taken 628833 times.
✓ Branch 1 taken 209611 times.
|
838444 | for (int i = 0; i < 3; i++) { |
194 |
4/4✓ Branch 0 taken 465036 times.
✓ Branch 1 taken 163797 times.
✓ Branch 2 taken 310024 times.
✓ Branch 3 taken 155012 times.
|
628833 | int chroma = (!(draw->desc->flags & AV_PIX_FMT_FLAG_RGB) && i > 0); |
195 |
2/2✓ Branch 0 taken 464973 times.
✓ Branch 1 taken 163860 times.
|
628833 | if (draw->range == AVCOL_RANGE_MPEG) { |
196 |
2/2✓ Branch 0 taken 309982 times.
✓ Branch 1 taken 154991 times.
|
464973 | yuvad[i] *= (chroma ? 224. : 219.) / 255.; |
197 |
2/2✓ Branch 0 taken 309982 times.
✓ Branch 1 taken 154991 times.
|
464973 | yuvad[i] += (chroma ? 128. : 16.) / 255.; |
198 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 163818 times.
|
163860 | } else if (chroma) { |
199 | 42 | yuvad[i] += 0.5; | |
200 | } | ||
201 | } | ||
202 | |||
203 | // Ensure we place the alpha appropriately for gray formats | ||
204 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 209601 times.
|
209611 | if (desc->nb_components <= 2) |
205 | 10 | yuvad[1] = yuvad[3]; | |
206 | |||
207 |
2/2✓ Branch 0 taken 654844 times.
✓ Branch 1 taken 209611 times.
|
864455 | for (unsigned i = 0; i < desc->nb_components; i++) { |
208 | 654844 | unsigned val = yuvad[i] * ((1 << (draw->desc->comp[i].depth + draw->desc->comp[i].shift)) - 1) + 0.5; | |
209 |
2/2✓ Branch 0 taken 59665 times.
✓ Branch 1 taken 595179 times.
|
654844 | if (desc->comp[i].depth > 8) |
210 | 59665 | color->comp[desc->comp[i].plane].u16[desc->comp[i].offset / 2] = val; | |
211 | else | ||
212 | 595179 | color->comp[desc->comp[i].plane].u8[desc->comp[i].offset] = val; | |
213 | } | ||
214 | 209611 | } | |
215 | |||
216 | 607550 | static uint8_t *pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[], | |
217 | int plane, int x, int y) | ||
218 | { | ||
219 | 607550 | return data[plane] + | |
220 | 1215100 | (y >> draw->vsub[plane]) * linesize[plane] + | |
221 | 607550 | (x >> draw->hsub[plane]) * draw->pixelstep[plane]; | |
222 | } | ||
223 | |||
224 | 37 | void ff_copy_rectangle2(FFDrawContext *draw, | |
225 | uint8_t *dst[], int dst_linesize[], | ||
226 | uint8_t *src[], int src_linesize[], | ||
227 | int dst_x, int dst_y, int src_x, int src_y, | ||
228 | int w, int h) | ||
229 | { | ||
230 | int wp, hp; | ||
231 | uint8_t *p, *q; | ||
232 | |||
233 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 37 times.
|
148 | for (int plane = 0; plane < draw->nb_planes; plane++) { |
234 | 111 | p = pointer_at(draw, src, src_linesize, plane, src_x, src_y); | |
235 | 111 | q = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y); | |
236 | 111 | wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]) * draw->pixelstep[plane]; | |
237 | 111 | hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]); | |
238 |
2/2✓ Branch 0 taken 21312 times.
✓ Branch 1 taken 111 times.
|
21423 | for (int y = 0; y < hp; y++) { |
239 | 21312 | memcpy(q, p, wp); | |
240 | 21312 | p += src_linesize[plane]; | |
241 | 21312 | q += dst_linesize[plane]; | |
242 | } | ||
243 | } | ||
244 | 37 | } | |
245 | |||
246 | 211271 | void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, | |
247 | uint8_t *dst[], int dst_linesize[], | ||
248 | int dst_x, int dst_y, int w, int h) | ||
249 | { | ||
250 | int wp, hp; | ||
251 | uint8_t *p0, *p; | ||
252 | 211271 | FFDrawColor color_tmp = *color; | |
253 | |||
254 |
2/2✓ Branch 0 taken 525408 times.
✓ Branch 1 taken 211271 times.
|
736679 | for (int plane = 0; plane < draw->nb_planes; plane++) { |
255 | 525408 | p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y); | |
256 | 525408 | wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]); | |
257 | 525408 | hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]); | |
258 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 525408 times.
|
525408 | if (!hp) |
259 | ✗ | return; | |
260 | 525408 | p = p0; | |
261 | |||
262 | if (HAVE_BIGENDIAN && draw->desc->comp[0].depth > 8) { | ||
263 | for (int x = 0; 2*x < draw->pixelstep[plane]; x++) | ||
264 | color_tmp.comp[plane].u16[x] = av_bswap16(color_tmp.comp[plane].u16[x]); | ||
265 | } | ||
266 | |||
267 | /* copy first line from color */ | ||
268 |
2/2✓ Branch 0 taken 2015395 times.
✓ Branch 1 taken 525408 times.
|
2540803 | for (int x = 0; x < wp; x++) { |
269 | 2015395 | memcpy(p, color_tmp.comp[plane].u8, draw->pixelstep[plane]); | |
270 | 2015395 | p += draw->pixelstep[plane]; | |
271 | } | ||
272 | 525408 | wp *= draw->pixelstep[plane]; | |
273 | /* copy next lines from first line */ | ||
274 | 525408 | p = p0 + dst_linesize[plane]; | |
275 |
2/2✓ Branch 0 taken 9009469 times.
✓ Branch 1 taken 525408 times.
|
9534877 | for (int y = 1; y < hp; y++) { |
276 | 9009469 | memcpy(p, p0, wp); | |
277 | 9009469 | p += dst_linesize[plane]; | |
278 | } | ||
279 | } | ||
280 | } | ||
281 | |||
282 | /** | ||
283 | * Clip interval [x; x+w[ within [0; wmax[. | ||
284 | * The resulting w may be negative if the final interval is empty. | ||
285 | * dx, if not null, return the difference between in and out value of x. | ||
286 | */ | ||
287 | 61560 | static void clip_interval(int wmax, int *x, int *w, int *dx) | |
288 | { | ||
289 |
2/2✓ Branch 0 taken 59648 times.
✓ Branch 1 taken 1912 times.
|
61560 | if (dx) |
290 | 59648 | *dx = 0; | |
291 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 61560 times.
|
61560 | if (*x < 0) { |
292 | ✗ | if (dx) | |
293 | ✗ | *dx = -*x; | |
294 | ✗ | *w += *x; | |
295 | ✗ | *x = 0; | |
296 | } | ||
297 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 61560 times.
|
61560 | if (*x + *w > wmax) |
298 | ✗ | *w = wmax - *x; | |
299 | 61560 | } | |
300 | |||
301 | /** | ||
302 | * Decompose w pixels starting at x | ||
303 | * into start + (w starting at x) + end | ||
304 | * with x and w aligned on multiples of 1<<sub. | ||
305 | */ | ||
306 | 163840 | static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end) | |
307 | { | ||
308 | 163840 | int mask = (1 << sub) - 1; | |
309 | |||
310 | 163840 | *start = (-*x) & mask; | |
311 | 163840 | *x += *start; | |
312 | 163840 | *start = FFMIN(*start, *w); | |
313 | 163840 | *w -= *start; | |
314 | 163840 | *end = *w & mask; | |
315 | 163840 | *w >>= sub; | |
316 | 163840 | } | |
317 | |||
318 | /* If alpha is in the [ 0 ; 0x1010101 ] range, | ||
319 | then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range, | ||
320 | and >> 24 gives a correct rounding. */ | ||
321 | 69660 | static void blend_line(uint8_t *dst, unsigned src, unsigned alpha, | |
322 | int dx, int w, unsigned hsub, int left, int right) | ||
323 | { | ||
324 | 69660 | unsigned asrc = alpha * src; | |
325 | 69660 | unsigned tau = 0x1010101 - alpha; | |
326 | |||
327 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 69660 times.
|
69660 | if (left) { |
328 | ✗ | unsigned suba = (left * alpha) >> hsub; | |
329 | ✗ | *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24; | |
330 | ✗ | dst += dx; | |
331 | } | ||
332 |
2/2✓ Branch 0 taken 5819400 times.
✓ Branch 1 taken 69660 times.
|
5889060 | for (int x = 0; x < w; x++) { |
333 | 5819400 | *dst = (*dst * tau + asrc) >> 24; | |
334 | 5819400 | dst += dx; | |
335 | } | ||
336 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 69660 times.
|
69660 | if (right) { |
337 | ✗ | unsigned suba = (right * alpha) >> hsub; | |
338 | ✗ | *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24; | |
339 | } | ||
340 | 69660 | } | |
341 | |||
342 | 11880 | static void blend_line16(uint8_t *dst, unsigned src, unsigned alpha, | |
343 | int dx, int w, unsigned hsub, int left, int right) | ||
344 | { | ||
345 | 11880 | unsigned asrc = alpha * src; | |
346 | 11880 | unsigned tau = 0x10001 - alpha; | |
347 | |||
348 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11880 times.
|
11880 | if (left) { |
349 | ✗ | unsigned suba = (left * alpha) >> hsub; | |
350 | ✗ | uint16_t value = AV_RL16(dst); | |
351 | ✗ | AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16); | |
352 | ✗ | dst += dx; | |
353 | } | ||
354 |
2/2✓ Branch 0 taken 792000 times.
✓ Branch 1 taken 11880 times.
|
803880 | for (int x = 0; x < w; x++) { |
355 | 792000 | uint16_t value = AV_RL16(dst); | |
356 | 792000 | AV_WL16(dst, (value * tau + asrc) >> 16); | |
357 | 792000 | dst += dx; | |
358 | } | ||
359 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11880 times.
|
11880 | if (right) { |
360 | ✗ | unsigned suba = (right * alpha) >> hsub; | |
361 | ✗ | uint16_t value = AV_RL16(dst); | |
362 | ✗ | AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16); | |
363 | } | ||
364 | 11880 | } | |
365 | |||
366 | 956 | void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, | |
367 | uint8_t *dst[], int dst_linesize[], | ||
368 | int dst_w, int dst_h, | ||
369 | int x0, int y0, int w, int h) | ||
370 | { | ||
371 | unsigned alpha, nb_planes, nb_comp; | ||
372 | int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom; | ||
373 | uint8_t *p0, *p; | ||
374 | |||
375 | 1912 | nb_comp = draw->desc->nb_components - | |
376 |
3/4✓ Branch 0 taken 71 times.
✓ Branch 1 taken 885 times.
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
|
956 | !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
377 | |||
378 | /* TODO optimize if alpha = 0xFF */ | ||
379 | 956 | clip_interval(dst_w, &x0, &w, NULL); | |
380 | 956 | clip_interval(dst_h, &y0, &h, NULL); | |
381 |
3/6✓ Branch 0 taken 956 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 956 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 956 times.
|
956 | if (w <= 0 || h <= 0 || !color->rgba[3]) |
382 | ✗ | return; | |
383 |
2/2✓ Branch 0 taken 846 times.
✓ Branch 1 taken 110 times.
|
956 | if (draw->desc->comp[0].depth <= 8) { |
384 | /* 0x10203 * alpha + 2 is in the [ 2 ; 0x1010101 - 2 ] range */ | ||
385 | 846 | alpha = 0x10203 * color->rgba[3] + 0x2; | |
386 | } else { | ||
387 | /* 0x101 * alpha is in the [ 2 ; 0x1001] range */ | ||
388 | 110 | alpha = 0x101 * color->rgba[3] + 0x2; | |
389 | } | ||
390 |
3/4✓ Branch 0 taken 71 times.
✓ Branch 1 taken 885 times.
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
|
956 | nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
391 | 956 | nb_planes += !nb_planes; | |
392 |
2/2✓ Branch 0 taken 2556 times.
✓ Branch 1 taken 956 times.
|
3512 | for (unsigned plane = 0; plane < nb_planes; plane++) { |
393 | 2556 | p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); | |
394 | 2556 | w_sub = w; | |
395 | 2556 | h_sub = h; | |
396 | 2556 | x_sub = x0; | |
397 | 2556 | y_sub = y0; | |
398 | 2556 | subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right); | |
399 | 2556 | subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); | |
400 |
2/2✓ Branch 0 taken 7668 times.
✓ Branch 1 taken 2556 times.
|
10224 | for (unsigned comp = 0; comp < nb_comp; comp++) { |
401 | 7668 | const int depth = draw->desc->comp[comp].depth; | |
402 | 7668 | const int offset = draw->desc->comp[comp].offset; | |
403 | 7668 | const int index = offset / ((depth + 7) / 8); | |
404 | |||
405 |
2/2✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 2868 times.
|
7668 | if (draw->desc->comp[comp].plane != plane) |
406 | 4800 | continue; | |
407 | 2868 | p = p0 + offset; | |
408 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2868 times.
|
2868 | if (top) { |
409 | ✗ | if (depth <= 8) { | |
410 | ✗ | blend_line(p, color->comp[plane].u8[index], alpha >> 1, | |
411 | draw->pixelstep[plane], w_sub, | ||
412 | ✗ | draw->hsub[plane], left, right); | |
413 | } else { | ||
414 | ✗ | blend_line16(p, color->comp[plane].u16[index], alpha >> 1, | |
415 | draw->pixelstep[plane], w_sub, | ||
416 | ✗ | draw->hsub[plane], left, right); | |
417 | } | ||
418 | ✗ | p += dst_linesize[plane]; | |
419 | } | ||
420 |
2/2✓ Branch 0 taken 2538 times.
✓ Branch 1 taken 330 times.
|
2868 | if (depth <= 8) { |
421 |
2/2✓ Branch 0 taken 69660 times.
✓ Branch 1 taken 2538 times.
|
72198 | for (int y = 0; y < h_sub; y++) { |
422 | 69660 | blend_line(p, color->comp[plane].u8[index], alpha, | |
423 | draw->pixelstep[plane], w_sub, | ||
424 | 69660 | draw->hsub[plane], left, right); | |
425 | 69660 | p += dst_linesize[plane]; | |
426 | } | ||
427 | } else { | ||
428 |
2/2✓ Branch 0 taken 11880 times.
✓ Branch 1 taken 330 times.
|
12210 | for (int y = 0; y < h_sub; y++) { |
429 | 11880 | blend_line16(p, color->comp[plane].u16[index], alpha, | |
430 | draw->pixelstep[plane], w_sub, | ||
431 | 11880 | draw->hsub[plane], left, right); | |
432 | 11880 | p += dst_linesize[plane]; | |
433 | } | ||
434 | } | ||
435 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2868 times.
|
2868 | if (bottom) { |
436 | ✗ | if (depth <= 8) { | |
437 | ✗ | blend_line(p, color->comp[plane].u8[index], alpha >> 1, | |
438 | draw->pixelstep[plane], w_sub, | ||
439 | ✗ | draw->hsub[plane], left, right); | |
440 | } else { | ||
441 | ✗ | blend_line16(p, color->comp[plane].u16[index], alpha >> 1, | |
442 | draw->pixelstep[plane], w_sub, | ||
443 | ✗ | draw->hsub[plane], left, right); | |
444 | } | ||
445 | } | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | |||
450 | 1070080 | static void blend_pixel16(uint8_t *dst, unsigned src, unsigned alpha, | |
451 | const uint8_t *mask, int mask_linesize, int l2depth, | ||
452 | unsigned w, unsigned h, unsigned shift, unsigned xm0) | ||
453 | { | ||
454 | 1070080 | unsigned t = 0; | |
455 | 1070080 | unsigned xmshf = 3 - l2depth; | |
456 | 1070080 | unsigned xmmod = 7 >> l2depth; | |
457 | 1070080 | unsigned mbits = (1 << (1 << l2depth)) - 1; | |
458 | 1070080 | unsigned mmult = 255 / mbits; | |
459 | 1070080 | uint16_t value = AV_RL16(dst); | |
460 | |||
461 |
2/2✓ Branch 0 taken 1070080 times.
✓ Branch 1 taken 1070080 times.
|
2140160 | for (unsigned y = 0; y < h; y++) { |
462 | 1070080 | unsigned xm = xm0; | |
463 |
2/2✓ Branch 0 taken 1605120 times.
✓ Branch 1 taken 1070080 times.
|
2675200 | for (unsigned x = 0; x < w; x++) { |
464 | 1605120 | t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits) | |
465 | 1605120 | * mmult; | |
466 | 1605120 | xm++; | |
467 | } | ||
468 | 1070080 | mask += mask_linesize; | |
469 | } | ||
470 | 1070080 | alpha = (t >> shift) * alpha; | |
471 | 1070080 | AV_WL16(dst, ((0x10001 - alpha) * value + alpha * src) >> 16); | |
472 | 1070080 | } | |
473 | |||
474 | 8018080 | static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha, | |
475 | const uint8_t *mask, int mask_linesize, int l2depth, | ||
476 | unsigned w, unsigned h, unsigned shift, unsigned xm0) | ||
477 | { | ||
478 | 8018080 | unsigned t = 0; | |
479 | 8018080 | unsigned xmshf = 3 - l2depth; | |
480 | 8018080 | unsigned xmmod = 7 >> l2depth; | |
481 | 8018080 | unsigned mbits = (1 << (1 << l2depth)) - 1; | |
482 | 8018080 | unsigned mmult = 255 / mbits; | |
483 | |||
484 |
2/2✓ Branch 0 taken 9481216 times.
✓ Branch 1 taken 8018080 times.
|
17499296 | for (unsigned y = 0; y < h; y++) { |
485 | 9481216 | unsigned xm = xm0; | |
486 |
2/2✓ Branch 0 taken 12489216 times.
✓ Branch 1 taken 9481216 times.
|
21970432 | for (unsigned x = 0; x < w; x++) { |
487 | 12489216 | t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits) | |
488 | 12489216 | * mmult; | |
489 | 12489216 | xm++; | |
490 | } | ||
491 | 9481216 | mask += mask_linesize; | |
492 | } | ||
493 | 8018080 | alpha = (t >> shift) * alpha; | |
494 | 8018080 | *dst = ((0x1010101 - alpha) * *dst + alpha * src) >> 24; | |
495 | 8018080 | } | |
496 | |||
497 | 163680 | static void blend_line_hv16(uint8_t *dst, int dst_delta, | |
498 | unsigned src, unsigned alpha, | ||
499 | const uint8_t *mask, int mask_linesize, int l2depth, int w, | ||
500 | unsigned hsub, unsigned vsub, | ||
501 | int xm, int left, int right, int hband) | ||
502 | { | ||
503 | |||
504 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 163680 times.
|
163680 | if (left) { |
505 | ✗ | blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth, | |
506 | left, hband, hsub + vsub, xm); | ||
507 | ✗ | dst += dst_delta; | |
508 | ✗ | xm += left; | |
509 | } | ||
510 |
2/2✓ Branch 0 taken 1070080 times.
✓ Branch 1 taken 163680 times.
|
1233760 | for (int x = 0; x < w; x++) { |
511 | 1070080 | blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth, | |
512 | 1070080 | 1 << hsub, hband, hsub + vsub, xm); | |
513 | 1070080 | dst += dst_delta; | |
514 | 1070080 | xm += 1 << hsub; | |
515 | } | ||
516 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 163680 times.
|
163680 | if (right) |
517 | ✗ | blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth, | |
518 | right, hband, hsub + vsub, xm); | ||
519 | 163680 | } | |
520 | |||
521 | 969204 | static void blend_line_hv(uint8_t *dst, int dst_delta, | |
522 | unsigned src, unsigned alpha, | ||
523 | const uint8_t *mask, int mask_linesize, int l2depth, int w, | ||
524 | unsigned hsub, unsigned vsub, | ||
525 | int xm, int left, int right, int hband) | ||
526 | { | ||
527 | |||
528 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 969204 times.
|
969204 | if (left) { |
529 | ✗ | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, | |
530 | left, hband, hsub + vsub, xm); | ||
531 | ✗ | dst += dst_delta; | |
532 | ✗ | xm += left; | |
533 | } | ||
534 |
2/2✓ Branch 0 taken 8018080 times.
✓ Branch 1 taken 969204 times.
|
8987284 | for (int x = 0; x < w; x++) { |
535 | 8018080 | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, | |
536 | 8018080 | 1 << hsub, hband, hsub + vsub, xm); | |
537 | 8018080 | dst += dst_delta; | |
538 | 8018080 | xm += 1 << hsub; | |
539 | } | ||
540 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 969204 times.
|
969204 | if (right) |
541 | ✗ | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, | |
542 | right, hband, hsub + vsub, xm); | ||
543 | 969204 | } | |
544 | |||
545 | 29824 | void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, | |
546 | uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, | ||
547 | const uint8_t *mask, int mask_linesize, int mask_w, int mask_h, | ||
548 | int l2depth, unsigned endianness, int x0, int y0) | ||
549 | { | ||
550 | unsigned alpha, nb_planes, nb_comp; | ||
551 | int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom; | ||
552 | uint8_t *p; | ||
553 | const uint8_t *m; | ||
554 | |||
555 | 59648 | nb_comp = draw->desc->nb_components - | |
556 |
3/4✓ Branch 0 taken 2434 times.
✓ Branch 1 taken 27390 times.
✓ Branch 2 taken 2434 times.
✗ Branch 3 not taken.
|
29824 | !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
557 | |||
558 | 29824 | clip_interval(dst_w, &x0, &mask_w, &xm0); | |
559 | 29824 | clip_interval(dst_h, &y0, &mask_h, &ym0); | |
560 | 29824 | mask += ym0 * mask_linesize; | |
561 |
3/6✓ Branch 0 taken 29824 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29824 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29824 times.
|
29824 | if (mask_w <= 0 || mask_h <= 0 || !color->rgba[3]) |
562 | ✗ | return; | |
563 |
2/2✓ Branch 0 taken 26414 times.
✓ Branch 1 taken 3410 times.
|
29824 | if (draw->desc->comp[0].depth <= 8) { |
564 | /* alpha is in the [ 0 ; 0x10203 ] range, | ||
565 | alpha * mask is in the [ 0 ; 0x1010101 - 4 ] range */ | ||
566 | 26414 | alpha = (0x10307 * color->rgba[3] + 0x3) >> 8; | |
567 | } else { | ||
568 | 3410 | alpha = (0x101 * color->rgba[3] + 0x2) >> 8; | |
569 | } | ||
570 |
3/4✓ Branch 0 taken 2434 times.
✓ Branch 1 taken 27390 times.
✓ Branch 2 taken 2434 times.
✗ Branch 3 not taken.
|
29824 | nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA)); |
571 | 29824 | nb_planes += !nb_planes; | |
572 |
2/2✓ Branch 0 taken 79364 times.
✓ Branch 1 taken 29824 times.
|
109188 | for (unsigned plane = 0; plane < nb_planes; plane++) { |
573 | 79364 | uint8_t *p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); | |
574 | 79364 | w_sub = mask_w; | |
575 | 79364 | h_sub = mask_h; | |
576 | 79364 | x_sub = x0; | |
577 | 79364 | y_sub = y0; | |
578 | 79364 | subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right); | |
579 | 79364 | subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); | |
580 |
2/2✓ Branch 0 taken 238092 times.
✓ Branch 1 taken 79364 times.
|
317456 | for (unsigned comp = 0; comp < nb_comp; comp++) { |
581 | 238092 | const int depth = draw->desc->comp[comp].depth; | |
582 | 238092 | const int offset = draw->desc->comp[comp].offset; | |
583 | 238092 | const int index = offset / ((depth + 7) / 8); | |
584 | |||
585 |
2/2✓ Branch 0 taken 148620 times.
✓ Branch 1 taken 89472 times.
|
238092 | if (draw->desc->comp[comp].plane != plane) |
586 | 148620 | continue; | |
587 | 89472 | p = p0 + offset; | |
588 | 89472 | m = mask; | |
589 |
2/2✓ Branch 0 taken 180 times.
✓ Branch 1 taken 89292 times.
|
89472 | if (top) { |
590 |
1/2✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
|
180 | if (depth <= 8) { |
591 | 180 | blend_line_hv(p, draw->pixelstep[plane], | |
592 | 180 | color->comp[plane].u8[index], alpha, | |
593 | m, mask_linesize, l2depth, w_sub, | ||
594 | 180 | draw->hsub[plane], draw->vsub[plane], | |
595 | xm0, left, right, top); | ||
596 | } else { | ||
597 | ✗ | blend_line_hv16(p, draw->pixelstep[plane], | |
598 | ✗ | color->comp[plane].u16[index], alpha, | |
599 | m, mask_linesize, l2depth, w_sub, | ||
600 | ✗ | draw->hsub[plane], draw->vsub[plane], | |
601 | xm0, left, right, top); | ||
602 | } | ||
603 | 180 | p += dst_linesize[plane]; | |
604 | 180 | m += top * mask_linesize; | |
605 | } | ||
606 |
2/2✓ Branch 0 taken 79242 times.
✓ Branch 1 taken 10230 times.
|
89472 | if (depth <= 8) { |
607 |
2/2✓ Branch 0 taken 968844 times.
✓ Branch 1 taken 79242 times.
|
1048086 | for (int y = 0; y < h_sub; y++) { |
608 | 968844 | blend_line_hv(p, draw->pixelstep[plane], | |
609 | 968844 | color->comp[plane].u8[index], alpha, | |
610 | m, mask_linesize, l2depth, w_sub, | ||
611 | 968844 | draw->hsub[plane], draw->vsub[plane], | |
612 | 968844 | xm0, left, right, 1 << draw->vsub[plane]); | |
613 | 968844 | p += dst_linesize[plane]; | |
614 | 968844 | m += mask_linesize << draw->vsub[plane]; | |
615 | } | ||
616 | } else { | ||
617 |
2/2✓ Branch 0 taken 163680 times.
✓ Branch 1 taken 10230 times.
|
173910 | for (int y = 0; y < h_sub; y++) { |
618 | 163680 | blend_line_hv16(p, draw->pixelstep[plane], | |
619 | 163680 | color->comp[plane].u16[index], alpha, | |
620 | m, mask_linesize, l2depth, w_sub, | ||
621 | 163680 | draw->hsub[plane], draw->vsub[plane], | |
622 | 163680 | xm0, left, right, 1 << draw->vsub[plane]); | |
623 | 163680 | p += dst_linesize[plane]; | |
624 | 163680 | m += mask_linesize << draw->vsub[plane]; | |
625 | } | ||
626 | } | ||
627 |
2/2✓ Branch 0 taken 180 times.
✓ Branch 1 taken 89292 times.
|
89472 | if (bottom) { |
628 |
1/2✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
|
180 | if (depth <= 8) { |
629 | 180 | blend_line_hv(p, draw->pixelstep[plane], | |
630 | 180 | color->comp[plane].u8[index], alpha, | |
631 | m, mask_linesize, l2depth, w_sub, | ||
632 | 180 | draw->hsub[plane], draw->vsub[plane], | |
633 | xm0, left, right, bottom); | ||
634 | } else { | ||
635 | ✗ | blend_line_hv16(p, draw->pixelstep[plane], | |
636 | ✗ | color->comp[plane].u16[index], alpha, | |
637 | m, mask_linesize, l2depth, w_sub, | ||
638 | ✗ | draw->hsub[plane], draw->vsub[plane], | |
639 | xm0, left, right, bottom); | ||
640 | } | ||
641 | } | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | |||
646 | 230100 | int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, | |
647 | int value) | ||
648 | { | ||
649 |
2/2✓ Branch 0 taken 206764 times.
✓ Branch 1 taken 23336 times.
|
230100 | unsigned shift = sub_dir ? draw->vsub_max : draw->hsub_max; |
650 | |||
651 |
2/2✓ Branch 0 taken 105718 times.
✓ Branch 1 taken 124382 times.
|
230100 | if (!shift) |
652 | 105718 | return value; | |
653 |
2/2✓ Branch 0 taken 104106 times.
✓ Branch 1 taken 20276 times.
|
124382 | if (round_dir >= 0) |
654 |
2/2✓ Branch 0 taken 3396 times.
✓ Branch 1 taken 100710 times.
|
104106 | value += round_dir ? (1 << shift) - 1 : 1 << (shift - 1); |
655 | 124382 | return (value >> shift) << shift; | |
656 | } | ||
657 | |||
658 | 166 | AVFilterFormats *ff_draw_supported_pixel_formats(unsigned flags) | |
659 | { | ||
660 | FFDrawContext draw; | ||
661 | 166 | AVFilterFormats *fmts = NULL; | |
662 | int ret; | ||
663 | |||
664 |
2/2✓ Branch 1 taken 42828 times.
✓ Branch 2 taken 166 times.
|
42994 | for (enum AVPixelFormat i = 0; av_pix_fmt_desc_get(i); i++) |
665 |
3/4✓ Branch 1 taken 15438 times.
✓ Branch 2 taken 27390 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15438 times.
|
58266 | if (ff_draw_init(&draw, i, flags) >= 0 && |
666 | 15438 | (ret = ff_add_format(&fmts, i)) < 0) | |
667 | ✗ | return NULL; | |
668 | 166 | return fmts; | |
669 | } | ||
670 |