GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 35.3% 540 / 0 / 1530
Functions: 39.5% 15 / 0 / 38
Branches: 32.4% 149 / 0 / 460

filters/overlay/OF_add.cpp
Line Branch Exec Source
1 // Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al.
2 // http://avisynth.nl
3
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
17 // http://www.gnu.org/copyleft/gpl.html .
18 //
19 // Linking Avisynth statically or dynamically with other modules is making a
20 // combined work based on Avisynth. Thus, the terms and conditions of the GNU
21 // General Public License cover the whole combination.
22 //
23 // As a special exception, the copyright holders of Avisynth give you
24 // permission to link Avisynth with independent modules that communicate with
25 // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
26 // terms of these independent modules, and to copy and distribute the
27 // resulting combined work under terms of your choice, provided that
28 // every copy of the combined work is accompanied by a complete copy of
29 // the source code of Avisynth (the version of Avisynth used to produce the
30 // combined work), being distributed under the terms of the GNU General
31 // Public License plus this exception. An independent module is a module
32 // which is not derived from or based on Avisynth, such as 3rd-party filters,
33 // import and export plugins, or graphical user interfaces.
34
35 // Overlay (c) 2003, 2004 by Klaus Post
36
37 #include "overlayfunctions.h"
38 #include "blend_common.h"
39
40 #include <stdint.h>
41 #include <type_traits>
42
43 1 void OL_AddImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {
44
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 17 taken 1 time.
1 if (rgb) {
45 if (of_mode == OF_Add) {
46 if (bits_per_pixel == 8)
47 BlendImageMask_RGB<uint8_t, true, true>(base, overlay, mask);
48 else if (bits_per_pixel <= 16)
49 BlendImageMask_RGB<uint16_t, true, true>(base, overlay, mask);
50 else if (bits_per_pixel == 32)
51 BlendImageMask_RGB_float<true, true>(base, overlay, mask);
52 } else {
53 // OF_Subtract
54 if (bits_per_pixel == 8)
55 BlendImageMask_RGB<uint8_t, true, false>(base, overlay, mask);
56 else if (bits_per_pixel <= 16)
57 BlendImageMask_RGB<uint16_t, true, false>(base, overlay, mask);
58 else if (bits_per_pixel == 32)
59 BlendImageMask_RGB_float<true, false>(base, overlay, mask);
60 }
61 return;
62 }
63 // existing YUV logic
64 1 const bool fullOpacity = (opacity_f == 1.0f); // becomes a template switch
65
1/2
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 30 not taken.
1 if(of_mode == OF_Add) {
66
1/2
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 22 not taken.
1 if (bits_per_pixel == 8) {
67
1/2
✓ Branch 19 → 20 taken 1 time.
✗ Branch 19 → 21 not taken.
1 if (fullOpacity) BlendImageMask<uint8_t, true, true, true>(base, overlay, mask);
68 else BlendImageMask<uint8_t, true, true, false>(base, overlay, mask);
69 } else if(bits_per_pixel <= 16) {
70 if (fullOpacity) BlendImageMask<uint16_t, true, true, true>(base, overlay, mask);
71 else BlendImageMask<uint16_t, true, true, false>(base, overlay, mask);
72 } else if(bits_per_pixel == 32) {
73 if (fullOpacity) BlendImageMask_float<true, true, true>(base, overlay, mask);
74 else BlendImageMask_float<true, true, false>(base, overlay, mask);
75 }
76 }
77 else {
78 // OF_Subtract
79 if (bits_per_pixel == 8) {
80 if (fullOpacity) BlendImageMask<uint8_t, true, false, true>(base, overlay, mask);
81 else BlendImageMask<uint8_t, true, false, false>(base, overlay, mask);
82 } else if(bits_per_pixel <= 16) {
83 if (fullOpacity) BlendImageMask<uint16_t, true, false, true>(base, overlay, mask);
84 else BlendImageMask<uint16_t, true, false, false>(base, overlay, mask);
85 } else if(bits_per_pixel == 32) {
86 if (fullOpacity) BlendImageMask_float<true, false, true>(base, overlay, mask);
87 else BlendImageMask_float<true, false, false>(base, overlay, mask);
88 }
89 }
90 }
91
92 17 void OL_AddImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {
93
2/2
✓ Branch 2 → 3 taken 8 times.
✓ Branch 2 → 17 taken 9 times.
17 if (rgb) {
94
2/2
✓ Branch 3 → 4 taken 4 times.
✓ Branch 3 → 10 taken 4 times.
8 if (of_mode == OF_Add) {
95
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 4 times.
4 if (bits_per_pixel == 8)
96 BlendImageMask_RGB<uint8_t, false, true>(base, overlay, nullptr);
97
2/2
✓ Branch 6 → 7 taken 2 times.
✓ Branch 6 → 8 taken 2 times.
4 else if (bits_per_pixel <= 16)
98 2 BlendImageMask_RGB<uint16_t, false, true>(base, overlay, nullptr);
99
1/2
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 16 not taken.
2 else if (bits_per_pixel == 32)
100 2 BlendImageMask_RGB_float<false, true>(base, overlay, nullptr);
101 }
102 else {
103 // OF_Subtract
104
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 4 times.
4 if (bits_per_pixel == 8)
105 BlendImageMask_RGB<uint8_t, false, false>(base, overlay, nullptr);
106
2/2
✓ Branch 12 → 13 taken 2 times.
✓ Branch 12 → 14 taken 2 times.
4 else if (bits_per_pixel <= 16)
107 2 BlendImageMask_RGB<uint16_t, false, false>(base, overlay, nullptr);
108
1/2
✓ Branch 14 → 15 taken 2 times.
✗ Branch 14 → 16 not taken.
2 else if (bits_per_pixel == 32)
109 2 BlendImageMask_RGB_float<false, false>(base, overlay, nullptr);
110 }
111 8 return;
112 }
113 // existing YUV logic
114 9 const bool fullOpacity = (opacity_f == 1.0f); // becomes a template switch
115
2/2
✓ Branch 17 → 18 taken 5 times.
✓ Branch 17 → 30 taken 4 times.
9 if(of_mode == OF_Add) {
116
2/2
✓ Branch 18 → 19 taken 3 times.
✓ Branch 18 → 22 taken 2 times.
5 if (bits_per_pixel == 8) {
117
2/2
✓ Branch 19 → 20 taken 2 times.
✓ Branch 19 → 21 taken 1 time.
3 if (fullOpacity) BlendImageMask<uint8_t, false, true, true>(base, overlay, nullptr);
118 1 else BlendImageMask<uint8_t, false, true, false>(base, overlay, nullptr);
119
1/2
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 26 taken 2 times.
2 } else if(bits_per_pixel <= 16) {
120 if (fullOpacity) BlendImageMask<uint16_t, false, true, true>(base, overlay, nullptr);
121 else BlendImageMask<uint16_t, false, true, false>(base, overlay, nullptr);
122
1/2
✓ Branch 26 → 27 taken 2 times.
✗ Branch 26 → 42 not taken.
2 } else if(bits_per_pixel == 32) {
123
2/2
✓ Branch 27 → 28 taken 1 time.
✓ Branch 27 → 29 taken 1 time.
2 if (fullOpacity) BlendImageMask_float<false, true, true>(base, overlay, nullptr);
124 1 else BlendImageMask_float<false, true, false>(base, overlay, nullptr);
125 }
126 }
127 else {
128 // OF_Subtract
129
2/2
✓ Branch 30 → 31 taken 2 times.
✓ Branch 30 → 34 taken 2 times.
4 if (bits_per_pixel == 8) {
130
2/2
✓ Branch 31 → 32 taken 1 time.
✓ Branch 31 → 33 taken 1 time.
2 if (fullOpacity) BlendImageMask<uint8_t, false, false, true>(base, overlay, nullptr);
131 1 else BlendImageMask<uint8_t, false, false, false>(base, overlay, nullptr);
132
1/2
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 38 taken 2 times.
2 } else if(bits_per_pixel <= 16) {
133 if (fullOpacity) BlendImageMask<uint16_t, false, false, true>(base, overlay, nullptr);
134 else BlendImageMask<uint16_t, false, false, false>(base, overlay, nullptr);
135
1/2
✓ Branch 38 → 39 taken 2 times.
✗ Branch 38 → 42 not taken.
2 } else if(bits_per_pixel == 32) {
136
2/2
✓ Branch 39 → 40 taken 1 time.
✓ Branch 39 → 41 taken 1 time.
2 if (fullOpacity) BlendImageMask_float<false, false, true>(base, overlay, nullptr);
137 1 else BlendImageMask_float<false, false, false>(base, overlay, nullptr);
138 }
139 }
140 }
141
142 // integer 8-16 bit add/subtract with YUV overshoot handling
143 template<typename pixel_t, bool maskMode, bool of_add, bool fullOpacity>
144 6 void OL_AddImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {
145
146 6 pixel_t* baseY = reinterpret_cast<pixel_t*>(base->GetPtr(PLANAR_Y));
147 6 pixel_t* baseU = reinterpret_cast<pixel_t*>(base->GetPtr(PLANAR_U));
148 6 pixel_t* baseV = reinterpret_cast<pixel_t*>(base->GetPtr(PLANAR_V));
149
150 6 pixel_t* ovY = reinterpret_cast<pixel_t*>(overlay->GetPtr(PLANAR_Y));
151 6 pixel_t* ovU = reinterpret_cast<pixel_t*>(overlay->GetPtr(PLANAR_U));
152 6 pixel_t* ovV = reinterpret_cast<pixel_t*>(overlay->GetPtr(PLANAR_V));
153
154 pixel_t* maskY;
155 pixel_t* maskU;
156 pixel_t* maskV;
157 if constexpr (maskMode) {
158 1 maskY = reinterpret_cast<pixel_t*>(mask->GetPtr(PLANAR_Y));
159 1 maskU = reinterpret_cast<pixel_t*>(mask->GetPtr(PLANAR_U));
160 1 maskV = reinterpret_cast<pixel_t*>(mask->GetPtr(PLANAR_V));
161 }
162 else {
163 5 maskY = nullptr;
164 5 maskU = nullptr;
165 5 maskV = nullptr;
166 }
167
168 6 const int half_pixel_value = (sizeof(pixel_t) == 1) ? 128 : (1 << (bits_per_pixel - 1));
169 6 const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;
170 6 const int pixel_range = max_pixel_value + 1;
171 6 const int SHIFT = (sizeof(pixel_t) == 1) ? 5 : 5 + (bits_per_pixel - 8);
172 6 const int over32 = (1 << SHIFT); // 32
173 6 const int basepitch = (base->pitch) / sizeof(pixel_t);
174 6 const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);
175 int maskpitch;
176 if constexpr (maskMode) {
177 1 maskpitch = (mask->pitch) / sizeof(pixel_t);
178 }
179 else {
180 5 maskpitch = 0;
181 }
182
183 6 const MagicDiv magic = get_magic_div(bits_per_pixel);
184
185 // fullOpacity is a template parameter (based on opacity_f==1.0f check).
186 // eff on the max_pixel_value scale, finer opacity granularity at >8-bit than the old
187 // fixed 0..256 scale. Unused when fullOpacity+!maskMode.
188 6 const int opacity_i = fullOpacity ? max_pixel_value : (int)(opacity_f * max_pixel_value + 0.5f);
189 6 const int rounder = max_pixel_value / 2;
190
191 /*
192 In YUV, "add" and "subtract" are not just per-channel math. The luma (Y) is added/subtracted, but if the result
193 overflows (Y > max) or underflows (Y < 0), the chroma (U/V) is "pulled" toward neutral (gray/white) to mimic
194 how RGB overbright/underbright behaves visually.
195
196 In RGB, adding two bright colors can result in "white" (all channels maxed). In YUV, if you just add Y, U, and V,
197 we can get weird color shifts. The code compensates by blending U/V toward neutral when Y is out of range,
198 making the result look more like RGB addition.
199
200 For RGB, a simple per-channel add/subtract (with clamping for 8/16-bit, or no clamping for float) is done.
201 The "magic" is only needed for YUV to avoid odd color artifacts. In RGB, overbright naturally becomes white,
202 so no special handling is needed.
203 */
204
205 6 int w = base->w();
206 6 int h = base->h();
207
10/32
void OL_AddImage::BlendImageMask<unsigned char, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 55 → 12 taken 3 times.
✓ Branch 55 → 56 taken 1 time.
void OL_AddImage::BlendImageMask<unsigned char, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 39 → 12 taken 3 times.
✓ Branch 39 → 40 taken 1 time.
void OL_AddImage::BlendImageMask<unsigned char, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 55 → 12 taken 3 times.
✓ Branch 55 → 56 taken 1 time.
void OL_AddImage::BlendImageMask<unsigned char, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 39 → 12 taken 5 times.
✓ Branch 39 → 40 taken 2 times.
void OL_AddImage::BlendImageMask<unsigned char, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 64 → 15 not taken.
✗ Branch 64 → 65 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 58 → 15 not taken.
✗ Branch 58 → 59 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 64 → 15 not taken.
✗ Branch 64 → 65 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 58 → 15 taken 2 times.
✓ Branch 58 → 59 taken 1 time.
void OL_AddImage::BlendImageMask<unsigned short, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 55 → 12 not taken.
✗ Branch 55 → 56 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 39 → 12 not taken.
✗ Branch 39 → 40 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 55 → 12 not taken.
✗ Branch 55 → 56 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 39 → 12 not taken.
✗ Branch 39 → 40 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 64 → 15 not taken.
✗ Branch 64 → 65 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 58 → 15 not taken.
✗ Branch 58 → 59 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 64 → 15 not taken.
✗ Branch 64 → 65 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 58 → 15 not taken.
✗ Branch 58 → 59 not taken.
22 for (int y = 0; y < h; y++) {
208
10/32
void OL_AddImage::BlendImageMask<unsigned char, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 53 → 13 taken 21 times.
✓ Branch 53 → 54 taken 3 times.
void OL_AddImage::BlendImageMask<unsigned char, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 37 → 13 taken 21 times.
✓ Branch 37 → 38 taken 3 times.
void OL_AddImage::BlendImageMask<unsigned char, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 53 → 13 taken 21 times.
✓ Branch 53 → 54 taken 3 times.
void OL_AddImage::BlendImageMask<unsigned char, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 37 → 13 taken 29 times.
✓ Branch 37 → 38 taken 5 times.
void OL_AddImage::BlendImageMask<unsigned char, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 62 → 16 not taken.
✗ Branch 62 → 63 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 56 → 16 not taken.
✗ Branch 56 → 57 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 62 → 16 not taken.
✗ Branch 62 → 63 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 56 → 16 taken 8 times.
✓ Branch 56 → 57 taken 2 times.
void OL_AddImage::BlendImageMask<unsigned short, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 53 → 13 not taken.
✗ Branch 53 → 54 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 37 → 13 not taken.
✗ Branch 37 → 38 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 53 → 13 not taken.
✗ Branch 53 → 54 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 37 → 13 not taken.
✗ Branch 37 → 38 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 62 → 16 not taken.
✗ Branch 62 → 63 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 56 → 16 not taken.
✗ Branch 56 → 57 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 62 → 16 not taken.
✗ Branch 62 → 63 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 56 → 16 not taken.
✗ Branch 56 → 57 not taken.
116 for (int x = 0; x < w; x++) {
209 int Y, U, V;
210 // U/V "blend toward neutral" chroma trick.
211 // Original: base + (half*(max-eff)+eff*ov)/max - half
212 // New: base+eff*(ov-half)/max
213 // (ov-half) is signed, but magic_div_rt is uint32_t only, so we split by sign.
214 // The split is bit-identical to the unsigned formula's rounding since max_pixel_value is
215 // always odd, so rounder (max_pixel_value/2, integer division) is never an exact
216 // 0.5-like value on the integer scale, so mask*abs(dU)/max_pixel_value can never be
217 // exactly at a tie, where the rounding half addition would to break the equivalence.
218 // (Nevertheless, this is an artistic effect, so we would even accept that the
219 // original formula differently rounded and yielded an LSB difference, but it's
220 // not even the case here).
221 100 int dU = (int)ovU[x] - half_pixel_value;
222 100 int dV = (int)ovV[x] - half_pixel_value;
223 int TU, TV;
224 if constexpr (fullOpacity && !maskMode) {
225 // eff == max_pixel_value
226 50 TU = dU;
227 50 TV = dV;
228 29 if constexpr (of_add) Y = baseY[x] + ovY[x];
229 21 else Y = baseY[x] - ovY[x];
230 }
231 else {
232 int effY, effU, effV; // effective masks/opacity/their combinations
233 if constexpr (maskMode) {
234 if constexpr (fullOpacity) {
235 8 effY = maskY[x];
236 8 effU = maskU[x];
237 8 effV = maskV[x];
238 }
239 else {
240 effY = magic_div_rt<pixel_t>((uint32_t)maskY[x] * (uint32_t)opacity_i + rounder, magic);
241 effU = magic_div_rt<pixel_t>((uint32_t)maskU[x] * (uint32_t)opacity_i + rounder, magic);
242 effV = magic_div_rt<pixel_t>((uint32_t)maskV[x] * (uint32_t)opacity_i + rounder, magic);
243 }
244 }
245 else {
246 42 effY = opacity_i;
247 42 effU = opacity_i;
248 42 effV = opacity_i;
249 }
250
5/24
void OL_AddImage::BlendImageMask<unsigned char, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 12 times.
✓ Branch 13 → 17 taken 9 times.
void OL_AddImage::BlendImageMask<unsigned char, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 12 times.
✓ Branch 13 → 17 taken 9 times.
void OL_AddImage::BlendImageMask<unsigned char, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 26 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 26 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 16 → 17 taken 8 times.
✗ Branch 16 → 20 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 17 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 17 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 26 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 26 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
82 TU = (dU >= 0) ? (int)magic_div_rt<pixel_t>((uint32_t)effU * (uint32_t)dU + rounder, magic)
251 36 : -(int)magic_div_rt<pixel_t>((uint32_t)effU * (uint32_t)(-dU) + rounder, magic);
252
5/24
void OL_AddImage::BlendImageMask<unsigned char, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 20 → 21 taken 12 times.
✓ Branch 20 → 24 taken 9 times.
void OL_AddImage::BlendImageMask<unsigned char, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 20 → 21 taken 12 times.
✓ Branch 20 → 24 taken 9 times.
void OL_AddImage::BlendImageMask<unsigned char, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 33 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 27 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 33 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 27 taken 8 times.
void OL_AddImage::BlendImageMask<unsigned short, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 33 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 27 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 33 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 27 not taken.
74 TV = (dV >= 0) ? (int)magic_div_rt<pixel_t>((uint32_t)effV * (uint32_t)dV + rounder, magic)
253 52 : -(int)magic_div_rt<pixel_t>((uint32_t)effV * (uint32_t)(-dV) + rounder, magic);
254 if constexpr (of_add)
255 29 Y = baseY[x] + magic_div_rt<pixel_t>((uint32_t)ovY[x] * (uint32_t)effY + rounder, magic);
256 else
257 21 Y = baseY[x] - magic_div_rt<pixel_t>((uint32_t)ovY[x] * (uint32_t)effY + rounder, magic);
258 }
259 if constexpr (of_add) {
260 58 U = baseU[x] + TU;
261 58 V = baseV[x] + TV;
262 // When Y is too high, U and V are blended toward half_pixel_value (neutral chroma),
263 // making the color "whiter".
264
5/16
void OL_AddImage::BlendImageMask<unsigned char, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 29 → 30 taken 9 times.
✓ Branch 29 → 36 taken 12 times.
void OL_AddImage::BlendImageMask<unsigned char, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 12 times.
✓ Branch 13 → 20 taken 17 times.
void OL_AddImage::BlendImageMask<unsigned char, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 45 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 39 taken 8 times.
void OL_AddImage::BlendImageMask<unsigned short, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 36 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 20 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 45 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 39 not taken.
58 if (Y > max_pixel_value) { // Apply overbrightness to UV
265
3/16
void OL_AddImage::BlendImageMask<unsigned char, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 32 taken 9 times.
void OL_AddImage::BlendImageMask<unsigned char, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 14 → 15 taken 2 times.
✓ Branch 14 → 16 taken 10 times.
void OL_AddImage::BlendImageMask<unsigned char, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 41 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 32 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 16 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 41 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
21 int multiplier = max(0, pixel_range + over32 - Y); // 0 to 32
266 21 U = ((U * (multiplier)) + (half_pixel_value * (over32 - multiplier))) >> SHIFT;
267 21 V = ((V * (multiplier)) + (half_pixel_value * (over32 - multiplier))) >> SHIFT;
268 21 Y = max_pixel_value;
269 }
270 }
271 else {
272 // of_subtract
273 42 U = baseU[x] - TU;
274 42 V = baseV[x] - TV;
275
4/16
void OL_AddImage::BlendImageMask<unsigned char, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 29 → 30 taken 6 times.
✓ Branch 29 → 36 taken 15 times.
void OL_AddImage::BlendImageMask<unsigned char, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 9 times.
✓ Branch 13 → 20 taken 12 times.
void OL_AddImage::BlendImageMask<unsigned char, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 45 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 39 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 36 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 20 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 45 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 39 not taken.
42 if (Y < 0) { // Apply superdark to UV
276
4/16
void OL_AddImage::BlendImageMask<unsigned char, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 30 → 31 taken 3 times.
✓ Branch 30 → 32 taken 3 times.
void OL_AddImage::BlendImageMask<unsigned char, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 14 → 15 taken 6 times.
✓ Branch 14 → 16 taken 3 times.
void OL_AddImage::BlendImageMask<unsigned char, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 41 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 32 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 16 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 41 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
15 int multiplier = min(-Y, over32); // 0 to 32
277 15 U = ((U * (over32 - multiplier)) + (half_pixel_value * (multiplier))) >> SHIFT;
278 15 V = ((V * (over32 - multiplier)) + (half_pixel_value * (multiplier))) >> SHIFT;
279 15 Y = 0;
280 }
281 }
282
7/32
void OL_AddImage::BlendImageMask<unsigned char, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 44 → 45 taken 6 times.
✓ Branch 44 → 46 taken 15 times.
void OL_AddImage::BlendImageMask<unsigned char, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 28 → 29 taken 6 times.
✓ Branch 28 → 30 taken 15 times.
void OL_AddImage::BlendImageMask<unsigned char, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 44 → 45 not taken.
✓ Branch 44 → 46 taken 21 times.
void OL_AddImage::BlendImageMask<unsigned char, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 29 times.
void OL_AddImage::BlendImageMask<unsigned char, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 49 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
void OL_AddImage::BlendImageMask<unsigned char, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 47 → 48 not taken.
✓ Branch 47 → 49 taken 8 times.
void OL_AddImage::BlendImageMask<unsigned short, false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 46 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 30 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 46 not taken.
void OL_AddImage::BlendImageMask<unsigned short, false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 30 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 49 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
void OL_AddImage::BlendImageMask<unsigned short, true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 49 not taken.
100 baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);
283 100 baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);
284 100 baseY[x] = (pixel_t)Y;
285 }
286 16 baseY += basepitch;
287 16 baseU += basepitch;
288 16 baseV += basepitch;
289
290 16 ovY += overlaypitch;
291 16 ovU += overlaypitch;
292 16 ovV += overlaypitch;
293
294 if constexpr (maskMode) {
295 2 maskY += maskpitch;
296 2 maskU += maskpitch;
297 2 maskV += maskpitch;
298 }
299 }
300 6 }
301
302 // A float-inside variant of BlendImageMask was benchmarked here.
303 // Verdict: not adopted. 20-50% slower, only special most complex case
304 // was quicker by 10%, not worth the code complexity.
305
306 // float add/subtract with YUV overshoot handling
307 template<bool maskMode, bool of_add, bool fullOpacity>
308 4 void OL_AddImage::BlendImageMask_float(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {
309 // specialized pixel_t float images
310 // No clamping needed.
311 // float range here is supposed to be [0.0f .. 1.0f] for Y, [-0.5f .. 0.5f] for U/V
312 // mask is [0.0f .. 1.0f]
313 4 float* baseY = reinterpret_cast<float*>(base->GetPtr(PLANAR_Y));
314 4 float* baseU = reinterpret_cast<float*>(base->GetPtr(PLANAR_U));
315 4 float* baseV = reinterpret_cast<float*>(base->GetPtr(PLANAR_V));
316
317 4 float* ovY = reinterpret_cast<float*>(overlay->GetPtr(PLANAR_Y));
318 4 float* ovU = reinterpret_cast<float*>(overlay->GetPtr(PLANAR_U));
319 4 float* ovV = reinterpret_cast<float*>(overlay->GetPtr(PLANAR_V));
320
321 4 float* maskY = maskMode ? reinterpret_cast<float*>(mask->GetPtr(PLANAR_Y)) : nullptr;
322 4 float* maskU = maskMode ? reinterpret_cast<float*>(mask->GetPtr(PLANAR_U)) : nullptr;
323 4 float* maskV = maskMode ? reinterpret_cast<float*>(mask->GetPtr(PLANAR_V)) : nullptr;
324
325 // For float, half_pixel_value is 0.0f, max_pixel_value is 1.0f for Y
326 4 constexpr float half_pixel_value = 0.0f; // intentionally keep it 0.0f for U/V calculation, compiler will optimize away
327 4 constexpr float max_pixel_value = 1.0f; // for Y overshoot check
328 4 constexpr float pixel_range = 1.0f; // mask must be in [0.0f, 1.0f]
329
330 4 const int basepitch = (base->pitch) / sizeof(float);
331 4 const int overlaypitch = (overlay->pitch) / sizeof(float);
332 4 const int maskpitch = maskMode ? (mask->pitch) / sizeof(float) : 0;
333
334 4 int w = base->w();
335 4 int h = base->h();
336
337
8/16
void OL_AddImage::BlendImageMask_float<false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 22 → 11 taken 3 times.
✓ Branch 22 → 23 taken 1 time.
void OL_AddImage::BlendImageMask_float<false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 22 → 11 taken 3 times.
✓ Branch 22 → 23 taken 1 time.
void OL_AddImage::BlendImageMask_float<false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 22 → 11 taken 3 times.
✓ Branch 22 → 23 taken 1 time.
void OL_AddImage::BlendImageMask_float<false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 22 → 11 taken 3 times.
✓ Branch 22 → 23 taken 1 time.
void OL_AddImage::BlendImageMask_float<true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 25 → 14 not taken.
✗ Branch 25 → 26 not taken.
void OL_AddImage::BlendImageMask_float<true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 25 → 14 not taken.
✗ Branch 25 → 26 not taken.
void OL_AddImage::BlendImageMask_float<true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 25 → 14 not taken.
✗ Branch 25 → 26 not taken.
void OL_AddImage::BlendImageMask_float<true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 25 → 14 not taken.
✗ Branch 25 → 26 not taken.
16 for (int y = 0; y < h; y++) {
338
8/16
void OL_AddImage::BlendImageMask_float<false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 20 → 12 taken 21 times.
✓ Branch 20 → 21 taken 3 times.
void OL_AddImage::BlendImageMask_float<false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 20 → 12 taken 21 times.
✓ Branch 20 → 21 taken 3 times.
void OL_AddImage::BlendImageMask_float<false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 20 → 12 taken 21 times.
✓ Branch 20 → 21 taken 3 times.
void OL_AddImage::BlendImageMask_float<false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 20 → 12 taken 21 times.
✓ Branch 20 → 21 taken 3 times.
void OL_AddImage::BlendImageMask_float<true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 23 → 15 not taken.
✗ Branch 23 → 24 not taken.
void OL_AddImage::BlendImageMask_float<true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 23 → 15 not taken.
✗ Branch 23 → 24 not taken.
void OL_AddImage::BlendImageMask_float<true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 23 → 15 not taken.
✗ Branch 23 → 24 not taken.
void OL_AddImage::BlendImageMask_float<true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 23 → 15 not taken.
✗ Branch 23 → 24 not taken.
96 for (int x = 0; x < w; ++x) {
339 float Y, U, V;
340 // eff on the 0.0f..1.0f opacity scale (mask == 1.0f when absent)
341 float effY, effU, effV;
342 if constexpr (maskMode) {
343 if constexpr (fullOpacity) {
344 effY = maskY[x]; // *1.0f
345 effU = maskU[x];
346 effV = maskV[x];
347 }
348 else {
349 effY = maskY[x] * opacity_f;
350 effU = maskU[x] * opacity_f;
351 effV = maskV[x] * opacity_f;
352 }
353 }
354 else {
355 84 effY = fullOpacity ? 1.0f : opacity_f;
356 84 effU = effY;
357 84 effV = effY;
358 }
359
360 if constexpr (of_add) {
361 42 Y = baseY[x] + ovY[x] * effY;
362 42 U = baseU[x] + (half_pixel_value * (pixel_range - effU) + effU * ovU[x]) - half_pixel_value;
363 42 V = baseV[x] + (half_pixel_value * (pixel_range - effV) + effV * ovV[x]) - half_pixel_value;
364 }
365 else {
366 42 Y = baseY[x] - ovY[x] * effY;
367 42 U = baseU[x] - (half_pixel_value * (pixel_range - effU) + effU * ovU[x]) + half_pixel_value;
368 42 V = baseV[x] - (half_pixel_value * (pixel_range - effV) + effV * ovV[x]) + half_pixel_value;
369 }
370
371 84 constexpr float over32 = 32.0f / 255.0f; // ~0.12549f
372
373 if constexpr (of_add) {
374
4/8
void OL_AddImage::BlendImageMask_float<false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 12 → 13 taken 6 times.
✓ Branch 12 → 19 taken 15 times.
void OL_AddImage::BlendImageMask_float<false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 12 → 13 taken 15 times.
✓ Branch 12 → 19 taken 6 times.
void OL_AddImage::BlendImageMask_float<true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
void OL_AddImage::BlendImageMask_float<true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
42 if (Y > max_pixel_value) { // Y > 1.0f
375
4/8
void OL_AddImage::BlendImageMask_float<false, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 3 times.
✓ Branch 13 → 15 taken 3 times.
void OL_AddImage::BlendImageMask_float<false, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 9 times.
✓ Branch 13 → 15 taken 6 times.
void OL_AddImage::BlendImageMask_float<true, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
void OL_AddImage::BlendImageMask_float<true, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
21 float multiplier = max(0.0f, 1.0f + over32 - Y); // 1.12549 - Y, clamp to >=0
376 // Blend U/V toward neutral (0.0f)
377 21 U = U * multiplier / over32;
378 21 V = V * multiplier / over32;
379 21 Y = max_pixel_value; // 1.0f
380 }
381 }
382 else {
383
4/8
void OL_AddImage::BlendImageMask_float<false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 12 → 13 taken 9 times.
✓ Branch 12 → 19 taken 12 times.
void OL_AddImage::BlendImageMask_float<false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 12 → 13 taken 12 times.
✓ Branch 12 → 19 taken 9 times.
void OL_AddImage::BlendImageMask_float<true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
void OL_AddImage::BlendImageMask_float<true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
42 if (Y < 0.0f) {
384
4/8
void OL_AddImage::BlendImageMask_float<false, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 6 times.
✓ Branch 13 → 15 taken 3 times.
void OL_AddImage::BlendImageMask_float<false, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 3 times.
✓ Branch 13 → 15 taken 9 times.
void OL_AddImage::BlendImageMask_float<true, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
void OL_AddImage::BlendImageMask_float<true, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
21 float multiplier = min(-Y, over32); // 0 to over32
385 21 U = U * (over32 - multiplier) / over32;
386 21 V = V * (over32 - multiplier) / over32;
387 21 Y = 0.0f;
388 }
389 }
390
391 // No other clamping for float
392 84 baseU[x] = U;
393 84 baseV[x] = V;
394 84 baseY[x] = Y;
395 }
396 12 baseY += basepitch;
397 12 baseU += basepitch;
398 12 baseV += basepitch;
399
400 12 ovY += overlaypitch;
401 12 ovU += overlaypitch;
402 12 ovV += overlaypitch;
403
404 if constexpr (maskMode) {
405 maskY += maskpitch;
406 maskU += maskpitch;
407 maskV += maskpitch;
408 }
409 }
410 4 }
411
412
413 // integer 8-16-bit RGB add/subtract
414 template<typename pixel_t, bool maskMode, bool of_add>
415 4 void OL_AddImage::BlendImageMask_RGB(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {
416 4 int w = base->w();
417 4 int h = base->h();
418 4 const int pixelsize = sizeof(pixel_t);
419 4 const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;
420 4 auto factor = maskMode ? opacity_f / max_pixel_value : opacity_f;
421
422
4/16
void OL_AddImage::BlendImageMask_RGB<unsigned char, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 26 → 5 not taken.
✗ Branch 26 → 27 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 26 → 5 not taken.
✗ Branch 26 → 27 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 28 → 5 not taken.
✗ Branch 28 → 29 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 28 → 5 not taken.
✗ Branch 28 → 29 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned short, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 26 → 5 taken 6 times.
✓ Branch 26 → 27 taken 2 times.
void OL_AddImage::BlendImageMask_RGB<unsigned short, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 26 → 5 taken 6 times.
✓ Branch 26 → 27 taken 2 times.
void OL_AddImage::BlendImageMask_RGB<unsigned short, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 28 → 5 not taken.
✗ Branch 28 → 29 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned short, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 28 → 5 not taken.
✗ Branch 28 → 29 not taken.
16 for (int p = 0; p < 3; ++p) {
423 12 pixel_t* baseP = reinterpret_cast<pixel_t*>(base->GetPtrByIndex(p));
424 12 pixel_t* ovP = reinterpret_cast<pixel_t*>(overlay->GetPtrByIndex(p));
425 12 pixel_t* maskP = maskMode ? reinterpret_cast<pixel_t*>(mask->GetPtrByIndex(p)) : nullptr;
426 12 int basePitch = base->GetPitchByIndex(p) / pixelsize;
427 12 int overlayPitch = overlay->GetPitchByIndex(p) / pixelsize;
428 12 int maskPitch = maskMode ? (mask->GetPitchByIndex(p) / pixelsize) : 0;
429
430
4/16
void OL_AddImage::BlendImageMask_RGB<unsigned char, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 24 → 10 not taken.
✗ Branch 24 → 25 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 24 → 10 not taken.
✗ Branch 24 → 25 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 26 → 12 not taken.
✗ Branch 26 → 27 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 26 → 12 not taken.
✗ Branch 26 → 27 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned short, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 24 → 10 taken 18 times.
✓ Branch 24 → 25 taken 6 times.
void OL_AddImage::BlendImageMask_RGB<unsigned short, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 24 → 10 taken 18 times.
✓ Branch 24 → 25 taken 6 times.
void OL_AddImage::BlendImageMask_RGB<unsigned short, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 26 → 12 not taken.
✗ Branch 26 → 27 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned short, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 26 → 12 not taken.
✗ Branch 26 → 27 not taken.
48 for (int y = 0; y < h; ++y) {
431
4/16
void OL_AddImage::BlendImageMask_RGB<unsigned char, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 22 → 11 not taken.
✗ Branch 22 → 23 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 22 → 11 not taken.
✗ Branch 22 → 23 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 24 → 13 not taken.
✗ Branch 24 → 25 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 24 → 13 not taken.
✗ Branch 24 → 25 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned short, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 22 → 11 taken 90 times.
✓ Branch 22 → 23 taken 18 times.
void OL_AddImage::BlendImageMask_RGB<unsigned short, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 22 → 11 taken 90 times.
✓ Branch 22 → 23 taken 18 times.
void OL_AddImage::BlendImageMask_RGB<unsigned short, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 24 → 13 not taken.
✗ Branch 24 → 25 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned short, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 24 → 13 not taken.
✗ Branch 24 → 25 not taken.
216 for (int x = 0; x < w; ++x) {
432 180 int baseVal = baseP[x];
433 180 int ovVal = ovP[x];
434
435 180 const float new_mask = maskMode ? (float)reinterpret_cast<const pixel_t*>(maskP)[x] * factor : factor;
436 float result;
437
438 if constexpr (of_add)
439 90 result = baseVal + ovVal * new_mask;
440 else
441 90 result = baseVal - ovVal * new_mask;
442
443
6/32
void OL_AddImage::BlendImageMask_RGB<unsigned char, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 13 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 13 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 20 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned char, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 20 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned short, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 11 → 12 taken 51 times.
✓ Branch 11 → 13 taken 39 times.
✓ Branch 16 → 17 taken 90 times.
✗ Branch 16 → 18 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned short, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 11 → 12 taken 90 times.
✗ Branch 11 → 13 not taken.
✓ Branch 16 → 17 taken 45 times.
✓ Branch 16 → 18 taken 45 times.
void OL_AddImage::BlendImageMask_RGB<unsigned short, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 20 not taken.
void OL_AddImage::BlendImageMask_RGB<unsigned short, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 20 not taken.
540 baseP[x] = (pixel_t)(min(max((int)(result + 0.5f), 0), max_pixel_value));
444 }
445 36 baseP += basePitch;
446 36 ovP += overlayPitch;
447 if constexpr (maskMode) maskP += maskPitch;
448 }
449 }
450 4 }
451
452
453 // 32-bit float RGB add/subtract
454 template<bool maskMode, bool of_add>
455 4 void OL_AddImage::BlendImageMask_RGB_float(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {
456 4 int w = base->w();
457 4 int h = base->h();
458
459 4 auto factor = maskMode ? opacity_f / 1.0f : opacity_f; // for float, max_pixel_value is 1.0f for masks
460
461
4/8
void OL_AddImage::BlendImageMask_RGB_float<false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 16 → 5 taken 6 times.
✓ Branch 16 → 17 taken 2 times.
void OL_AddImage::BlendImageMask_RGB_float<false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 16 → 5 taken 6 times.
✓ Branch 16 → 17 taken 2 times.
void OL_AddImage::BlendImageMask_RGB_float<true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 18 → 5 not taken.
✗ Branch 18 → 19 not taken.
void OL_AddImage::BlendImageMask_RGB_float<true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 18 → 5 not taken.
✗ Branch 18 → 19 not taken.
16 for (int p = 0; p < 3; ++p) {
462 12 float* baseP = reinterpret_cast<float*>(base->GetPtrByIndex(p));
463 12 float* ovP = reinterpret_cast<float*>(overlay->GetPtrByIndex(p));
464 12 float* maskP = maskMode ? reinterpret_cast<float*>(mask->GetPtrByIndex(p)) : nullptr;
465 12 int basePitch = base->GetPitchByIndex(p) / sizeof(float);
466 12 int overlayPitch = overlay->GetPitchByIndex(p) / sizeof(float);
467 12 int maskPitch = maskMode ? (mask->GetPitchByIndex(p) / sizeof(float)) : 0;
468
469
4/8
void OL_AddImage::BlendImageMask_RGB_float<false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 14 → 10 taken 18 times.
✓ Branch 14 → 15 taken 6 times.
void OL_AddImage::BlendImageMask_RGB_float<false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 14 → 10 taken 18 times.
✓ Branch 14 → 15 taken 6 times.
void OL_AddImage::BlendImageMask_RGB_float<true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 12 not taken.
✗ Branch 16 → 17 not taken.
void OL_AddImage::BlendImageMask_RGB_float<true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 12 not taken.
✗ Branch 16 → 17 not taken.
48 for (int y = 0; y < h; ++y) {
470
4/8
void OL_AddImage::BlendImageMask_RGB_float<false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 12 → 11 taken 90 times.
✓ Branch 12 → 13 taken 18 times.
void OL_AddImage::BlendImageMask_RGB_float<false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 12 → 11 taken 90 times.
✓ Branch 12 → 13 taken 18 times.
void OL_AddImage::BlendImageMask_RGB_float<true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 14 → 13 not taken.
✗ Branch 14 → 15 not taken.
void OL_AddImage::BlendImageMask_RGB_float<true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 14 → 13 not taken.
✗ Branch 14 → 15 not taken.
216 for (int x = 0; x < w; ++x) {
471 180 float baseVal = baseP[x];
472 180 float ovVal = ovP[x];
473
474 180 const float new_mask = maskMode ? (float)reinterpret_cast<const float*>(maskP)[x] * factor : factor;
475 float result;
476
477 if constexpr (of_add)
478 90 result = baseVal + ovVal * new_mask;
479 else
480 90 result = baseVal - ovVal * new_mask;
481 180 baseP[x] = result; // no clamping for float
482 }
483 36 baseP += basePitch;
484 36 ovP += overlayPitch;
485 if constexpr (maskMode) maskP += maskPitch;
486 }
487 }
488 4 }
489
490