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 | 1144 | static int fill_map(const AVPixFmtDescriptor *desc, uint8_t *map) | |
36 | { | ||
37 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1144 times.
|
1144 | 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 1110 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1144 times.
|
1144 | av_assert0(desc->nb_components == 3 + !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)); |
41 |
2/2✓ Branch 0 taken 913 times.
✓ Branch 1 taken 231 times.
|
1144 | if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) { |
42 |
2/2✓ Branch 2 taken 295 times.
✓ Branch 3 taken 618 times.
|
913 | if (desc->nb_components != av_pix_fmt_count_planes(av_pix_fmt_desc_get_id(desc))) |
43 | 295 | return AVERROR(EINVAL); | |
44 | 618 | map[RED] = desc->comp[0].plane; | |
45 | 618 | map[GREEN] = desc->comp[1].plane; | |
46 | 618 | map[BLUE] = desc->comp[2].plane; | |
47 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 602 times.
|
618 | 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 846 times.
|
846 | av_assert0(map[RED] != map[GREEN]); |
71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 846 times.
|
846 | av_assert0(map[GREEN] != map[BLUE]); |
72 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 846 times.
|
846 | av_assert0(map[BLUE] != map[RED]); |
73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 846 times.
|
846 | av_assert0(map[RED] != map[ALPHA]); |
74 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 846 times.
|
846 | av_assert0(map[GREEN] != map[ALPHA]); |
75 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 846 times.
|
846 | av_assert0(map[BLUE] != map[ALPHA]); |
76 | |||
77 | 846 | 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 | 600 | int ff_fill_ayuv_map(uint8_t *ayuv_map, enum AVPixelFormat pix_fmt) | |
89 | { | ||
90 | 600 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); | |
91 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 600 times.
|
600 | if (desc->flags & AV_PIX_FMT_FLAG_RGB) |
92 | ✗ | return AVERROR(EINVAL); | |
93 | 600 | return fill_map(desc, ayuv_map); | |
94 | } | ||
95 | |||
96 | 45886 | int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp, | |
97 | enum AVColorRange range, enum AVAlphaMode alpha, unsigned flags) | ||
98 | { | ||
99 | 45886 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); | |
100 | 45886 | const AVLumaCoefficients *luma = NULL; | |
101 | const AVComponentDescriptor *c; | ||
102 | 45886 | unsigned nb_planes = 0; | |
103 | 45886 | int pixelstep[MAX_PLANES] = { 0 }; | |
104 | 45886 | int depthb = 0; | |
105 | |||
106 |
2/4✓ Branch 0 taken 45886 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45886 times.
|
45886 | if (!desc || !desc->name) |
107 | ✗ | return AVERROR(EINVAL); | |
108 |
2/2✓ Branch 0 taken 16758 times.
✓ Branch 1 taken 29128 times.
|
45886 | if (desc->flags & AV_PIX_FMT_FLAG_BE) |
109 | 16758 | return AVERROR(ENOSYS); | |
110 |
2/2✓ Branch 0 taken 7182 times.
✓ Branch 1 taken 21946 times.
|
29128 | if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA)) |
111 | 7182 | return AVERROR(ENOSYS); | |
112 |
2/2✓ Branch 0 taken 21896 times.
✓ Branch 1 taken 50 times.
|
21946 | if (csp == AVCOL_SPC_UNSPECIFIED) |
113 |
2/2✓ Branch 0 taken 7182 times.
✓ Branch 1 taken 14714 times.
|
21896 | csp = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? AVCOL_SPC_RGB : AVCOL_SPC_SMPTE170M; |
114 |
3/4✓ Branch 0 taken 14714 times.
✓ Branch 1 taken 7232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14714 times.
|
21946 | 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 21765 times.
✓ Branch 1 taken 181 times.
|
21946 | if (range == AVCOL_RANGE_UNSPECIFIED) |
117 |
4/4✓ Branch 0 taken 21423 times.
✓ Branch 1 taken 171 times.
✓ Branch 2 taken 21252 times.
✓ Branch 3 taken 171 times.
|
43359 | range = (format == AV_PIX_FMT_YUVJ420P || format == AV_PIX_FMT_YUVJ422P || |
118 |
4/4✓ Branch 0 taken 21081 times.
✓ Branch 1 taken 171 times.
✓ Branch 2 taken 20910 times.
✓ Branch 3 taken 171 times.
|
21252 | format == AV_PIX_FMT_YUVJ444P || format == AV_PIX_FMT_YUVJ411P || |
119 |
2/2✓ Branch 0 taken 7182 times.
✓ Branch 1 taken 13728 times.
|
20910 | format == AV_PIX_FMT_YUVJ440P || csp == AVCOL_SPC_RGB) |
120 |
2/2✓ Branch 0 taken 21594 times.
✓ Branch 1 taken 171 times.
|
43359 | ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; |
121 |
3/4✓ Branch 0 taken 13838 times.
✓ Branch 1 taken 8108 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13838 times.
|
21946 | if (range != AVCOL_RANGE_JPEG && range != AVCOL_RANGE_MPEG) |
122 | ✗ | return AVERROR(EINVAL); | |
123 |
2/2✓ Branch 0 taken 59038 times.
✓ Branch 1 taken 16816 times.
|
75854 | for (unsigned i = 0; i < desc->nb_components; i++) { |
124 | int db; | ||
125 | 59038 | c = &desc->comp[i]; | |
126 | /* for now, only 8-16 bits formats */ | ||
127 |
4/4✓ Branch 0 taken 57328 times.
✓ Branch 1 taken 1710 times.
✓ Branch 2 taken 684 times.
✓ Branch 3 taken 56644 times.
|
59038 | if (c->depth < 8 || c->depth > 16) |
128 | 2394 | return AVERROR(ENOSYS); | |
129 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56644 times.
|
56644 | 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 6699 times.
✓ Branch 1 taken 49945 times.
✓ Branch 2 taken 684 times.
✓ Branch 3 taken 6015 times.
|
56644 | if (c->shift && ((c->shift + c->depth) & 0x7)) |
133 | 684 | return AVERROR(ENOSYS); | |
134 | /* mixed >8 and <=8 depth */ | ||
135 | 55960 | db = (c->depth + 7) / 8; | |
136 |
3/4✓ Branch 0 taken 36921 times.
✓ Branch 1 taken 19039 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36921 times.
|
55960 | if (depthb && (depthb != db)) |
137 | ✗ | return AVERROR(ENOSYS); | |
138 | 55960 | depthb = db; | |
139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 55960 times.
|
55960 | if (db * (c->offset + 1) > 16) |
140 | ✗ | return AVERROR(ENOSYS); | |
141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 55960 times.
|
55960 | if (c->offset % db) |
142 | ✗ | return AVERROR(ENOSYS); | |
143 | /* strange interleaving */ | ||
144 |
2/2✓ Branch 0 taken 11223 times.
✓ Branch 1 taken 44737 times.
|
55960 | if (pixelstep[c->plane] != 0 && |
145 |
2/2✓ Branch 0 taken 1197 times.
✓ Branch 1 taken 10026 times.
|
11223 | pixelstep[c->plane] != c->step) |
146 | 1197 | return AVERROR(ENOSYS); | |
147 | 54763 | pixelstep[c->plane] = c->step; | |
148 |
2/2✓ Branch 0 taken 855 times.
✓ Branch 1 taken 53908 times.
|
54763 | if (pixelstep[c->plane] >= 8) |
149 | 855 | return AVERROR(ENOSYS); | |
150 | 53908 | nb_planes = FFMAX(nb_planes, c->plane + 1); | |
151 | } | ||
152 | 16816 | memset(draw, 0, sizeof(*draw)); | |
153 | 16816 | draw->desc = desc; | |
154 | 16816 | draw->format = format; | |
155 | 16816 | draw->nb_planes = nb_planes; | |
156 | 16816 | draw->range = range; | |
157 | 16816 | draw->csp = csp; | |
158 | 16816 | draw->alpha = alpha; | |
159 | 16816 | draw->flags = flags; | |
160 |
2/2✓ Branch 0 taken 12491 times.
✓ Branch 1 taken 4325 times.
|
16816 | if (luma) |
161 | 12491 | ff_fill_rgb2yuv_table(luma, draw->rgb2yuv); | |
162 | 16816 | memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep)); | |
163 | 16816 | draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w; | |
164 | 16816 | draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h; | |
165 | 16816 | return 0; | |
166 | } | ||
167 | |||
168 | 229 | int ff_draw_init_from_link(FFDrawContext *draw, const AVFilterLink *link, | |
169 | unsigned flags) | ||
170 | { | ||
171 | 229 | return ff_draw_init2(draw, link->format, link->colorspace, link->color_range, link->alpha_mode, flags); | |
172 | } | ||
173 | |||
174 | 45657 | int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) | |
175 | { | ||
176 | 45657 | return ff_draw_init2(draw, format, AVCOL_SPC_UNSPECIFIED, AVCOL_RANGE_UNSPECIFIED, AVALPHA_MODE_UNSPECIFIED, flags); | |
177 | } | ||
178 | |||
179 | 209616 | void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4]) | |
180 | { | ||
181 | double yuvad[4]; | ||
182 | double rgbad[4]; | ||
183 | 209616 | const AVPixFmtDescriptor *desc = draw->desc; | |
184 | |||
185 |
1/2✓ Branch 0 taken 209616 times.
✗ Branch 1 not taken.
|
209616 | if (rgba != color->rgba) |
186 | 209616 | memcpy(color->rgba, rgba, sizeof(color->rgba)); | |
187 | |||
188 | 209616 | memset(color->comp, 0, sizeof(color->comp)); | |
189 | |||
190 |
2/2✓ Branch 0 taken 838464 times.
✓ Branch 1 taken 209616 times.
|
1048080 | for (int i = 0; i < 4; i++) |
191 | 838464 | rgbad[i] = color->rgba[i] / 255.; | |
192 | |||
193 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 209616 times.
|
209616 | if (draw->alpha == AVALPHA_MODE_PREMULTIPLIED) { |
194 | ✗ | for (int i = 0; i < 3; i++) | |
195 | ✗ | rgbad[i] *= rgbad[3]; | |
196 | } | ||
197 | |||
198 |
2/2✓ Branch 0 taken 54602 times.
✓ Branch 1 taken 155014 times.
|
209616 | if (draw->desc->flags & AV_PIX_FMT_FLAG_RGB) |
199 | 54602 | memcpy(yuvad, rgbad, sizeof(double) * 3); | |
200 | else | ||
201 | 155014 | ff_matrix_mul_3x3_vec(yuvad, rgbad, draw->rgb2yuv); | |
202 | |||
203 | 209616 | yuvad[3] = rgbad[3]; | |
204 | |||
205 |
2/2✓ Branch 0 taken 628848 times.
✓ Branch 1 taken 209616 times.
|
838464 | for (int i = 0; i < 3; i++) { |
206 |
4/4✓ Branch 0 taken 465042 times.
✓ Branch 1 taken 163806 times.
✓ Branch 2 taken 310028 times.
✓ Branch 3 taken 155014 times.
|
628848 | int chroma = (!(draw->desc->flags & AV_PIX_FMT_FLAG_RGB) && i > 0); |
207 |
2/2✓ Branch 0 taken 464979 times.
✓ Branch 1 taken 163869 times.
|
628848 | if (draw->range == AVCOL_RANGE_MPEG) { |
208 |
2/2✓ Branch 0 taken 309986 times.
✓ Branch 1 taken 154993 times.
|
464979 | yuvad[i] *= (chroma ? 224. : 219.) / 255.; |
209 |
2/2✓ Branch 0 taken 309986 times.
✓ Branch 1 taken 154993 times.
|
464979 | yuvad[i] += (chroma ? 128. : 16.) / 255.; |
210 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 163827 times.
|
163869 | } else if (chroma) { |
211 | 42 | yuvad[i] += 0.5; | |
212 | } | ||
213 | } | ||
214 | |||
215 | // Ensure we place the alpha appropriately for gray formats | ||
216 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 209606 times.
|
209616 | if (desc->nb_components <= 2) |
217 | 10 | yuvad[1] = yuvad[3]; | |
218 | |||
219 |
2/2✓ Branch 0 taken 654859 times.
✓ Branch 1 taken 209616 times.
|
864475 | for (unsigned i = 0; i < desc->nb_components; i++) { |
220 | 654859 | unsigned val = yuvad[i] * ((1 << (draw->desc->comp[i].depth + draw->desc->comp[i].shift)) - 1) + 0.5; | |
221 |
2/2✓ Branch 0 taken 59677 times.
✓ Branch 1 taken 595182 times.
|
654859 | if (desc->comp[i].depth > 8) |
222 | 59677 | color->comp[desc->comp[i].plane].u16[desc->comp[i].offset / 2] = val; | |
223 | else | ||
224 | 595182 | color->comp[desc->comp[i].plane].u8[desc->comp[i].offset] = val; | |
225 | } | ||
226 | 209616 | } | |
227 | |||
228 | 608737 | static uint8_t *pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[], | |
229 | int plane, int x, int y) | ||
230 | { | ||
231 | 608737 | return data[plane] + | |
232 | 1217474 | (y >> draw->vsub[plane]) * linesize[plane] + | |
233 | 608737 | (x >> draw->hsub[plane]) * draw->pixelstep[plane]; | |
234 | } | ||
235 | |||
236 | 40 | void ff_copy_rectangle2(FFDrawContext *draw, | |
237 | uint8_t *dst[], int dst_linesize[], | ||
238 | uint8_t *src[], int src_linesize[], | ||
239 | int dst_x, int dst_y, int src_x, int src_y, | ||
240 | int w, int h) | ||
241 | { | ||
242 | int wp, hp; | ||
243 | uint8_t *p, *q; | ||
244 | |||
245 |
2/2✓ Branch 0 taken 120 times.
✓ Branch 1 taken 40 times.
|
160 | for (int plane = 0; plane < draw->nb_planes; plane++) { |
246 | 120 | p = pointer_at(draw, src, src_linesize, plane, src_x, src_y); | |
247 | 120 | q = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y); | |
248 | 120 | wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]) * draw->pixelstep[plane]; | |
249 | 120 | hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]); | |
250 |
2/2✓ Branch 0 taken 23040 times.
✓ Branch 1 taken 120 times.
|
23160 | for (int y = 0; y < hp; y++) { |
251 | 23040 | memcpy(q, p, wp); | |
252 | 23040 | p += src_linesize[plane]; | |
253 | 23040 | q += dst_linesize[plane]; | |
254 | } | ||
255 | } | ||
256 | 40 | } | |
257 | |||
258 | 211727 | void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, | |
259 | uint8_t *dst[], int dst_linesize[], | ||
260 | int dst_x, int dst_y, int w, int h) | ||
261 | { | ||
262 | int wp, hp; | ||
263 | uint8_t *p0, *p; | ||
264 | 211727 | FFDrawColor color_tmp = *color; | |
265 | |||
266 |
2/2✓ Branch 0 taken 526577 times.
✓ Branch 1 taken 211727 times.
|
738304 | for (int plane = 0; plane < draw->nb_planes; plane++) { |
267 | 526577 | p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y); | |
268 | 526577 | wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]); | |
269 | 526577 | hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]); | |
270 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 526577 times.
|
526577 | if (!hp) |
271 | ✗ | return; | |
272 | 526577 | p = p0; | |
273 | |||
274 | if (HAVE_BIGENDIAN && draw->desc->comp[0].depth > 8) { | ||
275 | for (int x = 0; 2*x < draw->pixelstep[plane]; x++) | ||
276 | color_tmp.comp[plane].u16[x] = av_bswap16(color_tmp.comp[plane].u16[x]); | ||
277 | } | ||
278 | |||
279 | /* copy first line from color */ | ||
280 |
2/2✓ Branch 0 taken 2306733 times.
✓ Branch 1 taken 526577 times.
|
2833310 | for (int x = 0; x < wp; x++) { |
281 | 2306733 | memcpy(p, color_tmp.comp[plane].u8, draw->pixelstep[plane]); | |
282 | 2306733 | p += draw->pixelstep[plane]; | |
283 | } | ||
284 | 526577 | wp *= draw->pixelstep[plane]; | |
285 | /* copy next lines from first line */ | ||
286 | 526577 | p = p0 + dst_linesize[plane]; | |
287 |
2/2✓ Branch 0 taken 9198872 times.
✓ Branch 1 taken 526577 times.
|
9725449 | for (int y = 1; y < hp; y++) { |
288 | 9198872 | memcpy(p, p0, wp); | |
289 | 9198872 | p += dst_linesize[plane]; | |
290 | } | ||
291 | } | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * Clip interval [x; x+w[ within [0; wmax[. | ||
296 | * The resulting w may be negative if the final interval is empty. | ||
297 | * dx, if not null, return the difference between in and out value of x. | ||
298 | */ | ||
299 | 61560 | static void clip_interval(int wmax, int *x, int *w, int *dx) | |
300 | { | ||
301 |
2/2✓ Branch 0 taken 59648 times.
✓ Branch 1 taken 1912 times.
|
61560 | if (dx) |
302 | 59648 | *dx = 0; | |
303 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 61560 times.
|
61560 | if (*x < 0) { |
304 | ✗ | if (dx) | |
305 | ✗ | *dx = -*x; | |
306 | ✗ | *w += *x; | |
307 | ✗ | *x = 0; | |
308 | } | ||
309 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 61560 times.
|
61560 | if (*x + *w > wmax) |
310 | ✗ | *w = wmax - *x; | |
311 | 61560 | } | |
312 | |||
313 | /** | ||
314 | * Decompose w pixels starting at x | ||
315 | * into start + (w starting at x) + end | ||
316 | * with x and w aligned on multiples of 1<<sub. | ||
317 | */ | ||
318 | 163840 | static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end) | |
319 | { | ||
320 | 163840 | int mask = (1 << sub) - 1; | |
321 | |||
322 | 163840 | *start = (-*x) & mask; | |
323 | 163840 | *x += *start; | |
324 | 163840 | *start = FFMIN(*start, *w); | |
325 | 163840 | *w -= *start; | |
326 | 163840 | *end = *w & mask; | |
327 | 163840 | *w >>= sub; | |
328 | 163840 | } | |
329 | |||
330 | /* If alpha is in the [ 0 ; 0x1010101 ] range, | ||
331 | then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range, | ||
332 | and >> 24 gives a correct rounding. */ | ||
333 | 69660 | static void blend_line(uint8_t *dst, unsigned src, unsigned alpha, | |
334 | int dx, int w, unsigned hsub, int left, int right) | ||
335 | { | ||
336 | 69660 | unsigned asrc = alpha * src; | |
337 | 69660 | unsigned tau = 0x1010101 - alpha; | |
338 | |||
339 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 69660 times.
|
69660 | if (left) { |
340 | ✗ | unsigned suba = (left * alpha) >> hsub; | |
341 | ✗ | *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24; | |
342 | ✗ | dst += dx; | |
343 | } | ||
344 |
2/2✓ Branch 0 taken 5819400 times.
✓ Branch 1 taken 69660 times.
|
5889060 | for (int x = 0; x < w; x++) { |
345 | 5819400 | *dst = (*dst * tau + asrc) >> 24; | |
346 | 5819400 | dst += dx; | |
347 | } | ||
348 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 69660 times.
|
69660 | if (right) { |
349 | ✗ | unsigned suba = (right * alpha) >> hsub; | |
350 | ✗ | *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24; | |
351 | } | ||
352 | 69660 | } | |
353 | |||
354 | 11880 | static void blend_line16(uint8_t *dst, unsigned src, unsigned alpha, | |
355 | int dx, int w, unsigned hsub, int left, int right) | ||
356 | { | ||
357 | 11880 | unsigned asrc = alpha * src; | |
358 | 11880 | unsigned tau = 0x10001 - alpha; | |
359 | |||
360 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11880 times.
|
11880 | if (left) { |
361 | ✗ | unsigned suba = (left * alpha) >> hsub; | |
362 | ✗ | uint16_t value = AV_RL16(dst); | |
363 | ✗ | AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16); | |
364 | ✗ | dst += dx; | |
365 | } | ||
366 |
2/2✓ Branch 0 taken 792000 times.
✓ Branch 1 taken 11880 times.
|
803880 | for (int x = 0; x < w; x++) { |
367 | 792000 | uint16_t value = AV_RL16(dst); | |
368 | 792000 | AV_WL16(dst, (value * tau + asrc) >> 16); | |
369 | 792000 | dst += dx; | |
370 | } | ||
371 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11880 times.
|
11880 | if (right) { |
372 | ✗ | unsigned suba = (right * alpha) >> hsub; | |
373 | ✗ | uint16_t value = AV_RL16(dst); | |
374 | ✗ | AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16); | |
375 | } | ||
376 | 11880 | } | |
377 | |||
378 | 956 | void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, | |
379 | uint8_t *dst[], int dst_linesize[], | ||
380 | int dst_w, int dst_h, | ||
381 | int x0, int y0, int w, int h) | ||
382 | { | ||
383 | unsigned alpha, nb_planes, nb_comp; | ||
384 | int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom; | ||
385 | uint8_t *p0, *p; | ||
386 | |||
387 | 1912 | nb_comp = draw->desc->nb_components - | |
388 |
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)); |
389 | |||
390 | /* TODO optimize if alpha = 0xFF */ | ||
391 | 956 | clip_interval(dst_w, &x0, &w, NULL); | |
392 | 956 | clip_interval(dst_h, &y0, &h, NULL); | |
393 |
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]) |
394 | ✗ | return; | |
395 |
2/2✓ Branch 0 taken 846 times.
✓ Branch 1 taken 110 times.
|
956 | if (draw->desc->comp[0].depth <= 8) { |
396 | /* 0x10203 * alpha + 2 is in the [ 2 ; 0x1010101 - 2 ] range */ | ||
397 | 846 | alpha = 0x10203 * color->rgba[3] + 0x2; | |
398 | } else { | ||
399 | /* 0x101 * alpha is in the [ 2 ; 0x1001] range */ | ||
400 | 110 | alpha = 0x101 * color->rgba[3] + 0x2; | |
401 | } | ||
402 |
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)); |
403 | 956 | nb_planes += !nb_planes; | |
404 |
2/2✓ Branch 0 taken 2556 times.
✓ Branch 1 taken 956 times.
|
3512 | for (unsigned plane = 0; plane < nb_planes; plane++) { |
405 | 2556 | p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); | |
406 | 2556 | w_sub = w; | |
407 | 2556 | h_sub = h; | |
408 | 2556 | x_sub = x0; | |
409 | 2556 | y_sub = y0; | |
410 | 2556 | subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right); | |
411 | 2556 | subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); | |
412 |
2/2✓ Branch 0 taken 7668 times.
✓ Branch 1 taken 2556 times.
|
10224 | for (unsigned comp = 0; comp < nb_comp; comp++) { |
413 | 7668 | const int depth = draw->desc->comp[comp].depth; | |
414 | 7668 | const int offset = draw->desc->comp[comp].offset; | |
415 | 7668 | const int index = offset / ((depth + 7) / 8); | |
416 | |||
417 |
2/2✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 2868 times.
|
7668 | if (draw->desc->comp[comp].plane != plane) |
418 | 4800 | continue; | |
419 | 2868 | p = p0 + offset; | |
420 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2868 times.
|
2868 | if (top) { |
421 | ✗ | if (depth <= 8) { | |
422 | ✗ | blend_line(p, color->comp[plane].u8[index], alpha >> 1, | |
423 | draw->pixelstep[plane], w_sub, | ||
424 | ✗ | draw->hsub[plane], left, right); | |
425 | } else { | ||
426 | ✗ | blend_line16(p, color->comp[plane].u16[index], alpha >> 1, | |
427 | draw->pixelstep[plane], w_sub, | ||
428 | ✗ | draw->hsub[plane], left, right); | |
429 | } | ||
430 | ✗ | p += dst_linesize[plane]; | |
431 | } | ||
432 |
2/2✓ Branch 0 taken 2538 times.
✓ Branch 1 taken 330 times.
|
2868 | if (depth <= 8) { |
433 |
2/2✓ Branch 0 taken 69660 times.
✓ Branch 1 taken 2538 times.
|
72198 | for (int y = 0; y < h_sub; y++) { |
434 | 69660 | blend_line(p, color->comp[plane].u8[index], alpha, | |
435 | draw->pixelstep[plane], w_sub, | ||
436 | 69660 | draw->hsub[plane], left, right); | |
437 | 69660 | p += dst_linesize[plane]; | |
438 | } | ||
439 | } else { | ||
440 |
2/2✓ Branch 0 taken 11880 times.
✓ Branch 1 taken 330 times.
|
12210 | for (int y = 0; y < h_sub; y++) { |
441 | 11880 | blend_line16(p, color->comp[plane].u16[index], alpha, | |
442 | draw->pixelstep[plane], w_sub, | ||
443 | 11880 | draw->hsub[plane], left, right); | |
444 | 11880 | p += dst_linesize[plane]; | |
445 | } | ||
446 | } | ||
447 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2868 times.
|
2868 | if (bottom) { |
448 | ✗ | if (depth <= 8) { | |
449 | ✗ | blend_line(p, color->comp[plane].u8[index], alpha >> 1, | |
450 | draw->pixelstep[plane], w_sub, | ||
451 | ✗ | draw->hsub[plane], left, right); | |
452 | } else { | ||
453 | ✗ | blend_line16(p, color->comp[plane].u16[index], alpha >> 1, | |
454 | draw->pixelstep[plane], w_sub, | ||
455 | ✗ | draw->hsub[plane], left, right); | |
456 | } | ||
457 | } | ||
458 | } | ||
459 | } | ||
460 | } | ||
461 | |||
462 | 1070080 | static void blend_pixel16(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 | 1070080 | unsigned t = 0; | |
467 | 1070080 | unsigned xmshf = 3 - l2depth; | |
468 | 1070080 | unsigned xmmod = 7 >> l2depth; | |
469 | 1070080 | unsigned mbits = (1 << (1 << l2depth)) - 1; | |
470 | 1070080 | unsigned mmult = 255 / mbits; | |
471 | 1070080 | uint16_t value = AV_RL16(dst); | |
472 | |||
473 |
2/2✓ Branch 0 taken 1070080 times.
✓ Branch 1 taken 1070080 times.
|
2140160 | for (unsigned y = 0; y < h; y++) { |
474 | 1070080 | unsigned xm = xm0; | |
475 |
2/2✓ Branch 0 taken 1605120 times.
✓ Branch 1 taken 1070080 times.
|
2675200 | for (unsigned x = 0; x < w; x++) { |
476 | 1605120 | t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits) | |
477 | 1605120 | * mmult; | |
478 | 1605120 | xm++; | |
479 | } | ||
480 | 1070080 | mask += mask_linesize; | |
481 | } | ||
482 | 1070080 | alpha = (t >> shift) * alpha; | |
483 | 1070080 | AV_WL16(dst, ((0x10001 - alpha) * value + alpha * src) >> 16); | |
484 | 1070080 | } | |
485 | |||
486 | 8018080 | static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha, | |
487 | const uint8_t *mask, int mask_linesize, int l2depth, | ||
488 | unsigned w, unsigned h, unsigned shift, unsigned xm0) | ||
489 | { | ||
490 | 8018080 | unsigned t = 0; | |
491 | 8018080 | unsigned xmshf = 3 - l2depth; | |
492 | 8018080 | unsigned xmmod = 7 >> l2depth; | |
493 | 8018080 | unsigned mbits = (1 << (1 << l2depth)) - 1; | |
494 | 8018080 | unsigned mmult = 255 / mbits; | |
495 | |||
496 |
2/2✓ Branch 0 taken 9481216 times.
✓ Branch 1 taken 8018080 times.
|
17499296 | for (unsigned y = 0; y < h; y++) { |
497 | 9481216 | unsigned xm = xm0; | |
498 |
2/2✓ Branch 0 taken 12489216 times.
✓ Branch 1 taken 9481216 times.
|
21970432 | for (unsigned x = 0; x < w; x++) { |
499 | 12489216 | t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits) | |
500 | 12489216 | * mmult; | |
501 | 12489216 | xm++; | |
502 | } | ||
503 | 9481216 | mask += mask_linesize; | |
504 | } | ||
505 | 8018080 | alpha = (t >> shift) * alpha; | |
506 | 8018080 | *dst = ((0x1010101 - alpha) * *dst + alpha * src) >> 24; | |
507 | 8018080 | } | |
508 | |||
509 | 163680 | static void blend_line_hv16(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 | |||
516 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 163680 times.
|
163680 | if (left) { |
517 | ✗ | blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth, | |
518 | left, hband, hsub + vsub, xm); | ||
519 | ✗ | dst += dst_delta; | |
520 | ✗ | xm += left; | |
521 | } | ||
522 |
2/2✓ Branch 0 taken 1070080 times.
✓ Branch 1 taken 163680 times.
|
1233760 | for (int x = 0; x < w; x++) { |
523 | 1070080 | blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth, | |
524 | 1070080 | 1 << hsub, hband, hsub + vsub, xm); | |
525 | 1070080 | dst += dst_delta; | |
526 | 1070080 | xm += 1 << hsub; | |
527 | } | ||
528 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 163680 times.
|
163680 | if (right) |
529 | ✗ | blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth, | |
530 | right, hband, hsub + vsub, xm); | ||
531 | 163680 | } | |
532 | |||
533 | 969204 | static void blend_line_hv(uint8_t *dst, int dst_delta, | |
534 | unsigned src, unsigned alpha, | ||
535 | const uint8_t *mask, int mask_linesize, int l2depth, int w, | ||
536 | unsigned hsub, unsigned vsub, | ||
537 | int xm, int left, int right, int hband) | ||
538 | { | ||
539 | |||
540 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 969204 times.
|
969204 | if (left) { |
541 | ✗ | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, | |
542 | left, hband, hsub + vsub, xm); | ||
543 | ✗ | dst += dst_delta; | |
544 | ✗ | xm += left; | |
545 | } | ||
546 |
2/2✓ Branch 0 taken 8018080 times.
✓ Branch 1 taken 969204 times.
|
8987284 | for (int x = 0; x < w; x++) { |
547 | 8018080 | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, | |
548 | 8018080 | 1 << hsub, hband, hsub + vsub, xm); | |
549 | 8018080 | dst += dst_delta; | |
550 | 8018080 | xm += 1 << hsub; | |
551 | } | ||
552 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 969204 times.
|
969204 | if (right) |
553 | ✗ | blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, | |
554 | right, hband, hsub + vsub, xm); | ||
555 | 969204 | } | |
556 | |||
557 | 29824 | void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, | |
558 | uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, | ||
559 | const uint8_t *mask, int mask_linesize, int mask_w, int mask_h, | ||
560 | int l2depth, unsigned endianness, int x0, int y0) | ||
561 | { | ||
562 | unsigned alpha, nb_planes, nb_comp; | ||
563 | int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom; | ||
564 | uint8_t *p; | ||
565 | const uint8_t *m; | ||
566 | |||
567 | 59648 | nb_comp = draw->desc->nb_components - | |
568 |
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)); |
569 | |||
570 | 29824 | clip_interval(dst_w, &x0, &mask_w, &xm0); | |
571 | 29824 | clip_interval(dst_h, &y0, &mask_h, &ym0); | |
572 | 29824 | mask += ym0 * mask_linesize; | |
573 |
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]) |
574 | ✗ | return; | |
575 |
2/2✓ Branch 0 taken 26414 times.
✓ Branch 1 taken 3410 times.
|
29824 | if (draw->desc->comp[0].depth <= 8) { |
576 | /* alpha is in the [ 0 ; 0x10203 ] range, | ||
577 | alpha * mask is in the [ 0 ; 0x1010101 - 4 ] range */ | ||
578 | 26414 | alpha = (0x10307 * color->rgba[3] + 0x3) >> 8; | |
579 | } else { | ||
580 | 3410 | alpha = (0x101 * color->rgba[3] + 0x2) >> 8; | |
581 | } | ||
582 |
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)); |
583 | 29824 | nb_planes += !nb_planes; | |
584 |
2/2✓ Branch 0 taken 79364 times.
✓ Branch 1 taken 29824 times.
|
109188 | for (unsigned plane = 0; plane < nb_planes; plane++) { |
585 | 79364 | uint8_t *p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); | |
586 | 79364 | w_sub = mask_w; | |
587 | 79364 | h_sub = mask_h; | |
588 | 79364 | x_sub = x0; | |
589 | 79364 | y_sub = y0; | |
590 | 79364 | subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right); | |
591 | 79364 | subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); | |
592 |
2/2✓ Branch 0 taken 238092 times.
✓ Branch 1 taken 79364 times.
|
317456 | for (unsigned comp = 0; comp < nb_comp; comp++) { |
593 | 238092 | const int depth = draw->desc->comp[comp].depth; | |
594 | 238092 | const int offset = draw->desc->comp[comp].offset; | |
595 | 238092 | const int index = offset / ((depth + 7) / 8); | |
596 | |||
597 |
2/2✓ Branch 0 taken 148620 times.
✓ Branch 1 taken 89472 times.
|
238092 | if (draw->desc->comp[comp].plane != plane) |
598 | 148620 | continue; | |
599 | 89472 | p = p0 + offset; | |
600 | 89472 | m = mask; | |
601 |
2/2✓ Branch 0 taken 180 times.
✓ Branch 1 taken 89292 times.
|
89472 | if (top) { |
602 |
1/2✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
|
180 | if (depth <= 8) { |
603 | 180 | blend_line_hv(p, draw->pixelstep[plane], | |
604 | 180 | color->comp[plane].u8[index], alpha, | |
605 | m, mask_linesize, l2depth, w_sub, | ||
606 | 180 | draw->hsub[plane], draw->vsub[plane], | |
607 | xm0, left, right, top); | ||
608 | } else { | ||
609 | ✗ | blend_line_hv16(p, draw->pixelstep[plane], | |
610 | ✗ | color->comp[plane].u16[index], alpha, | |
611 | m, mask_linesize, l2depth, w_sub, | ||
612 | ✗ | draw->hsub[plane], draw->vsub[plane], | |
613 | xm0, left, right, top); | ||
614 | } | ||
615 | 180 | p += dst_linesize[plane]; | |
616 | 180 | m += top * mask_linesize; | |
617 | } | ||
618 |
2/2✓ Branch 0 taken 79242 times.
✓ Branch 1 taken 10230 times.
|
89472 | if (depth <= 8) { |
619 |
2/2✓ Branch 0 taken 968844 times.
✓ Branch 1 taken 79242 times.
|
1048086 | for (int y = 0; y < h_sub; y++) { |
620 | 968844 | blend_line_hv(p, draw->pixelstep[plane], | |
621 | 968844 | color->comp[plane].u8[index], alpha, | |
622 | m, mask_linesize, l2depth, w_sub, | ||
623 | 968844 | draw->hsub[plane], draw->vsub[plane], | |
624 | 968844 | xm0, left, right, 1 << draw->vsub[plane]); | |
625 | 968844 | p += dst_linesize[plane]; | |
626 | 968844 | m += mask_linesize << draw->vsub[plane]; | |
627 | } | ||
628 | } else { | ||
629 |
2/2✓ Branch 0 taken 163680 times.
✓ Branch 1 taken 10230 times.
|
173910 | for (int y = 0; y < h_sub; y++) { |
630 | 163680 | blend_line_hv16(p, draw->pixelstep[plane], | |
631 | 163680 | color->comp[plane].u16[index], alpha, | |
632 | m, mask_linesize, l2depth, w_sub, | ||
633 | 163680 | draw->hsub[plane], draw->vsub[plane], | |
634 | 163680 | xm0, left, right, 1 << draw->vsub[plane]); | |
635 | 163680 | p += dst_linesize[plane]; | |
636 | 163680 | m += mask_linesize << draw->vsub[plane]; | |
637 | } | ||
638 | } | ||
639 |
2/2✓ Branch 0 taken 180 times.
✓ Branch 1 taken 89292 times.
|
89472 | if (bottom) { |
640 |
1/2✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
|
180 | if (depth <= 8) { |
641 | 180 | blend_line_hv(p, draw->pixelstep[plane], | |
642 | 180 | color->comp[plane].u8[index], alpha, | |
643 | m, mask_linesize, l2depth, w_sub, | ||
644 | 180 | draw->hsub[plane], draw->vsub[plane], | |
645 | xm0, left, right, bottom); | ||
646 | } else { | ||
647 | ✗ | blend_line_hv16(p, draw->pixelstep[plane], | |
648 | ✗ | color->comp[plane].u16[index], alpha, | |
649 | m, mask_linesize, l2depth, w_sub, | ||
650 | ✗ | draw->hsub[plane], draw->vsub[plane], | |
651 | xm0, left, right, bottom); | ||
652 | } | ||
653 | } | ||
654 | } | ||
655 | } | ||
656 | } | ||
657 | |||
658 | 230124 | int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, | |
659 | int value) | ||
660 | { | ||
661 |
2/2✓ Branch 0 taken 206776 times.
✓ Branch 1 taken 23348 times.
|
230124 | unsigned shift = sub_dir ? draw->vsub_max : draw->hsub_max; |
662 | |||
663 |
2/2✓ Branch 0 taken 105742 times.
✓ Branch 1 taken 124382 times.
|
230124 | if (!shift) |
664 | 105742 | return value; | |
665 |
2/2✓ Branch 0 taken 104106 times.
✓ Branch 1 taken 20276 times.
|
124382 | if (round_dir >= 0) |
666 |
2/2✓ Branch 0 taken 3396 times.
✓ Branch 1 taken 100710 times.
|
104106 | value += round_dir ? (1 << shift) - 1 : 1 << (shift - 1); |
667 | 124382 | return (value >> shift) << shift; | |
668 | } | ||
669 | |||
670 | 171 | AVFilterFormats *ff_draw_supported_pixel_formats(unsigned flags) | |
671 | { | ||
672 | FFDrawContext draw; | ||
673 | 171 | AVFilterFormats *fmts = NULL; | |
674 | int ret; | ||
675 | |||
676 |
2/2✓ Branch 1 taken 45657 times.
✓ Branch 2 taken 171 times.
|
45828 | for (enum AVPixelFormat i = 0; av_pix_fmt_desc_get(i); i++) |
677 |
3/4✓ Branch 1 taken 16587 times.
✓ Branch 2 taken 29070 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16587 times.
|
62244 | if (ff_draw_init(&draw, i, flags) >= 0 && |
678 | 16587 | (ret = ff_add_format(&fmts, i)) < 0) | |
679 | ✗ | return NULL; | |
680 | 171 | return fmts; | |
681 | } | ||
682 |