GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 27.0% 10 / 0 / 37
Functions: 29.4% 5 / 0 / 17
Branches: 25.0% 4 / 0 / 16

filters/layer.h
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
37
38 // Avisynth filter: Layer
39 // by "poptones" (poptones@myrealbox.com)
40
41
42 #ifndef __Layer_H__
43 #define __Layer_H__
44
45 #include <avisynth.h>
46 #include <stdint.h>
47 #include "overlay/blend_common.h" // MaskMode enum + common blend infrastructure
48
49 // PLACEMENT_MPEG2 / PLACEMENT_MPEG1 defined in blend_common.h (included above)
50
51 // called only once, for all planes
52 // integer 8-16 bits version
53 using layer_yuv_lighten_darken_c_t = void (BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,
54 const BYTE* ovrp8, const BYTE* ovrp8_u, const BYTE* ovrp8_v, const BYTE* mask8,
55 int dst_pitch, int dst_pitchUV,
56 int overlay_pitch, int overlay_pitchUV,
57 int mask_pitch,
58 int width, int height, int level, int thresh,
59 int bits_per_pixel);
60
61 // 32 bit float version
62 using layer_yuv_lighten_darken_f_c_t = void (BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,
63 const BYTE* ovrp8, const BYTE* ovrp8_u, const BYTE* ovrp8_v, const BYTE* mask8,
64 int dst_pitch, int dst_pitchUV,
65 int overlay_pitch, int overlay_pitchUV,
66 int mask_pitch,
67 int width, int height, float level, float thresh);
68
69 using layer_planarrgb_lighten_darken_c_t = void(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int opacity_i, int thresh, int bits_per_pixel);
70 using layer_planarrgb_lighten_darken_f_c_t = void(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity, float thresh);
71
72 // YUV Mul function pointers
73 // integer 8-16 bits version
74 using layer_yuv_mul_c_t = void(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8,
75 int dst_pitch, int overlay_pitch, int mask_pitch,
76 int width, int height, int level, int bits_per_pixel);
77
78 // 32 bit float version
79 using layer_yuv_mul_f_c_t = void(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8,
80 int dst_pitch, int overlay_pitch, int mask_pitch,
81 int width, int height, float opacity);
82
83 // YUV mulovr ("Overlay-style multiply") function pointers.
84 // Overlay luma drives all planes: dark overlay Y darkens base Y and desaturates base UV.
85 // ovrp8: overlay Y plane only (UV planes of the overlay are not used).
86 // maskp8: overlay alpha plane at luma resolution (nullptr when has_alpha=false).
87 // integer 8-16 bits version
88 using layer_yuv_mulovr_c_t = void(
89 BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,
90 const BYTE* ovrp8,
91 const BYTE* maskp8,
92 int dst_pitch, int dst_pitchUV,
93 int overlay_pitch,
94 int mask_pitch,
95 int width, int height, int level, int bits_per_pixel);
96
97 // 32 bit float version
98 using layer_yuv_mulovr_f_c_t = void(
99 BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,
100 const BYTE* ovrp8,
101 const BYTE* maskp8,
102 int dst_pitch, int dst_pitchUV,
103 int overlay_pitch,
104 int mask_pitch,
105 int width, int height, float opacity);
106
107 // YUV Add function pointers
108 using layer_yuv_add_c_t = void(BYTE* dstp8, const BYTE* ovrp8, const BYTE* mask8,
109 int dst_pitch, int overlay_pitch, int mask_pitch,
110 int width, int height, int level, int bits_per_pixel);
111
112 using layer_yuv_add_f_c_t = void(BYTE* dstp8, const BYTE* ovrp8, const BYTE* mask8,
113 int dst_pitch, int overlay_pitch, int mask_pitch,
114 int width, int height, float opacity);
115
116 // integer 8-16 bits version
117 using layer_planarrgb_add_c_t = void(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int opacity_i, int bits_per_pixel);
118 // 32 bit float version
119 using layer_planarrgb_add_f_c_t = void(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity);
120
121 // Planar RGB mul function pointers
122 // integer 8-16 bits version
123 using layer_planarrgb_mul_c_t = void(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8,
124 int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int level, int bits_per_pixel);
125 // 32 bit float version
126 using layer_planarrgb_mul_f_c_t = void(BYTE** dstp8, const BYTE** ovrp8, const BYTE* maskp8,
127 int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity);
128
129 // Packed RGBA (RGB32 / RGB64) blend — magic-div arithmetic.
130 // opacity_i is in [0..max_pixel_value].
131 // maskp8: if non-null, points to a separate 1-channel (Y) alpha plane used as the
132 // per-pixel blend weight instead of ovrp8's own alpha component (offset +3).
133 // Used for Subtract: Create() extracts the original alpha before pre-inverting
134 // the overlay, then passes it here. Add passes nullptr → weight from ovrp8[x*4+3].
135 // mask_pitch: row stride of maskp8 in bytes (0 when maskp8 == nullptr).
136 // See masked_blend_packedrgba_c in blend_common.h for the reference implementation.
137 using layer_packedrgb_blend_c_t = void(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8,
138 int dst_pitch, int ovr_pitch, int mask_pitch,
139 int width, int height, int opacity_i);
140
141 /********************************************************************
142 ********************************************************************/
143
144 class Mask : public IClip
145 /**
146 * Class for overlaying a mask clip on a video clip
147 **/
148 {
149 public:
150 Mask(PClip _child1, PClip _child2, IScriptEnvironment* env);
151 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
152
153 inline virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override
154 {
155 child1->GetAudio(buf, start, count, env);
156 }
157 inline virtual const VideoInfo& __stdcall GetVideoInfo() override
158 {
159 return vi;
160 }
161 inline virtual bool __stdcall GetParity(int n) override
162 {
163 return child1->GetParity(n);
164 }
165
166 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
167
168 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
169 AVS_UNUSED(frame_range);
170 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
171 }
172
173 private:
174 const PClip child1, child2;
175 VideoInfo vi;
176 int mask_frames;
177 int pixelsize;
178 int bits_per_pixel;
179
180 };
181
182
183
184 class ColorKeyMask : public GenericVideoFilter
185 /**
186 * Class for setting a mask on a video clip based on a color key
187 **/
188 {
189 public:
190 ColorKeyMask(PClip _child, int _color, int _tolB, int _tolG, int _tolR, IScriptEnvironment* env);
191 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
192
193 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
194 AVS_UNUSED(frame_range);
195 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
196 }
197
198 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
199
200 private:
201 const int color, tolB, tolG, tolR;
202 uint64_t color64;
203 int tolB16, tolG16, tolR16;
204 int pixelsize;
205 int bits_per_pixel;
206 int max_pixel_value;
207
208 };
209
210
211
212 class ResetMask : public GenericVideoFilter
213 /**
214 * Class to set the mask to all-opaque
215 **/
216 {
217 public:
218 ResetMask(PClip _child, AVSValue _mask_f, AVSValue opacity_f, IScriptEnvironment* env);
219 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
220
221 2 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
222 AVS_UNUSED(frame_range);
223
1/2
✓ Branch 2 → 3 taken 2 times.
✗ Branch 2 → 4 not taken.
2 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
224 }
225
226 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
227
228 private:
229 float mask_f;
230 int mask;
231 };
232
233
234
235 class Invert : public GenericVideoFilter
236 /**
237 * Class to invert selected RGBA channels
238 **/
239 {
240 public:
241 Invert(PClip _child, const char* _channels, IScriptEnvironment* env);
242 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
243
244 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
245 AVS_UNUSED(frame_range);
246 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
247 }
248
249 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
250 private:
251 int mask;
252 bool doB, doG, doR, doA;
253 bool doY, doU, doV;
254
255 uint64_t mask64;
256 int pixelsize;
257 int bits_per_pixel; // 8,10..16
258 };
259
260
261
262 class ShowChannel : public GenericVideoFilter
263 /**
264 * Class to set the RGB components to the alpha mask
265 **/
266 {
267 public:
268 ShowChannel(PClip _child, const char* _pixel_type, int _channel, IScriptEnvironment* env);
269 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
270
271 1 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
272 AVS_UNUSED(frame_range);
273
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
1 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
274 }
275
276 static AVSValue __cdecl Create(AVSValue args, void* channel, IScriptEnvironment* env);
277 private:
278 int channel;
279 const int input_type;
280 const int pixelsize;
281 const int bits_per_pixel;
282 bool input_type_is_planar_rgb;
283 bool input_type_is_planar_rgba;
284 bool input_type_is_yuv;
285 bool input_type_is_yuva;
286 bool input_type_is_planar;
287 bool input_type_is_packed_rgb;
288 bool target_hasalpha;
289 bool source_hasalpha;
290 };
291
292
293
294
295 class MergeRGB : public GenericVideoFilter
296 /**
297 * Class to load the RGB components from specified clips
298 **/
299 {
300 public:
301 MergeRGB(PClip _child, PClip _blue, PClip _green, PClip _red, PClip _alpha,
302 const char* _pixel_type, IScriptEnvironment* env);
303 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
304
305 1 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
306 AVS_UNUSED(frame_range);
307
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
1 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
308 }
309
310 static AVSValue __cdecl Create(AVSValue args, void* mode, IScriptEnvironment* env);
311 private:
312 const PClip blue, green, red, alpha;
313 const VideoInfo& viB, & viG, & viR, & viA;
314 const char* myname;
315 };
316
317
318 enum
319 {
320 LIGHTEN = 0,
321 DARKEN = 1
322 };
323
324 // Simply Rec.601
325
326 // 15 bit scaled constants used for calculating luma mask from RGB
327 // original constants (3736,19235,9798) cause int32 overflow at 16 bits as sum()=32769
328 // modified constants (3736,19234,9798) O.K. at 16 bits as sum()=32768
329 // 32769 * 65535 + 16384 = 8000BFFF int32 overflow
330 // 32768 * 65535 + 16384 = 7FFFC000 OK
331 const int cyb = 3736; // int(0.114 * 32768 + 0.5); // 3736
332 const int cyg = 19235 - 1; // int(0.587 * 32768 + 0.5); // 19235
333 const int cyr = 9798; // int(0.299 * 32768 + 0.5); // 9798
334 // w/o correction: 32769
335 const float cyb_f = 0.114f;
336 const float cyg_f = 0.587f;
337 const float cyr_f = 0.299f;
338
339 class Layer : public IClip
340 /**
341 * Class for layering two clips on each other, combined by various functions
342 **/
343 {
344 public:
345 Layer(PClip _child1, PClip _child2, PClip _mask_child, const char _op[], int _lev, int _x, int _y,
346 int _t, bool _chroma, float _strength, int _placement, IScriptEnvironment* env);
347 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
348
349 inline virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override
350 {
351 child1->GetAudio(buf, start, count, env);
352 }
353 inline virtual const VideoInfo& __stdcall GetVideoInfo() override
354 {
355 return vi;
356 }
357 inline virtual bool __stdcall GetParity(int n) override
358 {
359 return child1->GetParity(n);
360 }
361
362 11 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
363 AVS_UNUSED(frame_range);
364
1/2
✓ Branch 2 → 3 taken 11 times.
✗ Branch 2 → 4 not taken.
11 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
365 }
366
367 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
368
369 private:
370 const PClip child1, child2;
371 // Pre-Subtract Invert alpha save: ExtractA of the overlay before all-channel Invert.
372 // Used as the per-pixel mask weight while ovrp[3] (inverted A) serves as the alpha target.
373 // nullptr for all ops other than Subtract, and for Subtract when overlay has no alpha.
374 const PClip mask_child;
375 VideoInfo vi;
376 const char* Op;
377 int levelB, ThresholdParam;
378 int ydest, xdest, ysrc, xsrc, ofsX, ofsY, ycount, xcount, overlay_frames;
379 const bool chroma; // use_chroma
380 bool hasAlpha; // overlay has alpha plane → per-pixel blend weight
381 bool process_alpha_channel; // both clips have alpha → blend A channel like colour channels
382 int bits_per_pixel;
383 float opacity; // like in "Overlay"
384 int placement; // PLACEMENT_MPEG1 or PLACEMENT_MPEG2
385 float ThresholdParam_f;
386 };
387
388
389
390 class Subtract : public IClip
391 /**
392 * Class for subtracting one clip from another
393 **/
394 {
395 public:
396 Subtract(PClip _child1, PClip _child2, IScriptEnvironment* env);
397 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
398
399 inline virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override
400 {
401 child1->GetAudio(buf, start, count, env);
402 }
403 1 inline virtual const VideoInfo& __stdcall GetVideoInfo() override
404 {
405 1 return vi;
406 }
407 inline virtual bool __stdcall GetParity(int n) override
408 {
409 return child1->GetParity(n);
410 }
411
412 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
413 AVS_UNUSED(frame_range);
414 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
415 }
416
417 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
418
419 private:
420 const PClip child1, child2;
421 VideoInfo vi;
422
423 // Common to all instances
424 static bool DiffFlag;
425 static BYTE LUT_Diff8[513];
426 int pixelsize;
427 int bits_per_pixel;
428
429 };
430
431
432
433 #endif // __Layer_H__
434