GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 27.5% 2072 / 0 / 7545
Functions: 29.7% 78 / 0 / 263
Branches: 20.8% 530 / 0 / 2554

filters/layer.hpp
Line Branch Exec Source
1
2 // Basic utils in C++ language, to be included in both base and processor specific (e.g. avx2) source modules, where they can
3 // be optimized for the specific instruction set.
4 // yuv add, subtract, mul, lighten, darken
5 // Chroma placement helpers (calculate_effective_mask*, prepare_effective_mask_for_row*)
6 // are now in overlay/blend_common.h, pulled in via layer.h.
7
8 // ---------------------------------------------------------------------------
9 // Rowprep function selectors — defined by the including TU to inject SIMD variants.
10 // Default: C scalar functions from overlay/blend_common.h.
11 //
12 // LAYER_ROWPREP_FN — spatial mask averaging (+ opacity baking when
13 // full_opacity=false.
14 // Used for the full_opacity=true path: returns only spatial
15 // averages (or maskp directly for MASK444).
16 //
17 // Including TU (e.g. layer_avx2.cpp) defines them before this #include:
18 // #define LAYER_ROWPREP_FN prepare_effective_mask_for_row_avx2
19 // to allow the same C template to compile with arch-spcific different rowprep variants
20 // ---------------------------------------------------------------------------
21 #ifndef LAYER_ROWPREP_FN
22 # define LAYER_ROWPREP_FN prepare_effective_mask_for_row
23 #endif
24
25 DISABLE_WARNING_PUSH
26 DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE
27
28 // YUV(A) mul 8-16 bits
29 // full_opacity == true : rowprep returns mask-average; subsample-aware avg mask is put into effective_mask_buffer[x]. 444 case: returns maskp directly.
30 // full_opacity == false: rowprep pre-calculates with 'opacity' in the formulae, effective_mask_buffer is filled even for 444.
31 template<MaskMode maskMode, typename pixel_t, bool is_chroma, bool has_alpha, bool full_opacity>
32 8 static void layer_yuv_mul_c_inner(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int opacity_i, int bits_per_pixel) {
33 8 pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);
34 8 const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);
35 8 const pixel_t* maskp = has_alpha ? reinterpret_cast<const pixel_t*>(maskp8) : nullptr;
36 8 dst_pitch /= sizeof(pixel_t);
37 8 overlay_pitch /= sizeof(pixel_t);
38 if constexpr (has_alpha)
39 5 mask_pitch /= sizeof(pixel_t);
40
41 if constexpr (sizeof(pixel_t) == 1)
42 6 bits_per_pixel = 8; // make quasi constexpr
43
44 8 const MagicDiv magic = get_magic_div(bits_per_pixel);
45 8 const int max_pixel_value = (1 << bits_per_pixel) - 1;
46 8 const int half = max_pixel_value / 2;
47
48 // Buffer: needed for subsampled spatial averaging, or MASK444+!full_opacity baking.
49 8 std::vector<pixel_t> effective_mask_buffer;
50 if constexpr (has_alpha && (maskMode != MASK444 || !full_opacity)) {
51
4/84
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 26 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, false, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 18 not taken.
✗ Branch 4 → 25 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 23 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, false, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 18 not taken.
✗ Branch 4 → 25 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 16 not taken.
✗ Branch 4 → 23 not taken.
5 effective_mask_buffer.resize(width);
52 }
53
54
12/162
void layer_yuv_mul_c_inner<(MaskMode)0, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 13 → 6 taken 7 times.
✓ Branch 13 → 14 taken 1 time.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 23 → 6 not taken.
✗ Branch 23 → 24 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 21 → 6 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, false, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 13 → 5 taken 3 times.
✓ Branch 13 → 14 taken 1 time.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, false, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 15 → 6 taken 3 times.
✓ Branch 15 → 16 taken 1 time.
✗ Branch 22 → 6 not taken.
✗ Branch 22 → 23 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, false, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 14 → 5 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 15 → 5 not taken.
✗ Branch 15 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 11 → 5 taken 6 times.
✓ Branch 11 → 12 taken 2 times.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 13 → 6 taken 6 times.
✓ Branch 13 → 14 taken 2 times.
✗ Branch 20 → 6 not taken.
✗ Branch 20 → 21 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 12 → 5 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 13 → 5 not taken.
✗ Branch 13 → 14 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, false, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 5 not taken.
✗ Branch 13 → 14 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, false, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 15 → 6 taken 7 times.
✓ Branch 15 → 16 taken 1 time.
✗ Branch 22 → 6 not taken.
✗ Branch 22 → 23 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, false, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 14 → 5 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 15 → 5 not taken.
✗ Branch 15 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 5 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 13 → 6 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 20 → 6 not taken.
✗ Branch 20 → 21 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 12 → 5 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 13 → 5 not taken.
✗ Branch 13 → 14 not taken.
40 for (int y = 0; y < height; ++y) {
55 32 const pixel_t* effective_mask_ptr = nullptr;
56
57 // Rowprep: full_opacity path returns spatial avg (or maskp for MASK444).
58 // !full_opacity path bakes (avg * opacity_i) / div
59 if constexpr (has_alpha) {
60 if constexpr (full_opacity)
61 effective_mask_ptr = LAYER_ROWPREP_FN<maskMode, pixel_t, true>(maskp, mask_pitch, width, effective_mask_buffer);
62 else
63
4/32
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 6 → 7 taken 7 times.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, false, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 6 → 7 taken 3 times.
✗ Branch 6 → 18 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 6 → 7 taken 6 times.
✗ Branch 6 → 16 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, false, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 6 → 7 taken 7 times.
✗ Branch 6 → 18 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 16 not taken.
23 effective_mask_ptr = LAYER_ROWPREP_FN<maskMode, pixel_t, false>(maskp, mask_pitch, width, effective_mask_buffer, opacity_i, half, magic);
64 }
65
66 // Main blending loop — alpha_mask is fully prepared by rowprep.
67
12/162
void layer_yuv_mul_c_inner<(MaskMode)0, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)1, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 11 → 8 taken 105 times.
✓ Branch 11 → 12 taken 7 times.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)2, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)3, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)4, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)5, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 21 → 18 not taken.
✗ Branch 21 → 22 not taken.
void layer_yuv_mul_c_inner<(MaskMode)6, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, false, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 11 → 6 taken 24 times.
✓ Branch 11 → 12 taken 3 times.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, false, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 13 → 8 taken 24 times.
✓ Branch 13 → 14 taken 3 times.
✗ Branch 20 → 15 not taken.
✗ Branch 20 → 21 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, false, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 12 → 7 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 13 → 8 not taken.
✗ Branch 13 → 14 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 9 → 6 taken 48 times.
✓ Branch 9 → 10 taken 6 times.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 11 → 8 taken 48 times.
✓ Branch 11 → 12 taken 6 times.
✗ Branch 18 → 15 not taken.
✗ Branch 18 → 19 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned char, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 10 → 7 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, false, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 6 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, false, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 13 → 8 taken 105 times.
✓ Branch 13 → 14 taken 7 times.
✗ Branch 20 → 15 not taken.
✗ Branch 20 → 21 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, false, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 12 → 7 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 13 → 8 not taken.
✗ Branch 13 → 14 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, true, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 9 → 6 not taken.
✗ Branch 9 → 10 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, true, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 18 → 15 not taken.
✗ Branch 18 → 19 not taken.
void layer_yuv_mul_c_inner<(MaskMode)7, unsigned short, true, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 10 → 7 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 8 not taken.
✗ Branch 11 → 12 not taken.
386 for (int x = 0; x < width; ++x) {
68 // has_alpha=true: rowprep baked level in (!full_opacity) or returned avg (full_opacity).
69 // has_alpha=false: flat level, no mask.
70 354 const uint32_t alpha_mask = has_alpha ? effective_mask_ptr[x] : opacity_i;
71 354 const uint32_t inv_alpha = max_pixel_value - alpha_mask;
72 uint32_t target_pixel;
73
74 if constexpr (!is_chroma) {
75 // luma: blend towards the "Multiplied" product. No explicit "+half" round-to-nearest
76 // is added here (unlike the alpha blend below). This calculates as floor(A*B/max), not a
77 // round(A*B/max). magic_div_rt (see blend_common.h) divides exactly like a true integer
78 // division by max_pixel_value, unlike the old >> bits_per_pixel shift it replaced.
79 // This keeps the max*max=max rule (e.g. 255*255 -> 255 instead of 254).
80 //
81 // There is currently no SIMD implementation of "Mul" (get_layer_yuv_mul_functions_avx2
82 // in layer_avx2.cpp just includes this scalar path, compiled possibly into a more optimized code).
83 153 const pixel_t prod = (pixel_t)magic_div_rt<pixel_t>((uint32_t)ovrp[x] * (uint32_t)dstp[x], magic);
84 153 target_pixel = prod;
85 // was: dstp[x] = (pixel_t)(dstp[x] + ((((((calc_t)ovrp[x] * dstp[x]) >> bits_per_pixel) - dstp[x]) * alpha_mask) >> bits_per_pixel));
86 }
87 else {
88 // Note: when use_chrome=false, ovrp is prefilled with neutral, so the same formula applies for both modes
89 // CHROMA (Normal): Blend towards the overlay chroma (use_chroma=true) or towards neutral (use_chroma=false).
90 // Instead of dst + ((ovr - dst) * alpha) >> bits we use ((dst * (max - alpha)) + (ovr * alpha)) / max
91 // U = U + ( ((Uovr - U)*level) >> 8 )
92 // V = V + ( ((Vovr - V)*level) >> 8 )
93 201 target_pixel = (uint32_t)ovrp[x];
94 // for use_chroma = false, ovrp is prefilled with neutral
95 // was: dstp[x] = (pixel_t)(dstp[x] + (((calc_t)(ovrp[x] - dstp[x]) * alpha_mask) >> bits_per_pixel));
96 // The YUY2 MMX heritage (cargo cult programming) of halving the strength is finally eliminated
97 /*
98 const int half = 1 << (bits_per_pixel - 1);
99 dstp[x] = (pixel_t)(dstp[x] + (((calc_t)(half - dstp[x]) * (alpha_mask / 2)) >> bits_per_pixel));
100 // U = U + ( ((128 - U)*(level/2)) >> 8 )
101 // V = V + ( ((128 - V)*(level/2)) >> 8 )
102 */
103 }
104
105 708 dstp[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp[x] * inv_alpha + target_pixel * alpha_mask + half, magic);
106 }
107 32 dstp += dst_pitch;
108 32 ovrp += overlay_pitch;
109 if constexpr (has_alpha) {
110 if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2 || maskMode == MASK420_TOPLEFT)
111 7 maskp += mask_pitch * 2;
112 else
113 16 maskp += mask_pitch;
114 }
115 }
116 8 }
117
118 // Outer dispatcher: full_opacity branch.
119 template<MaskMode maskMode, typename pixel_t, bool is_chroma, bool has_alpha>
120 8 static void layer_yuv_mul_c(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int opacity_i, int bits_per_pixel) {
121 if constexpr (!has_alpha) {
122 // No mask; full_opacity choice is irrelevant; use true to skip dead buffer allocation.
123 3 layer_yuv_mul_c_inner<maskMode, pixel_t, is_chroma, false, true>(
124 dstp8, ovrp8, maskp8, dst_pitch, overlay_pitch, mask_pitch, width, height, opacity_i, bits_per_pixel);
125 } else {
126 5 const int max_pixel_value = (1 << bits_per_pixel) - 1;
127
4/32
void layer_yuv_mul_c<(MaskMode)1, unsigned char, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)1, unsigned short, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)2, unsigned char, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)2, unsigned short, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void layer_yuv_mul_c<(MaskMode)3, unsigned char, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)3, unsigned short, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)4, unsigned char, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)4, unsigned short, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)5, unsigned char, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)5, unsigned short, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)6, unsigned char, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)6, unsigned short, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
void layer_yuv_mul_c<(MaskMode)7, unsigned char, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void layer_yuv_mul_c<(MaskMode)7, unsigned char, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2 times.
void layer_yuv_mul_c<(MaskMode)7, unsigned short, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void layer_yuv_mul_c<(MaskMode)7, unsigned short, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
5 if (opacity_i >= max_pixel_value) // full opacity
128 layer_yuv_mul_c_inner<maskMode, pixel_t, is_chroma, true, true>(
129 dstp8, ovrp8, maskp8, dst_pitch, overlay_pitch, mask_pitch, width, height, opacity_i, bits_per_pixel);
130 else
131 5 layer_yuv_mul_c_inner<maskMode, pixel_t, is_chroma, true, false>(
132 dstp8, ovrp8, maskp8, dst_pitch, overlay_pitch, mask_pitch, width, height, opacity_i, bits_per_pixel);
133 }
134 8 }
135
136 // YUV(A) mul 32 bits
137 template<MaskMode maskMode, bool is_chroma, bool has_alpha>
138 25 static void layer_yuv_mul_f_c(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity) {
139 25 float* dstp = reinterpret_cast<float*>(dstp8);
140 25 const float* ovrp = reinterpret_cast<const float*>(ovrp8);
141 25 const float* maskp = reinterpret_cast<const float*>(maskp8);
142 25 dst_pitch /= sizeof(float);
143 25 overlay_pitch /= sizeof(float);
144 25 mask_pitch /= sizeof(float);
145
146 // precalculate mask buffer
147 25 std::vector<float> effective_mask_buffer;
148 if constexpr (has_alpha && maskMode != MASK444) {
149
1/12
void layer_yuv_mul_f_c<(MaskMode)1, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 21 not taken.
void layer_yuv_mul_f_c<(MaskMode)2, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 3 → 4 taken 3 times.
✗ Branch 3 → 21 not taken.
void layer_yuv_mul_f_c<(MaskMode)3, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 21 not taken.
void layer_yuv_mul_f_c<(MaskMode)4, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 21 not taken.
void layer_yuv_mul_f_c<(MaskMode)5, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 21 not taken.
void layer_yuv_mul_f_c<(MaskMode)6, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 21 not taken.
3 effective_mask_buffer.resize(width);
150 }
151
152
14/32
void layer_yuv_mul_f_c<(MaskMode)1, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 4 taken 6 times.
✓ Branch 8 → 9 taken 2 times.
void layer_yuv_mul_f_c<(MaskMode)1, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 18 → 5 not taken.
✗ Branch 18 → 19 not taken.
void layer_yuv_mul_f_c<(MaskMode)2, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 4 taken 15 times.
✓ Branch 8 → 9 taken 5 times.
void layer_yuv_mul_f_c<(MaskMode)2, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 18 → 5 taken 9 times.
✓ Branch 18 → 19 taken 3 times.
void layer_yuv_mul_f_c<(MaskMode)3, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 4 taken 6 times.
✓ Branch 8 → 9 taken 2 times.
void layer_yuv_mul_f_c<(MaskMode)3, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 18 → 5 not taken.
✗ Branch 18 → 19 not taken.
void layer_yuv_mul_f_c<(MaskMode)4, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 4 not taken.
✗ Branch 8 → 9 not taken.
void layer_yuv_mul_f_c<(MaskMode)4, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 18 → 5 not taken.
✗ Branch 18 → 19 not taken.
void layer_yuv_mul_f_c<(MaskMode)5, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 4 not taken.
✗ Branch 8 → 9 not taken.
void layer_yuv_mul_f_c<(MaskMode)5, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 18 → 5 not taken.
✗ Branch 18 → 19 not taken.
void layer_yuv_mul_f_c<(MaskMode)6, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 4 not taken.
✗ Branch 8 → 9 not taken.
void layer_yuv_mul_f_c<(MaskMode)6, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 18 → 5 not taken.
✗ Branch 18 → 19 not taken.
void layer_yuv_mul_f_c<(MaskMode)7, false, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 4 taken 33 times.
✓ Branch 8 → 9 taken 7 times.
void layer_yuv_mul_f_c<(MaskMode)7, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 10 → 4 taken 9 times.
✓ Branch 10 → 11 taken 2 times.
void layer_yuv_mul_f_c<(MaskMode)7, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 4 taken 12 times.
✓ Branch 8 → 9 taken 4 times.
void layer_yuv_mul_f_c<(MaskMode)7, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 10 → 4 not taken.
✗ Branch 10 → 11 not taken.
115 for (int y = 0; y < height; ++y) {
153 90 const float* effective_mask_ptr = nullptr;
154
155 // precalculate effective mask for this row
156 if constexpr (has_alpha) {
157 18 effective_mask_ptr = prepare_effective_mask_for_row_float_c<maskMode>(maskp, mask_pitch, width, effective_mask_buffer);
158 }
159
160 // blending loop
161
14/32
void layer_yuv_mul_f_c<(MaskMode)1, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 6 → 5 taken 24 times.
✓ Branch 6 → 7 taken 6 times.
void layer_yuv_mul_f_c<(MaskMode)1, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 16 → 15 not taken.
✗ Branch 16 → 17 not taken.
void layer_yuv_mul_f_c<(MaskMode)2, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 6 → 5 taken 69 times.
✓ Branch 6 → 7 taken 15 times.
void layer_yuv_mul_f_c<(MaskMode)2, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 16 → 15 taken 45 times.
✓ Branch 16 → 17 taken 9 times.
void layer_yuv_mul_f_c<(MaskMode)3, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 6 → 5 taken 24 times.
✓ Branch 6 → 7 taken 6 times.
void layer_yuv_mul_f_c<(MaskMode)3, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 16 → 15 not taken.
✗ Branch 16 → 17 not taken.
void layer_yuv_mul_f_c<(MaskMode)4, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 6 → 5 not taken.
✗ Branch 6 → 7 not taken.
void layer_yuv_mul_f_c<(MaskMode)4, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 16 → 15 not taken.
✗ Branch 16 → 17 not taken.
void layer_yuv_mul_f_c<(MaskMode)5, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 6 → 5 not taken.
✗ Branch 6 → 7 not taken.
void layer_yuv_mul_f_c<(MaskMode)5, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 16 → 15 not taken.
✗ Branch 16 → 17 not taken.
void layer_yuv_mul_f_c<(MaskMode)6, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 6 → 5 not taken.
✗ Branch 6 → 7 not taken.
void layer_yuv_mul_f_c<(MaskMode)6, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 16 → 15 not taken.
✗ Branch 16 → 17 not taken.
void layer_yuv_mul_f_c<(MaskMode)7, false, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 6 → 5 taken 255 times.
✓ Branch 6 → 7 taken 33 times.
void layer_yuv_mul_f_c<(MaskMode)7, false, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 8 → 7 taken 69 times.
✓ Branch 8 → 9 taken 9 times.
void layer_yuv_mul_f_c<(MaskMode)7, true, false>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✓ Branch 6 → 5 taken 84 times.
✓ Branch 6 → 7 taken 12 times.
void layer_yuv_mul_f_c<(MaskMode)7, true, true>(unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, float):
✗ Branch 8 → 7 not taken.
✗ Branch 8 → 9 not taken.
660 for (int x = 0; x < width; ++x) {
162 570 float effective_mask = has_alpha ? effective_mask_ptr[x] : 0.0f;
163 570 float alpha_mask = has_alpha ? effective_mask * opacity : opacity;
164
165 if constexpr (!is_chroma)
166 324 dstp[x] = dstp[x] + (ovrp[x] * dstp[x] - dstp[x]) * alpha_mask;
167 else {
168 // Note: when use_chrome=false, ovrp is prefilled with neutral, so the same formula applies for both modes
169 246 dstp[x] = dstp[x] + (ovrp[x] - dstp[x]) * alpha_mask;
170 }
171 }
172 90 dstp += dst_pitch;
173 90 ovrp += overlay_pitch;
174 if constexpr (has_alpha) {
175 if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2 || maskMode == MASK420_TOPLEFT)
176 9 maskp += mask_pitch * 2;
177 else
178 9 maskp += mask_pitch;
179 }
180 }
181 25 }
182
183 /* Comparison of Multiply (Mul) blend mode: Overlay vs. Layer
184 * Luma (Y): Compatible. Both use standard (Base * Overlay) / Max logic.
185 * Chroma (UV): Incompatible. They utilize different "intent" for color:
186 * - Overlay (Legacy): Dynamic desaturation. Base chroma is pulled toward
187 * neutral (128/0.0) scaled by the specific Overlay Luma intensity (O_Y).
188 * Formula: Result_UV = (Base_UV * O_Y + Neutral * (Max - O_Y)) / Max
189 * - Layer (use_chroma=false): Static desaturation. Ignores overlay pixels
190 * entirely; blends toward a fixed neutral point via global opacity/mask.
191 * Formula: Result_UV = Base_UV + (Neutral - Base_UV) * Mask_Opacity
192 * Summary: Overlay treats darkness as a "color vacuum" (luma-dependent),
193 * while Layer treats Y and UV as independent channels.
194 * The function would need all plane parameters and work like lighten/darken instead of
195 * template<MaskMode maskMode, bool is_chroma, bool has_alpha>
196 * static void layer_yuv_mul_f_c(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity) {
197 * like this (?):
198 * template<int mode, MaskMode maskMode, typename pixel_t, bool lumaonly, bool has_alpha>
199 * static void layer_yuv_mul_overlaystyle_f_c(
200 */
201
202 // Unlike RGBA version, YUVA does not update destination alpha
203 // so no "blend_alpha" template parameter like at planar rgb lighten_darken
204
205 // Note, that we always call one instance of the filter: the lumaonly==false version,
206 // since the filter handles U and V first, then recursively calls itself with lumaonly==true;
207 // the chroma part needs unaltered luma for decision, so we delay Y processing.
208 // Except Y-only greayscale input, where only luma plane exists.
209 template<int mode, MaskMode maskMode, typename pixel_t, bool lumaonly, bool has_alpha>
210 static void layer_yuv_lighten_darken_c(
211 BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,/* BYTE* dstp8_a,*/
212 const BYTE* ovrp8, const BYTE* ovrp8_u, const BYTE* ovrp8_v, const BYTE* maskp8,
213 int dst_pitch, int dst_pitchUV,
214 int overlay_pitch, int overlay_pitchUV,
215 int mask_pitch,
216 int width, int height, int opacity_i, int thresh,
217 int bits_per_pixel) {
218
219 pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);
220 pixel_t* dstp_u = reinterpret_cast<pixel_t*>(dstp8_u);
221 pixel_t* dstp_v = reinterpret_cast<pixel_t*>(dstp8_v);
222 // pixel_t* dstp_a = reinterpret_cast<pixel_t *>(dstp8_a); // not destination alpha update
223
224 const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);
225 const pixel_t* ovrp_u = reinterpret_cast<const pixel_t*>(ovrp8_u);
226 const pixel_t* ovrp_v = reinterpret_cast<const pixel_t*>(ovrp8_v);
227 const pixel_t* maskp = has_alpha ? reinterpret_cast<const pixel_t*>(maskp8) : nullptr;
228
229 dst_pitch /= sizeof(pixel_t);
230 dst_pitchUV /= sizeof(pixel_t);
231 overlay_pitch /= sizeof(pixel_t);
232 overlay_pitchUV /= sizeof(pixel_t);
233 if constexpr (has_alpha)
234 mask_pitch /= sizeof(pixel_t);
235
236 const int cwidth = (maskMode == MASK444) ? width : (maskMode == MASK411) ? width >> 2 : width >> 1; // 444:/1 420,422:/2 411:/4
237 const int cheight = (maskMode == MASK444 || maskMode == MASK422 || maskMode == MASK422_MPEG2 || maskMode == MASK422_TOPLEFT || maskMode == MASK411) ? height : height >> 1; // 444,422,411:/1 420:/2
238
239 // In lighten/darken we need 3 buffers:
240 std::vector<pixel_t> ovr_buffer;
241 std::vector<pixel_t> src_buffer;
242 std::vector<pixel_t> mask_buffer;
243
244 // precalculate mask buffer et al.
245 if constexpr (maskMode != MASK444) {
246 ovr_buffer.resize(cwidth);
247 src_buffer.resize(cwidth);
248 if constexpr (has_alpha)
249 mask_buffer.resize(cwidth);
250 }
251
252 if constexpr (sizeof(pixel_t) == 1)
253 bits_per_pixel = 8; // make quasi constexpr
254
255 const MagicDiv magic = get_magic_div(bits_per_pixel);
256 const int max_pixel_value = (1 << bits_per_pixel) - 1;
257 const int half = max_pixel_value / 2;
258
259 // for subsampled color spaces first do chroma, luma is only used for decision
260 // second pass will do luma only
261 for (int y = 0; y < cheight; ++y) {
262
263 // Prepare all three pointers using the helper, full-opacity mode, no opacity_i-magicdiv baking
264 const pixel_t* ovr_ptr = prepare_effective_mask_for_row<maskMode, pixel_t>(ovrp, overlay_pitch, cwidth, ovr_buffer);
265 const pixel_t* src_ptr = prepare_effective_mask_for_row<maskMode, pixel_t>(dstp, dst_pitch, cwidth, src_buffer);
266 const pixel_t* effective_mask_ptr = nullptr;
267 if constexpr (has_alpha) {
268 effective_mask_ptr = prepare_effective_mask_for_row<maskMode, pixel_t>(maskp, mask_pitch, cwidth, mask_buffer);
269 }
270
271 for (int x = 0; x < cwidth; ++x) {
272 // opacity_i is in [0..max_pixel_value], the same convention as masked_merge.
273 uint32_t alpha_eff;
274 if constexpr (has_alpha) {
275 const uint32_t alpha_src = (uint32_t)effective_mask_ptr[x];
276 alpha_eff = (uint32_t)magic_div_rt<pixel_t>(alpha_src * (uint32_t)opacity_i + half, magic);
277 }
278 else {
279 alpha_eff = opacity_i;
280 }
281
282 int ovr = ovr_ptr[x];
283 int src = src_ptr[x];
284
285 // If the threshold isn't met, the overlay weight becomes 0 (no change to dst)
286 if constexpr (mode == LIGHTEN) {
287 if (!(ovr > (src + thresh))) alpha_eff = 0;
288 }
289 else { // DARKEN
290 if (!(ovr < (src - thresh))) alpha_eff = 0;
291 }
292
293 const uint32_t inv_alpha = max_pixel_value - alpha_eff;
294
295 // formula: dst = (dst * inv_alpha + ovr * alpha_eff) / max_val
296 if constexpr (!lumaonly)
297 {
298 // chroma u,v
299 dstp_u[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_u[x] * inv_alpha + (uint32_t)ovrp_u[x] * alpha_eff + half, magic);
300 dstp_v[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_v[x] * inv_alpha + (uint32_t)ovrp_v[x] * alpha_eff + half, magic);
301 }
302
303 // for 444: update here, width/height is the same as for chroma
304 if constexpr (maskMode == MASK444)
305 dstp[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp[x] * inv_alpha + (uint32_t)ovrp[x] * alpha_eff + half, magic);
306 }
307 if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2 || maskMode == MASK420_TOPLEFT) {
308 dstp += dst_pitch * 2; // skip vertical subsampling
309 ovrp += overlay_pitch * 2;
310 if constexpr (has_alpha) {
311 //dstp_a += dst_pitch * 2;
312 maskp += mask_pitch * 2;
313 }
314 }
315 else {
316 dstp += dst_pitch;
317 ovrp += overlay_pitch;
318 if constexpr (has_alpha) {
319 //dstp_a += dst_pitch;
320 maskp += mask_pitch;
321 }
322 }
323
324 if constexpr (!lumaonly) {
325 dstp_u += dst_pitchUV;
326 dstp_v += dst_pitchUV;
327 ovrp_u += overlay_pitchUV;
328 ovrp_v += overlay_pitchUV;
329 }
330
331 }
332
333 dst_pitch *= sizeof(pixel_t);
334 dst_pitchUV *= sizeof(pixel_t);
335 overlay_pitch *= sizeof(pixel_t);
336 overlay_pitchUV *= sizeof(pixel_t);
337 mask_pitch *= sizeof(pixel_t);
338
339 // Phase #2 recursively call the same function, but with lumaonly=true to update luma plane using the original chroma planes for decision
340 // make luma
341 if constexpr (!lumaonly && maskMode != MASK444)
342 layer_yuv_lighten_darken_c<mode, MASK444, pixel_t, true /* lumaonly*/, has_alpha>(
343 dstp8, dstp8_u, dstp8_v, //dstp8_a,
344 ovrp8, ovrp8_u, ovrp8_v, maskp8,
345 dst_pitch, dst_pitchUV, overlay_pitch, overlay_pitchUV, mask_pitch,
346 width, height, opacity_i, thresh, bits_per_pixel);
347 }
348
349 template<int mode, MaskMode maskMode, bool lumaonly, bool has_alpha>
350 10 static void layer_yuv_lighten_darken_f_c(
351 BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v /*, BYTE* dstp8_a*/,
352 const BYTE* ovrp8, const BYTE* ovrp8_u, const BYTE* ovrp8_v, const BYTE* maskp8,
353 int dst_pitch, int dst_pitchUV,
354 int overlay_pitch, int overlay_pitchUV,
355 int mask_pitch,
356 int width, int height, float opacity, float thresh) {
357
358 10 float* dstp = reinterpret_cast<float*>(dstp8);
359 10 float* dstp_u = reinterpret_cast<float*>(dstp8_u);
360 10 float* dstp_v = reinterpret_cast<float*>(dstp8_v);
361 //float* dstp_a = reinterpret_cast<float *>(dstp8_a);
362
363 10 const float* ovrp = reinterpret_cast<const float*>(ovrp8);
364 10 const float* ovrp_u = reinterpret_cast<const float*>(ovrp8_u);
365 10 const float* ovrp_v = reinterpret_cast<const float*>(ovrp8_v);
366 10 const float* maskp = has_alpha ? reinterpret_cast<const float*>(maskp8) : nullptr;
367
368 10 dst_pitch /= sizeof(float);
369 10 dst_pitchUV /= sizeof(float);
370 10 overlay_pitch /= sizeof(float);
371 10 overlay_pitchUV /= sizeof(float);
372 if constexpr (has_alpha)
373 mask_pitch /= sizeof(float);
374
375 10 const int cwidth = (maskMode == MASK444) ? width : (maskMode == MASK411) ? width >> 2 : width >> 1; // 444:/1 420,422:/2 411:/4
376 10 const int cheight = (maskMode == MASK444 || maskMode == MASK422 || maskMode == MASK422_MPEG2 || maskMode == MASK422_TOPLEFT || maskMode == MASK411) ? height : height >> 1; // 444,422,411:/1 420:/2
377
378 // In lighten/darken we need 3 buffers:
379 10 std::vector<float> ovr_buffer;
380 10 std::vector<float> src_buffer;
381 10 std::vector<float> mask_buffer;
382
383 // precalculate mask buffer et al.
384 if constexpr (maskMode != MASK444) {
385
3/24
void layer_yuv_lighten_darken_f_c<0, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 38 not taken.
4 ovr_buffer.resize(cwidth);
386
3/24
void layer_yuv_lighten_darken_f_c<0, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 6 → 7 taken 2 times.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 38 not taken.
4 src_buffer.resize(cwidth);
387 if constexpr (has_alpha)
388 mask_buffer.resize(cwidth);
389 }
390
391 // for subsampled color spaces first do chroma, because luma is used for decision
392 // second pass will do luma only
393
14/32
void layer_yuv_lighten_darken_f_c<0, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 32 → 8 taken 6 times.
✓ Branch 32 → 33 taken 2 times.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 32 → 8 not taken.
✗ Branch 32 → 33 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 32 → 8 taken 3 times.
✓ Branch 32 → 33 taken 1 time.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 32 → 8 not taken.
✗ Branch 32 → 33 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 32 → 8 not taken.
✗ Branch 32 → 33 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 32 → 8 not taken.
✗ Branch 32 → 33 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)7, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 16 → 6 taken 3 times.
✓ Branch 16 → 17 taken 1 time.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)7, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 16 → 6 taken 18 times.
✓ Branch 16 → 17 taken 3 times.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 32 → 8 not taken.
✗ Branch 32 → 33 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 32 → 8 taken 3 times.
✓ Branch 32 → 33 taken 1 time.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 32 → 8 not taken.
✗ Branch 32 → 33 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 32 → 8 not taken.
✗ Branch 32 → 33 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 32 → 8 not taken.
✗ Branch 32 → 33 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 32 → 8 not taken.
✗ Branch 32 → 33 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)7, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 16 → 6 taken 3 times.
✓ Branch 16 → 17 taken 1 time.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)7, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 16 → 6 taken 6 times.
✓ Branch 16 → 17 taken 1 time.
52 for (int y = 0; y < cheight; ++y) {
394 42 const float* ovr_ptr = prepare_effective_mask_for_row_float_c<maskMode>(ovrp, overlay_pitch, cwidth, ovr_buffer);
395 42 const float* src_ptr = prepare_effective_mask_for_row_float_c<maskMode>(dstp, dst_pitch, cwidth, src_buffer);
396 42 const float* effective_mask_ptr = nullptr;
397 if constexpr (has_alpha) {
398 effective_mask_ptr = prepare_effective_mask_for_row_float_c<maskMode>(maskp, mask_pitch, cwidth, mask_buffer);
399 }
400
401
14/32
void layer_yuv_lighten_darken_f_c<0, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 30 → 27 taken 24 times.
✓ Branch 30 → 31 taken 6 times.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 30 → 27 not taken.
✗ Branch 30 → 31 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 30 → 27 taken 12 times.
✓ Branch 30 → 31 taken 3 times.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 30 → 27 not taken.
✗ Branch 30 → 31 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 30 → 27 not taken.
✗ Branch 30 → 31 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 30 → 27 not taken.
✗ Branch 30 → 31 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)7, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 14 → 11 taken 21 times.
✓ Branch 14 → 15 taken 3 times.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)7, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 14 → 11 taken 144 times.
✓ Branch 14 → 15 taken 18 times.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 30 → 27 not taken.
✗ Branch 30 → 31 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 30 → 27 taken 12 times.
✓ Branch 30 → 31 taken 3 times.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 30 → 27 not taken.
✗ Branch 30 → 31 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 30 → 27 not taken.
✗ Branch 30 → 31 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 30 → 27 not taken.
✗ Branch 30 → 31 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 30 → 27 not taken.
✗ Branch 30 → 31 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)7, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 14 → 11 taken 21 times.
✓ Branch 14 → 15 taken 3 times.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)7, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 14 → 11 taken 48 times.
✓ Branch 14 → 15 taken 6 times.
324 for (int x = 0; x < cwidth; ++x) {
402 282 float alpha_eff = has_alpha ? effective_mask_ptr[x] * opacity : opacity;
403
404 282 float ovr = ovr_ptr[x];
405 282 float src = src_ptr[x];
406 if constexpr (mode == LIGHTEN) {
407
8/16
void layer_yuv_lighten_darken_f_c<0, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 27 → 28 taken 16 times.
✓ Branch 27 → 29 taken 8 times.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 27 → 28 taken 9 times.
✓ Branch 27 → 29 taken 3 times.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)7, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 11 → 12 taken 16 times.
✓ Branch 11 → 13 taken 5 times.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)7, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 11 → 12 taken 108 times.
✓ Branch 11 → 13 taken 36 times.
201 if (!(ovr > (src + thresh))) alpha_eff = 0;
408 }
409 else {// DARKEN
410
6/16
void layer_yuv_lighten_darken_f_c<1, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 27 → 28 taken 8 times.
✓ Branch 27 → 29 taken 4 times.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)7, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 11 → 12 taken 7 times.
✓ Branch 11 → 13 taken 14 times.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)7, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 11 → 12 taken 18 times.
✓ Branch 11 → 13 taken 30 times.
81 if (!(ovr < (src - thresh))) alpha_eff = 0;
411 }
412
413 if constexpr (!lumaonly)
414 {
415 // chroma u,v
416 90 dstp_u[x] = dstp_u[x] + (ovrp_u[x] - dstp_u[x]) * alpha_eff;
417 90 dstp_v[x] = dstp_v[x] + (ovrp_v[x] - dstp_v[x]) * alpha_eff;
418 //dstp_a[x] = dstp_a[x] + (maskp[x] - dstp_a[x]) * alpha_eff;
419 }
420
421 // for 444: update here, width/height is the same as for chroma
422 if constexpr (maskMode == MASK444)
423 234 dstp[x] = dstp[x] + (ovrp[x] - dstp[x]) * alpha_eff;
424 }
425 if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2 || maskMode == MASK420_TOPLEFT) {
426 12 dstp += dst_pitch * 2; // skip vertical subsampling
427 12 ovrp += overlay_pitch * 2;
428 if constexpr (has_alpha) {
429 //dstp_a += dst_pitch * 2;
430 maskp += mask_pitch * 2;
431 }
432 }
433 else {
434 30 dstp += dst_pitch;
435 30 ovrp += overlay_pitch;
436 if constexpr (has_alpha) {
437 //dstp_a += dst_pitch;
438 maskp += mask_pitch;
439 }
440 }
441
442 if constexpr (!lumaonly) {
443 18 dstp_u += dst_pitchUV;
444 18 dstp_v += dst_pitchUV;
445 18 ovrp_u += overlay_pitchUV;
446 18 ovrp_v += overlay_pitchUV;
447 }
448 }
449
450 10 dst_pitch *= sizeof(float);
451 10 dst_pitchUV *= sizeof(float);
452 10 overlay_pitch *= sizeof(float);
453 10 overlay_pitchUV *= sizeof(float);
454 if constexpr (has_alpha)
455 mask_pitch *= sizeof(float);
456
457 // make luma
458 // recursively call the same function, but with lumaonly=true to update luma plane using the original chroma planes for decision
459 if constexpr (!lumaonly && maskMode != MASK444)
460
3/24
void layer_yuv_lighten_darken_f_c<0, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 33 → 34 taken 2 times.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 33 → 34 taken 1 time.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<0, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✓ Branch 33 → 34 taken 1 time.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 38 not taken.
void layer_yuv_lighten_darken_f_c<1, (MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, float, float):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 38 not taken.
4 layer_yuv_lighten_darken_f_c<mode, MASK444, true /* lumaonly*/, has_alpha>(
461 dstp8, dstp8_u, dstp8_v, //dstp8_a,
462 ovrp8, ovrp8_u, ovrp8_v, maskp8,
463 dst_pitch, dst_pitchUV, overlay_pitch, overlay_pitchUV, mask_pitch,
464 width, height, opacity, thresh);
465 10 }
466
467 DISABLE_WARNING_POP
468
469 // Dispatchers
470
471 6 static void get_layer_yuv_lighten_darken_functions(bool isLighten, int placement, VideoInfo& vi, int bits_per_pixel,
472 /*out*/layer_yuv_lighten_darken_c_t** layer_fn,
473 /*out*/layer_yuv_lighten_darken_f_c_t** layer_f_fn)
474 {
475
476 #define YUV_LIGHTEN_DARKEN_DISPATCH(L_or_D, MaskType, lumaonly, has_alpha) \
477 { if (bits_per_pixel == 8) \
478 *layer_fn = layer_yuv_lighten_darken_c<L_or_D, MaskType, uint8_t, lumaonly /*lumaonly*/, has_alpha /*has_alpha*/>; \
479 else if (bits_per_pixel <= 16) \
480 *layer_fn = layer_yuv_lighten_darken_c<L_or_D, MaskType, uint16_t, lumaonly /*lumaonly*/, has_alpha /*has_alpha*/>; \
481 else /* float */ \
482 *layer_f_fn = layer_yuv_lighten_darken_f_c<L_or_D, MaskType, lumaonly /*lumaonly*/, has_alpha /*has_alpha*/>; \
483 }
484
485 // Note, that we always call one instance of the filter: the lumaonly==false version,
486 // since the filter handles U and V first, then recursively calls itself with lumaonly==true;
487 // the chroma part needs unaltered luma for decision, so we delay Y processing.
488 // Except Y-only greayscale input, where only luma plane exists.
489
490
2/2
✓ Branch 2 → 3 taken 4 times.
✓ Branch 2 → 58 taken 2 times.
6 if (isLighten) {
491
492
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 4 times.
4 if (vi.IsYV411())
493 *layer_fn = layer_yuv_lighten_darken_c<LIGHTEN, MASK411, uint8_t, false /*lumaonly*/, false /*has_alpha*/>;
494
2/2
✓ Branch 7 → 8 taken 3 times.
✓ Branch 7 → 25 taken 1 time.
4 else if (vi.Is420())
495 {
496
2/2
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 14 taken 1 time.
3 if (placement == PLACEMENT_MPEG1)
497
2/4
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 2 times.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 2 times.
2 YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK420, false, false)
498
1/2
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 20 not taken.
1 else if (placement == PLACEMENT_TOPLEFT)
499
2/4
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 1 time.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 1 time.
1 YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK420_TOPLEFT, false, false)
500 else
501 YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK420_MPEG2, false, false)
502 // PLACEMENT_MPEG2
503 }
504
1/2
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 44 taken 1 time.
1 else if (vi.Is422())
505 {
506 if (placement == PLACEMENT_MPEG1)
507 YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK422, false, false)
508 else if (placement == PLACEMENT_TOPLEFT)
509 YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK422_TOPLEFT, false, false)
510 else
511 YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK422_MPEG2, false, false)
512 // PLACEMENT_MPEG2
513 }
514
1/2
✓ Branch 45 → 46 taken 1 time.
✗ Branch 45 → 51 not taken.
1 else if (vi.Is444())
515
2/4
✗ Branch 46 → 47 not taken.
✓ Branch 46 → 48 taken 1 time.
✗ Branch 48 → 49 not taken.
✓ Branch 48 → 50 taken 1 time.
1 YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK444, false, false)
516 else if (vi.IsY())
517 YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK444, true, false)
518 }
519 else {
520 // darken
521
1/2
✗ Branch 59 → 60 not taken.
✓ Branch 59 → 61 taken 2 times.
2 if (vi.IsYV411())
522 *layer_fn = layer_yuv_lighten_darken_c<DARKEN, MASK411, uint8_t, false /*lumaonly*/, false /*has_alpha*/>;
523
2/2
✓ Branch 62 → 63 taken 1 time.
✓ Branch 62 → 80 taken 1 time.
2 else if (vi.Is420())
524 {
525
1/2
✗ Branch 63 → 64 not taken.
✓ Branch 63 → 69 taken 1 time.
1 if (placement == PLACEMENT_MPEG1)
526 YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK420, false, false)
527
1/2
✗ Branch 69 → 70 not taken.
✓ Branch 69 → 75 taken 1 time.
1 else if (placement == PLACEMENT_TOPLEFT)
528 YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK420_TOPLEFT, false, false)
529 else // PLACEMENT_MPEG2
530
2/4
✗ Branch 75 → 76 not taken.
✓ Branch 75 → 77 taken 1 time.
✗ Branch 77 → 78 not taken.
✓ Branch 77 → 79 taken 1 time.
1 YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK420_MPEG2, false, false)
531 }
532
1/2
✗ Branch 81 → 82 not taken.
✓ Branch 81 → 99 taken 1 time.
1 else if (vi.Is422())
533 {
534 if (placement == PLACEMENT_MPEG1)
535 YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK422, false, false)
536 else if (placement == PLACEMENT_TOPLEFT)
537 YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK422_TOPLEFT, false, false)
538 else // PLACEMENT_MPEG2
539 YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK422_MPEG2, false, false)
540 }
541
1/2
✓ Branch 100 → 101 taken 1 time.
✗ Branch 100 → 106 not taken.
1 else if (vi.Is444())
542
2/4
✗ Branch 101 → 102 not taken.
✓ Branch 101 → 103 taken 1 time.
✗ Branch 103 → 104 not taken.
✓ Branch 103 → 105 taken 1 time.
1 YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK444, false, false)
543 else if (vi.IsY())
544 YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK444, true, false)
545 }
546 #undef YUV_LIGHTEN_DARKEN_DISPATCH
547 6 }
548
549
550 1371 static void get_layer_yuv_mul_functions(
551 bool is_chroma, bool hasAlpha,
552 int placement, VideoInfo& vi, int bits_per_pixel,
553 /*out*/layer_yuv_mul_c_t** layer_fn,
554 /*out*/layer_yuv_mul_f_c_t** layer_f_fn)
555 {
556 #define YUV_MUL_DISPATCH(MaskType, is_chroma, has_alpha) \
557 { if (bits_per_pixel == 8) \
558 *layer_fn = layer_yuv_mul_c<MaskType, uint8_t, is_chroma, has_alpha>; \
559 else if (bits_per_pixel < 16) \
560 *layer_fn = layer_yuv_mul_c<MaskType, uint16_t, is_chroma, has_alpha>; \
561 else if (bits_per_pixel == 16) \
562 *layer_fn = layer_yuv_mul_c<MaskType, uint16_t, is_chroma, has_alpha>; \
563 else /* float */ \
564 *layer_f_fn = layer_yuv_mul_f_c<MaskType, is_chroma, has_alpha>; \
565 }
566
567
2/2
✓ Branch 2 → 3 taken 690 times.
✓ Branch 2 → 121 taken 681 times.
1371 if (is_chroma) // not luma channel
568 {
569
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 690 times.
690 if (vi.IsYV411())
570 {
571 // never has Alpha
572 *layer_fn = layer_yuv_mul_c<MASK411, uint8_t, true, false>;
573 }
574
2/2
✓ Branch 7 → 8 taken 682 times.
✓ Branch 7 → 55 taken 8 times.
690 else if (vi.Is420())
575 {
576
2/2
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 24 taken 680 times.
682 if (placement == PLACEMENT_MPEG1) {
577
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 17 taken 2 times.
2 if (hasAlpha) {
578 YUV_MUL_DISPATCH(MASK420, true, true)
579 }
580 else {
581
3/6
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 2 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 2 times.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 2 times.
2 YUV_MUL_DISPATCH(MASK420, true, false)
582 }
583 }
584
2/2
✓ Branch 24 → 25 taken 2 times.
✓ Branch 24 → 40 taken 678 times.
680 else if (placement == PLACEMENT_TOPLEFT) {
585
1/2
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 33 taken 2 times.
2 if (hasAlpha) {
586 YUV_MUL_DISPATCH(MASK420_TOPLEFT, true, true)
587 }
588 else {
589
3/6
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 2 times.
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 37 taken 2 times.
✗ Branch 37 → 38 not taken.
✓ Branch 37 → 39 taken 2 times.
2 YUV_MUL_DISPATCH(MASK420_TOPLEFT, true, false)
590 }
591 }
592 else {
593
2/2
✓ Branch 40 → 41 taken 450 times.
✓ Branch 40 → 48 taken 228 times.
678 if (hasAlpha) {
594
4/6
✗ Branch 41 → 42 not taken.
✓ Branch 41 → 43 taken 450 times.
✗ Branch 43 → 44 not taken.
✓ Branch 43 → 45 taken 450 times.
✓ Branch 45 → 46 taken 224 times.
✓ Branch 45 → 47 taken 226 times.
450 YUV_MUL_DISPATCH(MASK420_MPEG2, true, true)
595 }
596 else {
597
3/6
✗ Branch 48 → 49 not taken.
✓ Branch 48 → 50 taken 228 times.
✗ Branch 50 → 51 not taken.
✓ Branch 50 → 52 taken 228 times.
✗ Branch 52 → 53 not taken.
✓ Branch 52 → 54 taken 228 times.
228 YUV_MUL_DISPATCH(MASK420_MPEG2, true, false)
598 }
599 }
600 }
601
1/2
✗ Branch 56 → 57 not taken.
✓ Branch 56 → 104 taken 8 times.
8 else if (vi.Is422())
602 {
603 if (placement == PLACEMENT_MPEG1) {
604 if (hasAlpha) {
605 YUV_MUL_DISPATCH(MASK422, true, true)
606 }
607 else {
608 YUV_MUL_DISPATCH(MASK422, true, false)
609 }
610 }
611 else if (placement == PLACEMENT_TOPLEFT) {
612 if (hasAlpha) {
613 YUV_MUL_DISPATCH(MASK422_TOPLEFT, true, true)
614 }
615 else {
616 YUV_MUL_DISPATCH(MASK422_TOPLEFT, true, false)
617 }
618 }
619 else {
620 if (hasAlpha) {
621 YUV_MUL_DISPATCH(MASK422_MPEG2, true, true)
622 }
623 else {
624 YUV_MUL_DISPATCH(MASK422_MPEG2, true, false)
625 }
626 }
627 }
628
1/2
✓ Branch 105 → 106 taken 8 times.
✗ Branch 105 → 136 not taken.
8 else if (vi.Is444())
629 {
630
2/2
✓ Branch 106 → 107 taken 2 times.
✓ Branch 106 → 114 taken 6 times.
8 if (hasAlpha) {
631
1/6
✓ Branch 107 → 108 taken 2 times.
✗ Branch 107 → 109 not taken.
✗ Branch 109 → 110 not taken.
✗ Branch 109 → 111 not taken.
✗ Branch 111 → 112 not taken.
✗ Branch 111 → 113 not taken.
2 YUV_MUL_DISPATCH(MASK444, true, true)
632 }
633 else {
634
4/6
✓ Branch 114 → 115 taken 2 times.
✓ Branch 114 → 116 taken 4 times.
✗ Branch 116 → 117 not taken.
✓ Branch 116 → 118 taken 4 times.
✗ Branch 118 → 119 not taken.
✓ Branch 118 → 120 taken 4 times.
6 YUV_MUL_DISPATCH(MASK444, true, false)
635 }
636 }
637 }
638 else // luma channel
639 {
640
2/2
✓ Branch 121 → 122 taken 450 times.
✓ Branch 121 → 129 taken 231 times.
681 if (hasAlpha)
641
5/6
✓ Branch 122 → 123 taken 1 time.
✓ Branch 122 → 124 taken 449 times.
✗ Branch 124 → 125 not taken.
✓ Branch 124 → 126 taken 449 times.
✓ Branch 126 → 127 taken 224 times.
✓ Branch 126 → 128 taken 225 times.
450 YUV_MUL_DISPATCH(MASK444, false, true)
642 else
643
4/6
✓ Branch 129 → 130 taken 1 time.
✓ Branch 129 → 131 taken 230 times.
✗ Branch 131 → 132 not taken.
✓ Branch 131 → 133 taken 230 times.
✗ Branch 133 → 134 not taken.
✓ Branch 133 → 135 taken 230 times.
231 YUV_MUL_DISPATCH(MASK444, false, false)
644 }
645 #undef YUV_MUL_DISPATCH
646 1371 }
647
648 // ---------------------------------------------------------------------------
649 // mulovr: Overlay-style multiply.
650 // Overlay luma (Y) drives the effect on all planes:
651 // darken_factor = alpha_eff * (max - ovr_Y) / max
652 // result_Y = base_Y * (max - darken_factor) / max
653 // result_UV = base_UV * (max - darken_factor) / max + half_pix * darken_factor / max
654 // For float (neutral UV = 0.0): result = base * (1 - alpha_eff * (1 - ovr_Y)) for all planes.
655 // Two-pass for subsampled formats (mirrors lighten/darken):
656 // Pass 1 (lumaonly=false): UV update using spatially-averaged overlay Y; MASK444 also does Y.
657 // Pass 2 (lumaonly=true, MASK444): Y-only update at full luma resolution.
658 // greyscale (vi.IsY()): dispatched directly as lumaonly=true — identical to Layer "Mul" luma.
659 // ---------------------------------------------------------------------------
660
661 template<MaskMode maskMode, typename pixel_t, bool lumaonly, bool has_alpha>
662 2 static void layer_yuv_mulovr_c(
663 BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,
664 const BYTE* ovrp8,
665 const BYTE* maskp8,
666 int dst_pitch, int dst_pitchUV,
667 int overlay_pitch,
668 int mask_pitch,
669 int width, int height, int opacity_i, int bits_per_pixel)
670 {
671 2 pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);
672 2 pixel_t* dstp_u = reinterpret_cast<pixel_t*>(dstp8_u); // nullptr when lumaonly
673 2 pixel_t* dstp_v = reinterpret_cast<pixel_t*>(dstp8_v); // nullptr when lumaonly
674 2 const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);
675 2 const pixel_t* maskp = has_alpha ? reinterpret_cast<const pixel_t*>(maskp8) : nullptr;
676
677 2 dst_pitch /= sizeof(pixel_t);
678 2 dst_pitchUV /= sizeof(pixel_t);
679 2 overlay_pitch /= sizeof(pixel_t);
680 if constexpr (has_alpha)
681 1 mask_pitch /= sizeof(pixel_t);
682
683 if constexpr (sizeof(pixel_t) == 1)
684 2 bits_per_pixel = 8;
685
686 2 const MagicDiv magic = get_magic_div(bits_per_pixel);
687 2 const int max_pixel_value = (1 << bits_per_pixel) - 1;
688 2 const int half = max_pixel_value / 2; // rounding bias for magic_div
689 2 const uint32_t half_pix = (uint32_t)(max_pixel_value / 2); // integer chroma neutral
690
691 2 const int cwidth = (maskMode == MASK444) ? width : (maskMode == MASK411) ? width >> 2 : width >> 1;
692 2 const int cheight = (maskMode == MASK444 || maskMode == MASK422 || maskMode == MASK422_MPEG2 || maskMode == MASK422_TOPLEFT || maskMode == MASK411) ? height : height >> 1;
693
694 2 std::vector<pixel_t> ovr_y_buffer;
695 2 std::vector<pixel_t> mask_buffer;
696 if constexpr (maskMode != MASK444) {
697 ovr_y_buffer.resize(cwidth);
698 if constexpr (has_alpha)
699 mask_buffer.resize(cwidth);
700 }
701
702
4/136
void layer_yuv_mulovr_c<(MaskMode)0, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)0, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 7 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 26 → 7 not taken.
✗ Branch 26 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 8 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 38 → 8 not taken.
✗ Branch 38 → 39 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 19 → 6 not taken.
✗ Branch 19 → 20 not taken.
✓ Branch 20 → 6 taken 2 times.
✓ Branch 20 → 21 taken 1 time.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 6 not taken.
✗ Branch 22 → 23 not taken.
✓ Branch 24 → 6 taken 2 times.
✓ Branch 24 → 25 taken 1 time.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 15 → 6 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 16 → 6 not taken.
✗ Branch 16 → 17 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 6 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 20 → 6 not taken.
✗ Branch 20 → 21 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 19 → 6 not taken.
✗ Branch 19 → 20 not taken.
✗ Branch 20 → 6 not taken.
✗ Branch 20 → 21 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 22 → 6 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 24 → 6 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 15 → 6 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 16 → 6 not taken.
✗ Branch 16 → 17 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 18 → 6 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 20 → 6 not taken.
✗ Branch 20 → 21 not taken.
6 for (int y = 0; y < cheight; ++y) {
703 // Spatially average overlay Y to chroma resolution (full_opacity=true: no opacity baking).
704
0/68
void layer_yuv_mulovr_c<(MaskMode)0, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)0, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 26 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 19 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 22 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 26 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 19 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 22 not taken.
4 const pixel_t* ovr_y_ptr = LAYER_ROWPREP_FN<maskMode, pixel_t, true>(ovrp, overlay_pitch, cwidth, ovr_y_buffer);
705 4 const pixel_t* mask_ptr = nullptr;
706 if constexpr (has_alpha)
707
0/32
void layer_yuv_mulovr_c<(MaskMode)1, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 27 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 26 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 22 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 26 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 22 not taken.
2 mask_ptr = LAYER_ROWPREP_FN<maskMode, pixel_t, true>(maskp, mask_pitch, cwidth, mask_buffer);
708
709
4/136
void layer_yuv_mulovr_c<(MaskMode)0, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)0, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)1, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)2, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)3, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)4, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)5, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
void layer_yuv_mulovr_c<(MaskMode)6, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 11 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 36 → 27 not taken.
✗ Branch 36 → 37 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 17 → 8 not taken.
✗ Branch 17 → 18 not taken.
✓ Branch 18 → 9 taken 10 times.
✓ Branch 18 → 19 taken 2 times.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 9 not taken.
✗ Branch 20 → 21 not taken.
✓ Branch 22 → 11 taken 10 times.
✓ Branch 22 → 23 taken 2 times.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 13 → 8 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 14 → 9 not taken.
✗ Branch 14 → 15 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned char, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 18 → 11 not taken.
✗ Branch 18 → 19 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 17 → 8 not taken.
✗ Branch 17 → 18 not taken.
✗ Branch 18 → 9 not taken.
✗ Branch 18 → 19 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 20 → 9 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 22 → 11 not taken.
✗ Branch 22 → 23 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 13 → 8 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 14 → 9 not taken.
✗ Branch 14 → 15 not taken.
void layer_yuv_mulovr_c<(MaskMode)7, unsigned short, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, int, int):
✗ Branch 16 → 9 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 18 → 11 not taken.
✗ Branch 18 → 19 not taken.
24 for (int x = 0; x < cwidth; ++x) {
710 20 const uint32_t alpha_eff = has_alpha
711 10 ? magic_div_rt<pixel_t>((uint32_t)mask_ptr[x] * opacity_i + half, magic)
712 : (uint32_t)opacity_i;
713 // dark overlay Y → large darken_factor → strong pull toward neutral/black.
714 20 const uint32_t darken_factor = magic_div_rt<pixel_t>(alpha_eff * ((uint32_t)max_pixel_value - (uint32_t)ovr_y_ptr[x]) + half, magic);
715 20 const uint32_t inv_keep = (uint32_t)max_pixel_value - darken_factor;
716
717 if constexpr (!lumaonly) {
718 // UV: pull toward half_pix (chroma neutral). Overflow-safe in uint32 (see plan).
719 20 dstp_u[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_u[x] * inv_keep + half_pix * darken_factor + half, magic);
720 20 dstp_v[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_v[x] * inv_keep + half_pix * darken_factor + half, magic);
721 }
722 // For MASK444, luma and chroma share resolution — update Y here.
723 if constexpr (maskMode == MASK444)
724 40 dstp[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp[x] * inv_keep + half, magic);
725 }
726
727 if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2 || maskMode == MASK420_TOPLEFT) {
728 dstp += dst_pitch * 2;
729 ovrp += overlay_pitch * 2;
730 if constexpr (has_alpha)
731 maskp += mask_pitch * 2;
732 }
733 else {
734 4 dstp += dst_pitch;
735 4 ovrp += overlay_pitch;
736 if constexpr (has_alpha)
737 2 maskp += mask_pitch;
738 }
739
740 if constexpr (!lumaonly) {
741 4 dstp_u += dst_pitchUV;
742 4 dstp_v += dst_pitchUV;
743 }
744 }
745
746 2 dst_pitch *= sizeof(pixel_t);
747 2 dst_pitchUV *= sizeof(pixel_t);
748 2 overlay_pitch *= sizeof(pixel_t);
749 if constexpr (has_alpha)
750 1 mask_pitch *= sizeof(pixel_t);
751
752 // Phase 2: luma-only pass at full luma resolution.
753 if constexpr (!lumaonly && maskMode != MASK444)
754 layer_yuv_mulovr_c<MASK444, pixel_t, true, has_alpha>(
755 dstp8, nullptr, nullptr,
756 ovrp8, maskp8,
757 dst_pitch, 0, overlay_pitch, mask_pitch,
758 width, height, opacity_i, bits_per_pixel);
759 2 }
760
761 // Float version — neutral UV = 0.0f in AviSynth+ float YUV, so both luma and chroma
762 // collapse to the same formula: result = base * (1 - alpha_eff * (1 - ovr_Y)).
763 template<MaskMode maskMode, bool lumaonly, bool has_alpha>
764 9 static void layer_yuv_mulovr_f_c(
765 BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,
766 const BYTE* ovrp8,
767 const BYTE* maskp8,
768 int dst_pitch, int dst_pitchUV,
769 int overlay_pitch,
770 int mask_pitch,
771 int width, int height, float opacity)
772 {
773 9 float* dstp = reinterpret_cast<float*>(dstp8);
774 9 float* dstp_u = reinterpret_cast<float*>(dstp8_u); // nullptr when lumaonly
775 9 float* dstp_v = reinterpret_cast<float*>(dstp8_v); // nullptr when lumaonly
776 9 const float* ovrp = reinterpret_cast<const float*>(ovrp8);
777 9 const float* maskp = has_alpha ? reinterpret_cast<const float*>(maskp8) : nullptr;
778
779 9 dst_pitch /= sizeof(float);
780 9 dst_pitchUV /= sizeof(float);
781 9 overlay_pitch /= sizeof(float);
782 if constexpr (has_alpha)
783 2 mask_pitch /= sizeof(float);
784
785 9 const int cwidth = (maskMode == MASK444) ? width : (maskMode == MASK411) ? width >> 2 : width >> 1;
786 9 const int cheight = (maskMode == MASK444 || maskMode == MASK422 || maskMode == MASK422_MPEG2 || maskMode == MASK422_TOPLEFT || maskMode == MASK411) ? height : height >> 1;
787
788 9 std::vector<float> ovr_y_buffer;
789 9 std::vector<float> mask_buffer;
790 if constexpr (maskMode != MASK444) {
791
4/26
void layer_yuv_mulovr_f_c<(MaskMode)0, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)1, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)2, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)3, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)4, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)5, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)6, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 34 not taken.
4 ovr_y_buffer.resize(cwidth);
792 if constexpr (has_alpha)
793
1/12
void layer_yuv_mulovr_f_c<(MaskMode)1, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)2, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)3, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)4, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)5, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)6, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 34 not taken.
1 mask_buffer.resize(cwidth);
794 }
795
796
14/34
void layer_yuv_mulovr_f_c<(MaskMode)0, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 19 → 6 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 19 → 6 taken 3 times.
✓ Branch 19 → 20 taken 1 time.
void layer_yuv_mulovr_f_c<(MaskMode)1, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 29 → 7 not taken.
✗ Branch 29 → 30 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 19 → 6 taken 3 times.
✓ Branch 19 → 20 taken 1 time.
void layer_yuv_mulovr_f_c<(MaskMode)2, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 29 → 7 taken 3 times.
✓ Branch 29 → 30 taken 1 time.
void layer_yuv_mulovr_f_c<(MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 19 → 6 taken 3 times.
✓ Branch 19 → 20 taken 1 time.
void layer_yuv_mulovr_f_c<(MaskMode)3, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 29 → 7 not taken.
✗ Branch 29 → 30 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 19 → 6 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)4, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 29 → 7 not taken.
✗ Branch 29 → 30 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 19 → 6 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)5, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 29 → 7 not taken.
✗ Branch 29 → 30 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 19 → 6 not taken.
✗ Branch 19 → 20 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)6, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 29 → 7 not taken.
✗ Branch 29 → 30 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)7, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 11 → 5 taken 3 times.
✓ Branch 11 → 12 taken 1 time.
void layer_yuv_mulovr_f_c<(MaskMode)7, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 13 → 5 not taken.
✗ Branch 13 → 14 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)7, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 11 → 5 taken 18 times.
✓ Branch 11 → 12 taken 3 times.
void layer_yuv_mulovr_f_c<(MaskMode)7, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 13 → 5 taken 6 times.
✓ Branch 13 → 14 taken 1 time.
48 for (int y = 0; y < cheight; ++y) {
797 39 const float* ovr_y_ptr = prepare_effective_mask_for_row_float_c<maskMode>(ovrp, overlay_pitch, cwidth, ovr_y_buffer);
798 39 const float* mask_ptr = nullptr;
799 if constexpr (has_alpha)
800 9 mask_ptr = prepare_effective_mask_for_row_float_c<maskMode>(maskp, mask_pitch, cwidth, mask_buffer);
801
802
14/34
void layer_yuv_mulovr_f_c<(MaskMode)0, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 17 → 16 not taken.
✗ Branch 17 → 18 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 17 → 16 taken 12 times.
✓ Branch 17 → 18 taken 3 times.
void layer_yuv_mulovr_f_c<(MaskMode)1, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 27 → 26 not taken.
✗ Branch 27 → 28 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 17 → 16 taken 12 times.
✓ Branch 17 → 18 taken 3 times.
void layer_yuv_mulovr_f_c<(MaskMode)2, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 27 → 26 taken 12 times.
✓ Branch 27 → 28 taken 3 times.
void layer_yuv_mulovr_f_c<(MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 17 → 16 taken 12 times.
✓ Branch 17 → 18 taken 3 times.
void layer_yuv_mulovr_f_c<(MaskMode)3, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 27 → 26 not taken.
✗ Branch 27 → 28 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 17 → 16 not taken.
✗ Branch 17 → 18 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)4, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 27 → 26 not taken.
✗ Branch 27 → 28 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 17 → 16 not taken.
✗ Branch 17 → 18 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)5, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 27 → 26 not taken.
✗ Branch 27 → 28 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 17 → 16 not taken.
✗ Branch 17 → 18 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)6, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 27 → 26 not taken.
✗ Branch 27 → 28 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)7, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 9 → 8 taken 21 times.
✓ Branch 9 → 10 taken 3 times.
void layer_yuv_mulovr_f_c<(MaskMode)7, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 11 → 10 not taken.
✗ Branch 11 → 12 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)7, true, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 9 → 8 taken 144 times.
✓ Branch 9 → 10 taken 18 times.
void layer_yuv_mulovr_f_c<(MaskMode)7, true, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 11 → 10 taken 48 times.
✓ Branch 11 → 12 taken 6 times.
300 for (int x = 0; x < cwidth; ++x) {
803 261 const float alpha_eff = has_alpha ? mask_ptr[x] * opacity : opacity;
804 261 const float inv_keep = 1.0f - alpha_eff * (1.0f - ovr_y_ptr[x]);
805
806 if constexpr (!lumaonly) {
807 69 dstp_u[x] *= inv_keep; // neutral UV = 0.0f → same formula as luma
808 69 dstp_v[x] *= inv_keep;
809 }
810 if constexpr (maskMode == MASK444)
811 213 dstp[x] *= inv_keep;
812 }
813
814 if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2 || maskMode == MASK420_TOPLEFT) {
815 12 dstp += dst_pitch * 2;
816 12 ovrp += overlay_pitch * 2;
817 if constexpr (has_alpha)
818 3 maskp += mask_pitch * 2;
819 }
820 else {
821 27 dstp += dst_pitch;
822 27 ovrp += overlay_pitch;
823 if constexpr (has_alpha)
824 6 maskp += mask_pitch;
825 }
826
827 if constexpr (!lumaonly) {
828 15 dstp_u += dst_pitchUV;
829 15 dstp_v += dst_pitchUV;
830 }
831 }
832
833 9 dst_pitch *= sizeof(float);
834 9 dst_pitchUV *= sizeof(float);
835 9 overlay_pitch *= sizeof(float);
836 if constexpr (has_alpha)
837 2 mask_pitch *= sizeof(float);
838
839 if constexpr (!lumaonly && maskMode != MASK444)
840
4/26
void layer_yuv_mulovr_f_c<(MaskMode)0, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)1, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)1, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)2, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)2, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 30 → 31 taken 1 time.
✗ Branch 30 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)3, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)3, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)4, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)4, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)5, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)5, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 34 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)6, false, false>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void layer_yuv_mulovr_f_c<(MaskMode)6, false, true>(unsigned char*, unsigned char*, unsigned char*, unsigned char const*, unsigned char const*, int, int, int, int, int, int, float):
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 34 not taken.
4 layer_yuv_mulovr_f_c<MASK444, true, has_alpha>(
841 dstp8, nullptr, nullptr,
842 ovrp8, maskp8,
843 dst_pitch, 0, overlay_pitch, mask_pitch,
844 width, height, opacity);
845 9 }
846
847 7 static void get_layer_yuv_mulovr_functions(
848 bool has_alpha, int placement, VideoInfo& vi, int bits_per_pixel,
849 layer_yuv_mulovr_c_t** layer_fn,
850 layer_yuv_mulovr_f_c_t** layer_f_fn)
851 {
852 #define MULOVR_DISPATCH(MaskType, lumaonly, ha) \
853 { if (bits_per_pixel == 8) \
854 *layer_fn = layer_yuv_mulovr_c <MaskType, uint8_t, lumaonly, ha>; \
855 else if (bits_per_pixel <= 16) \
856 *layer_fn = layer_yuv_mulovr_c <MaskType, uint16_t, lumaonly, ha>; \
857 else \
858 *layer_f_fn = layer_yuv_mulovr_f_c<MaskType, lumaonly, ha>; \
859 }
860
861 #define MULOVR_HA(MaskType, lumaonly) \
862 { if (has_alpha) { MULOVR_DISPATCH(MaskType, lumaonly, true) } \
863 else { MULOVR_DISPATCH(MaskType, lumaonly, false) } }
864
865
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 15 taken 7 times.
7 if (vi.IsY()) {
866 // Greyscale: no UV planes — luma-only pass, identical to Layer "Mul" luma.
867 MULOVR_HA(MASK444, true)
868 }
869
1/2
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 22 taken 7 times.
7 else if (vi.IsYV411()) {
870 MULOVR_DISPATCH(MASK411, false, false) // YV411 never has alpha
871 }
872
2/2
✓ Branch 23 → 24 taken 4 times.
✓ Branch 23 → 59 taken 3 times.
7 else if (vi.Is420()) {
873
5/12
✓ Branch 24 → 25 taken 1 time.
✓ Branch 24 → 36 taken 3 times.
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 31 taken 1 time.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 28 not taken.
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 30 not taken.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 33 taken 1 time.
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 1 time.
4 if (placement == PLACEMENT_MPEG1) { MULOVR_HA(MASK420, false) }
874
5/12
✓ Branch 36 → 37 taken 1 time.
✓ Branch 36 → 48 taken 2 times.
✗ Branch 37 → 38 not taken.
✓ Branch 37 → 43 taken 1 time.
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 40 not taken.
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 42 not taken.
✗ Branch 43 → 44 not taken.
✓ Branch 43 → 45 taken 1 time.
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 47 taken 1 time.
3 else if (placement == PLACEMENT_TOPLEFT) { MULOVR_HA(MASK420_TOPLEFT, false) }
875
6/10
✓ Branch 48 → 49 taken 1 time.
✓ Branch 48 → 54 taken 1 time.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 1 time.
✗ Branch 51 → 52 not taken.
✓ Branch 51 → 53 taken 1 time.
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 56 taken 1 time.
✗ Branch 56 → 57 not taken.
✓ Branch 56 → 58 taken 1 time.
2 else { MULOVR_HA(MASK420_MPEG2, false) }
876 }
877
1/2
✗ Branch 60 → 61 not taken.
✓ Branch 60 → 96 taken 3 times.
3 else if (vi.Is422()) {
878 if (placement == PLACEMENT_MPEG1) { MULOVR_HA(MASK422, false) }
879 else if (placement == PLACEMENT_TOPLEFT) { MULOVR_HA(MASK422_TOPLEFT, false) }
880 else { MULOVR_HA(MASK422_MPEG2, false) }
881 }
882 else { // Is444() — cwidth == width, cheight == height; same-res, single pass
883
6/10
✓ Branch 96 → 97 taken 1 time.
✓ Branch 96 → 102 taken 2 times.
✓ Branch 97 → 98 taken 1 time.
✗ Branch 97 → 99 not taken.
✗ Branch 99 → 100 not taken.
✗ Branch 99 → 101 not taken.
✓ Branch 102 → 103 taken 1 time.
✓ Branch 102 → 104 taken 1 time.
✗ Branch 104 → 105 not taken.
✓ Branch 104 → 106 taken 1 time.
3 MULOVR_HA(MASK444, false)
884 }
885
886 #undef MULOVR_HA
887 #undef MULOVR_DISPATCH
888 7 }
889
890 // both masked merge (HasAlpha) and plain add (no alpha)
891 // Though we use it only for masked merge, kept for reference.
892 static void get_layer_yuv_add_masked_functions(
893 bool is_chroma, bool hasAlpha,
894 int placement, VideoInfo& vi, int bits_per_pixel,
895 /*out*/masked_merge_fn_t** layer_fn,
896 /*out*/masked_merge_float_fn_t** layer_f_fn)
897 {
898 // Use the unified (Layer,Overlay) masked merge functions
899 // Determine MaskMode from format and placement
900 MaskMode maskMode = MASK444;
901 if (is_chroma) {
902 if (vi.IsYV411())
903 maskMode = MASK411;
904 else if (vi.Is420())
905 maskMode = (placement == PLACEMENT_MPEG1) ? MASK420 : (placement == PLACEMENT_TOPLEFT) ? MASK420_TOPLEFT : MASK420_MPEG2;
906 else if (vi.Is422())
907 maskMode = (placement == PLACEMENT_MPEG1) ? MASK422 : (placement == PLACEMENT_TOPLEFT) ? MASK422_TOPLEFT : MASK422_MPEG2;
908 // Is444() / IsY(): stay MASK444
909 }
910 // is_chroma=false (luma): always MASK444
911 *layer_fn = get_overlay_blend_masked_fn_c(is_chroma, maskMode);
912 *layer_f_fn = get_overlay_blend_masked_float_fn_c(is_chroma, maskMode);
913
914 }
915
916 /* planar rgb */
917 template<int mode, typename pixel_t, bool has_alpha, bool blend_alpha>
918 12 static void layer_planarrgb_lighten_darken_c(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int opacity_i, int thresh, int bits_per_pixel) {
919 12 pixel_t* dstp_g = reinterpret_cast<pixel_t*>(dstp8[0]);
920 12 pixel_t* dstp_b = reinterpret_cast<pixel_t*>(dstp8[1]);
921 12 pixel_t* dstp_r = reinterpret_cast<pixel_t*>(dstp8[2]);
922 // dstp8[3]: written only when blend_alpha=true (both clips have alpha).
923 pixel_t* dstp_a;
924 if constexpr (blend_alpha)
925 4 dstp_a = reinterpret_cast<pixel_t*>(dstp8[3]);
926 12 const pixel_t* ovrp_g = reinterpret_cast<const pixel_t*>(ovrp8[0]);
927 12 const pixel_t* ovrp_b = reinterpret_cast<const pixel_t*>(ovrp8[1]);
928 12 const pixel_t* ovrp_r = reinterpret_cast<const pixel_t*>(ovrp8[2]);
929 // maskp: per-pixel blend weight — decoupled from ovrp8[3] so a future mask clip can be wired in.
930 12 const pixel_t* maskp = reinterpret_cast<const pixel_t*>(maskp8);
931 // alpha_target: value blended into dstp_a (only used when blend_alpha=true).
932 // For plain Add this is the same plane as maskp; for Subtract it is the inverted A plane.
933 const pixel_t* alpha_target;
934 if constexpr (blend_alpha)
935 4 alpha_target = reinterpret_cast<const pixel_t*>(ovrp8[3]);
936
937 12 dst_pitch /= sizeof(pixel_t);
938 12 overlay_pitch /= sizeof(pixel_t);
939 12 mask_pitch /= sizeof(pixel_t);
940
941 if constexpr (sizeof(pixel_t) == 1)
942 6 bits_per_pixel = 8; // make quasi constexpr
943
944 12 const MagicDiv magic = get_magic_div(bits_per_pixel);
945 12 const int max_pixel_value = (1 << bits_per_pixel) - 1;
946 12 const int half = max_pixel_value / 2;
947
948
24/24
void layer_planarrgb_lighten_darken_c<0, unsigned char, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 17 → 4 taken 5 times.
✓ Branch 17 → 18 taken 1 time.
void layer_planarrgb_lighten_darken_c<0, unsigned char, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 19 → 4 taken 5 times.
✓ Branch 19 → 20 taken 1 time.
void layer_planarrgb_lighten_darken_c<0, unsigned char, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 21 → 4 taken 5 times.
✓ Branch 21 → 22 taken 1 time.
void layer_planarrgb_lighten_darken_c<0, unsigned short, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 17 → 4 taken 3 times.
✓ Branch 17 → 18 taken 1 time.
void layer_planarrgb_lighten_darken_c<0, unsigned short, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 19 → 4 taken 3 times.
✓ Branch 19 → 20 taken 1 time.
void layer_planarrgb_lighten_darken_c<0, unsigned short, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 21 → 4 taken 3 times.
✓ Branch 21 → 22 taken 1 time.
void layer_planarrgb_lighten_darken_c<1, unsigned char, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 17 → 4 taken 5 times.
✓ Branch 17 → 18 taken 1 time.
void layer_planarrgb_lighten_darken_c<1, unsigned char, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 19 → 4 taken 5 times.
✓ Branch 19 → 20 taken 1 time.
void layer_planarrgb_lighten_darken_c<1, unsigned char, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 21 → 4 taken 5 times.
✓ Branch 21 → 22 taken 1 time.
void layer_planarrgb_lighten_darken_c<1, unsigned short, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 17 → 4 taken 3 times.
✓ Branch 17 → 18 taken 1 time.
void layer_planarrgb_lighten_darken_c<1, unsigned short, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 19 → 4 taken 3 times.
✓ Branch 19 → 20 taken 1 time.
void layer_planarrgb_lighten_darken_c<1, unsigned short, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 21 → 4 taken 3 times.
✓ Branch 21 → 22 taken 1 time.
60 for (int y = 0; y < height; ++y) {
949
24/24
void layer_planarrgb_lighten_darken_c<0, unsigned char, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 15 → 5 taken 65 times.
✓ Branch 15 → 16 taken 5 times.
void layer_planarrgb_lighten_darken_c<0, unsigned char, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 17 → 5 taken 65 times.
✓ Branch 17 → 18 taken 5 times.
void layer_planarrgb_lighten_darken_c<0, unsigned char, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 19 → 5 taken 65 times.
✓ Branch 19 → 20 taken 5 times.
void layer_planarrgb_lighten_darken_c<0, unsigned short, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 15 → 5 taken 57 times.
✓ Branch 15 → 16 taken 3 times.
void layer_planarrgb_lighten_darken_c<0, unsigned short, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 17 → 5 taken 57 times.
✓ Branch 17 → 18 taken 3 times.
void layer_planarrgb_lighten_darken_c<0, unsigned short, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 19 → 5 taken 57 times.
✓ Branch 19 → 20 taken 3 times.
void layer_planarrgb_lighten_darken_c<1, unsigned char, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 15 → 5 taken 65 times.
✓ Branch 15 → 16 taken 5 times.
void layer_planarrgb_lighten_darken_c<1, unsigned char, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 17 → 5 taken 65 times.
✓ Branch 17 → 18 taken 5 times.
void layer_planarrgb_lighten_darken_c<1, unsigned char, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 19 → 5 taken 65 times.
✓ Branch 19 → 20 taken 5 times.
void layer_planarrgb_lighten_darken_c<1, unsigned short, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 15 → 5 taken 57 times.
✓ Branch 15 → 16 taken 3 times.
void layer_planarrgb_lighten_darken_c<1, unsigned short, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 17 → 5 taken 57 times.
✓ Branch 17 → 18 taken 3 times.
void layer_planarrgb_lighten_darken_c<1, unsigned short, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 19 → 5 taken 57 times.
✓ Branch 19 → 20 taken 3 times.
780 for (int x = 0; x < width; ++x) {
950 // opacity_i is in [0..max_pixel_value], the same convention as masked_merge.
951 uint32_t alpha_eff;
952 if constexpr (has_alpha) {
953 488 const uint32_t alpha_src = (uint32_t)maskp[x];
954 488 alpha_eff = (uint32_t)magic_div_rt<pixel_t>(alpha_src * (uint32_t)opacity_i + half, magic);
955 } else {
956 244 alpha_eff = opacity_i;
957 }
958 // standard rgb->luma coefficients, scaled up by 15 bits
959 // no rounding, not really needed here
960 732 const int luma_ovr = (cyb * ovrp_b[x] + cyg * ovrp_g[x] + cyr * ovrp_r[x]) >> 15;
961 732 const int luma_src = (cyb * dstp_b[x] + cyg * dstp_g[x] + cyr * dstp_r[x]) >> 15;
962
963
964 if constexpr (mode == LIGHTEN)
965
12/12
void layer_planarrgb_lighten_darken_c<0, unsigned char, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 23 times.
✓ Branch 5 → 7 taken 42 times.
void layer_planarrgb_lighten_darken_c<0, unsigned char, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 23 times.
✓ Branch 7 → 9 taken 42 times.
void layer_planarrgb_lighten_darken_c<0, unsigned char, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 23 times.
✓ Branch 7 → 9 taken 42 times.
void layer_planarrgb_lighten_darken_c<0, unsigned short, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 26 times.
✓ Branch 5 → 7 taken 31 times.
void layer_planarrgb_lighten_darken_c<0, unsigned short, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 26 times.
✓ Branch 7 → 9 taken 31 times.
void layer_planarrgb_lighten_darken_c<0, unsigned short, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 26 times.
✓ Branch 7 → 9 taken 31 times.
366 alpha_eff = luma_ovr > luma_src + thresh ? alpha_eff : 0;
966 else // DARKEN
967
12/12
void layer_planarrgb_lighten_darken_c<1, unsigned char, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 31 times.
✓ Branch 5 → 7 taken 34 times.
void layer_planarrgb_lighten_darken_c<1, unsigned char, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 31 times.
✓ Branch 7 → 9 taken 34 times.
void layer_planarrgb_lighten_darken_c<1, unsigned char, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 31 times.
✓ Branch 7 → 9 taken 34 times.
void layer_planarrgb_lighten_darken_c<1, unsigned short, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 5 → 6 taken 28 times.
✓ Branch 5 → 7 taken 29 times.
void layer_planarrgb_lighten_darken_c<1, unsigned short, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 28 times.
✓ Branch 7 → 9 taken 29 times.
void layer_planarrgb_lighten_darken_c<1, unsigned short, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int, int):
✓ Branch 7 → 8 taken 28 times.
✓ Branch 7 → 9 taken 29 times.
366 alpha_eff = luma_ovr < luma_src - thresh ? alpha_eff : 0;
968
969 732 const uint32_t inv_alpha = max_pixel_value - alpha_eff;
970
971 // move to magicdiv
972 //dstp_r[x] = (pixel_t)(dstp_r[x] + (((ovrp_r[x] - dstp_r[x]) * alpha + rounder) >> bits_per_pixel));
973 //dstp_g[x] = (pixel_t)(dstp_g[x] + (((ovrp_g[x] - dstp_g[x]) * alpha + rounder) >> bits_per_pixel));
974 //dstp_b[x] = (pixel_t)(dstp_b[x] + (((ovrp_b[x] - dstp_b[x]) * alpha + rounder) >> bits_per_pixel));
975 732 dstp_r[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_r[x] * inv_alpha + (uint32_t)ovrp_r[x] * alpha_eff + half, magic);
976 732 dstp_g[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_g[x] * inv_alpha + (uint32_t)ovrp_g[x] * alpha_eff + half, magic);
977 1220 dstp_b[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_b[x] * inv_alpha + (uint32_t)ovrp_b[x] * alpha_eff + half, magic);
978 if constexpr (blend_alpha)
979 488 dstp_a[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_a[x] * inv_alpha + (uint32_t)alpha_target[x] * alpha_eff + half, magic);
980 }
981 48 dstp_g += dst_pitch;
982 48 dstp_b += dst_pitch;
983 48 dstp_r += dst_pitch;
984 if constexpr (blend_alpha)
985 16 dstp_a += dst_pitch;
986 48 ovrp_g += overlay_pitch;
987 48 ovrp_b += overlay_pitch;
988 48 ovrp_r += overlay_pitch;
989 if constexpr (has_alpha)
990 32 maskp += mask_pitch;
991 if constexpr (blend_alpha)
992 16 alpha_target += overlay_pitch;
993 }
994 12 }
995
996 template<int mode, bool has_alpha, bool blend_alpha>
997 10 static void layer_planarrgb_lighten_darken_f_c(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity, float thresh) {
998 10 float* dstp_g = reinterpret_cast<float*>(dstp8[0]);
999 10 float* dstp_b = reinterpret_cast<float*>(dstp8[1]);
1000 10 float* dstp_r = reinterpret_cast<float*>(dstp8[2]);
1001 // dstp8[3]: written only when blend_alpha=true (both clips have alpha).
1002 float* dstp_a;
1003 if constexpr (blend_alpha)
1004 3 dstp_a = reinterpret_cast<float*>(dstp8[3]);
1005 10 const float* ovrp_g = reinterpret_cast<const float*>(ovrp8[0]);
1006 10 const float* ovrp_b = reinterpret_cast<const float*>(ovrp8[1]);
1007 10 const float* ovrp_r = reinterpret_cast<const float*>(ovrp8[2]);
1008 // maskp: per-pixel blend weight — decoupled from ovrp8[3].
1009 10 const float* maskp = reinterpret_cast<const float*>(maskp8);
1010 const float* alpha_target;
1011 if constexpr (blend_alpha)
1012 3 alpha_target = reinterpret_cast<const float*>(ovrp8[3]);
1013
1014 10 dst_pitch /= sizeof(float);
1015 10 overlay_pitch /= sizeof(float);
1016 10 mask_pitch /= sizeof(float);
1017
1018
12/12
void layer_planarrgb_lighten_darken_f_c<0, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 10 → 3 taken 6 times.
✓ Branch 10 → 11 taken 2 times.
void layer_planarrgb_lighten_darken_f_c<0, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 10 → 3 taken 6 times.
✓ Branch 10 → 11 taken 2 times.
void layer_planarrgb_lighten_darken_f_c<0, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 10 → 3 taken 3 times.
✓ Branch 10 → 11 taken 1 time.
void layer_planarrgb_lighten_darken_f_c<1, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 10 → 3 taken 6 times.
✓ Branch 10 → 11 taken 2 times.
void layer_planarrgb_lighten_darken_f_c<1, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 10 → 3 taken 3 times.
✓ Branch 10 → 11 taken 1 time.
void layer_planarrgb_lighten_darken_f_c<1, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 10 → 3 taken 6 times.
✓ Branch 10 → 11 taken 2 times.
40 for (int y = 0; y < height; ++y) {
1019
12/12
void layer_planarrgb_lighten_darken_f_c<0, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 8 → 4 taken 42 times.
✓ Branch 8 → 9 taken 6 times.
void layer_planarrgb_lighten_darken_f_c<0, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 8 → 4 taken 42 times.
✓ Branch 8 → 9 taken 6 times.
void layer_planarrgb_lighten_darken_f_c<0, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 8 → 4 taken 21 times.
✓ Branch 8 → 9 taken 3 times.
void layer_planarrgb_lighten_darken_f_c<1, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 8 → 4 taken 42 times.
✓ Branch 8 → 9 taken 6 times.
void layer_planarrgb_lighten_darken_f_c<1, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 8 → 4 taken 21 times.
✓ Branch 8 → 9 taken 3 times.
void layer_planarrgb_lighten_darken_f_c<1, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 8 → 4 taken 42 times.
✓ Branch 8 → 9 taken 6 times.
240 for (int x = 0; x < width; ++x) {
1020 210 float alpha = has_alpha ? maskp[x] * opacity : opacity;
1021
1022 210 float luma_ovr = cyb_f * ovrp_b[x] + cyg_f * ovrp_g[x] + cyr_f * ovrp_r[x];
1023 210 float luma_src = cyb_f * dstp_b[x] + cyg_f * dstp_g[x] + cyr_f * dstp_r[x];
1024
1025 if constexpr (mode == LIGHTEN)
1026
6/6
void layer_planarrgb_lighten_darken_f_c<0, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 4 → 5 taken 18 times.
✓ Branch 4 → 6 taken 24 times.
void layer_planarrgb_lighten_darken_f_c<0, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 4 → 5 taken 18 times.
✓ Branch 4 → 6 taken 24 times.
void layer_planarrgb_lighten_darken_f_c<0, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 4 → 5 taken 8 times.
✓ Branch 4 → 6 taken 13 times.
105 alpha = luma_ovr > luma_src + thresh ? alpha : 0;
1027 else // DARKEN
1028
6/6
void layer_planarrgb_lighten_darken_f_c<1, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 4 → 5 taken 16 times.
✓ Branch 4 → 6 taken 26 times.
void layer_planarrgb_lighten_darken_f_c<1, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 4 → 5 taken 8 times.
✓ Branch 4 → 6 taken 13 times.
void layer_planarrgb_lighten_darken_f_c<1, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float, float):
✓ Branch 4 → 5 taken 16 times.
✓ Branch 4 → 6 taken 26 times.
105 alpha = luma_ovr < luma_src - thresh ? alpha : 0;
1029
1030 210 dstp_r[x] = dstp_r[x] + (ovrp_r[x] - dstp_r[x]) * alpha;
1031 210 dstp_g[x] = dstp_g[x] + (ovrp_g[x] - dstp_g[x]) * alpha;
1032 210 dstp_b[x] = dstp_b[x] + (ovrp_b[x] - dstp_b[x]) * alpha;
1033 if constexpr (blend_alpha)
1034 63 dstp_a[x] = dstp_a[x] + (alpha_target[x] - dstp_a[x]) * alpha;
1035 }
1036 30 dstp_g += dst_pitch;
1037 30 dstp_b += dst_pitch;
1038 30 dstp_r += dst_pitch;
1039 if constexpr (blend_alpha)
1040 9 dstp_a += dst_pitch;
1041 30 ovrp_g += overlay_pitch;
1042 30 ovrp_b += overlay_pitch;
1043 30 ovrp_r += overlay_pitch;
1044 if constexpr (has_alpha)
1045 18 maskp += mask_pitch;
1046 if constexpr (blend_alpha)
1047 9 alpha_target += overlay_pitch;
1048 }
1049 10 }
1050
1051
1052 4036 static void get_layer_planarrgb_lighten_darken_functions(bool isLighten, bool hasAlpha, bool blendAlpha, int bits_per_pixel, /*out*/layer_planarrgb_lighten_darken_c_t** layer_fn, /*out*/layer_planarrgb_lighten_darken_f_c_t** layer_f_fn) {
1053
1054 #define PLANARRGB_LD_DISPATCH(LorD, has_alpha, blend_alpha) \
1055 { if (bits_per_pixel == 8) \
1056 *layer_fn = layer_planarrgb_lighten_darken_c<LorD, uint8_t, has_alpha, blend_alpha>; \
1057 else if (bits_per_pixel <= 16) \
1058 *layer_fn = layer_planarrgb_lighten_darken_c<LorD, uint16_t, has_alpha, blend_alpha>; \
1059 else /* float */ \
1060 *layer_f_fn = layer_planarrgb_lighten_darken_f_c<LorD, has_alpha, blend_alpha>; \
1061 }
1062
1063
2/2
✓ Branch 2 → 3 taken 2018 times.
✓ Branch 2 → 20 taken 2018 times.
4036 if (isLighten) {
1064
2/2
✓ Branch 3 → 4 taken 1345 times.
✓ Branch 3 → 15 taken 673 times.
2018 if (hasAlpha) {
1065
6/6
✓ Branch 4 → 5 taken 672 times.
✓ Branch 4 → 10 taken 673 times.
✓ Branch 5 → 6 taken 224 times.
✓ Branch 5 → 7 taken 448 times.
✓ Branch 7 → 8 taken 224 times.
✓ Branch 7 → 9 taken 224 times.
1345 if (blendAlpha) { PLANARRGB_LD_DISPATCH(LIGHTEN, true, true) }
1066
4/4
✓ Branch 10 → 11 taken 224 times.
✓ Branch 10 → 12 taken 449 times.
✓ Branch 12 → 13 taken 224 times.
✓ Branch 12 → 14 taken 225 times.
673 else { PLANARRGB_LD_DISPATCH(LIGHTEN, true, false) }
1067 }
1068 else {
1069
4/4
✓ Branch 15 → 16 taken 224 times.
✓ Branch 15 → 17 taken 449 times.
✓ Branch 17 → 18 taken 224 times.
✓ Branch 17 → 19 taken 225 times.
673 PLANARRGB_LD_DISPATCH(LIGHTEN, false, false)
1070 }
1071 } // lighten end
1072 else {
1073
2/2
✓ Branch 20 → 21 taken 1345 times.
✓ Branch 20 → 32 taken 673 times.
2018 if (hasAlpha) {
1074
6/6
✓ Branch 21 → 22 taken 673 times.
✓ Branch 21 → 27 taken 672 times.
✓ Branch 22 → 23 taken 224 times.
✓ Branch 22 → 24 taken 449 times.
✓ Branch 24 → 25 taken 224 times.
✓ Branch 24 → 26 taken 225 times.
1345 if (blendAlpha) { PLANARRGB_LD_DISPATCH(DARKEN, true, true) }
1075
4/4
✓ Branch 27 → 28 taken 224 times.
✓ Branch 27 → 29 taken 448 times.
✓ Branch 29 → 30 taken 224 times.
✓ Branch 29 → 31 taken 224 times.
672 else { PLANARRGB_LD_DISPATCH(DARKEN, true, false) }
1076 }
1077 else {
1078
4/4
✓ Branch 32 → 33 taken 224 times.
✓ Branch 32 → 34 taken 449 times.
✓ Branch 34 → 35 taken 224 times.
✓ Branch 34 → 36 taken 225 times.
673 PLANARRGB_LD_DISPATCH(DARKEN, false, false)
1079 }
1080 }
1081 #undef PLANARRGB_LD_DISPATCH
1082 4036 }
1083
1084 // subtract=false only: overlay clip is pre-inverted by Layer::Create when op="Subtract".
1085 template<typename pixel_t,bool chroma, bool has_alpha, bool blend_alpha>
1086 static void layer_planarrgb_add_c(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int opacity_i, int bits_per_pixel) {
1087 pixel_t* dstp_g = reinterpret_cast<pixel_t*>(dstp8[0]);
1088 pixel_t* dstp_b = reinterpret_cast<pixel_t*>(dstp8[1]);
1089 pixel_t* dstp_r = reinterpret_cast<pixel_t*>(dstp8[2]);
1090 // dstp8[3]: written only when blend_alpha=true (both clips have alpha).
1091 pixel_t* dstp_a;
1092 if constexpr (blend_alpha)
1093 dstp_a = reinterpret_cast<pixel_t*>(dstp8[3]);
1094 const pixel_t* ovrp_g = reinterpret_cast<const pixel_t*>(ovrp8[0]);
1095 const pixel_t* ovrp_b = reinterpret_cast<const pixel_t*>(ovrp8[1]);
1096 const pixel_t* ovrp_r = reinterpret_cast<const pixel_t*>(ovrp8[2]);
1097 // maskp: per-pixel blend weight — decoupled from ovrp8[3] to support future mask clip param.
1098 const pixel_t* maskp = reinterpret_cast<const pixel_t*>(maskp8);
1099 // alpha_target: the value blended into dstp_a.
1100 // For plain Add: same as maskp (original overlay A).
1101 // For Subtract: ovrp8[3] is the inverted A; maskp is the saved pre-invert A.
1102 const pixel_t* alpha_target;
1103 if constexpr (blend_alpha)
1104 alpha_target = reinterpret_cast<const pixel_t*>(ovrp8[3]);
1105
1106 dst_pitch /= sizeof(pixel_t);
1107 overlay_pitch /= sizeof(pixel_t);
1108 mask_pitch /= sizeof(pixel_t);
1109
1110 if constexpr (sizeof(pixel_t) == 1)
1111 bits_per_pixel = 8; // make quasi constexpr
1112
1113 // use magic-div
1114 const MagicDiv magic = get_magic_div(bits_per_pixel);
1115 const int max_pixel_value = (1 << bits_per_pixel) - 1;
1116 const int half = max_pixel_value / 2;
1117
1118 for (int y = 0; y < height; ++y) {
1119 for (int x = 0; x < width; ++x) {
1120
1121 uint32_t alpha_eff;
1122 if constexpr (has_alpha) {
1123 const uint32_t alpha_src = (uint32_t)maskp[x];
1124 alpha_eff = (uint32_t)magic_div_rt<pixel_t>(alpha_src * (uint32_t)opacity_i + half, magic);
1125 }
1126 else {
1127 alpha_eff = opacity_i;
1128 }
1129 const uint32_t inv_alpha = max_pixel_value - alpha_eff;
1130
1131 if constexpr (chroma) {
1132 //dstp_r[x] = (pixel_t)(dstp_r[x] + (((ovrp_r[x] - dstp_r[x]) * alpha + rounder) >> bits_per_pixel));
1133 //dstp_g[x] = (pixel_t)(dstp_g[x] + (((ovrp_g[x] - dstp_g[x]) * alpha + rounder) >> bits_per_pixel));
1134 //dstp_b[x] = (pixel_t)(dstp_b[x] + (((ovrp_b[x] - dstp_b[x]) * alpha + rounder) >> bits_per_pixel));
1135 dstp_r[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_r[x] * inv_alpha + (uint32_t)ovrp_r[x] * alpha_eff + half, magic);
1136 dstp_g[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_g[x] * inv_alpha + (uint32_t)ovrp_g[x] * alpha_eff + half, magic);
1137 dstp_b[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_b[x] * inv_alpha + (uint32_t)ovrp_b[x] * alpha_eff + half, magic);
1138 }
1139 else { // use luma instead of overlay
1140 const int luma = (cyb * ovrp_b[x] + cyg * ovrp_g[x] + cyr * ovrp_r[x]) >> 15; // no rounding not really needed here
1141
1142 //dstp_r[x] = (pixel_t)(dstp_r[x] + (((luma - dstp_r[x]) * alpha + rounder) >> bits_per_pixel));
1143 //dstp_g[x] = (pixel_t)(dstp_g[x] + (((luma - dstp_g[x]) * alpha + rounder) >> bits_per_pixel));
1144 //dstp_b[x] = (pixel_t)(dstp_b[x] + (((luma - dstp_b[x]) * alpha + rounder) >> bits_per_pixel));
1145 const uint32_t luma_scaled = (uint32_t)luma * alpha_eff;
1146 dstp_r[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_r[x] * inv_alpha + luma_scaled + half, magic);
1147 dstp_g[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_g[x] * inv_alpha + luma_scaled + half, magic);
1148 dstp_b[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_b[x] * inv_alpha + luma_scaled + half, magic);
1149 }
1150 if constexpr (blend_alpha)
1151 dstp_a[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_a[x] * inv_alpha + (uint32_t)alpha_target[x] * alpha_eff + half, magic);
1152 }
1153 dstp_g += dst_pitch;
1154 dstp_b += dst_pitch;
1155 dstp_r += dst_pitch;
1156 if constexpr (blend_alpha)
1157 dstp_a += dst_pitch;
1158 ovrp_g += overlay_pitch;
1159 ovrp_b += overlay_pitch;
1160 ovrp_r += overlay_pitch;
1161 if constexpr (has_alpha)
1162 maskp += mask_pitch;
1163 if constexpr (blend_alpha)
1164 alpha_target += overlay_pitch;
1165 }
1166 }
1167
1168 // subtract=false only: overlay clip is pre-inverted by Layer::Create when op="Subtract".
1169 template<bool chroma, bool has_alpha, bool blend_alpha>
1170 6 static void layer_planarrgb_add_f_c(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity) {
1171 6 float* dstp_g = reinterpret_cast<float*>(dstp8[0]);
1172 6 float* dstp_b = reinterpret_cast<float*>(dstp8[1]);
1173 6 float* dstp_r = reinterpret_cast<float*>(dstp8[2]);
1174 // dstp8[3]: written only when blend_alpha=true (both clips have alpha).
1175 float* dstp_a;
1176 if constexpr (blend_alpha)
1177 2 dstp_a = reinterpret_cast<float*>(dstp8[3]);
1178 6 const float* ovrp_g = reinterpret_cast<const float*>(ovrp8[0]);
1179 6 const float* ovrp_b = reinterpret_cast<const float*>(ovrp8[1]);
1180 6 const float* ovrp_r = reinterpret_cast<const float*>(ovrp8[2]);
1181 // maskp: per-pixel blend weight — decoupled from ovrp8[3].
1182 6 const float* maskp = reinterpret_cast<const float*>(maskp8);
1183 const float* alpha_target;
1184 if constexpr (blend_alpha)
1185 2 alpha_target = reinterpret_cast<const float*>(ovrp8[3]);
1186
1187 6 dst_pitch /= sizeof(float);
1188 6 overlay_pitch /= sizeof(float);
1189 6 mask_pitch /= sizeof(float);
1190
1191
12/12
void layer_planarrgb_add_f_c<false, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
void layer_planarrgb_add_f_c<false, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
void layer_planarrgb_add_f_c<false, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
void layer_planarrgb_add_f_c<true, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
void layer_planarrgb_add_f_c<true, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
void layer_planarrgb_add_f_c<true, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
24 for (int y = 0; y < height; ++y) {
1192
12/12
void layer_planarrgb_add_f_c<false, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 21 times.
✓ Branch 5 → 6 taken 3 times.
void layer_planarrgb_add_f_c<false, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 21 times.
✓ Branch 5 → 6 taken 3 times.
void layer_planarrgb_add_f_c<false, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 21 times.
✓ Branch 5 → 6 taken 3 times.
void layer_planarrgb_add_f_c<true, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 21 times.
✓ Branch 5 → 6 taken 3 times.
void layer_planarrgb_add_f_c<true, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 21 times.
✓ Branch 5 → 6 taken 3 times.
void layer_planarrgb_add_f_c<true, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 21 times.
✓ Branch 5 → 6 taken 3 times.
144 for (int x = 0; x < width; ++x) {
1193 126 float alpha = has_alpha ? maskp[x] * opacity : opacity;
1194
1195 if constexpr (chroma) {
1196 63 dstp_r[x] = dstp_r[x] + (ovrp_r[x] - dstp_r[x]) * alpha;
1197 63 dstp_g[x] = dstp_g[x] + (ovrp_g[x] - dstp_g[x]) * alpha;
1198 63 dstp_b[x] = dstp_b[x] + (ovrp_b[x] - dstp_b[x]) * alpha;
1199 }
1200 else { // use luma instead of overlay
1201 63 float luma = cyb_f * ovrp_b[x] + cyg_f * ovrp_g[x] + cyr_f * ovrp_r[x];
1202 63 dstp_r[x] = dstp_r[x] + (luma - dstp_r[x]) * alpha;
1203 63 dstp_g[x] = dstp_g[x] + (luma - dstp_g[x]) * alpha;
1204 63 dstp_b[x] = dstp_b[x] + (luma - dstp_b[x]) * alpha;
1205 }
1206 if constexpr (blend_alpha)
1207 42 dstp_a[x] = dstp_a[x] + (alpha_target[x] - dstp_a[x]) * alpha;
1208 }
1209 18 dstp_g += dst_pitch;
1210 18 dstp_b += dst_pitch;
1211 18 dstp_r += dst_pitch;
1212 if constexpr (blend_alpha)
1213 6 dstp_a += dst_pitch;
1214 18 ovrp_g += overlay_pitch;
1215 18 ovrp_b += overlay_pitch;
1216 18 ovrp_r += overlay_pitch;
1217 if constexpr (has_alpha)
1218 12 maskp += mask_pitch;
1219 if constexpr (blend_alpha)
1220 6 alpha_target += overlay_pitch;
1221 }
1222 6 }
1223
1224 // ---------------------------------------------------------------------------
1225 // Planar RGB add — SSE4.1 per-plane wrappers (mirrors AVX2 counterparts).
1226 // All planar RGB planes are MASK444. maskp8 is the per-pixel weight.
1227 // chroma=false and float fall back to C templates.
1228
1229 static void layer_planarrgb_add_c_3plane(
1230 BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8,
1231 int dst_pitch, int overlay_pitch, int mask_pitch,
1232 int width, int height, int opacity_i, int bits_per_pixel)
1233 {
1234 for (int i = 0; i < 3; i++)
1235 masked_merge_c_impl<MASK444>(
1236 dstp8[i], ovrp8[i], maskp8,
1237 dst_pitch, overlay_pitch, mask_pitch,
1238 width, height, opacity_i, bits_per_pixel);
1239 }
1240
1241 static void layer_planarrgb_add_c_4plane(
1242 BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8,
1243 int dst_pitch, int overlay_pitch, int mask_pitch,
1244 int width, int height, int opacity_i, int bits_per_pixel)
1245 {
1246 for (int i = 0; i < 4; i++)
1247 masked_merge_c_impl<MASK444>(
1248 dstp8[i], ovrp8[i], maskp8,
1249 dst_pitch, overlay_pitch, mask_pitch,
1250 width, height, opacity_i, bits_per_pixel);
1251 }
1252
1253
1254 1344 static void get_layer_planarrgb_add_functions(
1255 bool chroma, bool hasAlpha, bool blendAlpha, int bits_per_pixel,
1256 /*out*/layer_planarrgb_add_c_t** layer_fn,
1257 /*out*/layer_planarrgb_add_f_c_t** layer_f_fn)
1258 {
1259
1260 // chroma is true: Layer can use the unified masked and weighted blend routines
1261 // chroma is false: Layer-specific extension
1262 // Integer + hasAlpha + chroma=true: dispatch per-plane to masked_merge_avx2_impl (MASK444).
1263 // chroma=false (blend toward luma) has a different formula — keep C template.
1264 // float: keep C template (float perf is usually fine; could add later).
1265
3/4
✓ Branch 2 → 3 taken 672 times.
✓ Branch 2 → 9 taken 672 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 9 taken 672 times.
1344 if (chroma && bits_per_pixel != 32) {
1266 if (hasAlpha) {
1267 *layer_fn = blendAlpha ? layer_planarrgb_add_c_4plane : layer_planarrgb_add_c_3plane;
1268 return;
1269 }
1270 // no alpha: standard weighted merge, to be added later.
1271 }
1272
1273 #define PLANARRGB_ADD_DISPATCH(chroma, has_alpha, blend_alpha) \
1274 { if (bits_per_pixel == 8) \
1275 *layer_fn = layer_planarrgb_add_c<uint8_t, chroma, has_alpha, blend_alpha>; \
1276 else if (bits_per_pixel <= 16) \
1277 *layer_fn = layer_planarrgb_add_c<uint16_t, chroma, has_alpha, blend_alpha>; \
1278 else /* float */ \
1279 *layer_f_fn = layer_planarrgb_add_f_c<chroma, has_alpha, blend_alpha>; \
1280 }
1281
1282
2/2
✓ Branch 9 → 10 taken 896 times.
✓ Branch 9 → 33 taken 448 times.
1344 if (hasAlpha) {
1283
2/2
✓ Branch 10 → 11 taken 448 times.
✓ Branch 10 → 22 taken 448 times.
896 if (chroma) {
1284
4/6
✓ Branch 11 → 12 taken 224 times.
✓ Branch 11 → 17 taken 224 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 224 times.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 224 times.
448 if (blendAlpha) { PLANARRGB_ADD_DISPATCH(true, true, true) }
1285
2/4
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 224 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 224 times.
224 else { PLANARRGB_ADD_DISPATCH(true, true, false) }
1286 }
1287 else {
1288
4/6
✓ Branch 22 → 23 taken 224 times.
✓ Branch 22 → 28 taken 224 times.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 224 times.
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 224 times.
448 if (blendAlpha) { PLANARRGB_ADD_DISPATCH(false, true, true) }
1289
2/4
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 224 times.
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 32 taken 224 times.
224 else { PLANARRGB_ADD_DISPATCH(false, true, false) }
1290 }
1291 }
1292 else {
1293
2/2
✓ Branch 33 → 34 taken 224 times.
✓ Branch 33 → 39 taken 224 times.
448 if (chroma) {
1294
2/4
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 36 taken 224 times.
✗ Branch 36 → 37 not taken.
✓ Branch 36 → 38 taken 224 times.
224 PLANARRGB_ADD_DISPATCH(true, false, false)
1295 }
1296 else {
1297
2/4
✗ Branch 39 → 40 not taken.
✓ Branch 39 → 41 taken 224 times.
✗ Branch 41 → 42 not taken.
✓ Branch 41 → 43 taken 224 times.
224 PLANARRGB_ADD_DISPATCH(false, false, false)
1298 }
1299 }
1300 #undef PLANARRGB_ADD_DISPATCH
1301 }
1302
1303 template<typename pixel_t, bool chroma, bool has_alpha, bool blend_alpha>
1304 7 static void layer_planarrgb_mul_c(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int opacity_i, int bits_per_pixel) {
1305 7 pixel_t* dstp_g = reinterpret_cast<pixel_t*>(dstp8[0]);
1306 7 pixel_t* dstp_b = reinterpret_cast<pixel_t*>(dstp8[1]);
1307 7 pixel_t* dstp_r = reinterpret_cast<pixel_t*>(dstp8[2]);
1308 // dstp8[3]: written only when blend_alpha=true (both clips have alpha).
1309 pixel_t* dstp_a;
1310 if constexpr (blend_alpha)
1311 3 dstp_a = reinterpret_cast<pixel_t*>(dstp8[3]);
1312 7 const pixel_t* ovrp_g = reinterpret_cast<const pixel_t*>(ovrp8[0]);
1313 7 const pixel_t* ovrp_b = reinterpret_cast<const pixel_t*>(ovrp8[1]);
1314 7 const pixel_t* ovrp_r = reinterpret_cast<const pixel_t*>(ovrp8[2]);
1315 // maskp: per-pixel blend weight — decoupled from ovrp8[3].
1316 7 const pixel_t* maskp = reinterpret_cast<const pixel_t*>(maskp8);
1317 // alpha_target: the value multiplied into dstp_a (only when blend_alpha=true).
1318 const pixel_t* alpha_target;
1319 if constexpr (blend_alpha)
1320 3 alpha_target = reinterpret_cast<const pixel_t*>(ovrp8[3]);
1321
1322 7 dst_pitch /= sizeof(pixel_t);
1323 7 overlay_pitch /= sizeof(pixel_t);
1324 7 mask_pitch /= sizeof(pixel_t);
1325
1326 if constexpr (sizeof(pixel_t) == 1)
1327 3 bits_per_pixel = 8; // make quasi constexpr
1328
1329 // use magic-div
1330 7 const MagicDiv magic = get_magic_div(bits_per_pixel);
1331 7 const int max_pixel_value = (1 << bits_per_pixel) - 1;
1332 7 const int half = max_pixel_value / 2;
1333
1334
12/24
void layer_planarrgb_mul_c<unsigned char, false, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 20 → 4 not taken.
✗ Branch 20 → 21 not taken.
void layer_planarrgb_mul_c<unsigned char, false, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 22 → 4 not taken.
✗ Branch 22 → 23 not taken.
void layer_planarrgb_mul_c<unsigned char, false, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 26 → 4 taken 5 times.
✓ Branch 26 → 27 taken 1 time.
void layer_planarrgb_mul_c<unsigned char, true, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 20 → 4 taken 5 times.
✓ Branch 20 → 21 taken 1 time.
void layer_planarrgb_mul_c<unsigned char, true, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 22 → 4 taken 5 times.
✓ Branch 22 → 23 taken 1 time.
void layer_planarrgb_mul_c<unsigned char, true, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 26 → 4 not taken.
✗ Branch 26 → 27 not taken.
void layer_planarrgb_mul_c<unsigned short, false, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 20 → 4 taken 3 times.
✓ Branch 20 → 21 taken 1 time.
void layer_planarrgb_mul_c<unsigned short, false, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 22 → 4 taken 3 times.
✓ Branch 22 → 23 taken 1 time.
void layer_planarrgb_mul_c<unsigned short, false, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 26 → 4 not taken.
✗ Branch 26 → 27 not taken.
void layer_planarrgb_mul_c<unsigned short, true, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 20 → 4 not taken.
✗ Branch 20 → 21 not taken.
void layer_planarrgb_mul_c<unsigned short, true, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 22 → 4 not taken.
✗ Branch 22 → 23 not taken.
void layer_planarrgb_mul_c<unsigned short, true, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 26 → 4 taken 5 times.
✓ Branch 26 → 27 taken 2 times.
33 for (int y = 0; y < height; ++y) {
1335
12/24
void layer_planarrgb_mul_c<unsigned char, false, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 18 → 5 not taken.
✗ Branch 18 → 19 not taken.
void layer_planarrgb_mul_c<unsigned char, false, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 20 → 5 not taken.
✗ Branch 20 → 21 not taken.
void layer_planarrgb_mul_c<unsigned char, false, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 24 → 5 taken 65 times.
✓ Branch 24 → 25 taken 5 times.
void layer_planarrgb_mul_c<unsigned char, true, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 18 → 5 taken 65 times.
✓ Branch 18 → 19 taken 5 times.
void layer_planarrgb_mul_c<unsigned char, true, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 20 → 5 taken 65 times.
✓ Branch 20 → 21 taken 5 times.
void layer_planarrgb_mul_c<unsigned char, true, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 24 → 5 not taken.
✗ Branch 24 → 25 not taken.
void layer_planarrgb_mul_c<unsigned short, false, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 18 → 5 taken 57 times.
✓ Branch 18 → 19 taken 3 times.
void layer_planarrgb_mul_c<unsigned short, false, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 20 → 5 taken 57 times.
✓ Branch 20 → 21 taken 3 times.
void layer_planarrgb_mul_c<unsigned short, false, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 24 → 5 not taken.
✗ Branch 24 → 25 not taken.
void layer_planarrgb_mul_c<unsigned short, true, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 18 → 5 not taken.
✗ Branch 18 → 19 not taken.
void layer_planarrgb_mul_c<unsigned short, true, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✗ Branch 20 → 5 not taken.
✗ Branch 20 → 21 not taken.
void layer_planarrgb_mul_c<unsigned short, true, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, int, int):
✓ Branch 24 → 5 taken 69 times.
✓ Branch 24 → 25 taken 5 times.
404 for (int x = 0; x < width; ++x) {
1336
1337 uint32_t alpha_eff;
1338 if constexpr (has_alpha) {
1339 256 const uint32_t alpha_src = (uint32_t)maskp[x];
1340 256 alpha_eff = (uint32_t)magic_div_rt<pixel_t>(alpha_src * (uint32_t)opacity_i + half, magic);
1341 }
1342 else {
1343 122 alpha_eff = opacity_i;
1344 }
1345 378 const uint32_t inv_alpha = max_pixel_value - alpha_eff;
1346
1347 if constexpr (chroma) {
1348 // Calculate the multiplied product (A*B)/max_pixel_value
1349 // Use the MagicDiv instead of bit-shift to keep max*max=max.
1350 199 const pixel_t prod_r = (pixel_t)magic_div_rt<pixel_t>((uint32_t)ovrp_r[x] * (uint32_t)dstp_r[x], magic);
1351 199 const pixel_t prod_g = (pixel_t)magic_div_rt<pixel_t>((uint32_t)ovrp_g[x] * (uint32_t)dstp_g[x], magic);
1352 199 const pixel_t prod_b = (pixel_t)magic_div_rt<pixel_t>((uint32_t)ovrp_b[x] * (uint32_t)dstp_b[x], magic);
1353
1354 199 dstp_r[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_r[x] * inv_alpha + (uint32_t)prod_r * alpha_eff + half, magic);
1355 199 dstp_g[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_g[x] * inv_alpha + (uint32_t)prod_g * alpha_eff + half, magic);
1356 329 dstp_b[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_b[x] * inv_alpha + (uint32_t)prod_b * alpha_eff + half, magic);
1357 }
1358 else {
1359 // use luma instead of overlay
1360 179 const int luma = (cyb * ovrp_b[x] + cyg * ovrp_g[x] + cyr * ovrp_r[x]) >> 15;
1361
1362 179 const pixel_t prod_r = (pixel_t)magic_div_rt<pixel_t>((uint32_t)luma * (uint32_t)dstp_r[x], magic);
1363 179 const pixel_t prod_g = (pixel_t)magic_div_rt<pixel_t>((uint32_t)luma * (uint32_t)dstp_g[x], magic);
1364 179 const pixel_t prod_b = (pixel_t)magic_div_rt<pixel_t>((uint32_t)luma * (uint32_t)dstp_b[x], magic);
1365
1366 179 dstp_r[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_r[x] * inv_alpha + (uint32_t)prod_r * alpha_eff + half, magic);
1367 179 dstp_g[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_g[x] * inv_alpha + (uint32_t)prod_g * alpha_eff + half, magic);
1368 293 dstp_b[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_b[x] * inv_alpha + (uint32_t)prod_b * alpha_eff + half, magic);
1369 }
1370
1371 if constexpr (blend_alpha) {
1372 134 const pixel_t prod_a = (pixel_t)magic_div_rt<pixel_t>((uint32_t)alpha_target[x] * (uint32_t)dstp_a[x], magic);
1373 268 dstp_a[x] = (pixel_t)magic_div_rt<pixel_t>((uint32_t)dstp_a[x] * inv_alpha + (uint32_t)prod_a * alpha_eff + half, magic);
1374 }
1375 }
1376 26 dstp_g += dst_pitch;
1377 26 dstp_b += dst_pitch;
1378 26 dstp_r += dst_pitch;
1379 if constexpr (blend_alpha)
1380 10 dstp_a += dst_pitch;
1381 26 ovrp_g += overlay_pitch;
1382 26 ovrp_b += overlay_pitch;
1383 26 ovrp_r += overlay_pitch;
1384 if constexpr (has_alpha)
1385 18 maskp += mask_pitch;
1386 if constexpr (blend_alpha)
1387 10 alpha_target += overlay_pitch;
1388 }
1389 7 }
1390
1391 template<bool chroma, bool has_alpha, bool blend_alpha>
1392 9 static void layer_planarrgb_mul_f_c(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity) {
1393 9 float* dstp_g = reinterpret_cast<float*>(dstp8[0]);
1394 9 float* dstp_b = reinterpret_cast<float*>(dstp8[1]);
1395 9 float* dstp_r = reinterpret_cast<float*>(dstp8[2]);
1396 // dstp8[3]: written only when blend_alpha=true (both clips have alpha).
1397 float* dstp_a;
1398 if constexpr (blend_alpha)
1399 3 dstp_a = reinterpret_cast<float*>(dstp8[3]);
1400 9 const float* ovrp_g = reinterpret_cast<const float*>(ovrp8[0]);
1401 9 const float* ovrp_b = reinterpret_cast<const float*>(ovrp8[1]);
1402 9 const float* ovrp_r = reinterpret_cast<const float*>(ovrp8[2]);
1403 // maskp: per-pixel blend weight — decoupled from ovrp8[3].
1404 9 const float* maskp = reinterpret_cast<const float*>(maskp8);
1405 const float* alpha_target;
1406 if constexpr (blend_alpha)
1407 3 alpha_target = reinterpret_cast<const float*>(ovrp8[3]);
1408
1409 9 dst_pitch /= sizeof(float);
1410 9 overlay_pitch /= sizeof(float);
1411 9 mask_pitch /= sizeof(float);
1412
1413
12/12
void layer_planarrgb_mul_f_c<false, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
void layer_planarrgb_mul_f_c<false, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
void layer_planarrgb_mul_f_c<false, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
void layer_planarrgb_mul_f_c<true, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 6 times.
✓ Branch 7 → 8 taken 2 times.
void layer_planarrgb_mul_f_c<true, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 6 times.
✓ Branch 7 → 8 taken 2 times.
void layer_planarrgb_mul_f_c<true, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 7 → 3 taken 6 times.
✓ Branch 7 → 8 taken 2 times.
36 for (int y = 0; y < height; ++y) {
1414
12/12
void layer_planarrgb_mul_f_c<false, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 21 times.
✓ Branch 5 → 6 taken 3 times.
void layer_planarrgb_mul_f_c<false, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 21 times.
✓ Branch 5 → 6 taken 3 times.
void layer_planarrgb_mul_f_c<false, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 21 times.
✓ Branch 5 → 6 taken 3 times.
void layer_planarrgb_mul_f_c<true, false, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 42 times.
✓ Branch 5 → 6 taken 6 times.
void layer_planarrgb_mul_f_c<true, true, false>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 42 times.
✓ Branch 5 → 6 taken 6 times.
void layer_planarrgb_mul_f_c<true, true, true>(unsigned char**, unsigned char const**, unsigned char const*, int, int, int, int, int, float):
✓ Branch 5 → 4 taken 42 times.
✓ Branch 5 → 6 taken 6 times.
216 for (int x = 0; x < width; ++x) {
1415 189 float alpha = has_alpha ? maskp[x] * opacity : opacity;
1416
1417 if constexpr (chroma) {
1418 126 dstp_r[x] = dstp_r[x] + (ovrp_r[x] * dstp_r[x] - dstp_r[x]) * alpha;
1419 126 dstp_g[x] = dstp_g[x] + (ovrp_g[x] * dstp_g[x] - dstp_g[x]) * alpha;
1420 126 dstp_b[x] = dstp_b[x] + (ovrp_b[x] * dstp_b[x] - dstp_b[x]) * alpha;
1421 }
1422 else { // use luma instead of overlay
1423 63 float luma = cyb_f * ovrp_b[x] + cyg_f * ovrp_g[x] + cyr_f * ovrp_r[x];
1424 63 dstp_r[x] = dstp_r[x] + (luma * dstp_r[x] - dstp_r[x]) * alpha;
1425 63 dstp_g[x] = dstp_g[x] + (luma * dstp_g[x] - dstp_g[x]) * alpha;
1426 63 dstp_b[x] = dstp_b[x] + (luma * dstp_b[x] - dstp_b[x]) * alpha;
1427 }
1428 if constexpr (blend_alpha)
1429 63 dstp_a[x] = dstp_a[x] + (alpha_target[x] * dstp_a[x] - dstp_a[x]) * alpha;
1430 }
1431 27 dstp_g += dst_pitch;
1432 27 dstp_b += dst_pitch;
1433 27 dstp_r += dst_pitch;
1434 if constexpr (blend_alpha)
1435 9 dstp_a += dst_pitch;
1436 27 ovrp_g += overlay_pitch;
1437 27 ovrp_b += overlay_pitch;
1438 27 ovrp_r += overlay_pitch;
1439 if constexpr (has_alpha)
1440 18 maskp += mask_pitch;
1441 if constexpr (blend_alpha)
1442 9 alpha_target += overlay_pitch;
1443 }
1444 9 }
1445
1446 2692 static void get_layer_planarrgb_mul_functions(
1447 bool chroma, bool hasAlpha, bool blendAlpha, int bits_per_pixel,
1448 /*out*/layer_planarrgb_mul_c_t** layer_fn,
1449 /*out*/layer_planarrgb_mul_f_c_t** layer_f_fn)
1450 {
1451 #define PLANARRGB_MUL_DISPATCH(chroma, has_alpha, blend_alpha) \
1452 { if (bits_per_pixel == 8) \
1453 *layer_fn = layer_planarrgb_mul_c<uint8_t, chroma, has_alpha, blend_alpha>; \
1454 else if (bits_per_pixel <= 16) \
1455 *layer_fn = layer_planarrgb_mul_c<uint16_t, chroma, has_alpha, blend_alpha>; \
1456 else /* float */ \
1457 *layer_f_fn = layer_planarrgb_mul_f_c<chroma, has_alpha, blend_alpha>; \
1458 }
1459
1460
2/2
✓ Branch 2 → 3 taken 1795 times.
✓ Branch 2 → 26 taken 897 times.
2692 if (hasAlpha) {
1461
2/2
✓ Branch 3 → 4 taken 899 times.
✓ Branch 3 → 15 taken 896 times.
1795 if (chroma) {
1462
5/6
✓ Branch 4 → 5 taken 450 times.
✓ Branch 4 → 10 taken 449 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 450 times.
✓ Branch 7 → 8 taken 225 times.
✓ Branch 7 → 9 taken 225 times.
899 if (blendAlpha) { PLANARRGB_MUL_DISPATCH(true, true, true) }
1463
3/4
✓ Branch 10 → 11 taken 224 times.
✓ Branch 10 → 12 taken 225 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 225 times.
449 else { PLANARRGB_MUL_DISPATCH(true, true, false) }
1464 }
1465 else {
1466
5/6
✓ Branch 15 → 16 taken 448 times.
✓ Branch 15 → 21 taken 448 times.
✓ Branch 16 → 17 taken 224 times.
✓ Branch 16 → 18 taken 224 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 224 times.
896 if (blendAlpha) { PLANARRGB_MUL_DISPATCH(false, true, true) }
1467
3/4
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 448 times.
✓ Branch 23 → 24 taken 224 times.
✓ Branch 23 → 25 taken 224 times.
448 else { PLANARRGB_MUL_DISPATCH(false, true, false) }
1468 }
1469 }
1470 else {
1471
2/2
✓ Branch 26 → 27 taken 449 times.
✓ Branch 26 → 32 taken 448 times.
897 if (chroma) {
1472
3/4
✓ Branch 27 → 28 taken 224 times.
✓ Branch 27 → 29 taken 225 times.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 225 times.
449 PLANARRGB_MUL_DISPATCH(true, false, false)
1473 }
1474 else {
1475
3/4
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 34 taken 448 times.
✓ Branch 34 → 35 taken 224 times.
✓ Branch 34 → 36 taken 224 times.
448 PLANARRGB_MUL_DISPATCH(false, false, false)
1476 }
1477 }
1478 #undef PLANARRGB_MUL_DISPATCH
1479 2692 }
1480
1481 // ---------------------------------------------------------------------------
1482 // Packed RGBA (RGB32 / RGB64) blend dispatcher — C reference.
1483 // Returns the appropriate masked_blend_packedrgba_c instantiation for the
1484 // given bit depth. Subtract is handled by pre-inverting the overlay and
1485 // passing a separate maskp8 pointer in the caller (Layer::Create/GetFrame).
1486 // The C reference function selects the alpha source at runtime via the
1487 // maskp8 null-check, so a single function covers both Add and Subtract.
1488 // ---------------------------------------------------------------------------
1489 1 static void get_layer_packedrgb_blend_functions(
1490 bool has_separate_mask,
1491 int bits_per_pixel,
1492 layer_packedrgb_blend_c_t** fn)
1493 {
1494
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 7 taken 1 time.
1 if (bits_per_pixel == 8)
1495 *fn = has_separate_mask ? masked_blend_packedrgba_c<uint8_t, true> : masked_blend_packedrgba_c<uint8_t, false>;
1496 else // 16-bit (RGB64)
1497
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
1 *fn = has_separate_mask ? masked_blend_packedrgba_c<uint16_t, true> : masked_blend_packedrgba_c<uint16_t, false>;
1498 1 }
1499
1500 // Clean up rowprep macros (defined near top of this file or by including TU).
1501 #undef LAYER_ROWPREP_FN
1502
1503