1 /*
2 * Simd Library (http://ermig1979.github.io/Simd).
3 *
4 * Copyright (c) 2011-2019 Yermalayeu Ihar,
5 * 2014-2018 Antonenka Mikhail,
6 * 2018-2018 Radchenko Andrey,
7 * 2019-2019 Facundo Galan.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27 #include "Simd/SimdConfig.h"
28
29 #ifndef SIMD_LIB_CPP
30 #define SIMD_LIB_CPP
31 #endif
32
33 #if defined(WIN32) && !defined(SIMD_STATIC)
34
35 #define SIMD_EXPORTS
36 #ifndef NOMINMAX
37 #define NOMINMAX
38 #endif
39 #include <windows.h>
40
DllMain(HMODULE hModule,DWORD dwReasonForCall,LPVOID lpReserved)41 BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
42 {
43 switch (dwReasonForCall)
44 {
45 case DLL_PROCESS_DETACH:
46 case DLL_PROCESS_ATTACH:
47 case DLL_THREAD_ATTACH:
48 case DLL_THREAD_DETACH:
49 return TRUE;
50 }
51 return TRUE;
52 }
53 #endif//WIN32
54
55 #include "Simd/SimdLib.h"
56
57 #include "Simd/SimdMemory.h"
58 #include "Simd/SimdEnable.h"
59 #include "Simd/SimdConst.h"
60 #include "Simd/SimdCpu.h"
61 #include "Simd/SimdLog.h"
62
63 #include "Simd/SimdResizer.h"
64 #include "Simd/SimdGaussianBlur.h"
65
66 #include "Simd/SimdBase.h"
67 #include "Simd/SimdSse1.h"
68 #include "Simd/SimdSse2.h"
69 #include "Simd/SimdSsse3.h"
70 #include "Simd/SimdAvx1.h"
71 #include "Simd/SimdAvx2.h"
72 #include "Simd/SimdNeon.h"
73
74 #if !defined(SIMD_VERSION)
75 #include "Simd/SimdVersion.h"
76 #endif
77
SimdVersion()78 SIMD_API const char * SimdVersion()
79 {
80 return SIMD_VERSION;
81 }
82
83 using namespace Simd;
84
SimdPerformanceStatistic()85 SIMD_API const char * SimdPerformanceStatistic()
86 {
87 #if defined(SIMD_PERFORMANCE_STATISTIC) && defined(NDEBUG)
88 return Base::PerformanceMeasurerStorage::s_storage.PerformanceStatistic();
89 #else
90 return "";
91 #endif
92 }
93
SimdAllocate(size_t size,size_t align)94 SIMD_API void * SimdAllocate(size_t size, size_t align)
95 {
96 return Allocate(size, align);
97 }
98
SimdFree(void * ptr)99 SIMD_API void SimdFree(void * ptr)
100 {
101 Free(ptr);
102 }
103
SimdAlign(size_t size,size_t align)104 SIMD_API size_t SimdAlign(size_t size, size_t align)
105 {
106 return AlignHi(size, align);
107 }
108
SimdAlignment()109 SIMD_API size_t SimdAlignment()
110 {
111 return Simd::ALIGNMENT;
112 }
113
SimdRelease(void * context)114 SIMD_API void SimdRelease(void * context)
115 {
116 delete (Deletable*)context;
117 }
118
SimdGetFastMode()119 SIMD_API SimdBool SimdGetFastMode()
120 {
121 #ifdef SIMD_SSE_ENABLE
122 if (Sse::Enable)
123 return Sse::GetFastMode();
124 else
125 #endif
126 #ifdef SIMD_NEON_ENABLE
127 if (Neon::Enable)
128 return Neon::GetFastMode();
129 else
130 #endif
131 return SimdFalse;
132 }
133
SimdSetFastMode(SimdBool value)134 SIMD_API void SimdSetFastMode(SimdBool value)
135 {
136 #ifdef SIMD_SSE_ENABLE
137 if (Sse::Enable)
138 Sse::SetFastMode(value);
139 #endif
140 #ifdef SIMD_NEON_ENABLE
141 if (Neon::Enable)
142 Neon::SetFastMode(value);
143 #endif
144 }
145
SimdBgraToBgr(const uint8_t * bgra,size_t width,size_t height,size_t bgraStride,uint8_t * bgr,size_t bgrStride)146 SIMD_API void SimdBgraToBgr(const uint8_t * bgra, size_t width, size_t height, size_t bgraStride, uint8_t * bgr, size_t bgrStride)
147 {
148 #ifdef SIMD_SSSE3_ENABLE
149 if(Ssse3::Enable && width >= Ssse3::A)
150 Ssse3::BgraToBgr(bgra, width, height, bgraStride, bgr, bgrStride);
151 else
152 #endif
153 #ifdef SIMD_NEON_ENABLE
154 if (Neon::Enable && width >= Neon::A)
155 Neon::BgraToBgr(bgra, width, height, bgraStride, bgr, bgrStride);
156 else
157 #endif
158 Base::BgraToBgr(bgra, width, height, bgraStride, bgr, bgrStride);
159 }
160
SimdBgraToGray(const uint8_t * bgra,size_t width,size_t height,size_t bgraStride,uint8_t * gray,size_t grayStride)161 SIMD_API void SimdBgraToGray(const uint8_t *bgra, size_t width, size_t height, size_t bgraStride, uint8_t *gray, size_t grayStride)
162 {
163 #ifdef SIMD_AVX2_ENABLE
164 if(Avx2::Enable && width >= Avx2::A)
165 Avx2::BgraToGray(bgra, width, height, bgraStride, gray, grayStride);
166 else
167 #endif
168 #ifdef SIMD_SSE2_ENABLE
169 if(Sse2::Enable && width >= Sse2::A)
170 Sse2::BgraToGray(bgra, width, height, bgraStride, gray, grayStride);
171 else
172 #endif
173 #ifdef SIMD_NEON_ENABLE
174 if (Neon::Enable && width >= Neon::HA)
175 Neon::BgraToGray(bgra, width, height, bgraStride, gray, grayStride);
176 else
177 #endif
178 Base::BgraToGray(bgra, width, height, bgraStride, gray, grayStride);
179 }
180
SimdRgbaToGray(const uint8_t * rgba,size_t width,size_t height,size_t rgbaStride,uint8_t * gray,size_t grayStride)181 SIMD_API void SimdRgbaToGray(const uint8_t *rgba, size_t width, size_t height, size_t rgbaStride, uint8_t *gray, size_t grayStride)
182 {
183 #ifdef SIMD_AVX2_ENABLE
184 if(Avx2::Enable && width >= Avx2::A)
185 Avx2::RgbaToGray(rgba, width, height, rgbaStride, gray, grayStride);
186 else
187 #endif
188 #ifdef SIMD_SSE2_ENABLE
189 if(Sse2::Enable && width >= Sse2::A)
190 Sse2::RgbaToGray(rgba, width, height, rgbaStride, gray, grayStride);
191 else
192 #endif
193 #ifdef SIMD_NEON_ENABLE
194 if (Neon::Enable && width >= Neon::HA)
195 Neon::RgbaToGray(rgba, width, height, rgbaStride, gray, grayStride);
196 else
197 #endif
198 Base::RgbaToGray(rgba, width, height, rgbaStride, gray, grayStride);
199 }
200
SimdBgrToBgra(const uint8_t * bgr,size_t width,size_t height,size_t bgrStride,uint8_t * bgra,size_t bgraStride,uint8_t alpha)201 SIMD_API void SimdBgrToBgra(const uint8_t *bgr, size_t width, size_t height, size_t bgrStride, uint8_t *bgra, size_t bgraStride, uint8_t alpha)
202 {
203 #if defined(SIMD_AVX2_ENABLE) && !defined(SIMD_CLANG_AVX2_BGR_TO_BGRA_ERROR)
204 if(Avx2::Enable && width >= Avx2::A)
205 Avx2::BgrToBgra(bgr, width, height, bgrStride, bgra, bgraStride, alpha);
206 else
207 #endif
208 #ifdef SIMD_SSSE3_ENABLE
209 if(Ssse3::Enable && width >= Ssse3::A)
210 Ssse3::BgrToBgra(bgr, width, height, bgrStride, bgra, bgraStride, alpha);
211 else
212 #endif
213 #ifdef SIMD_NEON_ENABLE
214 if (Neon::Enable && width >= Neon::A)
215 Neon::BgrToBgra(bgr, width, height, bgrStride, bgra, bgraStride, alpha);
216 else
217 #endif
218 Base::BgrToBgra(bgr, width, height, bgrStride, bgra, bgraStride, alpha);
219 }
220
SimdBgrToRgba(const uint8_t * bgr,size_t width,size_t height,size_t bgrStride,uint8_t * rgba,size_t rgbaStride,uint8_t alpha)221 SIMD_API void SimdBgrToRgba(const uint8_t *bgr, size_t width, size_t height, size_t bgrStride, uint8_t *rgba, size_t rgbaStride, uint8_t alpha)
222 {
223 #if defined(SIMD_AVX2_ENABLE) && !defined(SIMD_CLANG_AVX2_BGR_TO_BGRA_ERROR)
224 if(Avx2::Enable && width >= Avx2::A)
225 Avx2::BgrToRgba(bgr, width, height, bgrStride, rgba, rgbaStride, alpha);
226 else
227 #endif
228 #ifdef SIMD_SSSE3_ENABLE
229 if(Ssse3::Enable && width >= Ssse3::A)
230 Ssse3::BgrToRgba(bgr, width, height, bgrStride, rgba, rgbaStride, alpha);
231 else
232 #endif
233 #ifdef SIMD_NEON_ENABLE
234 if (Neon::Enable && width >= Neon::A)
235 Neon::BgrToRgba(bgr, width, height, bgrStride, rgba, rgbaStride, alpha);
236 else
237 #endif
238 Base::BgrToRgba(bgr, width, height, bgrStride, rgba, rgbaStride, alpha);
239 }
240
SimdBgraToRgba(const uint8_t * bgra,size_t width,size_t height,size_t bgraStride,uint8_t * rgba,size_t rgbaStride)241 SIMD_API void SimdBgraToRgba(const uint8_t *bgra, size_t width, size_t height, size_t bgraStride, uint8_t *rgba, size_t rgbaStride)
242 {
243 #if defined(SIMD_AVX2_ENABLE)
244 if(Avx2::Enable && width >= Avx2::A)
245 Avx2::BgraToRgba(bgra, width, height, bgraStride, rgba, rgbaStride);
246 else
247 #endif
248 #ifdef SIMD_SSSE3_ENABLE
249 if(Ssse3::Enable && width >= Ssse3::A)
250 Ssse3::BgraToRgba(bgra, width, height, bgraStride, rgba, rgbaStride);
251 else
252 #endif
253 #ifdef SIMD_NEON_ENABLE
254 if (Neon::Enable && width >= Neon::A)
255 Neon::BgraToRgba(bgra, width, height, bgraStride, rgba, rgbaStride);
256 else
257 #endif
258 Base::BgraToRgba(bgra, width, height, bgraStride, rgba, rgbaStride);
259 }
260
SimdBgr48pToBgra32(const uint8_t * blue,size_t blueStride,size_t width,size_t height,const uint8_t * green,size_t greenStride,const uint8_t * red,size_t redStride,uint8_t * bgra,size_t bgraStride,uint8_t alpha)261 SIMD_API void SimdBgr48pToBgra32(const uint8_t * blue, size_t blueStride, size_t width, size_t height,
262 const uint8_t * green, size_t greenStride, const uint8_t * red, size_t redStride, uint8_t * bgra, size_t bgraStride, uint8_t alpha)
263 {
264 #ifdef SIMD_AVX2_ENABLE
265 if(Avx2::Enable && width >= Avx2::HA)
266 Avx2::Bgr48pToBgra32(blue, blueStride, width, height, green, greenStride, red, redStride, bgra, bgraStride, alpha);
267 else
268 #endif
269 #ifdef SIMD_SSE2_ENABLE
270 if(Sse2::Enable && width >= Sse2::HA)
271 Sse2::Bgr48pToBgra32(blue, blueStride, width, height, green, greenStride, red, redStride, bgra, bgraStride, alpha);
272 else
273 #endif
274 #ifdef SIMD_NEON_ENABLE
275 if (Neon::Enable && width >= Neon::A)
276 Neon::Bgr48pToBgra32(blue, blueStride, width, height, green, greenStride, red, redStride, bgra, bgraStride, alpha);
277 else
278 #endif
279 Base::Bgr48pToBgra32(blue, blueStride, width, height, green, greenStride, red, redStride, bgra, bgraStride, alpha);
280 }
281
SimdBgrToGray(const uint8_t * bgr,size_t width,size_t height,size_t bgrStride,uint8_t * gray,size_t grayStride)282 SIMD_API void SimdBgrToGray(const uint8_t *bgr, size_t width, size_t height, size_t bgrStride, uint8_t *gray, size_t grayStride)
283 {
284 #if defined(SIMD_AVX2_ENABLE) && !defined(SIMD_CLANG_AVX2_BGR_TO_BGRA_ERROR)
285 if(Avx2::Enable && width >= Avx2::A)
286 Avx2::BgrToGray(bgr, width, height, bgrStride, gray, grayStride);
287 else
288 #endif
289 #ifdef SIMD_SSSE3_ENABLE
290 if(Ssse3::Enable && width >= Ssse3::A)
291 Ssse3::BgrToGray(bgr, width, height, bgrStride, gray, grayStride);
292 else
293 #endif
294 #ifdef SIMD_SSE2_ENABLE
295 if(Sse2::Enable && width >= Sse2::A)
296 Sse2::BgrToGray(bgr, width, height, bgrStride, gray, grayStride);
297 else
298 #endif
299 #ifdef SIMD_NEON_ENABLE
300 if (Neon::Enable && width >= Neon::A)
301 Neon::BgrToGray(bgr, width, height, bgrStride, gray, grayStride);
302 else
303 #endif
304 Base::BgrToGray(bgr, width, height, bgrStride, gray, grayStride);
305 }
306
SimdRgbToGray(const uint8_t * rgb,size_t width,size_t height,size_t rgbStride,uint8_t * gray,size_t grayStride)307 SIMD_API void SimdRgbToGray(const uint8_t *rgb, size_t width, size_t height, size_t rgbStride, uint8_t *gray, size_t grayStride)
308 {
309 #if defined(SIMD_AVX2_ENABLE) && !defined(SIMD_CLANG_AVX2_BGR_TO_BGRA_ERROR)
310 if (Avx2::Enable && width >= Avx2::A)
311 Avx2::RgbToGray(rgb, width, height, rgbStride, gray, grayStride);
312 else
313 #endif
314 #ifdef SIMD_SSSE3_ENABLE
315 if (Ssse3::Enable && width >= Ssse3::A)
316 Ssse3::RgbToGray(rgb, width, height, rgbStride, gray, grayStride);
317 else
318 #endif
319 #ifdef SIMD_SSE2_ENABLE
320 if (Sse2::Enable && width >= Sse2::A)
321 Sse2::RgbToGray(rgb, width, height, rgbStride, gray, grayStride);
322 else
323 #endif
324 #ifdef SIMD_NEON_ENABLE
325 if (Neon::Enable && width >= Neon::A)
326 Neon::RgbToGray(rgb, width, height, rgbStride, gray, grayStride);
327 else
328 #endif
329 Base::RgbToGray(rgb, width, height, rgbStride, gray, grayStride);
330 }
331
SimdBgrToRgb(const uint8_t * bgr,size_t bgrStride,size_t width,size_t height,uint8_t * rgb,size_t rgbStride)332 SIMD_API void SimdBgrToRgb(const uint8_t *bgr, size_t bgrStride, size_t width, size_t height, uint8_t * rgb, size_t rgbStride)
333 {
334 #ifdef SIMD_AVX2_ENABLE
335 if (Avx2::Enable && width >= Avx2::A)
336 Avx2::BgrToRgb(bgr, bgrStride, width, height, rgb, rgbStride);
337 else
338 #endif
339 #ifdef SIMD_SSSE3_ENABLE
340 if (Ssse3::Enable && width >= Ssse3::A)
341 Ssse3::BgrToRgb(bgr, bgrStride, width, height, rgb, rgbStride);
342 else
343 #endif
344 #ifdef SIMD_NEON_ENABLE
345 if (Neon::Enable && width >= Neon::A)
346 Neon::BgrToRgb(bgr, bgrStride, width, height, rgb, rgbStride);
347 else
348 #endif
349 Base::BgrToRgb(bgr, bgrStride, width, height, rgb, rgbStride);
350 }
351
SimdCopy(const uint8_t * src,size_t srcStride,size_t width,size_t height,size_t pixelSize,uint8_t * dst,size_t dstStride)352 SIMD_API void SimdCopy(const uint8_t * src, size_t srcStride, size_t width, size_t height, size_t pixelSize, uint8_t * dst, size_t dstStride)
353 {
354 Base::Copy(src, srcStride, width, height, pixelSize, dst, dstStride);
355 }
356
SimdCopyFrame(const uint8_t * src,size_t srcStride,size_t width,size_t height,size_t pixelSize,size_t frameLeft,size_t frameTop,size_t frameRight,size_t frameBottom,uint8_t * dst,size_t dstStride)357 SIMD_API void SimdCopyFrame(const uint8_t * src, size_t srcStride, size_t width, size_t height, size_t pixelSize,
358 size_t frameLeft, size_t frameTop, size_t frameRight, size_t frameBottom, uint8_t * dst, size_t dstStride)
359 {
360 Base::CopyFrame(src, srcStride, width, height, pixelSize, frameLeft, frameTop, frameRight, frameBottom, dst, dstStride);
361 }
362
SimdDeinterleaveBgr(const uint8_t * bgr,size_t bgrStride,size_t width,size_t height,uint8_t * b,size_t bStride,uint8_t * g,size_t gStride,uint8_t * r,size_t rStride)363 SIMD_API void SimdDeinterleaveBgr(const uint8_t * bgr, size_t bgrStride, size_t width, size_t height,
364 uint8_t * b, size_t bStride, uint8_t * g, size_t gStride, uint8_t * r, size_t rStride)
365 {
366 #ifdef SIMD_AVX2_ENABLE
367 if (Avx2::Enable && width >= Avx2::A)
368 Avx2::DeinterleaveBgr(bgr, bgrStride, width, height, b, bStride, g, gStride, r, rStride);
369 else
370 #endif
371 #ifdef SIMD_SSSE3_ENABLE
372 if (Ssse3::Enable && width >= Ssse3::A)
373 Ssse3::DeinterleaveBgr(bgr, bgrStride, width, height, b, bStride, g, gStride, r, rStride);
374 else
375 #endif
376 #ifdef SIMD_NEON_ENABLE
377 if (Neon::Enable && width >= Neon::A)
378 Neon::DeinterleaveBgr(bgr, bgrStride, width, height, b, bStride, g, gStride, r, rStride);
379 else
380 #endif
381 Base::DeinterleaveBgr(bgr, bgrStride, width, height, b, bStride, g, gStride, r, rStride);
382 }
383
SimdDeinterleaveBgra(const uint8_t * bgra,size_t bgraStride,size_t width,size_t height,uint8_t * b,size_t bStride,uint8_t * g,size_t gStride,uint8_t * r,size_t rStride,uint8_t * a,size_t aStride)384 SIMD_API void SimdDeinterleaveBgra(const uint8_t * bgra, size_t bgraStride, size_t width, size_t height,
385 uint8_t * b, size_t bStride, uint8_t * g, size_t gStride, uint8_t * r, size_t rStride, uint8_t * a, size_t aStride)
386 {
387 #ifdef SIMD_AVX2_ENABLE
388 if (Avx2::Enable && width >= Avx2::A)
389 Avx2::DeinterleaveBgra(bgra, bgraStride, width, height, b, bStride, g, gStride, r, rStride, a, aStride);
390 else
391 #endif
392 #ifdef SIMD_SSSE3_ENABLE
393 if (Ssse3::Enable && width >= Ssse3::A)
394 Ssse3::DeinterleaveBgra(bgra, bgraStride, width, height, b, bStride, g, gStride, r, rStride, a, aStride);
395 else
396 #endif
397 #ifdef SIMD_NEON_ENABLE
398 if (Neon::Enable && width >= Neon::A)
399 Neon::DeinterleaveBgra(bgra, bgraStride, width, height, b, bStride, g, gStride, r, rStride, a, aStride);
400 else
401 #endif
402 Base::DeinterleaveBgra(bgra, bgraStride, width, height, b, bStride, g, gStride, r, rStride, a, aStride);
403 }
404
SimdGaussianBlur3x3(const uint8_t * src,size_t srcStride,size_t width,size_t height,size_t channelCount,uint8_t * dst,size_t dstStride)405 SIMD_API void SimdGaussianBlur3x3(const uint8_t * src, size_t srcStride, size_t width, size_t height,
406 size_t channelCount, uint8_t * dst, size_t dstStride)
407 {
408 #ifdef SIMD_AVX2_ENABLE
409 if(Avx2::Enable && (width - 1)*channelCount >= Avx2::A)
410 Avx2::GaussianBlur3x3(src, srcStride, width, height, channelCount, dst, dstStride);
411 else
412 #endif
413 #ifdef SIMD_SSSE3_ENABLE
414 if(Ssse3::Enable && (width - 1)*channelCount >= Ssse3::A)
415 Ssse3::GaussianBlur3x3(src, srcStride, width, height, channelCount, dst, dstStride);
416 else
417 #endif
418 #ifdef SIMD_SSE2_ENABLE
419 if(Sse2::Enable && (width - 1)*channelCount >= Sse2::A)
420 Sse2::GaussianBlur3x3(src, srcStride, width, height, channelCount, dst, dstStride);
421 else
422 #endif
423 #ifdef SIMD_NEON_ENABLE
424 if (Neon::Enable && (width - 1)*channelCount >= Neon::A)
425 Neon::GaussianBlur3x3(src, srcStride, width, height, channelCount, dst, dstStride);
426 else
427 #endif
428 Base::GaussianBlur3x3(src, srcStride, width, height, channelCount, dst, dstStride);
429 }
430
SimdGaussianBlurInit(size_t width,size_t height,size_t channels,const float * sigma,const float * epsilon)431 SIMD_API void* SimdGaussianBlurInit(size_t width, size_t height, size_t channels, const float* sigma, const float* epsilon)
432 {
433 typedef void* (*SimdGaussianBlurInitPtr) (size_t width, size_t height, size_t channels, const float* sigma, const float* epsilon);
434 const static SimdGaussianBlurInitPtr simdGaussianBlurInit = SIMD_FUNC3(GaussianBlurInit, SIMD_AVX2_FUNC, SIMD_SSE41_FUNC, SIMD_NEON_FUNC);
435
436 return simdGaussianBlurInit(width, height, channels, sigma, epsilon);
437 }
438
SimdGaussianBlurRun(const void * filter,const uint8_t * src,size_t srcStride,uint8_t * dst,size_t dstStride)439 SIMD_API void SimdGaussianBlurRun(const void* filter, const uint8_t* src, size_t srcStride, uint8_t* dst, size_t dstStride)
440 {
441 ((GaussianBlur*)filter)->Run(src, srcStride, dst, dstStride);
442 }
443
SimdGrayToBgr(const uint8_t * gray,size_t width,size_t height,size_t grayStride,uint8_t * bgr,size_t bgrStride)444 SIMD_API void SimdGrayToBgr(const uint8_t * gray, size_t width, size_t height, size_t grayStride, uint8_t * bgr, size_t bgrStride)
445 {
446 #ifdef SIMD_AVX2_ENABLE
447 if(Avx2::Enable && width >= Avx2::A)
448 Avx2::GrayToBgr(gray, width, height, grayStride, bgr, bgrStride);
449 else
450 #endif
451 #ifdef SIMD_SSSE3_ENABLE
452 if(Ssse3::Enable && width >= Ssse3::A)
453 Ssse3::GrayToBgr(gray, width, height, grayStride, bgr, bgrStride);
454 else
455 #endif
456 #ifdef SIMD_NEON_ENABLE
457 if (Neon::Enable && width >= Neon::A)
458 Neon::GrayToBgr(gray, width, height, grayStride, bgr, bgrStride);
459 else
460 #endif
461 Base::GrayToBgr(gray, width, height, grayStride, bgr, bgrStride);
462 }
463
SimdGrayToBgra(const uint8_t * gray,size_t width,size_t height,size_t grayStride,uint8_t * bgra,size_t bgraStride,uint8_t alpha)464 SIMD_API void SimdGrayToBgra(const uint8_t * gray, size_t width, size_t height, size_t grayStride, uint8_t * bgra, size_t bgraStride, uint8_t alpha)
465 {
466 #ifdef SIMD_AVX2_ENABLE
467 if(Avx2::Enable && width >= Avx2::A)
468 Avx2::GrayToBgra(gray, width, height, grayStride, bgra, bgraStride, alpha);
469 else
470 #endif
471 #ifdef SIMD_SSE2_ENABLE
472 if(Sse2::Enable && width >= Sse2::A)
473 Sse2::GrayToBgra(gray, width, height, grayStride, bgra, bgraStride, alpha);
474 else
475 #endif
476 #ifdef SIMD_NEON_ENABLE
477 if (Neon::Enable && width >= Neon::A)
478 Neon::GrayToBgra(gray, width, height, grayStride, bgra, bgraStride, alpha);
479 else
480 #endif
481 Base::GrayToBgra(gray, width, height, grayStride, bgra, bgraStride, alpha);
482 }
483
SimdInterleaveBgr(const uint8_t * b,size_t bStride,const uint8_t * g,size_t gStride,const uint8_t * r,size_t rStride,size_t width,size_t height,uint8_t * bgr,size_t bgrStride)484 SIMD_API void SimdInterleaveBgr(const uint8_t * b, size_t bStride, const uint8_t * g, size_t gStride, const uint8_t * r, size_t rStride,
485 size_t width, size_t height, uint8_t * bgr, size_t bgrStride)
486 {
487 #ifdef SIMD_AVX2_ENABLE
488 if (Avx2::Enable && width >= Avx2::A)
489 Avx2::InterleaveBgr(b, bStride, g, gStride, r, rStride, width, height, bgr, bgrStride);
490 else
491 #endif
492 #ifdef SIMD_SSSE3_ENABLE
493 if (Ssse3::Enable && width >= Ssse3::A)
494 Ssse3::InterleaveBgr(b, bStride, g, gStride, r, rStride, width, height, bgr, bgrStride);
495 else
496 #endif
497 #ifdef SIMD_NEON_ENABLE
498 if (Neon::Enable && width >= Neon::A)
499 Neon::InterleaveBgr(b, bStride, g, gStride, r, rStride, width, height, bgr, bgrStride);
500 else
501 #endif
502 Base::InterleaveBgr(b, bStride, g, gStride, r, rStride, width, height, bgr, bgrStride);
503 }
504
SimdInterleaveBgra(const uint8_t * b,size_t bStride,const uint8_t * g,size_t gStride,const uint8_t * r,size_t rStride,const uint8_t * a,size_t aStride,size_t width,size_t height,uint8_t * bgra,size_t bgraStride)505 SIMD_API void SimdInterleaveBgra(const uint8_t * b, size_t bStride, const uint8_t * g, size_t gStride, const uint8_t * r, size_t rStride, const uint8_t * a, size_t aStride,
506 size_t width, size_t height, uint8_t * bgra, size_t bgraStride)
507 {
508 #ifdef SIMD_AVX2_ENABLE
509 if (Avx2::Enable && width >= Avx2::A)
510 Avx2::InterleaveBgra(b, bStride, g, gStride, r, rStride, a, aStride, width, height, bgra, bgraStride);
511 else
512 #endif
513 #ifdef SIMD_SSSE3_ENABLE
514 if (Ssse3::Enable && width >= Ssse3::A)
515 Ssse3::InterleaveBgra(b, bStride, g, gStride, r, rStride, a, aStride, width, height, bgra, bgraStride);
516 else
517 #endif
518 #ifdef SIMD_NEON_ENABLE
519 if (Neon::Enable && width >= Neon::A)
520 Neon::InterleaveBgra(b, bStride, g, gStride, r, rStride, a, aStride, width, height, bgra, bgraStride);
521 else
522 #endif
523 Base::InterleaveBgra(b, bStride, g, gStride, r, rStride, a, aStride, width, height, bgra, bgraStride);
524 }
525
SimdOperationBinary8u(const uint8_t * a,size_t aStride,const uint8_t * b,size_t bStride,size_t width,size_t height,size_t channelCount,uint8_t * dst,size_t dstStride,SimdOperationBinary8uType type)526 SIMD_API void SimdOperationBinary8u(const uint8_t * a, size_t aStride, const uint8_t * b, size_t bStride,
527 size_t width, size_t height, size_t channelCount, uint8_t * dst, size_t dstStride, SimdOperationBinary8uType type)
528 {
529 #ifdef SIMD_AVX2_ENABLE
530 if(Avx2::Enable && width*channelCount >= Avx2::A)
531 Avx2::OperationBinary8u(a, aStride, b, bStride, width, height, channelCount, dst, dstStride, type);
532 else
533 #endif
534 #ifdef SIMD_SSE2_ENABLE
535 if(Sse2::Enable && width*channelCount >= Sse2::A)
536 Sse2::OperationBinary8u(a, aStride, b, bStride, width, height, channelCount, dst, dstStride, type);
537 else
538 #endif
539 #ifdef SIMD_NEON_ENABLE
540 if (Neon::Enable && width*channelCount >= Neon::A)
541 Neon::OperationBinary8u(a, aStride, b, bStride, width, height, channelCount, dst, dstStride, type);
542 else
543 #endif
544 Base::OperationBinary8u(a, aStride, b, bStride, width, height, channelCount, dst, dstStride, type);
545 }
546
SimdReduceColor2x2(const uint8_t * src,size_t srcWidth,size_t srcHeight,size_t srcStride,uint8_t * dst,size_t dstWidth,size_t dstHeight,size_t dstStride,size_t channelCount)547 SIMD_API void SimdReduceColor2x2(const uint8_t *src, size_t srcWidth, size_t srcHeight, size_t srcStride,
548 uint8_t *dst, size_t dstWidth, size_t dstHeight, size_t dstStride, size_t channelCount)
549 {
550 #ifdef SIMD_AVX2_ENABLE
551 if (Avx2::Enable && srcWidth >= Avx2::DA)
552 Avx2::ReduceColor2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
553 else
554 #endif
555 #ifdef SIMD_SSSE3_ENABLE
556 if (Ssse3::Enable && srcWidth >= Ssse3::DA)
557 Ssse3::ReduceColor2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
558 else
559 #endif
560 #ifdef SIMD_SSE2_ENABLE
561 if (Sse2::Enable && srcWidth >= Sse2::DA)
562 Sse2::ReduceColor2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
563 else
564 #endif
565 #ifdef SIMD_NEON_ENABLE
566 if (Neon::Enable && srcWidth >= Neon::DA)
567 Neon::ReduceColor2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
568 else
569 #endif
570 Base::ReduceColor2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
571 }
572
SimdReduceGray2x2(const uint8_t * src,size_t srcWidth,size_t srcHeight,size_t srcStride,uint8_t * dst,size_t dstWidth,size_t dstHeight,size_t dstStride)573 SIMD_API void SimdReduceGray2x2(const uint8_t *src, size_t srcWidth, size_t srcHeight, size_t srcStride,
574 uint8_t *dst, size_t dstWidth, size_t dstHeight, size_t dstStride)
575 {
576 #ifdef SIMD_AVX2_ENABLE
577 if(Avx2::Enable && srcWidth >= Avx2::DA)
578 Avx2::ReduceGray2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
579 else
580 #endif
581 #ifdef SIMD_SSSE3_ENABLE
582 if(Ssse3::Enable && srcWidth >= Ssse3::DA)
583 Ssse3::ReduceGray2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
584 else
585 #endif
586 #ifdef SIMD_SSE2_ENABLE
587 if(Sse2::Enable && srcWidth >= Sse2::DA)
588 Sse2::ReduceGray2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
589 else
590 #endif
591 #ifdef SIMD_NEON_ENABLE
592 if (Neon::Enable && srcWidth >= Neon::DA)
593 Neon::ReduceGray2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
594 else
595 #endif
596 Base::ReduceGray2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
597 }
598
SimdReduceGray3x3(const uint8_t * src,size_t srcWidth,size_t srcHeight,size_t srcStride,uint8_t * dst,size_t dstWidth,size_t dstHeight,size_t dstStride,int compensation)599 SIMD_API void SimdReduceGray3x3(const uint8_t *src, size_t srcWidth, size_t srcHeight, size_t srcStride,
600 uint8_t *dst, size_t dstWidth, size_t dstHeight, size_t dstStride, int compensation)
601 {
602 #ifdef SIMD_AVX2_ENABLE
603 if(Avx2::Enable && srcWidth >= Avx2::DA)
604 Avx2::ReduceGray3x3(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, compensation);
605 else
606 #endif
607 #ifdef SIMD_SSE2_ENABLE
608 if(Sse2::Enable && srcWidth >= Sse2::A)
609 Sse2::ReduceGray3x3(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, compensation);
610 else
611 #endif
612 #ifdef SIMD_NEON_ENABLE
613 if (Neon::Enable && srcWidth >= Neon::DA)
614 Neon::ReduceGray3x3(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, compensation);
615 else
616 #endif
617 Base::ReduceGray3x3(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, compensation);
618 }
619
SimdReduceGray4x4(const uint8_t * src,size_t srcWidth,size_t srcHeight,size_t srcStride,uint8_t * dst,size_t dstWidth,size_t dstHeight,size_t dstStride)620 SIMD_API void SimdReduceGray4x4(const uint8_t *src, size_t srcWidth, size_t srcHeight, size_t srcStride,
621 uint8_t *dst, size_t dstWidth, size_t dstHeight, size_t dstStride)
622 {
623 #ifdef SIMD_AVX2_ENABLE
624 if(Avx2::Enable && srcWidth > Avx2::DA)
625 Avx2::ReduceGray4x4(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
626 else
627 #endif
628 #ifdef SIMD_SSSE3_ENABLE
629 if(Ssse3::Enable && srcWidth > Ssse3::A)
630 Ssse3::ReduceGray4x4(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
631 else
632 #endif
633 #ifdef SIMD_SSE2_ENABLE
634 if(Sse2::Enable && srcWidth > Sse2::A)
635 Sse2::ReduceGray4x4(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
636 else
637 #endif
638 #ifdef SIMD_NEON_ENABLE
639 if (Neon::Enable && srcWidth > Neon::DA)
640 Neon::ReduceGray4x4(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
641 else
642 #endif
643 Base::ReduceGray4x4(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
644 }
645
SimdReduceGray5x5(const uint8_t * src,size_t srcWidth,size_t srcHeight,size_t srcStride,uint8_t * dst,size_t dstWidth,size_t dstHeight,size_t dstStride,int compensation)646 SIMD_API void SimdReduceGray5x5(const uint8_t *src, size_t srcWidth, size_t srcHeight, size_t srcStride,
647 uint8_t *dst, size_t dstWidth, size_t dstHeight, size_t dstStride, int compensation)
648 {
649 #ifdef SIMD_AVX2_ENABLE
650 if(Avx2::Enable && srcWidth >= Avx2::DA)
651 Avx2::ReduceGray5x5(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, compensation);
652 else
653 #endif
654 #ifdef SIMD_SSE2_ENABLE
655 if(Sse2::Enable && srcWidth >= Sse2::A)
656 Sse2::ReduceGray5x5(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, compensation);
657 else
658 #endif
659 #ifdef SIMD_NEON_ENABLE
660 if (Neon::Enable && srcWidth >= Neon::DA)
661 Neon::ReduceGray5x5(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, compensation);
662 else
663 #endif
664 Base::ReduceGray5x5(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, compensation);
665 }
666
SimdResizeBilinear(const uint8_t * src,size_t srcWidth,size_t srcHeight,size_t srcStride,uint8_t * dst,size_t dstWidth,size_t dstHeight,size_t dstStride,size_t channelCount)667 SIMD_API void SimdResizeBilinear(const uint8_t *src, size_t srcWidth, size_t srcHeight, size_t srcStride,
668 uint8_t *dst, size_t dstWidth, size_t dstHeight, size_t dstStride, size_t channelCount)
669 {
670 #ifdef SIMD_AVX2_ENABLE
671 if(Avx2::Enable && dstWidth >= Avx2::A)
672 Avx2::ResizeBilinear(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
673 else
674 #endif
675 #ifdef SIMD_SSSE3_ENABLE
676 if(Ssse3::Enable && dstWidth >= Ssse3::A)
677 Ssse3::ResizeBilinear(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
678 else
679 #endif
680 #ifdef SIMD_SSE2_ENABLE
681 if(Sse2::Enable && dstWidth >= Sse2::A)
682 Sse2::ResizeBilinear(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
683 else
684 #endif
685 #ifdef SIMD_NEON_ENABLE
686 if (Neon::Enable && dstWidth >= Neon::A)
687 Neon::ResizeBilinear(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
688 else
689 #endif
690 Base::ResizeBilinear(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride, channelCount);
691 }
692
SimdResizerInit(size_t srcX,size_t srcY,size_t dstX,size_t dstY,size_t channels,SimdResizeChannelType type,SimdResizeMethodType method)693 SIMD_API void * SimdResizerInit(size_t srcX, size_t srcY, size_t dstX, size_t dstY, size_t channels, SimdResizeChannelType type, SimdResizeMethodType method)
694 {
695 #ifdef SIMD_AVX2_ENABLE
696 if (Avx2::Enable)
697 return Avx2::ResizerInit(srcX, srcY, dstX, dstY, channels, type, method);
698 else
699 #endif
700 #ifdef SIMD_AVX_ENABLE
701 if (Avx::Enable)
702 return Avx::ResizerInit(srcX, srcY, dstX, dstY, channels, type, method);
703 else
704 #endif
705 #ifdef SIMD_SSE41_ENABLE
706 if (Sse41::Enable)
707 return Sse41::ResizerInit(srcX, srcY, dstX, dstY, channels, type, method);
708 else
709 #endif
710 #ifdef SIMD_SSSE3_ENABLE
711 if (Ssse3::Enable)
712 return Ssse3::ResizerInit(srcX, srcY, dstX, dstY, channels, type, method);
713 else
714 #endif
715 #ifdef SIMD_SSE2_ENABLE
716 if (Sse2::Enable)
717 return Sse2::ResizerInit(srcX, srcY, dstX, dstY, channels, type, method);
718 else
719 #endif
720 #ifdef SIMD_SSE_ENABLE
721 if (Sse::Enable)
722 return Sse::ResizerInit(srcX, srcY, dstX, dstY, channels, type, method);
723 else
724 #endif
725 #ifdef SIMD_NEON_ENABLE
726 if (Neon::Enable)
727 return Neon::ResizerInit(srcX, srcY, dstX, dstY, channels, type, method);
728 else
729 #endif
730 return Base::ResizerInit(srcX, srcY, dstX, dstY, channels, type, method);
731 }
732
SimdResizerRun(const void * resizer,const uint8_t * src,size_t srcStride,uint8_t * dst,size_t dstStride)733 SIMD_API void SimdResizerRun(const void * resizer, const uint8_t * src, size_t srcStride, uint8_t * dst, size_t dstStride)
734 {
735 ((Resizer*)resizer)->Run(src, srcStride, dst, dstStride);
736 }
737
SimdStretchGray2x2(const uint8_t * src,size_t srcWidth,size_t srcHeight,size_t srcStride,uint8_t * dst,size_t dstWidth,size_t dstHeight,size_t dstStride)738 SIMD_API void SimdStretchGray2x2(const uint8_t *src, size_t srcWidth, size_t srcHeight, size_t srcStride,
739 uint8_t *dst, size_t dstWidth, size_t dstHeight, size_t dstStride)
740 {
741 #ifdef SIMD_AVX2_ENABLE
742 if(Avx2::Enable && srcWidth >= Avx2::A)
743 Avx2::StretchGray2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
744 else
745 #endif
746 #ifdef SIMD_SSE2_ENABLE
747 if(Sse2::Enable && srcWidth >= Sse2::A)
748 Sse2::StretchGray2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
749 else
750 #endif
751 #ifdef SIMD_NEON_ENABLE
752 if (Neon::Enable && srcWidth >= Neon::A)
753 Neon::StretchGray2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
754 else
755 #endif
756 Base::StretchGray2x2(src, srcWidth, srcHeight, srcStride, dst, dstWidth, dstHeight, dstStride);
757 }
758
759 /* ViSP custom SIMD code */
SimdImageErosion(uint8_t * img,const uint8_t * buff,size_t width,size_t height,SimdImageConnexityType connexityType)760 SIMD_API void SimdImageErosion(uint8_t * img, const uint8_t * buff, size_t width, size_t height, SimdImageConnexityType connexityType)
761 {
762 #ifdef SIMD_SSE2_ENABLE
763 if (Sse2::Enable && width >= Sse2::A)
764 Sse2::ImageErosion(img, buff, width, height, connexityType);
765 else
766 #endif
767 Base::ImageErosion(img, buff, width, height, connexityType);
768 }
769
SimdImageDilatation(uint8_t * img,const uint8_t * buff,size_t width,size_t height,SimdImageConnexityType connexityType)770 SIMD_API void SimdImageDilatation(uint8_t * img, const uint8_t * buff, size_t width, size_t height, SimdImageConnexityType connexityType)
771 {
772 #ifdef SIMD_SSE2_ENABLE
773 if (Sse2::Enable && width >= Sse2::A)
774 Sse2::ImageDilatation(img, buff, width, height, connexityType);
775 else
776 #endif
777 Base::ImageDilatation(img, buff, width, height, connexityType);
778 }
779
SimdVectorSum(const double * vec,size_t size)780 SIMD_API double SimdVectorSum(const double * vec, size_t size)
781 {
782 #ifdef SIMD_SSE2_ENABLE
783 const int unrollLoopSize = 2;
784 if (Sse2::Enable && size*sizeof(double) >= unrollLoopSize*Sse2::A)
785 return Sse2::SimdVectorSum(vec, size);
786 else
787 #endif
788 return Base::SimdVectorSum(vec, size);
789 }
790
SimdVectorSumSquare(const double * vec,size_t size)791 SIMD_API double SimdVectorSumSquare(const double * vec, size_t size)
792 {
793 #ifdef SIMD_SSE2_ENABLE
794 const int unrollLoopSize = 2;
795 if (Sse2::Enable && size*sizeof(double) >= unrollLoopSize*Sse2::A)
796 return Sse2::SimdVectorSumSquare(vec, size);
797 else
798 #endif
799 return Base::SimdVectorSumSquare(vec, size);
800 }
801
SimdVectorStdev(const double * vec,size_t size,bool useBesselCorrection)802 SIMD_API double SimdVectorStdev(const double * vec, size_t size, bool useBesselCorrection)
803 {
804 #ifdef SIMD_SSE2_ENABLE
805 const int unrollLoopSize = 2;
806 if (Sse2::Enable && size*sizeof(double) >= unrollLoopSize*Sse2::A)
807 return Sse2::SimdVectorStdev(vec, size, useBesselCorrection);
808 else
809 #endif
810 return Base::SimdVectorStdev(vec, size, useBesselCorrection);
811 }
812
SimdVectorHadamard(const double * src1,const double * src2,size_t size,double * dst)813 SIMD_API void SimdVectorHadamard(const double * src1, const double * src2, size_t size, double * dst)
814 {
815 #ifdef SIMD_SSE2_ENABLE
816 if (Sse2::Enable && size*sizeof(double) >= Sse2::A)
817 Sse2::SimdVectorHadamard(src1, src2, size, dst);
818 else
819 #endif
820 Base::SimdVectorHadamard(src1, src2, size, dst);
821 }
822
SimdMatMulTwist(const double * mat,size_t rows,const double * twist,double * dst)823 SIMD_API void SimdMatMulTwist(const double * mat, size_t rows, const double * twist, double * dst)
824 {
825 #ifdef SIMD_SSE2_ENABLE
826 if (Sse2::Enable)
827 Sse2::SimdMatMulTwist(mat, rows, twist, dst);
828 else
829 #endif
830 Base::SimdMatMulTwist(mat, rows, twist, dst);
831 }
832
SimdMatTranspose(const double * mat,size_t rows,size_t cols,double * dst)833 SIMD_API void SimdMatTranspose(const double * mat, size_t rows, size_t cols, double * dst)
834 {
835 #ifdef SIMD_AVX_ENABLE
836 if (Avx::Enable)
837 Avx::SimdMatTranspose(mat, rows, cols, dst);
838 else
839 #endif
840 Base::SimdMatTranspose(mat, rows, cols, dst);
841 }
842
SimdImageDifference(const unsigned char * img1,const unsigned char * img2,size_t size,unsigned char * imgDiff)843 SIMD_API void SimdImageDifference(const unsigned char * img1, const unsigned char * img2, size_t size, unsigned char * imgDiff)
844 {
845 #ifdef SIMD_SSSE3_ENABLE
846 if (Ssse3::Enable && size >= Ssse3::A)
847 Ssse3::SimdImageDifference(img1,img2, size, imgDiff);
848 else
849 #endif
850 Base::SimdImageDifference(img1, img2, size, imgDiff);
851 }
852
SimdNormalizedCorrelation(const double * img1,double mean1,const double * img2,double mean2,size_t size,double & a2,double & b2,double & ab,bool useOptimized)853 SIMD_API void SimdNormalizedCorrelation(const double * img1, double mean1, const double * img2, double mean2, size_t size,
854 double& a2, double& b2, double& ab, bool useOptimized)
855 {
856 if (useOptimized) {
857 #ifdef SIMD_SSE2_ENABLE
858 if (Sse2::Enable && size*sizeof(double) >= Sse2::A)
859 Sse2::SimdNormalizedCorrelation(img1, mean1, img2, mean2, size, a2, b2, ab);
860 else
861 #endif
862 Base::SimdNormalizedCorrelation(img1, mean1, img2, mean2, size, a2, b2, ab);
863 } else {
864 Base::SimdNormalizedCorrelation(img1, mean1, img2, mean2, size, a2, b2, ab);
865 }
866 }
867
SimdNormalizedCorrelation2(const double * img1,size_t width1,const double * img2,size_t width2,size_t height2,size_t i0,size_t j0,double & ab)868 SIMD_API void SimdNormalizedCorrelation2(const double * img1, size_t width1, const double * img2,
869 size_t width2, size_t height2, size_t i0, size_t j0, double& ab)
870 {
871 #ifdef SIMD_SSE2_ENABLE
872 if (Sse2::Enable && width2*sizeof(double) >= Sse2::A)
873 Sse2::SimdNormalizedCorrelation2(img1, width1, img2, width2, height2, i0, j0, ab);
874 else
875 #endif
876 Base::SimdNormalizedCorrelation2(img1, width1, img2, width2, height2, i0, j0, ab);
877 }
878
SimdRemap(const unsigned char * src,size_t channels,size_t width,size_t height,size_t offset,const int * mapU,const int * mapV,const float * mapDu,const float * mapDv,unsigned char * dst)879 SIMD_API void SimdRemap(const unsigned char * src, size_t channels, size_t width, size_t height, size_t offset,
880 const int * mapU, const int * mapV, const float * mapDu, const float * mapDv, unsigned char * dst)
881 {
882 #ifdef SIMD_SSE2_ENABLE
883 if (Sse2::Enable && channels >= 4)
884 Sse2::SimdRemap(src, channels, width, height, offset, mapU, mapV, mapDu, mapDv, dst);
885 else
886 #endif
887 Base::SimdRemap(src, channels, width, height, offset, mapU, mapV, mapDu, mapDv, dst);
888 }
889
SimdComputeJtR(const double * J,size_t rows,const double * R,double * dst)890 SIMD_API void SimdComputeJtR(const double * J, size_t rows, const double * R, double * dst)
891 {
892 #ifdef SIMD_SSE2_ENABLE
893 if (Sse2::Enable)
894 Sse2::SimdComputeJtR(J, rows, R, dst);
895 else
896 #endif
897 Base::SimdComputeJtR(J, rows, R, dst);
898 }
899