GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 28.5% 101 / 0 / 354
Functions: 66.7% 4 / 0 / 6
Branches: 20.0% 16 / 0 / 80

filters/overlay/OF_exclusion.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 <avs/minmax.h>
39
40 #include <stdint.h>
41 #include <type_traits>
42
43 1 void OL_ExclusionImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {
44
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
1 if (bits_per_pixel == 8)
45 1 BlendImageMask<uint8_t, true>(base, overlay, mask);
46 else if(bits_per_pixel <= 16)
47 BlendImageMask<uint16_t, true>(base, overlay, mask);
48 //else if(bits_per_pixel == 32)
49 // BlendImageMask<float>(base, overlay, mask);
50 1 }
51
52 1 void OL_ExclusionImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {
53
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
1 if (bits_per_pixel == 8)
54 1 BlendImageMask<uint8_t, false>(base, overlay, nullptr);
55 else if(bits_per_pixel <= 16)
56 BlendImageMask<uint16_t, false>(base, overlay, nullptr);
57 //else if(bits_per_pixel == 32)
58 // BlendImage<float>(base, overlay);
59 1 }
60
61
62 template<typename pixel_t, bool maskMode>
63 2 void OL_ExclusionImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {
64 2 pixel_t* baseY = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_Y));
65 2 pixel_t* baseU = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_U));
66 2 pixel_t* baseV = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_V));
67
68 2 pixel_t* ovY = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_Y));
69 2 pixel_t* ovU = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_U));
70 2 pixel_t* ovV = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_V));
71
72 2 pixel_t* maskY = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_Y)) : nullptr;
73 2 pixel_t* maskU = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_U)) : nullptr;
74 2 pixel_t* maskV = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_V)) : nullptr;
75
76 2 const int half_pixel_value = (sizeof(pixel_t) == 1) ? 128 : (1 << (bits_per_pixel - 1));
77 2 const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;
78 2 const int xor_mask = max_pixel_value;
79 2 const int pixel_range = max_pixel_value + 1;
80 2 const int SHIFT = (sizeof(pixel_t) == 1) ? 5 : 5 + (bits_per_pixel - 8);
81 2 const int MASK_CORR_SHIFT = (sizeof(pixel_t) == 1) ? 8 : bits_per_pixel;
82 2 const int OPACITY_SHIFT = 8; // opacity always max 0..256
83 2 const int over32 = (1 << SHIFT); // 32
84 2 const int basepitch = (base->pitch) / sizeof(pixel_t);
85 2 const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);
86 2 const int maskpitch = maskMode ? (mask->pitch) / sizeof(pixel_t) : 0;
87
88 // avoid "uint16*uint16 can't get into int32" overflows
89 typedef typename std::conditional < sizeof(pixel_t) == 1, int, typename std::conditional < sizeof(pixel_t) == 2, int64_t, float>::type >::type result_t;
90
91 2 int w = base->w();
92 2 int h = base->h();
93
94
2/8
void OL_ExclusionImage::BlendImageMask<unsigned char, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 25 not taken.
void OL_ExclusionImage::BlendImageMask<unsigned char, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 28 not taken.
void OL_ExclusionImage::BlendImageMask<unsigned short, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 25 not taken.
void OL_ExclusionImage::BlendImageMask<unsigned short, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 28 not taken.
2 if (opacity == 256) {
95
4/8
void OL_ExclusionImage::BlendImageMask<unsigned char, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 24 → 12 taken 2 times.
✓ Branch 24 → 39 taken 1 time.
void OL_ExclusionImage::BlendImageMask<unsigned char, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 27 → 15 taken 2 times.
✓ Branch 27 → 42 taken 1 time.
void OL_ExclusionImage::BlendImageMask<unsigned short, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 24 → 12 not taken.
✗ Branch 24 → 39 not taken.
void OL_ExclusionImage::BlendImageMask<unsigned short, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 27 → 15 not taken.
✗ Branch 27 → 42 not taken.
6 for (int y = 0; y < h; y++) {
96
4/8
void OL_ExclusionImage::BlendImageMask<unsigned char, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 22 → 13 taken 8 times.
✓ Branch 22 → 23 taken 2 times.
void OL_ExclusionImage::BlendImageMask<unsigned char, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 25 → 16 taken 8 times.
✓ Branch 25 → 26 taken 2 times.
void OL_ExclusionImage::BlendImageMask<unsigned short, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 22 → 13 not taken.
✗ Branch 22 → 23 not taken.
void OL_ExclusionImage::BlendImageMask<unsigned short, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 25 → 16 not taken.
✗ Branch 25 → 26 not taken.
20 for (int x = 0; x < w; x++) {
97 16 result_t ovYx = ovY[x];
98 16 int Y = (int)(((baseY[x] ^ xor_mask)*ovYx + (ovYx ^ xor_mask)*baseY[x]) >> MASK_CORR_SHIFT);
99 16 int U = (int)(((baseU[x] ^ xor_mask)*ovYx + (ovYx ^ xor_mask)*baseU[x]) >> MASK_CORR_SHIFT);
100 16 int V = (int)(((baseV[x] ^ xor_mask)*ovYx + (ovYx ^ xor_mask)*baseV[x]) >> MASK_CORR_SHIFT);
101 if constexpr (maskMode) {
102 8 result_t mY = maskY[x];
103 8 result_t mU = maskU[x];
104 8 result_t mV = maskV[x];
105 8 Y = (int)(((Y*mY) + ((pixel_range - mY)*baseY[x])) >> MASK_CORR_SHIFT);
106 8 U = (int)(((U*mU) + ((pixel_range - mU)*baseU[x])) >> MASK_CORR_SHIFT);
107 8 V = (int)(((V*mV) + ((pixel_range - mV)*baseV[x])) >> MASK_CORR_SHIFT);
108 }
109
2/8
void OL_ExclusionImage::BlendImageMask<unsigned char, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 8 times.
void OL_ExclusionImage::BlendImageMask<unsigned char, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 19 taken 8 times.
void OL_ExclusionImage::BlendImageMask<unsigned short, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 16 not taken.
void OL_ExclusionImage::BlendImageMask<unsigned short, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 19 not taken.
16 if (Y>max_pixel_value) { // Apply overbrightness to UV
110 int multiplier = max(0,pixel_range + over32 -Y); // 0 to 32
111 U = ((U*( multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;
112 V = ((V*( multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;
113 Y = max_pixel_value;
114
2/8
void OL_ExclusionImage::BlendImageMask<unsigned char, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 19 taken 8 times.
void OL_ExclusionImage::BlendImageMask<unsigned char, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 22 taken 8 times.
void OL_ExclusionImage::BlendImageMask<unsigned short, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 19 not taken.
void OL_ExclusionImage::BlendImageMask<unsigned short, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 22 not taken.
16 } else if (Y<0) { // Apply superdark to UV
115 int multiplier = min(-Y,over32); // 0 to 32
116 U = ((U*(over32 - multiplier)) + (half_pixel_value*( multiplier)))>>SHIFT;
117 V = ((V*(over32 - multiplier)) + (half_pixel_value*( multiplier)))>>SHIFT;
118 Y = 0;
119 }
120 16 baseY[x] = (pixel_t)Y;
121 16 baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);
122 16 baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);
123 }
124 4 baseY += basepitch;
125 4 baseU += basepitch;
126 4 baseV += basepitch;
127
128 4 ovY += overlaypitch;
129 4 ovU += overlaypitch;
130 4 ovV += overlaypitch;
131
132 if constexpr (maskMode) {
133 2 maskY += maskpitch;
134 2 maskU += maskpitch;
135 2 maskV += maskpitch;
136 }
137 } // for y
138 } else {
139 for (int y = 0; y < h; y++) {
140 for (int x = 0; x < w; x++) {
141 result_t ovYx = ovY[x];
142 int Y = (int)(((baseY[x] ^ xor_mask)*ovYx + (ovYx^xor_mask)*baseY[x]) >> MASK_CORR_SHIFT);
143 int U = (int)(((baseU[x] ^ xor_mask)*ovYx + (ovYx^xor_mask)*baseU[x]) >> MASK_CORR_SHIFT);
144 int V = (int)(((baseV[x] ^ xor_mask)*ovYx + (ovYx^xor_mask)*baseV[x]) >> MASK_CORR_SHIFT);
145 if constexpr (maskMode) {
146 result_t mY = (maskY[x] * opacity) >> OPACITY_SHIFT;
147 result_t mU = (maskU[x] * opacity) >> OPACITY_SHIFT;
148 result_t mV = (maskV[x] * opacity) >> OPACITY_SHIFT;
149 Y = (int)(((Y*mY) + ((pixel_range - mY)*baseY[x])) >> MASK_CORR_SHIFT);
150 U = (int)(((U*mU) + ((pixel_range - mU)*baseU[x])) >> MASK_CORR_SHIFT);
151 V = (int)(((V*mV) + ((pixel_range - mV)*baseV[x])) >> MASK_CORR_SHIFT);
152 }
153 else {
154 Y = ((Y*opacity) + (inv_opacity*baseY[x])) >> OPACITY_SHIFT;
155 U = ((U*opacity) + (inv_opacity*baseU[x])) >> OPACITY_SHIFT;
156 V = ((V*opacity) + (inv_opacity*baseV[x])) >> OPACITY_SHIFT;
157 }
158 if (Y>max_pixel_value) { // Apply overbrightness to UV
159 int multiplier = max(0,pixel_range + over32 -Y); // 0 to 32
160 U = ((U*( multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;
161 V = ((V*( multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;
162 Y = max_pixel_value;
163 } else if (Y<0) { // Apply superdark to UV
164 int multiplier = min(-Y,over32); // 0 to 32
165 U = ((U*(over32 - multiplier)) + (half_pixel_value*( multiplier)))>>SHIFT;
166 V = ((V*(over32 - multiplier)) + (half_pixel_value*( multiplier)))>>SHIFT;
167 Y = 0;
168 }
169 baseY[x] = (pixel_t)Y;
170 baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);
171 baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);
172 }
173 baseY += basepitch;
174 baseU += basepitch;
175 baseV += basepitch;
176
177 ovY += overlaypitch;
178 ovU += overlaypitch;
179 ovV += overlaypitch;
180
181 if constexpr (maskMode) {
182 maskY += maskpitch;
183 maskU += maskpitch;
184 maskV += maskpitch;
185 }
186 } // for x
187 } // for y
188 2 }
189
190