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