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/16void 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/16void 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/16void 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 |