GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 53.3% 137 / 0 / 257
Functions: 43.8% 7 / 0 / 16
Branches: 29.6% 224 / 0 / 756

filters/merge.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
36 // Avisynth filter: YUV merge / Swap planes
37 // by Klaus Post (kp@interact.dk)
38 // adapted by Richard Berg (avisynth-dev@richardberg.net)
39 // iSSE code by Ian Brabham
40
41 #include <avisynth.h>
42 #include "merge.h"
43 #ifdef INTEL_INTRINSICS
44 #include "intel/merge_sse.h"
45 #include "intel/merge_avx2.h"
46 #endif
47 #include "../core/internal.h"
48 #include "avs/alignment.h"
49 #include <cstdint>
50
51
52 /* -----------------------------------
53 * weighted_merge_chroma_yuy2
54 * -----------------------------------
55 */
56 static void weighted_merge_chroma_yuy2_c(BYTE *src, const BYTE *chroma, int pitch, int chroma_pitch,int width, int height, int weight, int invweight) {
57 for (int y = 0; y < height; ++y) {
58 for (int x = 0; x < width; x+=2) {
59 src[x+1] = (chroma[x+1] * weight + src[x+1] * invweight + 16384) >> 15;
60 }
61 src+=pitch;
62 chroma+=chroma_pitch;
63 }
64 }
65
66
67 /* -----------------------------------
68 * weighted_merge_luma_yuy2
69 * -----------------------------------
70 */
71 static void weighted_merge_luma_yuy2_c(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height, int weight, int invweight) {
72 for (int y = 0; y < height; ++y) {
73 for (int x = 0; x < width; x+=2) {
74 src[x] = (luma[x] * weight + src[x] * invweight + 16384) >> 15;
75 }
76 src+=pitch;
77 luma+=luma_pitch;
78 }
79 }
80
81
82 /* -----------------------------------
83 * replace_luma_yuy2
84 * -----------------------------------
85 */
86 static void replace_luma_yuy2_c(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height ) {
87 for (int y = 0; y < height; ++y) {
88 for (int x = 0; x < width; x+=2) {
89 src[x] = luma[x];
90 }
91 src+=pitch;
92 luma+=luma_pitch;
93 }
94 }
95
96
97 /* -----------------------------------
98 * average_plane
99 * -----------------------------------
100 */
101 // for uint8_t and uint16_t
102 template<typename pixel_t>
103 static void average_plane_c(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) {
104 for (int y = 0; y < height; ++y) {
105 for (size_t x = 0; x < rowsize / sizeof(pixel_t); ++x) {
106 reinterpret_cast<pixel_t *>(p1)[x] = (int(reinterpret_cast<pixel_t *>(p1)[x]) + reinterpret_cast<const pixel_t *>(p2)[x] + 1) >> 1;
107 }
108 p1 += p1_pitch;
109 p2 += p2_pitch;
110 }
111 }
112 // for float
113 static void average_plane_c_float(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) {
114
115 size_t rs = rowsize / sizeof(float);
116
117 for (int y = 0; y < height; ++y) {
118 for (size_t x = 0; x < rs; ++x) {
119 reinterpret_cast<float *>(p1)[x] = (reinterpret_cast<float *>(p1)[x] + reinterpret_cast<const float *>(p2)[x]) / 2.0f;
120 }
121 p1 += p1_pitch;
122 p2 += p2_pitch;
123 }
124 }
125
126 // weighted_merge_planar C reference and SIMD are now in overlay/blend_common*.
127 // merge_plane uses get_weighted_merge_fn / get_weighted_merge_float_fn from merge.h.
128
129
130 /********************************************************************
131 ***** Declare index of new filters for Avisynth's filter engine *****
132 ********************************************************************/
133 extern const AVSFunction Merge_filters[] = {
134 { "Merge", BUILTIN_FUNC_PREFIX, "cc[weight]f", MergeAll::Create }, // src, src2, weight
135 { "MergeChroma", BUILTIN_FUNC_PREFIX, "cc[weight]f", MergeChroma::Create }, // src, chroma src, weight
136 { "MergeChroma", BUILTIN_FUNC_PREFIX, "cc[chromaweight]f", MergeChroma::Create }, // Legacy!
137 { "MergeLuma", BUILTIN_FUNC_PREFIX, "cc[weight]f", MergeLuma::Create }, // src, luma src, weight
138 { "MergeLuma", BUILTIN_FUNC_PREFIX, "cc[lumaweight]f", MergeLuma::Create }, // Legacy!
139 { 0 }
140 };
141
142 35 void merge_plane(BYTE* srcp, const BYTE* otherp, int src_pitch, int other_pitch, int src_rowsize, int src_height, float weight, int bits_per_pixel, bool use_padded_width, IScriptEnvironment* env) {
143
144
2/2
✓ Branch 2 → 3 taken 26 times.
✓ Branch 2 → 4 taken 9 times.
35 if (use_padded_width) {
145 // Align the width to the next multiple of FRAME_ALIGN (64) bytes, which is the alignment used for AviSynth+ frame buffers.
146 // This allows SIMD kernels to process the entire row without a scalar tail, improving performance for full-frame merges.
147 26 src_rowsize = AlignNumber(src_rowsize, FRAME_ALIGN);
148 }
149
150 // 15 bit arithmetic for integer weighted merge: weight is in [0..32768], invweight = 32768 - weight.
151 35 const int weight_i = (int)(weight * 32768.0f + 0.5f);
152 35 const int invweight_i = 32768 - weight_i;
153
154
1/4
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 8 taken 35 times.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
35 const int pixelsize = bits_per_pixel == 8 ? 1 : (bits_per_pixel <= 16 ? 2 : 4);
155
156
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 35 times.
35 const bool use_average = (bits_per_pixel == 32) ? (weight == 0.5f) : (weight_i == 16384);
157
2/2
✓ Branch 12 → 13 taken 9 times.
✓ Branch 12 → 34 taken 26 times.
35 if (use_average)
158 {
159 //average of two planes
160
1/2
✓ Branch 13 → 14 taken 9 times.
✗ Branch 13 → 27 not taken.
9 if (pixelsize != 4) // 1 or 2
161 {
162 #ifdef INTEL_INTRINSICS
163
1/2
✓ Branch 15 → 16 taken 9 times.
✗ Branch 15 → 19 not taken.
9 if (env->GetCPUFlags() & CPUF_AVX2) {
164
1/2
✓ Branch 16 → 17 taken 9 times.
✗ Branch 16 → 18 not taken.
9 if (pixelsize == 1)
165 9 average_plane_avx2<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);
166 else // pixel_size==2
167 average_plane_avx2<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);
168 }
169 else if (env->GetCPUFlags() & CPUF_SSE2) {
170 if (pixelsize == 1)
171 average_plane_sse2<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);
172 else // pixel_size==2
173 average_plane_sse2<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);
174 }
175 else
176 #endif
177 {
178 if (pixelsize == 1)
179 average_plane_c<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);
180 else // pixel_size==2
181 average_plane_c<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);
182 }
183 }
184 else { // if (pixelsize == 4)
185 #ifdef INTEL_INTRINSICS
186 if (env->GetCPUFlags() & CPUF_AVX2)
187 average_plane_avx2_float(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);
188 else if (env->GetCPUFlags() & CPUF_SSE2)
189 average_plane_sse2_float(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);
190 else
191 #endif
192 average_plane_c_float(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);
193 }
194 }
195 else
196 {
197 // Frame scanlines are always padded to FRAME_ALIGN (64) bytes in AviSynth+.
198 // When called from the "Merge" filter, we are passing the aligned width, since it eliminates the
199 // scalar tail in all weighted_merge SIMD kernels.
200 // When called from other filters, like Overlay and Layer, the width must be exact.
201 // Overreading/writing into the alignment padding is safe for full-frame merges.
202 // See use_padded_width parameter.
203 26 const int width_pixels = src_rowsize / pixelsize;
204 26 const int cpuFlags = env->GetCPUFlags();
205
1/2
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 38 taken 26 times.
26 if (bits_per_pixel == 32) {
206 get_weighted_merge_float_fn(cpuFlags)(srcp, otherp, src_pitch, other_pitch, width_pixels, src_height, weight);
207 } else {
208 26 get_weighted_merge_fn(cpuFlags, weight_i)(srcp, otherp, src_pitch, other_pitch, width_pixels, src_height, weight_i, invweight_i, bits_per_pixel);
209 }
210 }
211 35 }
212
213 /****************************
214 ****** Merge Chroma *****
215 ****************************/
216
217 6 MergeChroma::MergeChroma(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env)
218
3/6
✓ Branch 2 → 3 taken 6 times.
✗ Branch 2 → 35 not taken.
✓ Branch 3 → 4 taken 6 times.
✗ Branch 3 → 33 not taken.
✓ Branch 5 → 6 taken 6 times.
✗ Branch 5 → 38 not taken.
6 : GenericVideoFilter(_child), clip(_clip), weight(_weight)
219 {
220
1/2
✓ Branch 7 → 8 taken 6 times.
✗ Branch 7 → 36 not taken.
6 const VideoInfo& vi2 = clip->GetVideoInfo();
221
222
11/18
✓ Branch 8 → 9 taken 6 times.
✗ Branch 8 → 36 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 12 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 36 not taken.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 16 not taken.
✓ Branch 12 → 13 taken 6 times.
✗ Branch 12 → 36 not taken.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 17 taken 5 times.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 36 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 1 time.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 6 times.
6 if (!(vi.IsYUV() || vi.IsYUVA()) || !(vi2.IsYUV() || vi2.IsYUVA()))
223 env->ThrowError("MergeChroma: YUV data only (no RGB); use ConvertToYUY2, ConvertToYV12/16/24 or ConvertToYUVxxx");
224
225
2/4
✓ Branch 20 → 21 taken 6 times.
✗ Branch 20 → 36 not taken.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 6 times.
6 if (!(vi.IsSameColorspace(vi2)))
226 env->ThrowError("MergeChroma: YUV images must have same data type.");
227
228
2/4
✓ Branch 23 → 24 taken 6 times.
✗ Branch 23 → 25 not taken.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 6 times.
6 if (vi.width!=vi2.width || vi.height!=vi2.height)
229 env->ThrowError("MergeChroma: Images must have same width and height!");
230
231
1/2
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 28 taken 6 times.
6 if (weight<0.0f) weight=0.0f;
232
1/2
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 6 times.
6 if (weight>1.0f) weight=1.0f;
233
234
1/2
✓ Branch 30 → 31 taken 6 times.
✗ Branch 30 → 36 not taken.
6 pixelsize = vi.ComponentSize();
235
1/2
✓ Branch 31 → 32 taken 6 times.
✗ Branch 31 → 36 not taken.
6 bits_per_pixel = vi.BitsPerComponent();
236 6 }
237
238
239 5 PVideoFrame __stdcall MergeChroma::GetFrame(int n, IScriptEnvironment* env)
240 {
241
1/2
✓ Branch 3 → 4 taken 5 times.
✗ Branch 3 → 211 not taken.
5 PVideoFrame src = child->GetFrame(n, env);
242
243 // Threshold: for integer clips snap based on the SIMD integer scale (0..32768);
244 // for float clips use exact float comparison.
245
1/2
✓ Branch 4 → 5 taken 5 times.
✗ Branch 4 → 6 not taken.
5 const int weight_i_simd = (bits_per_pixel != 32) ? (int)(weight * 32768.0f + 0.5f) : 0;
246 5 const int inv_weight_i_simd = 32768 - weight_i_simd;
247
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 5 times.
5 const bool weight_is_zero = (bits_per_pixel == 32) ? (weight == 0.0f) : (weight_i_simd == 0);
248
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 5 times.
5 const bool weight_is_one = (bits_per_pixel == 32) ? (weight == 1.0f) : (weight_i_simd >= 32768);
249
250
1/4
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 5 times.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 209 not taken.
5 if (weight_is_zero) return src;
251
252
1/2
✓ Branch 17 → 18 taken 5 times.
✗ Branch 17 → 209 not taken.
5 PVideoFrame chroma = clip->GetFrame(n, env);
253
254
1/2
✓ Branch 19 → 20 taken 5 times.
✗ Branch 19 → 207 not taken.
5 int h = src->GetHeight();
255
1/2
✓ Branch 21 → 22 taken 5 times.
✗ Branch 21 → 207 not taken.
5 int w = src->GetRowSize(); // width in pixels
256
257
2/2
✓ Branch 22 → 23 taken 4 times.
✓ Branch 22 → 76 taken 1 time.
5 if (!weight_is_one) {
258
2/4
✓ Branch 23 → 24 taken 4 times.
✗ Branch 23 → 207 not taken.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 38 taken 4 times.
4 if (vi.IsYUY2()) {
259 env->MakeWritable(&src);
260 BYTE* srcp = src->GetWritePtr();
261 const BYTE* chromap = chroma->GetReadPtr();
262
263 int src_pitch = src->GetPitch();
264 int chroma_pitch = chroma->GetPitch();
265 #ifdef INTEL_INTRINSICS
266 if (env->GetCPUFlags() & CPUF_SSE2)
267 {
268 weighted_merge_chroma_yuy2_sse2(srcp, chromap, src_pitch, chroma_pitch, w, h, weight_i_simd, inv_weight_i_simd);
269 }
270 else
271 #ifdef X86_32
272 if (env->GetCPUFlags() & CPUF_MMX)
273 {
274 weighted_merge_chroma_yuy2_mmx(srcp, chromap, src_pitch, chroma_pitch, w, h, weight_i_simd, inv_weight_i_simd);
275 }
276 else
277 #endif
278 #endif
279 {
280 weighted_merge_chroma_yuy2_c(srcp, chromap, src_pitch, chroma_pitch, w, h, weight_i_simd, inv_weight_i_simd);
281 }
282 }
283 else { // Planar YUV
284
1/2
✓ Branch 38 → 39 taken 4 times.
✗ Branch 38 → 207 not taken.
4 env->MakeWritable(&src);
285
1/2
✓ Branch 40 → 41 taken 4 times.
✗ Branch 40 → 207 not taken.
4 src->GetWritePtr(PLANAR_Y); //Must be requested
286
287
1/2
✓ Branch 42 → 43 taken 4 times.
✗ Branch 42 → 207 not taken.
4 BYTE* srcpU = (BYTE*)src->GetWritePtr(PLANAR_U);
288
1/2
✓ Branch 44 → 45 taken 4 times.
✗ Branch 44 → 207 not taken.
4 BYTE* chromapU = (BYTE*)chroma->GetReadPtr(PLANAR_U);
289
1/2
✓ Branch 46 → 47 taken 4 times.
✗ Branch 46 → 207 not taken.
4 BYTE* srcpV = (BYTE*)src->GetWritePtr(PLANAR_V);
290
1/2
✓ Branch 48 → 49 taken 4 times.
✗ Branch 48 → 207 not taken.
4 BYTE* chromapV = (BYTE*)chroma->GetReadPtr(PLANAR_V);
291
1/2
✓ Branch 50 → 51 taken 4 times.
✗ Branch 50 → 207 not taken.
4 int src_pitch_uv = src->GetPitch(PLANAR_U);
292
1/2
✓ Branch 52 → 53 taken 4 times.
✗ Branch 52 → 207 not taken.
4 int chroma_pitch_uv = chroma->GetPitch(PLANAR_U);
293
1/2
✓ Branch 54 → 55 taken 4 times.
✗ Branch 54 → 207 not taken.
4 int src_rowsize_u = src->GetRowSize(PLANAR_U_ALIGNED);
294
1/2
✓ Branch 56 → 57 taken 4 times.
✗ Branch 56 → 207 not taken.
4 int src_rowsize_v = src->GetRowSize(PLANAR_V_ALIGNED);
295
1/2
✓ Branch 58 → 59 taken 4 times.
✗ Branch 58 → 207 not taken.
4 int src_height_uv = src->GetHeight(PLANAR_U);
296
297
1/2
✓ Branch 59 → 60 taken 4 times.
✗ Branch 59 → 207 not taken.
4 merge_plane(srcpU, chromapU, src_pitch_uv, chroma_pitch_uv, src_rowsize_u, src_height_uv, weight, bits_per_pixel, true, env);
298
1/2
✓ Branch 60 → 61 taken 4 times.
✗ Branch 60 → 207 not taken.
4 merge_plane(srcpV, chromapV, src_pitch_uv, chroma_pitch_uv, src_rowsize_v, src_height_uv, weight, bits_per_pixel, true, env);
299
300 // FIXME: MergeChroma should not be modifying the alpha plane
301
3/4
✓ Branch 61 → 62 taken 4 times.
✗ Branch 61 → 207 not taken.
✓ Branch 62 → 63 taken 1 time.
✓ Branch 62 → 198 taken 3 times.
4 if (vi.IsYUVA())
302
7/14
✓ Branch 64 → 65 taken 1 time.
✗ Branch 64 → 207 not taken.
✓ Branch 66 → 67 taken 1 time.
✗ Branch 66 → 207 not taken.
✓ Branch 68 → 69 taken 1 time.
✗ Branch 68 → 207 not taken.
✓ Branch 70 → 71 taken 1 time.
✗ Branch 70 → 207 not taken.
✓ Branch 72 → 73 taken 1 time.
✗ Branch 72 → 207 not taken.
✓ Branch 74 → 75 taken 1 time.
✗ Branch 74 → 207 not taken.
✓ Branch 75 → 198 taken 1 time.
✗ Branch 75 → 207 not taken.
1 merge_plane(src->GetWritePtr(PLANAR_A), chroma->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), chroma->GetPitch(PLANAR_A),
303 src->GetRowSize(PLANAR_A_ALIGNED), src->GetHeight(PLANAR_A), weight, bits_per_pixel, true, env);
304 }
305 }
306 else { // weight == 1.0
307
2/4
✓ Branch 76 → 77 taken 1 time.
✗ Branch 76 → 207 not taken.
✗ Branch 77 → 78 not taken.
✓ Branch 77 → 93 taken 1 time.
1 if (vi.IsYUY2()) {
308 const BYTE* srcp = src->GetReadPtr();
309 env->MakeWritable(&chroma);
310 BYTE* chromap = chroma->GetWritePtr();
311
312 int src_pitch = src->GetPitch();
313 int chroma_pitch = chroma->GetPitch();
314 #ifdef INTEL_INTRINSICS
315 if (env->GetCPUFlags() & CPUF_SSE2)
316 {
317 replace_luma_yuy2_sse2(chromap, srcp, chroma_pitch, src_pitch, w, h); // Just swap luma/chroma
318 }
319 else
320 #ifdef X86_32
321 if (env->GetCPUFlags() & CPUF_MMX)
322 {
323 replace_luma_yuy2_mmx(chromap, srcp, chroma_pitch, src_pitch, w, h); // Just swap luma/chroma
324 }
325 else
326 #endif
327 #endif
328 {
329 replace_luma_yuy2_c(chromap, srcp, chroma_pitch, src_pitch, w, h); // Just swap luma/chroma
330 }
331
332 return chroma;
333 }
334 else {
335
2/4
✓ Branch 94 → 95 taken 1 time.
✗ Branch 94 → 207 not taken.
✗ Branch 95 → 96 not taken.
✓ Branch 95 → 139 taken 1 time.
1 if (src->IsWritable()) {
336 src->GetWritePtr(PLANAR_Y); //Must be requested
337 env->BitBlt(src->GetWritePtr(PLANAR_U), src->GetPitch(PLANAR_U), chroma->GetReadPtr(PLANAR_U), chroma->GetPitch(PLANAR_U), chroma->GetRowSize(PLANAR_U), chroma->GetHeight(PLANAR_U));
338 env->BitBlt(src->GetWritePtr(PLANAR_V), src->GetPitch(PLANAR_V), chroma->GetReadPtr(PLANAR_V), chroma->GetPitch(PLANAR_V), chroma->GetRowSize(PLANAR_V), chroma->GetHeight(PLANAR_V));
339 if (vi.IsYUVA())
340 env->BitBlt(src->GetWritePtr(PLANAR_A), src->GetPitch(PLANAR_A), chroma->GetReadPtr(PLANAR_A), chroma->GetPitch(PLANAR_A), chroma->GetRowSize(PLANAR_A), chroma->GetHeight(PLANAR_A));
341 }
342 else { // avoid the cost of 2 chroma blits
343
1/2
✓ Branch 139 → 140 taken 1 time.
✗ Branch 139 → 206 not taken.
1 PVideoFrame dst = env->NewVideoFrameP(vi, &src);
344
345
7/14
✓ Branch 141 → 142 taken 1 time.
✗ Branch 141 → 204 not taken.
✓ Branch 143 → 144 taken 1 time.
✗ Branch 143 → 204 not taken.
✓ Branch 145 → 146 taken 1 time.
✗ Branch 145 → 204 not taken.
✓ Branch 147 → 148 taken 1 time.
✗ Branch 147 → 204 not taken.
✓ Branch 149 → 150 taken 1 time.
✗ Branch 149 → 204 not taken.
✓ Branch 151 → 152 taken 1 time.
✗ Branch 151 → 204 not taken.
✓ Branch 152 → 153 taken 1 time.
✗ Branch 152 → 204 not taken.
1 env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y));
346
7/14
✓ Branch 154 → 155 taken 1 time.
✗ Branch 154 → 204 not taken.
✓ Branch 156 → 157 taken 1 time.
✗ Branch 156 → 204 not taken.
✓ Branch 158 → 159 taken 1 time.
✗ Branch 158 → 204 not taken.
✓ Branch 160 → 161 taken 1 time.
✗ Branch 160 → 204 not taken.
✓ Branch 162 → 163 taken 1 time.
✗ Branch 162 → 204 not taken.
✓ Branch 164 → 165 taken 1 time.
✗ Branch 164 → 204 not taken.
✓ Branch 165 → 166 taken 1 time.
✗ Branch 165 → 204 not taken.
1 env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), chroma->GetReadPtr(PLANAR_U), chroma->GetPitch(PLANAR_U), chroma->GetRowSize(PLANAR_U), chroma->GetHeight(PLANAR_U));
347
7/14
✓ Branch 167 → 168 taken 1 time.
✗ Branch 167 → 204 not taken.
✓ Branch 169 → 170 taken 1 time.
✗ Branch 169 → 204 not taken.
✓ Branch 171 → 172 taken 1 time.
✗ Branch 171 → 204 not taken.
✓ Branch 173 → 174 taken 1 time.
✗ Branch 173 → 204 not taken.
✓ Branch 175 → 176 taken 1 time.
✗ Branch 175 → 204 not taken.
✓ Branch 177 → 178 taken 1 time.
✗ Branch 177 → 204 not taken.
✓ Branch 178 → 179 taken 1 time.
✗ Branch 178 → 204 not taken.
1 env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), chroma->GetReadPtr(PLANAR_V), chroma->GetPitch(PLANAR_V), chroma->GetRowSize(PLANAR_V), chroma->GetHeight(PLANAR_V));
348
2/4
✓ Branch 179 → 180 taken 1 time.
✗ Branch 179 → 204 not taken.
✗ Branch 180 → 181 not taken.
✓ Branch 180 → 194 taken 1 time.
1 if (vi.IsYUVA())
349 env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), chroma->GetReadPtr(PLANAR_A), chroma->GetPitch(PLANAR_A), chroma->GetRowSize(PLANAR_A), chroma->GetHeight(PLANAR_A));
350
351
1/2
✓ Branch 194 → 195 taken 1 time.
✗ Branch 194 → 204 not taken.
1 return dst;
352 1 }
353 }
354 }
355
1/2
✓ Branch 198 → 199 taken 4 times.
✗ Branch 198 → 207 not taken.
4 return src;
356 5 }
357
358
359 AVSValue __cdecl MergeChroma::Create(AVSValue args, void* , IScriptEnvironment* env)
360 {
361 return new MergeChroma(args[0].AsClip(), args[1].AsClip(), (float)args[2].AsFloat(1.0f), env);
362 }
363
364
365 /**************************
366 ****** Merge Luma *****
367 **************************/
368
369
370 6 MergeLuma::MergeLuma(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env)
371
3/6
✓ Branch 2 → 3 taken 6 times.
✗ Branch 2 → 45 not taken.
✓ Branch 3 → 4 taken 6 times.
✗ Branch 3 → 43 not taken.
✓ Branch 5 → 6 taken 6 times.
✗ Branch 5 → 48 not taken.
6 : GenericVideoFilter(_child), clip(_clip), weight(_weight)
372 {
373
1/2
✓ Branch 7 → 8 taken 6 times.
✗ Branch 7 → 46 not taken.
6 const VideoInfo& vi2 = clip->GetVideoInfo();
374
375
11/18
✓ Branch 8 → 9 taken 6 times.
✗ Branch 8 → 46 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 12 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 46 not taken.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 16 not taken.
✓ Branch 12 → 13 taken 6 times.
✗ Branch 12 → 46 not taken.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 17 taken 5 times.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 1 time.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 6 times.
6 if (!(vi.IsYUV() || vi.IsYUVA()) || !(vi2.IsYUV() || vi2.IsYUVA()))
376 env->ThrowError("MergeLuma: YUV data only (no RGB); use ConvertToYUY2, ConvertToYV12/16/24 or ConvertToYUVxxx");
377
378
1/2
✓ Branch 20 → 21 taken 6 times.
✗ Branch 20 → 46 not taken.
6 pixelsize = vi.ComponentSize();
379
1/2
✓ Branch 21 → 22 taken 6 times.
✗ Branch 21 → 46 not taken.
6 bits_per_pixel = vi.BitsPerComponent();
380
381
2/4
✓ Branch 22 → 23 taken 6 times.
✗ Branch 22 → 46 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 35 taken 6 times.
6 if (!vi.IsSameColorspace(vi2)) { // Since this is luma we allow all planar formats to be merged.
382 if (!(vi.IsPlanar() && vi2.IsPlanar())) {
383 env->ThrowError("MergeLuma: YUV data is not same type. YUY2 and planar images doesn't mix.");
384 }
385 if (pixelsize != vi2.ComponentSize()) {
386 env->ThrowError("MergeLuma: YUV data bit depth is not same.");
387 }
388 }
389
390
2/4
✓ Branch 35 → 36 taken 6 times.
✗ Branch 35 → 37 not taken.
✗ Branch 36 → 37 not taken.
✓ Branch 36 → 38 taken 6 times.
6 if (vi.width!=vi2.width || vi.height!=vi2.height)
391 env->ThrowError("MergeLuma: Images must have same width and height!");
392
393
1/2
✗ Branch 38 → 39 not taken.
✓ Branch 38 → 40 taken 6 times.
6 if (weight<0.0f) weight=0.0f;
394
1/2
✗ Branch 40 → 41 not taken.
✓ Branch 40 → 42 taken 6 times.
6 if (weight>1.0f) weight=1.0f;
395
396 6 }
397
398
399 5 PVideoFrame __stdcall MergeLuma::GetFrame(int n, IScriptEnvironment* env)
400 {
401
1/2
✓ Branch 3 → 4 taken 5 times.
✗ Branch 3 → 206 not taken.
5 PVideoFrame src = child->GetFrame(n, env);
402
403 // Threshold: for integer clips snap based on the SIMD integer scale (0..32767);
404 // for float clips use exact float comparison.
405
1/2
✓ Branch 4 → 5 taken 5 times.
✗ Branch 4 → 6 not taken.
5 const int weight_i_simd = (bits_per_pixel != 32) ? (int)(weight * 32767.0f + 0.5f) : 0;
406
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 5 times.
5 const bool weight_is_zero = (bits_per_pixel == 32) ? (weight == 0.0f) : (weight_i_simd == 0);
407
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 5 times.
5 const bool weight_is_one = (bits_per_pixel == 32) ? (weight == 1.0f) : (weight_i_simd >= 32767);
408
409
1/4
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 5 times.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 204 not taken.
5 if (weight_is_zero) return src;
410
411
1/2
✓ Branch 17 → 18 taken 5 times.
✗ Branch 17 → 204 not taken.
5 PVideoFrame luma = clip->GetFrame(n, env);
412
413
2/4
✓ Branch 18 → 19 taken 5 times.
✗ Branch 18 → 202 not taken.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 44 taken 5 times.
5 if (vi.IsYUY2()) {
414 env->MakeWritable(&src);
415 BYTE* srcp = src->GetWritePtr();
416 const BYTE* lumap = luma->GetReadPtr();
417
418 int isrc_pitch = src->GetPitch();
419 int iluma_pitch = luma->GetPitch();
420
421 int h = src->GetHeight();
422 int w = src->GetRowSize();
423
424 if (!weight_is_one) {
425 #ifdef INTEL_INTRINSICS
426 if (env->GetCPUFlags() & CPUF_SSE2)
427 {
428 weighted_merge_luma_yuy2_sse2(srcp, lumap, isrc_pitch, iluma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f));
429 }
430 else
431 #ifdef X86_32
432 if (env->GetCPUFlags() & CPUF_MMX)
433 {
434 weighted_merge_luma_yuy2_mmx(srcp, lumap, isrc_pitch, iluma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f));
435 }
436 else
437 #endif
438 #endif
439 {
440 weighted_merge_luma_yuy2_c(srcp, lumap, isrc_pitch, iluma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f));
441 }
442 }
443 else {
444 #ifdef INTEL_INTRINSICS
445 if (env->GetCPUFlags() & CPUF_SSE2)
446 {
447 replace_luma_yuy2_sse2(srcp, lumap, isrc_pitch, iluma_pitch, w, h);
448 }
449 else
450 #ifdef X86_32
451 if (env->GetCPUFlags() & CPUF_MMX)
452 {
453 replace_luma_yuy2_mmx(srcp, lumap, isrc_pitch, iluma_pitch, w, h);
454 }
455 else
456 #endif
457 #endif
458 {
459 replace_luma_yuy2_c(srcp, lumap, isrc_pitch, iluma_pitch, w, h);
460 }
461 }
462 return src;
463 } // Planar
464
2/2
✓ Branch 44 → 45 taken 1 time.
✓ Branch 44 → 179 taken 4 times.
5 if (weight_is_one) {
465 // 2nd clip weight is 100%: no merge, just copy
466
1/2
✓ Branch 46 → 47 taken 1 time.
✗ Branch 46 → 202 not taken.
1 const VideoInfo& vi2 = clip->GetVideoInfo();
467
3/10
✓ Branch 48 → 49 taken 1 time.
✗ Branch 48 → 202 not taken.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 53 taken 1 time.
✗ Branch 50 → 51 not taken.
✗ Branch 50 → 202 not taken.
✗ Branch 51 → 52 not taken.
✗ Branch 51 → 53 not taken.
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 104 taken 1 time.
1 if (luma->IsWritable() && vi.IsSameColorspace(vi2)) {
468 if (luma->GetRowSize(PLANAR_U)) {
469 luma->GetWritePtr(PLANAR_Y); //Must be requested BUT only if we actually do something
470 env->BitBlt(luma->GetWritePtr(PLANAR_U), luma->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U));
471 env->BitBlt(luma->GetWritePtr(PLANAR_V), luma->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V));
472 }
473 if (luma->GetPitch(PLANAR_A)) // copy Alpha if exists
474 env->BitBlt(luma->GetWritePtr(PLANAR_A), luma->GetPitch(PLANAR_A), src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A));
475
476 return luma;
477 }
478 else { // avoid the cost of 2 chroma blits
479
1/2
✓ Branch 104 → 105 taken 1 time.
✗ Branch 104 → 201 not taken.
1 PVideoFrame dst = env->NewVideoFrameP(vi, &luma);
480
481
7/14
✓ Branch 106 → 107 taken 1 time.
✗ Branch 106 → 199 not taken.
✓ Branch 108 → 109 taken 1 time.
✗ Branch 108 → 199 not taken.
✓ Branch 110 → 111 taken 1 time.
✗ Branch 110 → 199 not taken.
✓ Branch 112 → 113 taken 1 time.
✗ Branch 112 → 199 not taken.
✓ Branch 114 → 115 taken 1 time.
✗ Branch 114 → 199 not taken.
✓ Branch 116 → 117 taken 1 time.
✗ Branch 116 → 199 not taken.
✓ Branch 117 → 118 taken 1 time.
✗ Branch 117 → 199 not taken.
1 env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), luma->GetReadPtr(PLANAR_Y), luma->GetPitch(PLANAR_Y), luma->GetRowSize(PLANAR_Y), luma->GetHeight(PLANAR_Y));
482
5/10
✓ Branch 119 → 120 taken 1 time.
✗ Branch 119 → 199 not taken.
✓ Branch 120 → 121 taken 1 time.
✗ Branch 120 → 125 not taken.
✓ Branch 122 → 123 taken 1 time.
✗ Branch 122 → 199 not taken.
✓ Branch 123 → 124 taken 1 time.
✗ Branch 123 → 125 not taken.
✓ Branch 126 → 127 taken 1 time.
✗ Branch 126 → 153 not taken.
1 if (src->GetRowSize(PLANAR_U) && dst->GetRowSize(PLANAR_U)) {
483
7/14
✓ Branch 128 → 129 taken 1 time.
✗ Branch 128 → 199 not taken.
✓ Branch 130 → 131 taken 1 time.
✗ Branch 130 → 199 not taken.
✓ Branch 132 → 133 taken 1 time.
✗ Branch 132 → 199 not taken.
✓ Branch 134 → 135 taken 1 time.
✗ Branch 134 → 199 not taken.
✓ Branch 136 → 137 taken 1 time.
✗ Branch 136 → 199 not taken.
✓ Branch 138 → 139 taken 1 time.
✗ Branch 138 → 199 not taken.
✓ Branch 139 → 140 taken 1 time.
✗ Branch 139 → 199 not taken.
1 env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U));
484
7/14
✓ Branch 141 → 142 taken 1 time.
✗ Branch 141 → 199 not taken.
✓ Branch 143 → 144 taken 1 time.
✗ Branch 143 → 199 not taken.
✓ Branch 145 → 146 taken 1 time.
✗ Branch 145 → 199 not taken.
✓ Branch 147 → 148 taken 1 time.
✗ Branch 147 → 199 not taken.
✓ Branch 149 → 150 taken 1 time.
✗ Branch 149 → 199 not taken.
✓ Branch 151 → 152 taken 1 time.
✗ Branch 151 → 199 not taken.
✓ Branch 152 → 153 taken 1 time.
✗ Branch 152 → 199 not taken.
1 env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V));
485 }
486
3/10
✓ Branch 154 → 155 taken 1 time.
✗ Branch 154 → 199 not taken.
✗ Branch 155 → 156 not taken.
✓ Branch 155 → 160 taken 1 time.
✗ Branch 157 → 158 not taken.
✗ Branch 157 → 199 not taken.
✗ Branch 158 → 159 not taken.
✗ Branch 158 → 160 not taken.
✗ Branch 161 → 162 not taken.
✓ Branch 161 → 175 taken 1 time.
1 if (dst->GetPitch(PLANAR_A) && src->GetPitch(PLANAR_A)) // copy Alpha if in both clip exists
487 env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A));
488
489
1/2
✓ Branch 175 → 176 taken 1 time.
✗ Branch 175 → 199 not taken.
1 return dst;
490 1 }
491 }
492 else { // weight < 1.0 (integer scale)
493
1/2
✓ Branch 179 → 180 taken 4 times.
✗ Branch 179 → 202 not taken.
4 env->MakeWritable(&src);
494
1/2
✓ Branch 181 → 182 taken 4 times.
✗ Branch 181 → 202 not taken.
4 BYTE* srcpY = (BYTE*)src->GetWritePtr(PLANAR_Y);
495
1/2
✓ Branch 183 → 184 taken 4 times.
✗ Branch 183 → 202 not taken.
4 BYTE* lumapY = (BYTE*)luma->GetReadPtr(PLANAR_Y);
496
1/2
✓ Branch 185 → 186 taken 4 times.
✗ Branch 185 → 202 not taken.
4 int src_pitch = src->GetPitch(PLANAR_Y);
497
1/2
✓ Branch 187 → 188 taken 4 times.
✗ Branch 187 → 202 not taken.
4 int luma_pitch = luma->GetPitch(PLANAR_Y);
498
1/2
✓ Branch 189 → 190 taken 4 times.
✗ Branch 189 → 202 not taken.
4 int src_rowsize = src->GetRowSize(PLANAR_Y);
499
1/2
✓ Branch 191 → 192 taken 4 times.
✗ Branch 191 → 202 not taken.
4 int src_height = src->GetHeight(PLANAR_Y);
500
501
1/2
✓ Branch 192 → 193 taken 4 times.
✗ Branch 192 → 202 not taken.
4 merge_plane(srcpY, lumapY, src_pitch, luma_pitch, src_rowsize, src_height, weight, bits_per_pixel, true, env);
502 }
503
504
1/2
✓ Branch 193 → 194 taken 4 times.
✗ Branch 193 → 202 not taken.
4 return src;
505 5 }
506
507
508 AVSValue __cdecl MergeLuma::Create(AVSValue args, void* , IScriptEnvironment* env)
509 {
510 return new MergeLuma(args[0].AsClip(), args[1].AsClip(), (float)args[2].AsFloat(1.0f), env);
511 }
512
513
514 /*************************
515 ****** Merge All *****
516 *************************/
517
518
519 7 MergeAll::MergeAll(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env)
520
3/6
✓ Branch 2 → 3 taken 7 times.
✗ Branch 2 → 23 not taken.
✓ Branch 3 → 4 taken 7 times.
✗ Branch 3 → 21 not taken.
✓ Branch 5 → 6 taken 7 times.
✗ Branch 5 → 26 not taken.
7 : GenericVideoFilter(_child), clip(_clip), weight(_weight)
521 {
522
1/2
✓ Branch 7 → 8 taken 7 times.
✗ Branch 7 → 24 not taken.
7 const VideoInfo& vi2 = clip->GetVideoInfo();
523
524
2/4
✓ Branch 8 → 9 taken 7 times.
✗ Branch 8 → 24 not taken.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 7 times.
7 if (!vi.IsSameColorspace(vi2))
525 env->ThrowError("Merge: Pixel types are not the same. Both must be the same.");
526
527
2/4
✓ Branch 11 → 12 taken 7 times.
✗ Branch 11 → 13 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 7 times.
7 if (vi.width!=vi2.width || vi.height!=vi2.height)
528 env->ThrowError("Merge: Images must have same width and height!");
529
530
1/2
✓ Branch 14 → 15 taken 7 times.
✗ Branch 14 → 24 not taken.
7 pixelsize = vi.ComponentSize();
531
1/2
✓ Branch 15 → 16 taken 7 times.
✗ Branch 15 → 24 not taken.
7 bits_per_pixel = vi.BitsPerComponent();
532
533
1/2
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 7 times.
7 if (weight<0.0f) weight=0.0f;
534
1/2
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 7 times.
7 if (weight>1.0f) weight=1.0f;
535 7 }
536
537
538 6 PVideoFrame __stdcall MergeAll::GetFrame(int n, IScriptEnvironment* env)
539 {
540 // Threshold: for integer clips snap based on the SIMD integer scale (0..32768);
541 // for float clips use exact float comparison.
542
1/2
✓ Branch 2 → 3 taken 6 times.
✗ Branch 2 → 4 not taken.
6 const int weight_i_simd = (bits_per_pixel != 32) ? (int)(weight * 32768.0f + 0.5f) : 0;
543
4/6
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 6 times.
✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 12 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 74 not taken.
6 if ((bits_per_pixel == 32) ? (weight == 0.0f) : (weight_i_simd == 0)) return child->GetFrame(n, env);
544
4/6
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 5 times.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 19 taken 4 times.
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 74 not taken.
5 if ((bits_per_pixel == 32) ? (weight == 1.0f) : (weight_i_simd >= 32768)) return clip->GetFrame(n, env);
545
546
1/2
✓ Branch 20 → 21 taken 4 times.
✗ Branch 20 → 74 not taken.
4 PVideoFrame src = child->GetFrame(n, env);
547
1/2
✓ Branch 22 → 23 taken 4 times.
✗ Branch 22 → 72 not taken.
4 PVideoFrame src2 = clip->GetFrame(n, env);
548
549
1/2
✓ Branch 23 → 24 taken 4 times.
✗ Branch 23 → 70 not taken.
4 env->MakeWritable(&src);
550
1/2
✓ Branch 25 → 26 taken 4 times.
✗ Branch 25 → 70 not taken.
4 BYTE* srcp = src->GetWritePtr();
551
1/2
✓ Branch 27 → 28 taken 4 times.
✗ Branch 27 → 70 not taken.
4 const BYTE* srcp2 = src2->GetReadPtr();
552
553
1/2
✓ Branch 29 → 30 taken 4 times.
✗ Branch 29 → 70 not taken.
4 const int src_pitch = src->GetPitch();
554
1/2
✓ Branch 31 → 32 taken 4 times.
✗ Branch 31 → 70 not taken.
4 const int src_rowsize = src->GetRowSize();
555
556
3/6
✓ Branch 33 → 34 taken 4 times.
✗ Branch 33 → 70 not taken.
✓ Branch 35 → 36 taken 4 times.
✗ Branch 35 → 70 not taken.
✓ Branch 36 → 37 taken 4 times.
✗ Branch 36 → 70 not taken.
4 merge_plane(srcp, srcp2, src_pitch, src2->GetPitch(), src_rowsize, src->GetHeight(), weight, bits_per_pixel, true, env);
557
558
2/4
✓ Branch 37 → 38 taken 4 times.
✗ Branch 37 → 70 not taken.
✓ Branch 38 → 39 taken 4 times.
✗ Branch 38 → 63 not taken.
4 if (vi.IsPlanar()) {
559 4 const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A};
560 4 const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A};
561
5/8
✓ Branch 39 → 40 taken 4 times.
✗ Branch 39 → 69 not taken.
✓ Branch 40 → 41 taken 1 time.
✓ Branch 40 → 43 taken 3 times.
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 69 not taken.
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 44 not taken.
4 const int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planesYUV : planesRGB;
562 // first plane is already processed
563
3/4
✓ Branch 60 → 61 taken 13 times.
✗ Branch 60 → 69 not taken.
✓ Branch 61 → 46 taken 9 times.
✓ Branch 61 → 62 taken 4 times.
13 for (int p = 1; p < vi.NumComponents(); p++) {
564 9 const int plane = planes[p];
565
7/14
✓ Branch 47 → 48 taken 9 times.
✗ Branch 47 → 69 not taken.
✓ Branch 49 → 50 taken 9 times.
✗ Branch 49 → 69 not taken.
✓ Branch 51 → 52 taken 9 times.
✗ Branch 51 → 69 not taken.
✓ Branch 53 → 54 taken 9 times.
✗ Branch 53 → 69 not taken.
✓ Branch 55 → 56 taken 9 times.
✗ Branch 55 → 69 not taken.
✓ Branch 57 → 58 taken 9 times.
✗ Branch 57 → 69 not taken.
✓ Branch 58 → 59 taken 9 times.
✗ Branch 58 → 69 not taken.
9 merge_plane(src->GetWritePtr(plane), src2->GetReadPtr(plane), src->GetPitch(plane), src2->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane), weight, bits_per_pixel, true, env);
566 }
567 }
568
569
1/2
✓ Branch 63 → 64 taken 4 times.
✗ Branch 63 → 70 not taken.
4 return src;
570 4 }
571
572
573 AVSValue __cdecl MergeAll::Create(AVSValue args, void* , IScriptEnvironment* env)
574 {
575 return new MergeAll(args[0].AsClip(), args[1].AsClip(), (float)args[2].AsFloat(0.5f), env);
576 }
577