GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 451 / 0 / 451
Functions: 100.0% 8 / 0 / 8
Branches: 100.0% 48 / 0 / 48

filters/overlay/intel/OF_multiply_sse.cpp
Line Branch Exec Source
1 // Avisynth+
2 // https://avs-plus.net
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 #include "avisynth.h"
36 #include "OF_multiply_sse.h"
37
38 #include <stdint.h>
39 #include <type_traits>
40
41 // Intrinsics base header + really required extension headers
42 #if defined(_MSC_VER)
43 #include <intrin.h> // MSVC
44 #else
45 #include <x86intrin.h> // GCC/MinGW/Clang/LLVM
46 #endif
47 #include <smmintrin.h> // SSE4.1
48
49 template<typename pixel_t>
50 static AVS_FORCEINLINE __m128 Fourpixels_to_floats(const pixel_t* src) {
51 180 auto zero = _mm_setzero_si128();
52 __m128i srci;
53 if constexpr (sizeof(pixel_t) == 1) {
54 228 srci = _mm_cvtsi32_si128(*(uint32_t*)src);
55 114 srci = _mm_unpacklo_epi8(srci, zero);
56 114 srci = _mm_unpacklo_epi16(srci, zero);
57 }
58 else {
59 180 srci = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src));
60 180 srci = _mm_unpacklo_epi16(srci, zero);
61 }
62 294 return _mm_cvtepi32_ps(srci);
63 }
64
65 template<typename pixel_t>
66 static AVS_FORCEINLINE __m128 FourChromapixels_to_floats(const pixel_t* src, const __m128i half) {
67 108 auto zero = _mm_setzero_si128();
68 __m128i srci;
69 if constexpr (sizeof(pixel_t) == 1) {
70 120 srci = _mm_cvtsi32_si128(*(uint32_t*)src);
71 60 srci = _mm_unpacklo_epi8(srci, zero);
72 60 srci = _mm_unpacklo_epi16(srci, zero);
73 }
74 else {
75 108 srci = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src));
76 108 srci = _mm_unpacklo_epi16(srci, zero);
77 }
78 168 srci = _mm_sub_epi32(srci, half);
79 168 return _mm_cvtepi32_ps(srci);
80 }
81
82 template<typename pixel_t>
83 #if defined(GCC) || defined(CLANG)
84 __attribute__((__target__("sse4.1")))
85 #endif
86 static AVS_FORCEINLINE void Store_Fourpixels(pixel_t* dst, __m128 what, const __m128 rounder) {
87 84 what = _mm_add_ps(what, rounder); // round
88 84 __m128i si32 = _mm_cvttps_epi32(what); // truncate
89 84 __m128i result_16 = _mm_packus_epi32(si32, si32); // sse4.1
90 if constexpr (sizeof(pixel_t) == 1) {
91 30 __m128i result_8 = _mm_packus_epi16(result_16, result_16);
92 30 *(uint32_t*)(dst) = _mm_cvtsi128_si32(result_8);
93 }
94 else {
95 _mm_storel_epi64(reinterpret_cast<__m128i*>(dst), result_16);
96 }
97 84 }
98
99 template<typename pixel_t>
100 #if defined(GCC) || defined(CLANG)
101 __attribute__((__target__("sse4.1")))
102 #endif
103 static AVS_FORCEINLINE void Store_FourChromapixels(pixel_t* dst, __m128 what, const __m128 half_plus_rounder) {
104 168 what = _mm_add_ps(what, half_plus_rounder); // chroma offset back with rounder
105 168 __m128i si32 = _mm_cvttps_epi32(what); // truncate
106 168 __m128i result_16 = _mm_packus_epi32(si32, si32); // sse4.1
107 if constexpr (sizeof(pixel_t) == 1) {
108 60 __m128i result_8 = _mm_packus_epi16(result_16, result_16);
109 60 *(uint32_t*)(dst) = _mm_cvtsi128_si32(result_8);
110 }
111 else {
112 _mm_storel_epi64(reinterpret_cast<__m128i*>(dst), result_16);
113 }
114 168 }
115
116
117 template<typename pixel_t, bool opacity_is_full, bool has_mask>
118 #if defined(GCC) || defined(CLANG)
119 __attribute__((__target__("sse4.1")))
120 #endif
121 14 void of_multiply_sse41(
122 int bits_per_pixel,
123 const float opacity_f,
124 const int opacity,
125 int width, int height,
126 const pixel_t* ovY,
127 int overlaypitch,
128 pixel_t* baseY, pixel_t* baseU, pixel_t* baseV,
129 int basepitch,
130 const pixel_t* maskY, const pixel_t* maskU, const pixel_t* maskV,
131 int maskpitch
132 )
133 {
134 14 const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;
135 14 const float factor = 1.0f / max_pixel_value;
136 14 const int half_i = sizeof(pixel_t) == 1 ? 128 : 1 << (bits_per_pixel - 1);
137 14 const float half_f = (float)half_i;
138
139 float factor_mul_opacity;
140 if constexpr (opacity_is_full)
141 6 factor_mul_opacity = factor * 1.0f;
142 else
143 8 factor_mul_opacity = factor * opacity_f;
144
145 14 auto opacity_simd = _mm_set1_ps(opacity_f);
146 14 auto factor_simd = _mm_set1_ps(factor);
147 14 auto factor_mul_opacity_simd = _mm_set1_ps(factor_mul_opacity);
148 14 auto one_ps_simd = _mm_set1_ps(1.0f);
149 14 const __m128i half_i_simd = _mm_set1_epi32(half_i);
150 23 const __m128 half_and_rounder_simd = _mm_set1_ps(half_f + 0.5f);
151 14 const __m128 rounder_simd = _mm_set1_ps(0.5f);
152
153 14 const int wMod4 = width / 4 * 4;
154
155 // start processing
156
16/16
void of_multiply_sse41<unsigned char, false, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 133 → 19 taken 3 times.
✓ Branch 133 → 134 taken 1 time.
void of_multiply_sse41<unsigned char, false, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 189 → 19 taken 6 times.
✓ Branch 189 → 190 taken 2 times.
void of_multiply_sse41<unsigned char, true, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 133 → 19 taken 3 times.
✓ Branch 133 → 134 taken 1 time.
void of_multiply_sse41<unsigned char, true, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 189 → 19 taken 3 times.
✓ Branch 189 → 190 taken 1 time.
void of_multiply_sse41<unsigned short, false, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 124 → 19 taken 9 times.
✓ Branch 124 → 125 taken 3 times.
void of_multiply_sse41<unsigned short, false, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 180 → 19 taken 6 times.
✓ Branch 180 → 181 taken 2 times.
void of_multiply_sse41<unsigned short, true, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 124 → 19 taken 6 times.
✓ Branch 124 → 125 taken 2 times.
void of_multiply_sse41<unsigned short, true, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 180 → 19 taken 6 times.
✓ Branch 180 → 181 taken 2 times.
56 for (int y = 0; y < height; y++) {
157
16/16
void of_multiply_sse41<unsigned char, false, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 128 → 20 taken 6 times.
✓ Branch 128 → 129 taken 3 times.
void of_multiply_sse41<unsigned char, false, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 184 → 20 taken 12 times.
✓ Branch 184 → 185 taken 6 times.
void of_multiply_sse41<unsigned char, true, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 128 → 20 taken 6 times.
✓ Branch 128 → 129 taken 3 times.
void of_multiply_sse41<unsigned char, true, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 184 → 20 taken 6 times.
✓ Branch 184 → 185 taken 3 times.
void of_multiply_sse41<unsigned short, false, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 119 → 20 taken 18 times.
✓ Branch 119 → 120 taken 9 times.
void of_multiply_sse41<unsigned short, false, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 175 → 20 taken 12 times.
✓ Branch 175 → 176 taken 6 times.
void of_multiply_sse41<unsigned short, true, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 119 → 20 taken 12 times.
✓ Branch 119 → 120 taken 6 times.
void of_multiply_sse41<unsigned short, true, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 175 → 20 taken 12 times.
✓ Branch 175 → 176 taken 6 times.
126 for (int x = 0; x < wMod4; x += 4) {
158 __m128 Y, U, V;
159 // 4 pixels at a time. 8 or 16 bits to floats
160 168 __m128 ovY_ps = Fourpixels_to_floats<pixel_t>(ovY + x);
161
162 // generic, 8-16 bits
163 if constexpr (has_mask) {
164 __m128 final_opacity;
165 42 auto overlay_opacity_minus1 = _mm_sub_ps(_mm_mul_ps(ovY_ps, factor_simd), one_ps_simd); // ovY[x] * factor - 1.0f;
166
167 84 __m128 maskY_ps = Fourpixels_to_floats<pixel_t>(maskY + x);
168 42 final_opacity = _mm_mul_ps(maskY_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity;
169 42 auto Yfactor = _mm_add_ps(one_ps_simd, _mm_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity;
170 84 __m128 baseY_ps = Fourpixels_to_floats<pixel_t>(baseY + x);
171 42 Y = _mm_mul_ps(baseY_ps, Yfactor); // Y = (int)(baseY[x] * Yfactor);
172
173 84 __m128 maskU_ps = Fourpixels_to_floats<pixel_t>(maskU + x);
174 42 final_opacity = _mm_mul_ps(maskU_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity;
175 42 auto Ufactor = _mm_add_ps(one_ps_simd, _mm_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity;
176 84 __m128 baseU_ps = FourChromapixels_to_floats<pixel_t>(baseU + x, half_i_simd);
177 42 U = _mm_mul_ps(baseU_ps, Ufactor); // U = (int)((baseU[x] - half_i) * Ufactor) not yet: + half_i;
178
179 84 __m128 maskV_ps = Fourpixels_to_floats<pixel_t>(maskV + x);
180 42 final_opacity = _mm_mul_ps(maskV_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity;
181 42 auto Vfactor = _mm_add_ps(one_ps_simd, _mm_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity;
182 84 __m128 baseV_ps = FourChromapixels_to_floats<pixel_t>(baseV + x, half_i_simd);
183 42 V = _mm_mul_ps(baseV_ps, Vfactor); // V = (int)((baseV[x] - half_i) * Vfactor) not yet: + half_i;
184
185 }
186 else {
187 84 auto overlay_opacity_minus1 = _mm_sub_ps(_mm_mul_ps(ovY_ps, factor_simd), one_ps_simd); // ovY[x] * factor - 1.0f;
188 42 auto common_factor = _mm_add_ps(one_ps_simd, _mm_mul_ps(overlay_opacity_minus1, opacity_simd)); // 1.0f + overlay_opacity_minus1 * opacity_f;
189
190 42 auto Yfactor = common_factor;
191 84 __m128 baseY_ps = Fourpixels_to_floats<pixel_t>(baseY + x);
192 42 Y = _mm_mul_ps(baseY_ps, Yfactor); // Y = (int)(baseY[x] * Yfactor);
193
194 42 auto Ufactor = common_factor;
195 84 __m128 baseU_ps = FourChromapixels_to_floats<pixel_t>(baseU + x, half_i_simd);
196 42 U = _mm_mul_ps(baseU_ps, Ufactor); // U = (int)((baseU[x] - half_i) * Ufactor) not yet: + half_i;
197
198 42 auto Vfactor = common_factor;
199 84 __m128 baseV_ps = FourChromapixels_to_floats<pixel_t>(baseV + x, half_i_simd);
200 42 V = _mm_mul_ps(baseV_ps, Vfactor); // V = (int)((baseV[x] - half_i) * Vfactor) not yet: + half_i;
201
202 }
203
204 84 Store_Fourpixels<pixel_t>(baseY + x, Y, rounder_simd);
205 84 Store_FourChromapixels<pixel_t>(baseU + x, U, half_and_rounder_simd);
206 84 Store_FourChromapixels<pixel_t>(baseV + x, V, half_and_rounder_simd);
207
208 }
209
210
16/16
void of_multiply_sse41<unsigned char, false, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 131 → 130 taken 9 times.
✓ Branch 131 → 132 taken 3 times.
void of_multiply_sse41<unsigned char, false, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 187 → 186 taken 18 times.
✓ Branch 187 → 188 taken 6 times.
void of_multiply_sse41<unsigned char, true, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 131 → 130 taken 9 times.
✓ Branch 131 → 132 taken 3 times.
void of_multiply_sse41<unsigned char, true, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 187 → 186 taken 9 times.
✓ Branch 187 → 188 taken 3 times.
void of_multiply_sse41<unsigned short, false, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 122 → 121 taken 27 times.
✓ Branch 122 → 123 taken 9 times.
void of_multiply_sse41<unsigned short, false, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 178 → 177 taken 18 times.
✓ Branch 178 → 179 taken 6 times.
void of_multiply_sse41<unsigned short, true, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 122 → 121 taken 18 times.
✓ Branch 122 → 123 taken 6 times.
void of_multiply_sse41<unsigned short, true, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 178 → 177 taken 18 times.
✓ Branch 178 → 179 taken 6 times.
168 for (int x = wMod4; x < width; x++) {
211 // from of_mul_c
212 int Y, U, V;
213
214 // generic, 8-16 bits
215 // This part re-appears in SSE2 code (non mod4 end-of-line fragment)
216 // Unlike the old integer version here is proper rounding
217 126 const float overlay_opacity_minus1 = ovY[x] * factor - 1.0f;
218 if constexpr (has_mask) {
219 float final_opacity;
220
221 63 final_opacity = maskY[x] * factor_mul_opacity;
222 63 auto Yfactor = 1.0f + overlay_opacity_minus1 * final_opacity;
223 63 Y = (int)(baseY[x] * Yfactor + 0.5f);
224
225 63 final_opacity = maskU[x] * factor_mul_opacity;
226 63 auto Ufactor = 1.0f + overlay_opacity_minus1 * final_opacity;
227 63 U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f);
228
229 63 final_opacity = maskV[x] * factor_mul_opacity;
230 63 auto Vfactor = 1.0f + overlay_opacity_minus1 * final_opacity;
231 63 V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f);
232 }
233 else {
234 63 const float common_factor = 1.0f + overlay_opacity_minus1 * opacity_f;
235
236 63 auto Yfactor = common_factor;
237 63 Y = (int)((float)baseY[x] * Yfactor + 0.5f);
238
239 63 auto Ufactor = common_factor;
240 63 U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f);
241
242 63 auto Vfactor = common_factor;
243 63 V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f);
244
245 }
246
247 126 baseU[x] = (pixel_t)U;
248 126 baseV[x] = (pixel_t)V;
249 126 baseY[x] = (pixel_t)Y;
250 }
251
252 if constexpr (has_mask) {
253 21 maskY += maskpitch;
254 21 maskU += maskpitch;
255 21 maskV += maskpitch;
256 }
257
258 42 baseY += basepitch;
259 42 baseU += basepitch;
260 42 baseV += basepitch;
261
262 42 ovY += overlaypitch;
263
264 }
265 14 }
266
267
268 // instantiate
269 template
270 #if defined(GCC) || defined(CLANG)
271 __attribute__((__target__("sse4.1")))
272 #endif
273 void of_multiply_sse41<uint8_t, false, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,
274 const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);
275
276 template
277 #if defined(GCC) || defined(CLANG)
278 __attribute__((__target__("sse4.1")))
279 #endif
280 void of_multiply_sse41<uint8_t, false, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,
281 const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);
282
283 template
284 #if defined(GCC) || defined(CLANG)
285 __attribute__((__target__("sse4.1")))
286 #endif
287 void of_multiply_sse41<uint8_t, true, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,
288 const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);
289
290 template
291 #if defined(GCC) || defined(CLANG)
292 __attribute__((__target__("sse4.1")))
293 #endif
294 void of_multiply_sse41<uint8_t, true, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,
295 const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);
296
297 template
298 #if defined(GCC) || defined(CLANG)
299 __attribute__((__target__("sse4.1")))
300 #endif
301 void of_multiply_sse41<uint16_t, false, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,
302 const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);
303
304 template
305 #if defined(GCC) || defined(CLANG)
306 __attribute__((__target__("sse4.1")))
307 #endif
308 void of_multiply_sse41<uint16_t, false, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,
309 const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);
310
311 template
312 #if defined(GCC) || defined(CLANG)
313 __attribute__((__target__("sse4.1")))
314 #endif
315 void of_multiply_sse41<uint16_t, true, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,
316 const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);
317
318 template
319 #if defined(GCC) || defined(CLANG)
320 __attribute__((__target__("sse4.1")))
321 #endif
322 void of_multiply_sse41<uint16_t, true, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,
323 const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);
324