GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 34.8% 144 / 0 / 414
Functions: 60.0% 6 / 0 / 10
Branches: 22.4% 26 / 0 / 116

filters/overlay/OF_darken.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
39 #include "blend_common.h"
40 #ifdef INTEL_INTRINSICS
41 #include "intel/blend_common_sse.h"
42 #endif
43
44 #include <stdint.h>
45 #include <type_traits>
46
47 4 void OL_DarkenImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {
48
2/2
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 7 taken 2 times.
4 if(of_mode == OF_Darken) {
49
1/2
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 5 not taken.
2 if (bits_per_pixel == 8)
50 2 BlendImageMask<uint8_t, true, true>(base, overlay, mask);
51 else if(bits_per_pixel <= 16)
52 BlendImageMask<uint16_t, true, true>(base, overlay, mask);
53 //else if(bits_per_pixel == 32)
54 // BlendImageMask<float>(base, overlay, mask);
55 }
56 else {
57 // OF_Lighten
58
1/2
✓ Branch 7 → 8 taken 2 times.
✗ Branch 7 → 9 not taken.
2 if (bits_per_pixel == 8)
59 2 BlendImageMask<uint8_t, true, false>(base, overlay, mask);
60 else if(bits_per_pixel <= 16)
61 BlendImageMask<uint16_t, true, false>(base, overlay, mask);
62 //else if(bits_per_pixel == 32)
63 // BlendImageMask<float>(base, overlay, mask);
64 }
65 4 }
66
67 4 void OL_DarkenImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {
68
2/2
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 7 taken 2 times.
4 if(of_mode == OF_Darken) {
69
1/2
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 5 not taken.
2 if (bits_per_pixel == 8)
70 2 BlendImageMask<uint8_t, false, true>(base, overlay, nullptr);
71 else if(bits_per_pixel <= 16)
72 BlendImageMask<uint16_t, false, true>(base, overlay, nullptr);
73 //else if(bits_per_pixel == 32)
74 // BlendImageMask<float>(base, overlay, mask);
75 }
76 else {
77 // OF_Lighten
78
1/2
✓ Branch 7 → 8 taken 2 times.
✗ Branch 7 → 9 not taken.
2 if (bits_per_pixel == 8)
79 2 BlendImageMask<uint8_t, false, false>(base, overlay, nullptr);
80 else if(bits_per_pixel <= 16)
81 BlendImageMask<uint16_t, false, false>(base, overlay, nullptr);
82 //else if(bits_per_pixel == 32)
83 // BlendImageMask<float>(base, overlay, mask);
84 }
85 4 }
86
87 // float not supported yet
88 template<typename pixel_t, bool maskMode, bool of_darken>
89 8 void OL_DarkenImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {
90
91 8 pixel_t* baseY = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_Y));
92 8 pixel_t* baseU = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_U));
93 8 pixel_t* baseV = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_V));
94
95 8 pixel_t* ovY = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_Y));
96 8 pixel_t* ovU = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_U));
97 8 pixel_t* ovV = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_V));
98
99 8 pixel_t* maskY = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_Y)) : nullptr;
100 8 pixel_t* maskU = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_U)) : nullptr;
101 8 pixel_t* maskV = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_V)) : nullptr;
102
103 8 const int half_pixel_value = (sizeof(pixel_t) == 1) ? 128 : (1 << (bits_per_pixel - 1));
104 8 const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;
105 8 const int pixel_range = max_pixel_value + 1;
106 8 const int MASK_CORR_SHIFT = (sizeof(pixel_t) == 1) ? 8 : bits_per_pixel;
107 8 const int OPACITY_SHIFT = 8; // opacity always max 0..256
108 8 const int basepitch = (base->pitch) / sizeof(pixel_t);
109 8 const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);
110 8 const int maskpitch = maskMode ? (mask->pitch) / sizeof(pixel_t) : 0;
111
112 // avoid "uint16*uint16 can't get into int32" overflows
113 using result_t = typename std::conditional<sizeof(pixel_t) == 1, int, int64_t>::type;
114
115 8 int w = base->w();
116 8 int h = base->h();
117
4/16
void OL_DarkenImage::BlendImageMask<unsigned char, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 10 → 11 taken 2 times.
✗ Branch 10 → 18 not taken.
void OL_DarkenImage::BlendImageMask<unsigned char, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 10 → 11 taken 2 times.
✗ Branch 10 → 18 not taken.
void OL_DarkenImage::BlendImageMask<unsigned char, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 2 times.
✗ Branch 13 → 22 not taken.
void OL_DarkenImage::BlendImageMask<unsigned char, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 13 → 14 taken 2 times.
✗ Branch 13 → 22 not taken.
void OL_DarkenImage::BlendImageMask<unsigned short, false, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
void OL_DarkenImage::BlendImageMask<unsigned short, false, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
void OL_DarkenImage::BlendImageMask<unsigned short, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 22 not taken.
void OL_DarkenImage::BlendImageMask<unsigned short, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 22 not taken.
8 if (opacity == 256) {
118 // full opacity - optimize
119 if constexpr (maskMode) {
120 // opacity == 256 && maskMode
121
4/8
void OL_DarkenImage::BlendImageMask<unsigned char, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 21 → 15 taken 4 times.
✓ Branch 21 → 30 taken 2 times.
void OL_DarkenImage::BlendImageMask<unsigned char, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 21 → 15 taken 4 times.
✓ Branch 21 → 30 taken 2 times.
void OL_DarkenImage::BlendImageMask<unsigned short, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 21 → 15 not taken.
✗ Branch 21 → 30 not taken.
void OL_DarkenImage::BlendImageMask<unsigned short, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 21 → 15 not taken.
✗ Branch 21 → 30 not taken.
12 for (int y = 0; y < h; y++) {
122
4/8
void OL_DarkenImage::BlendImageMask<unsigned char, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 19 → 16 taken 16 times.
✓ Branch 19 → 20 taken 4 times.
void OL_DarkenImage::BlendImageMask<unsigned char, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 19 → 16 taken 16 times.
✓ Branch 19 → 20 taken 4 times.
void OL_DarkenImage::BlendImageMask<unsigned short, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
void OL_DarkenImage::BlendImageMask<unsigned short, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
40 for (int x = 0; x < w; x++) {
123 bool cmp;
124 if constexpr (of_darken)
125 16 cmp = ovY[x] < baseY[x];
126 else
127 16 cmp = ovY[x] > baseY[x];
128
4/8
void OL_DarkenImage::BlendImageMask<unsigned char, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 16 → 17 taken 8 times.
✓ Branch 16 → 18 taken 8 times.
void OL_DarkenImage::BlendImageMask<unsigned char, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✓ Branch 16 → 17 taken 8 times.
✓ Branch 16 → 18 taken 8 times.
void OL_DarkenImage::BlendImageMask<unsigned short, true, false>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
void OL_DarkenImage::BlendImageMask<unsigned short, true, true>(ImageOverlayInternal*, ImageOverlayInternal*, ImageOverlayInternal*):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
32 if (cmp) {
129 16 result_t maskYx = maskY[x];
130 16 result_t maskUx = maskU[x];
131 16 result_t maskVx = maskV[x];
132 16 baseY[x] = (pixel_t)((((pixel_range - maskYx)*baseY[x]) + (maskYx * ovY[x] + half_pixel_value)) >> MASK_CORR_SHIFT);
133 16 baseU[x] = (pixel_t)((((pixel_range - maskUx)*baseU[x]) + (maskUx * ovU[x] + half_pixel_value)) >> MASK_CORR_SHIFT);
134 16 baseV[x] = (pixel_t)((((pixel_range - maskVx)*baseV[x]) + (maskVx * ovV[x] + half_pixel_value)) >> MASK_CORR_SHIFT);
135 }
136 }
137 8 maskY += maskpitch;
138 8 maskU += maskpitch;
139 8 maskV += maskpitch;
140
141 8 baseY += basepitch;
142 8 baseU += basepitch;
143 8 baseV += basepitch;
144
145 8 ovY += overlaypitch;
146 8 ovU += overlaypitch;
147 8 ovV += overlaypitch;
148 }
149 } else {
150 // opacity == 256 && !maskMode
151 if constexpr (of_darken) {
152 #ifdef INTEL_INTRINSICS
153
1/2
✓ Branch 12 → 13 taken 2 times.
✗ Branch 12 → 14 not taken.
2 if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_SSE4_1)) {
154 2 overlay_darken_sse41((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);
155 } else if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_SSE2)) {
156 overlay_darken_sse2((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);
157 } else
158 #ifdef X86_32
159 if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_MMX)) {
160 overlay_darken_mmx((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);
161 } else
162 #endif
163 #endif
164 {
165
166 overlay_darken_c<pixel_t>((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);
167 }
168 } else {
169 // OF_Lighten
170 #ifdef INTEL_INTRINSICS
171
1/2
✓ Branch 12 → 13 taken 2 times.
✗ Branch 12 → 14 not taken.
2 if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_SSE4_1)) {
172 2 overlay_lighten_sse41((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);
173 } else if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_SSE2)) {
174 overlay_lighten_sse2((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);
175 } else
176 #ifdef X86_32
177 if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_MMX)) {
178 overlay_lighten_mmx((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);
179 } else
180 #endif
181 #endif
182 {
183 overlay_lighten_c<pixel_t>((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);
184 }
185 }
186
187 }
188 } else {
189 // opacity != 256 && maskMode
190 for (int y = 0; y < h; y++) {
191 for (int x = 0; x < w; x++) {
192 bool cmp;
193 if constexpr (of_darken)
194 cmp = ovY[x] < baseY[x];
195 else
196 cmp = ovY[x] > baseY[x];
197 if (cmp) {
198 if constexpr (maskMode) {
199 result_t mY = (maskY[x] * opacity) >> OPACITY_SHIFT;
200 result_t mU = (maskU[x] * opacity) >> OPACITY_SHIFT;
201 result_t mV = (maskV[x] * opacity) >> OPACITY_SHIFT;
202 baseY[x] = (pixel_t)((((pixel_range - mY)*baseY[x]) + (mY*ovY[x] + half_pixel_value)) >> MASK_CORR_SHIFT);
203 baseU[x] = (pixel_t)((((pixel_range - mU)*baseU[x]) + (mU*ovU[x] + half_pixel_value)) >> MASK_CORR_SHIFT);
204 baseV[x] = (pixel_t)((((pixel_range - mV)*baseV[x]) + (mV*ovV[x] + half_pixel_value)) >> MASK_CORR_SHIFT);
205 }
206 else {
207 baseY[x] = (pixel_t)(((inv_opacity*baseY[x]) + (opacity*ovY[x] + 128)) >> OPACITY_SHIFT); // 128: half 256 opacity mul rounding
208 baseU[x] = (pixel_t)(((inv_opacity*baseU[x]) + (opacity*ovU[x] + 128)) >> OPACITY_SHIFT);
209 baseV[x] = (pixel_t)(((inv_opacity*baseV[x]) + (opacity*ovV[x] + 128)) >> OPACITY_SHIFT);
210 }
211 }
212 }
213 baseY += basepitch;
214 baseU += basepitch;
215 baseV += basepitch;
216
217 ovY += overlaypitch;
218 ovU += overlaypitch;
219 ovV += overlaypitch;
220
221 if constexpr (maskMode) {
222 maskY += maskpitch;
223 maskU += maskpitch;
224 maskV += maskpitch;
225 }
226 }
227 }
228 8 }
229
230