| 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 | 1188 | static int fill_map(const AVPixFmtDescriptor *desc, uint8_t *map) | |
| 36 | { | ||
| 37 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1188 times.
|
1188 | 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 1154 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1188 times.
|
1188 | av_assert0(desc->nb_components == 3 + !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)); |
| 41 |
2/2✓ Branch 0 taken 949 times.
✓ Branch 1 taken 239 times.
|
1188 | if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) { |
| 42 |
2/2✓ Branch 2 taken 307 times.
✓ Branch 3 taken 642 times.
|
949 | if (desc->nb_components != av_pix_fmt_count_planes(av_pix_fmt_desc_get_id(desc))) |
| 43 | 307 | return AVERROR(EINVAL); | |
| 44 | 642 | map[RED] = desc->comp[0].plane; | |
| 45 | 642 | map[GREEN] = desc->comp[1].plane; | |
| 46 | 642 | map[BLUE] = desc->comp[2].plane; | |
| 47 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 626 times.
|
642 | map[ALPHA] = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? desc->comp[3].plane : 3; |
| 48 | } else { | ||
| 49 | 239 | int had0 = 0; | |
| 50 | 239 | unsigned depthb = 0; | |
| 51 |
2/2✓ Branch 0 taken 730 times.
✓ Branch 1 taken 236 times.
|
966 | for (unsigned i = 0; i < desc->nb_components; i++) { |
| 52 | /* all components must have same depth in bytes */ | ||
| 53 | 730 | unsigned db = (desc->comp[i].depth + 7) / 8; | |
| 54 | 730 | unsigned pos = desc->comp[i].offset / db; | |
| 55 |
3/4✓ Branch 0 taken 491 times.
✓ Branch 1 taken 239 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 491 times.
|
730 | if (depthb && (depthb != db)) |
| 56 | ✗ | return AVERROR(ENOSYS); | |
| 57 | |||
| 58 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 727 times.
|
730 | if (desc->comp[i].offset % db) |
| 59 | 3 | return AVERROR(ENOSYS); | |
| 60 | |||
| 61 | 727 | had0 |= pos == 0; | |
| 62 | 727 | map[i] = pos; | |
| 63 | 727 | depthb = db; | |
| 64 | } | ||
| 65 | |||
| 66 |
2/2✓ Branch 0 taken 218 times.
✓ Branch 1 taken 18 times.
|
236 | if (desc->nb_components == 3) |
| 67 |
1/2✓ Branch 0 taken 218 times.
✗ Branch 1 not taken.
|
218 | map[ALPHA] = had0 ? 3 : 0; |
| 68 | } | ||
| 69 | |||
| 70 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 878 times.
|
878 | av_assert0(map[RED] != map[GREEN]); |
| 71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 878 times.
|
878 | av_assert0(map[GREEN] != map[BLUE]); |
| 72 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 878 times.
|
878 | av_assert0(map[BLUE] != map[RED]); |
| 73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 878 times.
|
878 | av_assert0(map[RED] != map[ALPHA]); |
| 74 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 878 times.
|
878 | av_assert0(map[GREEN] != map[ALPHA]); |
| 75 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 878 times.
|
878 | av_assert0(map[BLUE] != map[ALPHA]); |
| 76 | |||
| 77 | 878 | return 0; | |
| 78 | } | ||
| 79 | |||
| 80 | 611 | int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt) | |
| 81 | { | ||
| 82 | 611 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); | |
| 83 |
2/2✓ Branch 0 taken 47 times.
✓ Branch 1 taken 564 times.
|
611 | if (!(desc->flags & AV_PIX_FMT_FLAG_RGB)) |
| 84 | 47 | return AVERROR(EINVAL); | |
| 85 | 564 | return fill_map(desc, rgba_map); | |
| 86 | } | ||
| 87 | |||
| 88 | 624 | int ff_fill_ayuv_map(uint8_t *ayuv_map, enum AVPixelFormat pix_fmt) | |
| 89 | { | ||
| 90 | 624 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); | |
| 91 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 624 times.
|
624 | if (desc->flags & AV_PIX_FMT_FLAG_RGB) |
| 92 | ✗ | return AVERROR(EINVAL); | |
| 93 | 624 | return fill_map(desc, ayuv_map); | |
| 94 | } | ||
| 95 | |||
| 96 | 46690 | int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp, | |
| 97 | enum AVColorRange range, enum AVAlphaMode alpha, unsigned flags) | ||
| 98 | { | ||
| 99 | 46690 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); | |
| 100 | 46690 | const AVLumaCoefficients *luma = NULL; | |
| 101 | const AVComponentDescriptor *c; | ||
| 102 | 46690 | unsigned nb_planes = 0; | |
| 103 | 46690 | int pixelstep[MAX_PLANES] = { 0 }; | |
| 104 | 46690 | int depthb = 0; | |
| 105 | |||
| 106 |
2/4✓ Branch 0 taken 46690 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 46690 times.
|
46690 | if (!desc || !desc->name) |
| 107 | ✗ | return AVERROR(EINVAL); | |
| 108 |
2/2✓ Branch 0 taken 17052 times.
✓ Branch 1 taken 29638 times.
|
46690 | if (desc->flags & AV_PIX_FMT_FLAG_BE) |
| 109 | 17052 | return AVERROR(ENOSYS); | |
| 110 |
2/2✓ Branch 0 taken 7308 times.
✓ Branch 1 taken 22330 times.
|
29638 | if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA)) |
| 111 | 7308 | return AVERROR(ENOSYS); | |
| 112 |
2/2✓ Branch 0 taken 22280 times.
✓ Branch 1 taken 50 times.
|
22330 | if (csp == AVCOL_SPC_UNSPECIFIED) |
| 113 |
2/2✓ Branch 0 taken 7308 times.
✓ Branch 1 taken 14972 times.
|
22280 | csp = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? AVCOL_SPC_RGB : AVCOL_SPC_SMPTE170M; |
| 114 |
3/4✓ Branch 0 taken 14972 times.
✓ Branch 1 taken 7358 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14972 times.
|
22330 | 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 22146 times.
✓ Branch 1 taken 184 times.
|
22330 | if (range == AVCOL_RANGE_UNSPECIFIED) |
| 117 |
4/4✓ Branch 0 taken 21798 times.
✓ Branch 1 taken 174 times.
✓ Branch 2 taken 21624 times.
✓ Branch 3 taken 174 times.
|
44118 | range = (format == AV_PIX_FMT_YUVJ420P || format == AV_PIX_FMT_YUVJ422P || |
| 118 |
4/4✓ Branch 0 taken 21450 times.
✓ Branch 1 taken 174 times.
✓ Branch 2 taken 21276 times.
✓ Branch 3 taken 174 times.
|
21624 | format == AV_PIX_FMT_YUVJ444P || format == AV_PIX_FMT_YUVJ411P || |
| 119 |
2/2✓ Branch 0 taken 7308 times.
✓ Branch 1 taken 13968 times.
|
21276 | format == AV_PIX_FMT_YUVJ440P || csp == AVCOL_SPC_RGB) |
| 120 |
2/2✓ Branch 0 taken 21972 times.
✓ Branch 1 taken 174 times.
|
44118 | ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; |
| 121 |
3/4✓ Branch 0 taken 14081 times.
✓ Branch 1 taken 8249 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14081 times.
|
22330 | if (range != AVCOL_RANGE_JPEG && range != AVCOL_RANGE_MPEG) |
| 122 | ✗ | return AVERROR(EINVAL); | |
| 123 |
2/2✓ Branch 0 taken 60070 times.
✓ Branch 1 taken 17110 times.
|
77180 | for (unsigned i = 0; i < desc->nb_components; i++) { |
| 124 | int db; | ||
| 125 | 60070 | c = &desc->comp[i]; | |
| 126 | /* for now, only 8-16 bits formats */ | ||
| 127 |
4/4✓ Branch 0 taken 58330 times.
✓ Branch 1 taken 1740 times.
✓ Branch 2 taken 696 times.
✓ Branch 3 taken 57634 times.
|
60070 | if (c->depth < 8 || c->depth > 16) |
| 128 | 2436 | return AVERROR(ENOSYS); | |
| 129 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 57634 times.
|
57634 | 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 6816 times.
✓ Branch 1 taken 50818 times.
✓ Branch 2 taken 696 times.
✓ Branch 3 taken 6120 times.
|
57634 | if (c->shift && ((c->shift + c->depth) & 0x7)) |
| 133 | 696 | return AVERROR(ENOSYS); | |
| 134 | /* mixed >8 and <=8 depth */ | ||
| 135 | 56938 | db = (c->depth + 7) / 8; | |
| 136 |
3/4✓ Branch 0 taken 37566 times.
✓ Branch 1 taken 19372 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 37566 times.
|
56938 | if (depthb && (depthb != db)) |
| 137 | ✗ | return AVERROR(ENOSYS); | |
| 138 | 56938 | depthb = db; | |
| 139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56938 times.
|
56938 | if (db * (c->offset + 1) > 16) |
| 140 | ✗ | return AVERROR(ENOSYS); | |
| 141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56938 times.
|
56938 | if (c->offset % db) |
| 142 | ✗ | return AVERROR(ENOSYS); | |
| 143 | /* strange interleaving */ | ||
| 144 |
2/2✓ Branch 0 taken 11418 times.
✓ Branch 1 taken 45520 times.
|
56938 | if (pixelstep[c->plane] != 0 && |
| 145 |
2/2✓ Branch 0 taken 1218 times.
✓ Branch 1 taken 10200 times.
|
11418 | pixelstep[c->plane] != c->step) |
| 146 | 1218 | return AVERROR(ENOSYS); | |
| 147 | 55720 | pixelstep[c->plane] = c->step; | |
| 148 |
2/2✓ Branch 0 taken 870 times.
✓ Branch 1 taken 54850 times.
|
55720 | if (pixelstep[c->plane] >= 8) |
| 149 | 870 | return AVERROR(ENOSYS); | |
| 150 | 54850 | nb_planes = FFMAX(nb_planes, c->plane + 1); | |
| 151 | } | ||
| 152 | 17110 | memset(draw, 0, sizeof(*draw)); | |
| 153 | 17110 | draw->desc = desc; | |
| 154 | 17110 | draw->format = format; | |
| 155 | 17110 | draw->nb_planes = nb_planes; | |
| 156 | 17110 | draw->range = range; | |
| 157 | 17110 | draw->csp = csp; | |
| 158 | 17110 | draw->alpha = alpha; | |
| 159 | 17110 | draw->flags = flags; | |
| 160 |
2/2✓ Branch 0 taken 12710 times.
✓ Branch 1 taken 4400 times.
|
17110 | if (luma) |
| 161 | 12710 | ff_fill_rgb2yuv_table(luma, draw->rgb2yuv); | |
| 162 | 17110 | memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep)); | |
| 163 | 17110 | draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w; | |
| 164 | 17110 | draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h; | |
| 165 | 17110 | return 0; | |
| 166 | } | ||
| 167 | |||
| 168 | 232 | int ff_draw_init_from_link(FFDrawContext *draw, const AVFilterLink *link, | |
| 169 | unsigned flags) | ||
| 170 | { | ||
| 171 | 232 | return ff_draw_init2(draw, link->format, link->colorspace, link->color_range, link->alpha_mode, flags); | |
| 172 | } | ||
| 173 | |||
| 174 | 46458 | int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) | |
| 175 | { | ||
| 176 | 46458 | return ff_draw_init2(draw, format, AVCOL_SPC_UNSPECIFIED, AVCOL_RANGE_UNSPECIFIED, AVALPHA_MODE_UNSPECIFIED, flags); | |
| 177 | } | ||
| 178 | |||
| 179 | 209619 | void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4]) | |
| 180 | { | ||
| 181 | double yuvad[4]; | ||
| 182 | double rgbad[4]; | ||
| 183 | 209619 | const AVPixFmtDescriptor *desc = draw->desc; | |
| 184 | |||
| 185 |
1/2✓ Branch 0 taken 209619 times.
✗ Branch 1 not taken.
|
209619 | if (rgba != color->rgba) |
| 186 | 209619 | memcpy(color->rgba, rgba, sizeof(color->rgba)); | |
| 187 | |||
| 188 | 209619 | memset(color->comp, 0, sizeof(color->comp)); | |
| 189 | |||
| 190 |
2/2✓ Branch 0 taken 838476 times.
✓ Branch 1 taken 209619 times.
|
1048095 | for (int i = 0; i < 4; i++) |
| 191 | 838476 | rgbad[i] = color->rgba[i] / 255.; | |
| 192 | |||
| 193 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 209619 times.
|
209619 | 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 155017 times.
|
209619 | if (draw->desc->flags & AV_PIX_FMT_FLAG_RGB) |
| 199 | 54602 | memcpy(yuvad, rgbad, sizeof(double) * 3); | |
| 200 | else | ||
| 201 | 155017 | ff_matrix_mul_3x3_vec(yuvad, rgbad, draw->rgb2yuv); | |
| 202 | |||
| 203 | 209619 | yuvad[3] = rgbad[3]; | |
| 204 | |||
| 205 |
2/2✓ Branch 0 taken 628857 times.
✓ Branch 1 taken 209619 times.
|
838476 | for (int i = 0; i < 3; i++) { |
| 206 |
4/4✓ Branch 0 taken 465051 times.
✓ Branch 1 taken 163806 times.
✓ Branch 2 taken 310034 times.
✓ Branch 3 taken 155017 times.
|
628857 | int chroma = (!(draw->desc->flags & AV_PIX_FMT_FLAG_RGB) && i > 0); |
| 207 |
2/2✓ Branch 0 taken 464988 times.
✓ Branch 1 taken 163869 times.
|
628857 | if (draw->range == AVCOL_RANGE_MPEG) { |
| 208 |
2/2✓ Branch 0 taken 309992 times.
✓ Branch 1 taken 154996 times.
|
464988 | yuvad[i] *= (chroma ? 224. : 219.) / 255.; |
| 209 |
2/2✓ Branch 0 taken 309992 times.
✓ Branch 1 taken 154996 times.
|
464988 | 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 209609 times.
|
209619 | if (desc->nb_components <= 2) |
| 217 | 10 | yuvad[1] = yuvad[3]; | |
| 218 | |||
| 219 |
2/2✓ Branch 0 taken 654868 times.
✓ Branch 1 taken 209619 times.
|
864487 | for (unsigned i = 0; i < desc->nb_components; i++) { |
| 220 | 654868 | 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 595191 times.
|
654868 | if (desc->comp[i].depth > 8) |
| 222 | 59677 | color->comp[desc->comp[i].plane].u16[desc->comp[i].offset / 2] = val; | |
| 223 | else | ||
| 224 | 595191 | color->comp[desc->comp[i].plane].u8[desc->comp[i].offset] = val; | |
| 225 | } | ||
| 226 | 209619 | } | |
| 227 | |||
| 228 | 608746 | static uint8_t *pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[], | |
| 229 | int plane, int x, int y) | ||
| 230 | { | ||
| 231 | 608746 | return data[plane] + | |
| 232 | 1217492 | (y >> draw->vsub[plane]) * linesize[plane] + | |
| 233 | 608746 | (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 | 211730 | 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 | 211730 | FFDrawColor color_tmp = *color; | |
| 265 | |||
| 266 |
2/2✓ Branch 0 taken 526586 times.
✓ Branch 1 taken 211730 times.
|
738316 | for (int plane = 0; plane < draw->nb_planes; plane++) { |
| 267 | 526586 | p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y); | |
| 268 | 526586 | wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]); | |
| 269 | 526586 | hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]); | |
| 270 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 526586 times.
|
526586 | if (!hp) |
| 271 | ✗ | return; | |
| 272 | 526586 | 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 2322093 times.
✓ Branch 1 taken 526586 times.
|
2848679 | for (int x = 0; x < wp; x++) { |
| 281 | 2322093 | memcpy(p, color_tmp.comp[plane].u8, draw->pixelstep[plane]); | |
| 282 | 2322093 | p += draw->pixelstep[plane]; | |
| 283 | } | ||
| 284 | 526586 | wp *= draw->pixelstep[plane]; | |
| 285 | /* copy next lines from first line */ | ||
| 286 | 526586 | p = p0 + dst_linesize[plane]; | |
| 287 |
2/2✓ Branch 0 taken 9207503 times.
✓ Branch 1 taken 526586 times.
|
9734089 | for (int y = 1; y < hp; y++) { |
| 288 | 9207503 | memcpy(p, p0, wp); | |
| 289 | 9207503 | 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 | 174 | AVFilterFormats *ff_draw_supported_pixel_formats(unsigned flags) | |
| 671 | { | ||
| 672 | FFDrawContext draw; | ||
| 673 | 174 | AVFilterFormats *fmts = NULL; | |
| 674 | int ret; | ||
| 675 | |||
| 676 |
2/2✓ Branch 1 taken 46458 times.
✓ Branch 2 taken 174 times.
|
46632 | for (enum AVPixelFormat i = 0; av_pix_fmt_desc_get(i); i++) |
| 677 |
3/4✓ Branch 1 taken 16878 times.
✓ Branch 2 taken 29580 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16878 times.
|
63336 | if (ff_draw_init(&draw, i, flags) >= 0 && |
| 678 | 16878 | (ret = ff_add_format(&fmts, i)) < 0) | |
| 679 | ✗ | return NULL; | |
| 680 | 174 | return fmts; | |
| 681 | } | ||
| 682 |