mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Merge pull request #3591 from ilya-lavrenov:sse_avx
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
/
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2014, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, NVIDIA Corporation, all rights reserved.
|
||||
// Copyright (C) 2014, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
|
||||
+1840
-8
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014-2015, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -270,6 +271,8 @@ cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
|
||||
#ifdef HAVE_TEGRA_OPTIMIZATION
|
||||
if (tegra::cornerEigenValsVecs(src, eigenv, block_size, aperture_size, op_type, k, borderType))
|
||||
return;
|
||||
#elif CV_SSE2
|
||||
bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2);
|
||||
#endif
|
||||
|
||||
int depth = src.depth();
|
||||
@@ -318,6 +321,33 @@ cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
|
||||
|
||||
vst3q_f32(cov_data + j * 3, v_dst);
|
||||
}
|
||||
#elif CV_SSE2
|
||||
if (haveSSE2)
|
||||
{
|
||||
for( ; j <= size.width - 8; j += 8 )
|
||||
{
|
||||
__m128 v_dx_0 = _mm_loadu_ps(dxdata + j);
|
||||
__m128 v_dx_1 = _mm_loadu_ps(dxdata + j + 4);
|
||||
__m128 v_dy_0 = _mm_loadu_ps(dydata + j);
|
||||
__m128 v_dy_1 = _mm_loadu_ps(dydata + j + 4);
|
||||
|
||||
__m128 v_dx2_0 = _mm_mul_ps(v_dx_0, v_dx_0);
|
||||
__m128 v_dxy_0 = _mm_mul_ps(v_dx_0, v_dy_0);
|
||||
__m128 v_dy2_0 = _mm_mul_ps(v_dy_0, v_dy_0);
|
||||
__m128 v_dx2_1 = _mm_mul_ps(v_dx_1, v_dx_1);
|
||||
__m128 v_dxy_1 = _mm_mul_ps(v_dx_1, v_dy_1);
|
||||
__m128 v_dy2_1 = _mm_mul_ps(v_dy_1, v_dy_1);
|
||||
|
||||
_mm_interleave_ps(v_dx2_0, v_dx2_1, v_dxy_0, v_dxy_1, v_dy2_0, v_dy2_1);
|
||||
|
||||
_mm_storeu_ps(cov_data + j * 3, v_dx2_0);
|
||||
_mm_storeu_ps(cov_data + j * 3 + 4, v_dx2_1);
|
||||
_mm_storeu_ps(cov_data + j * 3 + 8, v_dxy_0);
|
||||
_mm_storeu_ps(cov_data + j * 3 + 12, v_dxy_1);
|
||||
_mm_storeu_ps(cov_data + j * 3 + 16, v_dy2_0);
|
||||
_mm_storeu_ps(cov_data + j * 3 + 20, v_dy2_1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; j < size.width; j++ )
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
|
||||
@@ -2284,15 +2284,20 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
|
||||
|
||||
CV_Assert( it.planes[0].isContinuous() && it.planes[1].isContinuous() );
|
||||
|
||||
#if CV_SSE2
|
||||
bool haveSIMD = checkHardwareSupport(CV_CPU_SSE2);
|
||||
#endif
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
const float* h1 = it.planes[0].ptr<float>();
|
||||
const float* h2 = it.planes[1].ptr<float>();
|
||||
len = it.planes[0].rows*it.planes[0].cols*H1.channels();
|
||||
j = 0;
|
||||
|
||||
if( (method == CV_COMP_CHISQR) || (method == CV_COMP_CHISQR_ALT))
|
||||
{
|
||||
for( j = 0; j < len; j++ )
|
||||
for( ; j < len; j++ )
|
||||
{
|
||||
double a = h1[j] - h2[j];
|
||||
double b = (method == CV_COMP_CHISQR) ? h1[j] : h1[j] + h2[j];
|
||||
@@ -2302,7 +2307,51 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
|
||||
}
|
||||
else if( method == CV_COMP_CORREL )
|
||||
{
|
||||
for( j = 0; j < len; j++ )
|
||||
#if CV_SSE2
|
||||
if (haveSIMD)
|
||||
{
|
||||
__m128d v_s1 = _mm_setzero_pd(), v_s2 = v_s1;
|
||||
__m128d v_s11 = v_s1, v_s22 = v_s1, v_s12 = v_s1;
|
||||
|
||||
for ( ; j <= len - 4; j += 4)
|
||||
{
|
||||
__m128 v_a = _mm_loadu_ps(h1 + j);
|
||||
__m128 v_b = _mm_loadu_ps(h2 + j);
|
||||
|
||||
// 0-1
|
||||
__m128d v_ad = _mm_cvtps_pd(v_a);
|
||||
__m128d v_bd = _mm_cvtps_pd(v_b);
|
||||
v_s12 = _mm_add_pd(v_s12, _mm_mul_pd(v_ad, v_bd));
|
||||
v_s11 = _mm_add_pd(v_s11, _mm_mul_pd(v_ad, v_ad));
|
||||
v_s22 = _mm_add_pd(v_s22, _mm_mul_pd(v_bd, v_bd));
|
||||
v_s1 = _mm_add_pd(v_s1, v_ad);
|
||||
v_s2 = _mm_add_pd(v_s2, v_bd);
|
||||
|
||||
// 2-3
|
||||
v_ad = _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_a), 8)));
|
||||
v_bd = _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_b), 8)));
|
||||
v_s12 = _mm_add_pd(v_s12, _mm_mul_pd(v_ad, v_bd));
|
||||
v_s11 = _mm_add_pd(v_s11, _mm_mul_pd(v_ad, v_ad));
|
||||
v_s22 = _mm_add_pd(v_s22, _mm_mul_pd(v_bd, v_bd));
|
||||
v_s1 = _mm_add_pd(v_s1, v_ad);
|
||||
v_s2 = _mm_add_pd(v_s2, v_bd);
|
||||
}
|
||||
|
||||
double CV_DECL_ALIGNED(16) ar[10];
|
||||
_mm_store_pd(ar, v_s12);
|
||||
_mm_store_pd(ar + 2, v_s11);
|
||||
_mm_store_pd(ar + 4, v_s22);
|
||||
_mm_store_pd(ar + 6, v_s1);
|
||||
_mm_store_pd(ar + 8, v_s2);
|
||||
|
||||
s12 += ar[0] + ar[1];
|
||||
s11 += ar[2] + ar[3];
|
||||
s22 += ar[4] + ar[5];
|
||||
s1 += ar[6] + ar[7];
|
||||
s2 += ar[8] + ar[9];
|
||||
}
|
||||
#endif
|
||||
for( ; j < len; j++ )
|
||||
{
|
||||
double a = h1[j];
|
||||
double b = h2[j];
|
||||
@@ -2316,7 +2365,6 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
|
||||
}
|
||||
else if( method == CV_COMP_INTERSECT )
|
||||
{
|
||||
j = 0;
|
||||
#if CV_NEON
|
||||
float32x4_t v_result = vdupq_n_f32(0.0f);
|
||||
for( ; j <= len - 4; j += 4 )
|
||||
@@ -2324,13 +2372,61 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
|
||||
float CV_DECL_ALIGNED(16) ar[4];
|
||||
vst1q_f32(ar, v_result);
|
||||
result += ar[0] + ar[1] + ar[2] + ar[3];
|
||||
#elif CV_SSE2
|
||||
if (haveSIMD)
|
||||
{
|
||||
__m128d v_result = _mm_setzero_pd();
|
||||
for ( ; j <= len - 4; j += 4)
|
||||
{
|
||||
__m128 v_src = _mm_min_ps(_mm_loadu_ps(h1 + j),
|
||||
_mm_loadu_ps(h2 + j));
|
||||
v_result = _mm_add_pd(v_result, _mm_cvtps_pd(v_src));
|
||||
v_src = _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_src), 8));
|
||||
v_result = _mm_add_pd(v_result, _mm_cvtps_pd(v_src));
|
||||
}
|
||||
|
||||
double CV_DECL_ALIGNED(16) ar[2];
|
||||
_mm_store_pd(ar, v_result);
|
||||
result += ar[0] + ar[1];
|
||||
}
|
||||
#endif
|
||||
for( ; j < len; j++ )
|
||||
result += std::min(h1[j], h2[j]);
|
||||
}
|
||||
else if( method == CV_COMP_BHATTACHARYYA )
|
||||
{
|
||||
for( j = 0; j < len; j++ )
|
||||
#if CV_SSE2
|
||||
if (haveSIMD)
|
||||
{
|
||||
__m128d v_s1 = _mm_setzero_pd(), v_s2 = v_s1, v_result = v_s1;
|
||||
for ( ; j <= len - 4; j += 4)
|
||||
{
|
||||
__m128 v_a = _mm_loadu_ps(h1 + j);
|
||||
__m128 v_b = _mm_loadu_ps(h2 + j);
|
||||
|
||||
__m128d v_ad = _mm_cvtps_pd(v_a);
|
||||
__m128d v_bd = _mm_cvtps_pd(v_b);
|
||||
v_s1 = _mm_add_pd(v_s1, v_ad);
|
||||
v_s2 = _mm_add_pd(v_s2, v_bd);
|
||||
v_result = _mm_add_pd(v_result, _mm_sqrt_pd(_mm_mul_pd(v_ad, v_bd)));
|
||||
|
||||
v_ad = _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_a), 8)));
|
||||
v_bd = _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_b), 8)));
|
||||
v_s1 = _mm_add_pd(v_s1, v_ad);
|
||||
v_s2 = _mm_add_pd(v_s2, v_bd);
|
||||
v_result = _mm_add_pd(v_result, _mm_sqrt_pd(_mm_mul_pd(v_ad, v_bd)));
|
||||
}
|
||||
|
||||
double CV_DECL_ALIGNED(16) ar[6];
|
||||
_mm_store_pd(ar, v_s1);
|
||||
_mm_store_pd(ar + 2, v_s2);
|
||||
_mm_store_pd(ar + 4, v_result);
|
||||
s1 += ar[0] + ar[1];
|
||||
s2 += ar[2] + ar[3];
|
||||
result += ar[4] + ar[5];
|
||||
}
|
||||
#endif
|
||||
for( ; j < len; j++ )
|
||||
{
|
||||
double a = h1[j];
|
||||
double b = h2[j];
|
||||
@@ -2341,7 +2437,7 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
|
||||
}
|
||||
else if( method == CV_COMP_KL_DIV )
|
||||
{
|
||||
for( j = 0; j < len; j++ )
|
||||
for( ; j < len; j++ )
|
||||
{
|
||||
double p = h1[j];
|
||||
double q = h2[j];
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014-2015, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -1962,9 +1963,9 @@ private:
|
||||
struct ResizeAreaFastVec_SIMD_32f
|
||||
{
|
||||
ResizeAreaFastVec_SIMD_32f(int _scale_x, int _scale_y, int _cn, int _step) :
|
||||
scale_x(_scale_x), scale_y(_scale_y), cn(_cn), step(_step)
|
||||
cn(_cn), step(_step)
|
||||
{
|
||||
fast_mode = scale_x == 2 && scale_y == 2 && (cn == 1 || cn == 3 || cn == 4);
|
||||
fast_mode = _scale_x == 2 && _scale_y == 2 && (cn == 1 || cn == 4);
|
||||
}
|
||||
|
||||
int operator() (const float * S, float * D, int w) const
|
||||
@@ -2004,7 +2005,6 @@ struct ResizeAreaFastVec_SIMD_32f
|
||||
}
|
||||
|
||||
private:
|
||||
int scale_x, scale_y;
|
||||
int cn;
|
||||
bool fast_mode;
|
||||
int step;
|
||||
@@ -2199,8 +2199,146 @@ private:
|
||||
bool use_simd;
|
||||
};
|
||||
|
||||
typedef ResizeAreaFastNoVec<short, short> ResizeAreaFastVec_SIMD_16s;
|
||||
typedef ResizeAreaFastNoVec<float, float> ResizeAreaFastVec_SIMD_32f;
|
||||
class ResizeAreaFastVec_SIMD_16s
|
||||
{
|
||||
public:
|
||||
ResizeAreaFastVec_SIMD_16s(int _cn, int _step) :
|
||||
cn(_cn), step(_step)
|
||||
{
|
||||
use_simd = checkHardwareSupport(CV_CPU_SSE2);
|
||||
}
|
||||
|
||||
int operator() (const short* S, short* D, int w) const
|
||||
{
|
||||
if (!use_simd)
|
||||
return 0;
|
||||
|
||||
int dx = 0;
|
||||
const short* S0 = (const short*)S;
|
||||
const short* S1 = (const short*)((const uchar*)(S) + step);
|
||||
__m128i masklow = _mm_set1_epi32(0x0000ffff);
|
||||
__m128i zero = _mm_setzero_si128();
|
||||
__m128i delta2 = _mm_set1_epi32(2);
|
||||
|
||||
if (cn == 1)
|
||||
{
|
||||
for ( ; dx <= w - 4; dx += 4, S0 += 8, S1 += 8, D += 4)
|
||||
{
|
||||
__m128i r0 = _mm_loadu_si128((const __m128i*)S0);
|
||||
__m128i r1 = _mm_loadu_si128((const __m128i*)S1);
|
||||
|
||||
__m128i s0 = _mm_add_epi32(_mm_srai_epi32(r0, 16),
|
||||
_mm_srai_epi32(_mm_slli_epi32(_mm_and_si128(r0, masklow), 16), 16));
|
||||
__m128i s1 = _mm_add_epi32(_mm_srai_epi32(r1, 16),
|
||||
_mm_srai_epi32(_mm_slli_epi32(_mm_and_si128(r1, masklow), 16), 16));
|
||||
s0 = _mm_add_epi32(_mm_add_epi32(s0, s1), delta2);
|
||||
s0 = _mm_srai_epi32(s0, 2);
|
||||
s0 = _mm_packs_epi32(s0, zero);
|
||||
|
||||
_mm_storel_epi64((__m128i*)D, s0);
|
||||
}
|
||||
}
|
||||
else if (cn == 3)
|
||||
for ( ; dx <= w - 4; dx += 3, S0 += 6, S1 += 6, D += 3)
|
||||
{
|
||||
__m128i r0 = _mm_loadu_si128((const __m128i*)S0);
|
||||
__m128i r1 = _mm_loadu_si128((const __m128i*)S1);
|
||||
|
||||
__m128i r0_16l = _mm_srai_epi32(_mm_unpacklo_epi16(zero, r0), 16);
|
||||
__m128i r0_16h = _mm_srai_epi32(_mm_unpacklo_epi16(zero, _mm_srli_si128(r0, 6)), 16);
|
||||
__m128i r1_16l = _mm_srai_epi32(_mm_unpacklo_epi16(zero, r1), 16);
|
||||
__m128i r1_16h = _mm_srai_epi32(_mm_unpacklo_epi16(zero, _mm_srli_si128(r1, 6)), 16);
|
||||
|
||||
__m128i s0 = _mm_add_epi32(r0_16l, r0_16h);
|
||||
__m128i s1 = _mm_add_epi32(r1_16l, r1_16h);
|
||||
s0 = _mm_add_epi32(delta2, _mm_add_epi32(s0, s1));
|
||||
s0 = _mm_packs_epi32(_mm_srai_epi32(s0, 2), zero);
|
||||
_mm_storel_epi64((__m128i*)D, s0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert(cn == 4);
|
||||
for ( ; dx <= w - 4; dx += 4, S0 += 8, S1 += 8, D += 4)
|
||||
{
|
||||
__m128i r0 = _mm_loadu_si128((const __m128i*)S0);
|
||||
__m128i r1 = _mm_loadu_si128((const __m128i*)S1);
|
||||
|
||||
__m128i r0_32l = _mm_srai_epi32(_mm_unpacklo_epi16(zero, r0), 16);
|
||||
__m128i r0_32h = _mm_srai_epi32(_mm_unpackhi_epi16(zero, r0), 16);
|
||||
__m128i r1_32l = _mm_srai_epi32(_mm_unpacklo_epi16(zero, r1), 16);
|
||||
__m128i r1_32h = _mm_srai_epi32(_mm_unpackhi_epi16(zero, r1), 16);
|
||||
|
||||
__m128i s0 = _mm_add_epi32(r0_32l, r0_32h);
|
||||
__m128i s1 = _mm_add_epi32(r1_32l, r1_32h);
|
||||
s0 = _mm_add_epi32(s1, _mm_add_epi32(s0, delta2));
|
||||
s0 = _mm_packs_epi32(_mm_srai_epi32(s0, 2), zero);
|
||||
_mm_storel_epi64((__m128i*)D, s0);
|
||||
}
|
||||
}
|
||||
|
||||
return dx;
|
||||
}
|
||||
|
||||
private:
|
||||
int cn;
|
||||
int step;
|
||||
bool use_simd;
|
||||
};
|
||||
|
||||
struct ResizeAreaFastVec_SIMD_32f
|
||||
{
|
||||
ResizeAreaFastVec_SIMD_32f(int _scale_x, int _scale_y, int _cn, int _step) :
|
||||
cn(_cn), step(_step)
|
||||
{
|
||||
fast_mode = _scale_x == 2 && _scale_y == 2 && (cn == 1 || cn == 4);
|
||||
fast_mode = fast_mode && checkHardwareSupport(CV_CPU_SSE2);
|
||||
}
|
||||
|
||||
int operator() (const float * S, float * D, int w) const
|
||||
{
|
||||
if (!fast_mode)
|
||||
return 0;
|
||||
|
||||
const float * S0 = S, * S1 = (const float *)((const uchar *)(S0) + step);
|
||||
int dx = 0;
|
||||
|
||||
__m128 v_025 = _mm_set1_ps(0.25f);
|
||||
|
||||
if (cn == 1)
|
||||
{
|
||||
const int shuffle_lo = _MM_SHUFFLE(2, 0, 2, 0), shuffle_hi = _MM_SHUFFLE(3, 1, 3, 1);
|
||||
for ( ; dx <= w - 4; dx += 4, S0 += 8, S1 += 8, D += 4)
|
||||
{
|
||||
__m128 v_row00 = _mm_loadu_ps(S0), v_row01 = _mm_loadu_ps(S0 + 4),
|
||||
v_row10 = _mm_loadu_ps(S1), v_row11 = _mm_loadu_ps(S1 + 4);
|
||||
|
||||
__m128 v_dst0 = _mm_add_ps(_mm_shuffle_ps(v_row00, v_row01, shuffle_lo),
|
||||
_mm_shuffle_ps(v_row00, v_row01, shuffle_hi));
|
||||
__m128 v_dst1 = _mm_add_ps(_mm_shuffle_ps(v_row10, v_row11, shuffle_lo),
|
||||
_mm_shuffle_ps(v_row10, v_row11, shuffle_hi));
|
||||
|
||||
_mm_storeu_ps(D, _mm_mul_ps(_mm_add_ps(v_dst0, v_dst1), v_025));
|
||||
}
|
||||
}
|
||||
else if (cn == 4)
|
||||
{
|
||||
for ( ; dx <= w - 4; dx += 4, S0 += 8, S1 += 8, D += 4)
|
||||
{
|
||||
__m128 v_dst0 = _mm_add_ps(_mm_loadu_ps(S0), _mm_loadu_ps(S0 + 4));
|
||||
__m128 v_dst1 = _mm_add_ps(_mm_loadu_ps(S1), _mm_loadu_ps(S1 + 4));
|
||||
|
||||
_mm_storeu_ps(D, _mm_mul_ps(_mm_add_ps(v_dst0, v_dst1), v_025));
|
||||
}
|
||||
}
|
||||
|
||||
return dx;
|
||||
}
|
||||
|
||||
private:
|
||||
int cn;
|
||||
bool fast_mode;
|
||||
int step;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
@@ -4678,6 +4816,13 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
#if CV_SSE2
|
||||
bool useSSE2 = checkHardwareSupport(CV_CPU_SSE2);
|
||||
#endif
|
||||
#if CV_SSE4_1
|
||||
bool useSSE4_1 = checkHardwareSupport(CV_CPU_SSE4_1);
|
||||
#endif
|
||||
|
||||
const float scale = 1.f/INTER_TAB_SIZE;
|
||||
int x, y;
|
||||
for( y = 0; y < size.height; y++ )
|
||||
@@ -4708,6 +4853,29 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
|
||||
vst2q_s16(dst1 + (x << 1), v_dst);
|
||||
}
|
||||
#elif CV_SSE4_1
|
||||
if (useSSE4_1)
|
||||
{
|
||||
for( ; x <= size.width - 16; x += 16 )
|
||||
{
|
||||
__m128i v_dst0 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_loadu_ps(src1f + x)),
|
||||
_mm_cvtps_epi32(_mm_loadu_ps(src1f + x + 4)));
|
||||
__m128i v_dst1 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_loadu_ps(src1f + x + 8)),
|
||||
_mm_cvtps_epi32(_mm_loadu_ps(src1f + x + 12)));
|
||||
|
||||
__m128i v_dst2 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_loadu_ps(src2f + x)),
|
||||
_mm_cvtps_epi32(_mm_loadu_ps(src2f + x + 4)));
|
||||
__m128i v_dst3 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_loadu_ps(src2f + x + 8)),
|
||||
_mm_cvtps_epi32(_mm_loadu_ps(src2f + x + 12)));
|
||||
|
||||
_mm_interleave_epi16(v_dst0, v_dst1, v_dst2, v_dst3);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x * 2), v_dst0);
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x * 2 + 8), v_dst1);
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x * 2 + 16), v_dst2);
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x * 2 + 24), v_dst3);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
@@ -4742,6 +4910,52 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
vandq_s32(v_ix1, v_mask)));
|
||||
vst1q_u16(dst2 + x, vcombine_u16(v_dst0, v_dst1));
|
||||
}
|
||||
#elif CV_SSE4_1
|
||||
if (useSSE4_1)
|
||||
{
|
||||
__m128 v_its = _mm_set1_ps(INTER_TAB_SIZE);
|
||||
__m128i v_its1 = _mm_set1_epi32(INTER_TAB_SIZE-1);
|
||||
|
||||
for( ; x <= size.width - 16; x += 16 )
|
||||
{
|
||||
__m128i v_ix0 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src1f + x), v_its));
|
||||
__m128i v_ix1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src1f + x + 4), v_its));
|
||||
__m128i v_iy0 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src2f + x), v_its));
|
||||
__m128i v_iy1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src2f + x + 4), v_its));
|
||||
|
||||
__m128i v_dst10 = _mm_packs_epi32(_mm_srai_epi32(v_ix0, INTER_BITS),
|
||||
_mm_srai_epi32(v_ix1, INTER_BITS));
|
||||
__m128i v_dst12 = _mm_packs_epi32(_mm_srai_epi32(v_iy0, INTER_BITS),
|
||||
_mm_srai_epi32(v_iy1, INTER_BITS));
|
||||
__m128i v_dst20 = _mm_add_epi32(_mm_slli_epi32(_mm_and_si128(v_iy0, v_its1), INTER_BITS),
|
||||
_mm_and_si128(v_ix0, v_its1));
|
||||
__m128i v_dst21 = _mm_add_epi32(_mm_slli_epi32(_mm_and_si128(v_iy1, v_its1), INTER_BITS),
|
||||
_mm_and_si128(v_ix1, v_its1));
|
||||
_mm_storeu_si128((__m128i *)(dst2 + x), _mm_packus_epi32(v_dst20, v_dst21));
|
||||
|
||||
v_ix0 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src1f + x + 8), v_its));
|
||||
v_ix1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src1f + x + 12), v_its));
|
||||
v_iy0 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src2f + x + 8), v_its));
|
||||
v_iy1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src2f + x + 12), v_its));
|
||||
|
||||
__m128i v_dst11 = _mm_packs_epi32(_mm_srai_epi32(v_ix0, INTER_BITS),
|
||||
_mm_srai_epi32(v_ix1, INTER_BITS));
|
||||
__m128i v_dst13 = _mm_packs_epi32(_mm_srai_epi32(v_iy0, INTER_BITS),
|
||||
_mm_srai_epi32(v_iy1, INTER_BITS));
|
||||
v_dst20 = _mm_add_epi32(_mm_slli_epi32(_mm_and_si128(v_iy0, v_its1), INTER_BITS),
|
||||
_mm_and_si128(v_ix0, v_its1));
|
||||
v_dst21 = _mm_add_epi32(_mm_slli_epi32(_mm_and_si128(v_iy1, v_its1), INTER_BITS),
|
||||
_mm_and_si128(v_ix1, v_its1));
|
||||
_mm_storeu_si128((__m128i *)(dst2 + x + 8), _mm_packus_epi32(v_dst20, v_dst21));
|
||||
|
||||
_mm_interleave_epi16(v_dst10, v_dst11, v_dst12, v_dst13);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x * 2), v_dst10);
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x * 2 + 8), v_dst11);
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x * 2 + 16), v_dst12);
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x * 2 + 24), v_dst13);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
@@ -4761,6 +4975,12 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
for( ; x <= (size.width << 1) - 8; x += 8 )
|
||||
vst1q_s16(dst1 + x, vcombine_s16(vqmovn_s32(cv_vrndq_s32_f32(vld1q_f32(src1f + x))),
|
||||
vqmovn_s32(cv_vrndq_s32_f32(vld1q_f32(src1f + x + 4)))));
|
||||
#elif CV_SSE2
|
||||
for( ; x <= (size.width << 1) - 8; x += 8 )
|
||||
{
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x), _mm_packs_epi32(_mm_cvtps_epi32(_mm_loadu_ps(src1f + x)),
|
||||
_mm_cvtps_epi32(_mm_loadu_ps(src1f + x + 4))));
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
@@ -4796,6 +5016,30 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
vandq_s32(v_ix1, v_mask)));
|
||||
vst1q_u16(dst2 + x, vcombine_u16(v_dst0, v_dst1));
|
||||
}
|
||||
#elif CV_SSE4_1
|
||||
if (useSSE4_1)
|
||||
{
|
||||
__m128 v_its = _mm_set1_ps(INTER_TAB_SIZE);
|
||||
__m128i v_its1 = _mm_set1_epi32(INTER_TAB_SIZE-1);
|
||||
__m128i v_y_mask = _mm_set1_epi32((INTER_TAB_SIZE-1) << 16);
|
||||
|
||||
for( ; x <= size.width - 4; x += 4 )
|
||||
{
|
||||
__m128i v_src0 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src1f + x * 2), v_its));
|
||||
__m128i v_src1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_loadu_ps(src1f + x * 2 + 4), v_its));
|
||||
|
||||
__m128i v_dst1 = _mm_packs_epi32(_mm_srai_epi32(v_src0, INTER_BITS),
|
||||
_mm_srai_epi32(v_src1, INTER_BITS));
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x * 2), v_dst1);
|
||||
|
||||
// x0 y0 x1 y1 . . .
|
||||
v_src0 = _mm_packs_epi32(_mm_and_si128(v_src0, v_its1),
|
||||
_mm_and_si128(v_src1, v_its1));
|
||||
__m128i v_dst2 = _mm_or_si128(_mm_srli_epi32(_mm_and_si128(v_src0, v_y_mask), 16 - INTER_BITS), // y0 0 y1 0 . . .
|
||||
_mm_and_si128(v_src0, v_its1)); // 0 x0 0 x1 . . .
|
||||
_mm_storel_epi64((__m128i *)(dst2 + x), _mm_packus_epi32(v_dst2, v_dst2));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
@@ -4841,6 +5085,44 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
vst1q_f32(dst1f + x + 4, v_dst1);
|
||||
vst1q_f32(dst2f + x + 4, v_dst2);
|
||||
}
|
||||
#elif CV_SSE2
|
||||
__m128i v_mask2 = _mm_set1_epi16(INTER_TAB_SIZE2-1);
|
||||
__m128i v_zero = _mm_setzero_si128(), v_mask = _mm_set1_epi32(INTER_TAB_SIZE-1);
|
||||
__m128 v_scale = _mm_set1_ps(scale);
|
||||
|
||||
for( ; x <= size.width - 16; x += 16)
|
||||
{
|
||||
__m128i v_src10 = _mm_loadu_si128((__m128i const *)(src1 + x * 2));
|
||||
__m128i v_src11 = _mm_loadu_si128((__m128i const *)(src1 + x * 2 + 8));
|
||||
__m128i v_src20 = _mm_loadu_si128((__m128i const *)(src1 + x * 2 + 16));
|
||||
__m128i v_src21 = _mm_loadu_si128((__m128i const *)(src1 + x * 2 + 24));
|
||||
|
||||
_mm_deinterleave_epi16(v_src10, v_src11, v_src20, v_src21);
|
||||
|
||||
__m128i v_fxy = src2 ? _mm_and_si128(_mm_loadu_si128((__m128i const *)(src2 + x)), v_mask2) : v_zero;
|
||||
__m128i v_fxy_p = _mm_unpacklo_epi16(v_fxy, v_zero);
|
||||
_mm_storeu_ps(dst1f + x, _mm_add_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(v_zero, v_src10), 16)),
|
||||
_mm_mul_ps(v_scale, _mm_cvtepi32_ps(_mm_and_si128(v_fxy_p, v_mask)))));
|
||||
_mm_storeu_ps(dst2f + x, _mm_add_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(v_zero, v_src20), 16)),
|
||||
_mm_mul_ps(v_scale, _mm_cvtepi32_ps(_mm_srli_epi32(v_fxy_p, INTER_BITS)))));
|
||||
v_fxy_p = _mm_unpackhi_epi16(v_fxy, v_zero);
|
||||
_mm_storeu_ps(dst1f + x + 4, _mm_add_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpackhi_epi16(v_zero, v_src10), 16)),
|
||||
_mm_mul_ps(v_scale, _mm_cvtepi32_ps(_mm_and_si128(v_fxy_p, v_mask)))));
|
||||
_mm_storeu_ps(dst2f + x + 4, _mm_add_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpackhi_epi16(v_zero, v_src20), 16)),
|
||||
_mm_mul_ps(v_scale, _mm_cvtepi32_ps(_mm_srli_epi32(v_fxy_p, INTER_BITS)))));
|
||||
|
||||
v_fxy = src2 ? _mm_and_si128(_mm_loadu_si128((__m128i const *)(src2 + x + 8)), v_mask2) : v_zero;
|
||||
v_fxy_p = _mm_unpackhi_epi16(v_fxy, v_zero);
|
||||
_mm_storeu_ps(dst1f + x + 8, _mm_add_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(v_zero, v_src11), 16)),
|
||||
_mm_mul_ps(v_scale, _mm_cvtepi32_ps(_mm_and_si128(v_fxy_p, v_mask)))));
|
||||
_mm_storeu_ps(dst2f + x + 8, _mm_add_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpacklo_epi16(v_zero, v_src21), 16)),
|
||||
_mm_mul_ps(v_scale, _mm_cvtepi32_ps(_mm_srli_epi32(v_fxy_p, INTER_BITS)))));
|
||||
v_fxy_p = _mm_unpackhi_epi16(v_fxy, v_zero);
|
||||
_mm_storeu_ps(dst1f + x + 12, _mm_add_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpackhi_epi16(v_zero, v_src11), 16)),
|
||||
_mm_mul_ps(v_scale, _mm_cvtepi32_ps(_mm_and_si128(v_fxy_p, v_mask)))));
|
||||
_mm_storeu_ps(dst2f + x + 12, _mm_add_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_unpackhi_epi16(v_zero, v_src21), 16)),
|
||||
_mm_mul_ps(v_scale, _mm_cvtepi32_ps(_mm_srli_epi32(v_fxy_p, INTER_BITS)))));
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
@@ -4882,6 +5164,27 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
v_scale, vcvtq_f32_s32(vshrq_n_s32(v_fxy2, INTER_BITS)));
|
||||
vst2q_f32(dst1f + (x << 1) + 8, v_dst);
|
||||
}
|
||||
#elif CV_SSE2
|
||||
if (useSSE2)
|
||||
{
|
||||
__m128i v_mask2 = _mm_set1_epi16(INTER_TAB_SIZE2-1);
|
||||
__m128i v_zero = _mm_set1_epi32(0), v_mask = _mm_set1_epi32(INTER_TAB_SIZE-1);
|
||||
__m128 v_scale = _mm_set1_ps(scale);
|
||||
|
||||
for ( ; x <= size.width - 8; x += 8)
|
||||
{
|
||||
__m128i v_src = _mm_loadu_si128((__m128i const *)(src1 + x * 2));
|
||||
__m128i v_fxy = src2 ? _mm_and_si128(_mm_loadu_si128((__m128i const *)(src2 + x)), v_mask2) : v_zero;
|
||||
__m128i v_fxy1 = _mm_and_si128(v_fxy, v_mask);
|
||||
__m128i v_fxy2 = _mm_srli_epi16(v_fxy, INTER_BITS);
|
||||
|
||||
__m128 v_add = _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi16(v_fxy1, v_fxy2)), v_scale);
|
||||
_mm_storeu_ps(dst1f + x * 2, _mm_add_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi16(v_src, v_zero)), v_add));
|
||||
|
||||
v_add = _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi16(v_fxy1, v_fxy2)), v_scale);
|
||||
_mm_storeu_ps(dst1f + x * 2, _mm_add_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi16(v_src, v_zero)), v_add));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
@@ -4919,7 +5222,10 @@ public:
|
||||
const int AB_SCALE = 1 << AB_BITS;
|
||||
int round_delta = interpolation == INTER_NEAREST ? AB_SCALE/2 : AB_SCALE/INTER_TAB_SIZE/2, x, y, x1, y1;
|
||||
#if CV_SSE2
|
||||
bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);
|
||||
bool useSSE2 = checkHardwareSupport(CV_CPU_SSE2);
|
||||
#endif
|
||||
#if CV_SSE4_1
|
||||
bool useSSE4_1 = checkHardwareSupport(CV_CPU_SSE4_1);
|
||||
#endif
|
||||
|
||||
int bh0 = std::min(BLOCK_SZ/2, dst.rows);
|
||||
@@ -4957,6 +5263,31 @@ public:
|
||||
|
||||
vst2q_s16(xy + (x1 << 1), v_dst);
|
||||
}
|
||||
#elif CV_SSE4_1
|
||||
if (useSSE4_1)
|
||||
{
|
||||
__m128i v_X0 = _mm_set1_epi32(X0);
|
||||
__m128i v_Y0 = _mm_set1_epi32(Y0);
|
||||
for ( ; x1 <= bw - 16; x1 += 16)
|
||||
{
|
||||
__m128i v_x0 = _mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(v_X0, _mm_loadu_si128((__m128i const *)(adelta + x + x1))), AB_BITS),
|
||||
_mm_srai_epi32(_mm_add_epi32(v_X0, _mm_loadu_si128((__m128i const *)(adelta + x + x1 + 4))), AB_BITS));
|
||||
__m128i v_x1 = _mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(v_X0, _mm_loadu_si128((__m128i const *)(adelta + x + x1 + 8))), AB_BITS),
|
||||
_mm_srai_epi32(_mm_add_epi32(v_X0, _mm_loadu_si128((__m128i const *)(adelta + x + x1 + 12))), AB_BITS));
|
||||
|
||||
__m128i v_y0 = _mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(v_Y0, _mm_loadu_si128((__m128i const *)(bdelta + x + x1))), AB_BITS),
|
||||
_mm_srai_epi32(_mm_add_epi32(v_Y0, _mm_loadu_si128((__m128i const *)(bdelta + x + x1 + 4))), AB_BITS));
|
||||
__m128i v_y1 = _mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(v_Y0, _mm_loadu_si128((__m128i const *)(bdelta + x + x1 + 8))), AB_BITS),
|
||||
_mm_srai_epi32(_mm_add_epi32(v_Y0, _mm_loadu_si128((__m128i const *)(bdelta + x + x1 + 12))), AB_BITS));
|
||||
|
||||
_mm_interleave_epi16(v_x0, v_x1, v_y0, v_y1);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2), v_x0);
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2 + 8), v_x1);
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2 + 16), v_y0);
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2 + 24), v_y1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for( ; x1 < bw; x1++ )
|
||||
{
|
||||
@@ -4971,7 +5302,7 @@ public:
|
||||
short* alpha = A + y1*bw;
|
||||
x1 = 0;
|
||||
#if CV_SSE2
|
||||
if( useSIMD )
|
||||
if( useSSE2 )
|
||||
{
|
||||
__m128i fxy_mask = _mm_set1_epi32(INTER_TAB_SIZE - 1);
|
||||
__m128i XX = _mm_set1_epi32(X0), YY = _mm_set1_epi32(Y0);
|
||||
@@ -5364,6 +5695,20 @@ public:
|
||||
int bw0 = std::min(BLOCK_SZ*BLOCK_SZ/bh0, width);
|
||||
bh0 = std::min(BLOCK_SZ*BLOCK_SZ/bw0, height);
|
||||
|
||||
#if CV_SSE4_1
|
||||
bool haveSSE4_1 = checkHardwareSupport(CV_CPU_SSE4_1);
|
||||
__m128d v_M0 = _mm_set1_pd(M[0]);
|
||||
__m128d v_M3 = _mm_set1_pd(M[3]);
|
||||
__m128d v_M6 = _mm_set1_pd(M[6]);
|
||||
__m128d v_intmax = _mm_set1_pd((double)INT_MAX);
|
||||
__m128d v_intmin = _mm_set1_pd((double)INT_MIN);
|
||||
__m128d v_2 = _mm_set1_pd(2),
|
||||
v_zero = _mm_setzero_pd(),
|
||||
v_1 = _mm_set1_pd(1),
|
||||
v_its = _mm_set1_pd(INTER_TAB_SIZE);
|
||||
__m128i v_itsi1 = _mm_set1_epi32(INTER_TAB_SIZE - 1);
|
||||
#endif
|
||||
|
||||
for( y = range.start; y < range.end; y += bh0 )
|
||||
{
|
||||
for( x = 0; x < width; x += bw0 )
|
||||
@@ -5382,7 +5727,120 @@ public:
|
||||
double W0 = M[6]*x + M[7]*(y + y1) + M[8];
|
||||
|
||||
if( interpolation == INTER_NEAREST )
|
||||
for( x1 = 0; x1 < bw; x1++ )
|
||||
{
|
||||
x1 = 0;
|
||||
|
||||
#if CV_SSE4_1
|
||||
if (haveSSE4_1)
|
||||
{
|
||||
__m128d v_X0d = _mm_set1_pd(X0);
|
||||
__m128d v_Y0d = _mm_set1_pd(Y0);
|
||||
__m128d v_W0 = _mm_set1_pd(W0);
|
||||
__m128d v_x1 = _mm_set_pd(1, 0);
|
||||
|
||||
for( ; x1 <= bw - 16; x1 += 16 )
|
||||
{
|
||||
// 0-3
|
||||
__m128i v_X0, v_Y0;
|
||||
{
|
||||
__m128d v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_1, v_W));
|
||||
__m128d v_fX0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_1, v_W));
|
||||
__m128d v_fX1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_X0 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX1))));
|
||||
v_Y0 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY1))));
|
||||
}
|
||||
|
||||
// 4-8
|
||||
__m128i v_X1, v_Y1;
|
||||
{
|
||||
__m128d v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_1, v_W));
|
||||
__m128d v_fX0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_1, v_W));
|
||||
__m128d v_fX1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_X1 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX1))));
|
||||
v_Y1 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY1))));
|
||||
}
|
||||
|
||||
// 8-11
|
||||
__m128i v_X2, v_Y2;
|
||||
{
|
||||
__m128d v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_1, v_W));
|
||||
__m128d v_fX0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_1, v_W));
|
||||
__m128d v_fX1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_X2 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX1))));
|
||||
v_Y2 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY1))));
|
||||
}
|
||||
|
||||
// 12-15
|
||||
__m128i v_X3, v_Y3;
|
||||
{
|
||||
__m128d v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_1, v_W));
|
||||
__m128d v_fX0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_1, v_W));
|
||||
__m128d v_fX1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_X3 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX1))));
|
||||
v_Y3 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY1))));
|
||||
}
|
||||
|
||||
// convert to 16s
|
||||
v_X0 = _mm_packs_epi32(v_X0, v_X1);
|
||||
v_X1 = _mm_packs_epi32(v_X2, v_X3);
|
||||
v_Y0 = _mm_packs_epi32(v_Y0, v_Y1);
|
||||
v_Y1 = _mm_packs_epi32(v_Y2, v_Y3);
|
||||
|
||||
_mm_interleave_epi16(v_X0, v_X1, v_Y0, v_Y1);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2), v_X0);
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2 + 8), v_X1);
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2 + 16), v_Y0);
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2 + 24), v_Y1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; x1 < bw; x1++ )
|
||||
{
|
||||
double W = W0 + M[6]*x1;
|
||||
W = W ? 1./W : 0;
|
||||
@@ -5394,10 +5852,136 @@ public:
|
||||
xy[x1*2] = saturate_cast<short>(X);
|
||||
xy[x1*2+1] = saturate_cast<short>(Y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
short* alpha = A + y1*bw;
|
||||
for( x1 = 0; x1 < bw; x1++ )
|
||||
x1 = 0;
|
||||
|
||||
#if CV_SSE4_1
|
||||
if (haveSSE4_1)
|
||||
{
|
||||
__m128d v_X0d = _mm_set1_pd(X0);
|
||||
__m128d v_Y0d = _mm_set1_pd(Y0);
|
||||
__m128d v_W0 = _mm_set1_pd(W0);
|
||||
__m128d v_x1 = _mm_set_pd(1, 0);
|
||||
|
||||
for( ; x1 <= bw - 16; x1 += 16 )
|
||||
{
|
||||
// 0-3
|
||||
__m128i v_X0, v_Y0;
|
||||
{
|
||||
__m128d v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_its, v_W));
|
||||
__m128d v_fX0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_its, v_W));
|
||||
__m128d v_fX1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_X0 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX1))));
|
||||
v_Y0 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY1))));
|
||||
}
|
||||
|
||||
// 4-8
|
||||
__m128i v_X1, v_Y1;
|
||||
{
|
||||
__m128d v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_its, v_W));
|
||||
__m128d v_fX0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_its, v_W));
|
||||
__m128d v_fX1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_X1 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX1))));
|
||||
v_Y1 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY1))));
|
||||
}
|
||||
|
||||
// 8-11
|
||||
__m128i v_X2, v_Y2;
|
||||
{
|
||||
__m128d v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_its, v_W));
|
||||
__m128d v_fX0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_its, v_W));
|
||||
__m128d v_fX1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_X2 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX1))));
|
||||
v_Y2 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY1))));
|
||||
}
|
||||
|
||||
// 12-15
|
||||
__m128i v_X3, v_Y3;
|
||||
{
|
||||
__m128d v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_its, v_W));
|
||||
__m128d v_fX0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY0 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_W = _mm_add_pd(_mm_mul_pd(v_M6, v_x1), v_W0);
|
||||
v_W = _mm_andnot_pd(_mm_cmpeq_pd(v_W, v_zero), _mm_div_pd(v_its, v_W));
|
||||
__m128d v_fX1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_X0d, _mm_mul_pd(v_M0, v_x1)), v_W)));
|
||||
__m128d v_fY1 = _mm_max_pd(v_intmin, _mm_min_pd(v_intmax, _mm_mul_pd(_mm_add_pd(v_Y0d, _mm_mul_pd(v_M3, v_x1)), v_W)));
|
||||
v_x1 = _mm_add_pd(v_x1, v_2);
|
||||
|
||||
v_X3 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fX1))));
|
||||
v_Y3 = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY0)),
|
||||
_mm_castsi128_ps(_mm_cvtpd_epi32(v_fY1))));
|
||||
}
|
||||
|
||||
// store alpha
|
||||
__m128i v_alpha0 = _mm_add_epi32(_mm_slli_epi32(_mm_and_si128(v_Y0, v_itsi1), INTER_BITS),
|
||||
_mm_and_si128(v_X0, v_itsi1));
|
||||
__m128i v_alpha1 = _mm_add_epi32(_mm_slli_epi32(_mm_and_si128(v_Y1, v_itsi1), INTER_BITS),
|
||||
_mm_and_si128(v_X1, v_itsi1));
|
||||
_mm_storeu_si128((__m128i *)(alpha + x1), _mm_packs_epi32(v_alpha0, v_alpha1));
|
||||
|
||||
v_alpha0 = _mm_add_epi32(_mm_slli_epi32(_mm_and_si128(v_Y2, v_itsi1), INTER_BITS),
|
||||
_mm_and_si128(v_X2, v_itsi1));
|
||||
v_alpha1 = _mm_add_epi32(_mm_slli_epi32(_mm_and_si128(v_Y3, v_itsi1), INTER_BITS),
|
||||
_mm_and_si128(v_X3, v_itsi1));
|
||||
_mm_storeu_si128((__m128i *)(alpha + x1 + 8), _mm_packs_epi32(v_alpha0, v_alpha1));
|
||||
|
||||
// convert to 16s
|
||||
v_X0 = _mm_packs_epi32(_mm_srai_epi32(v_X0, INTER_BITS), _mm_srai_epi32(v_X1, INTER_BITS));
|
||||
v_X1 = _mm_packs_epi32(_mm_srai_epi32(v_X2, INTER_BITS), _mm_srai_epi32(v_X3, INTER_BITS));
|
||||
v_Y0 = _mm_packs_epi32(_mm_srai_epi32(v_Y0, INTER_BITS), _mm_srai_epi32(v_Y1, INTER_BITS));
|
||||
v_Y1 = _mm_packs_epi32(_mm_srai_epi32(v_Y2, INTER_BITS), _mm_srai_epi32(v_Y3, INTER_BITS));
|
||||
|
||||
_mm_interleave_epi16(v_X0, v_X1, v_Y0, v_Y1);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2), v_X0);
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2 + 8), v_X1);
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2 + 16), v_Y0);
|
||||
_mm_storeu_si128((__m128i *)(xy + x1 * 2 + 24), v_Y1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; x1 < bw; x1++ )
|
||||
{
|
||||
double W = W0 + M[6]*x1;
|
||||
W = W ? INTER_TAB_SIZE/W : 0;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014-2015, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -183,13 +184,336 @@ struct PyrDownVec_32f
|
||||
}
|
||||
};
|
||||
|
||||
typedef PyrDownNoVec<int, ushort> PyrDownVec_32s16u;
|
||||
typedef PyrDownNoVec<int, short> PyrDownVec_32s16s;
|
||||
#if CV_SSE4_1
|
||||
|
||||
struct PyrDownVec_32s16u
|
||||
{
|
||||
PyrDownVec_32s16u()
|
||||
{
|
||||
haveSSE = checkHardwareSupport(CV_CPU_SSE4_1);
|
||||
}
|
||||
|
||||
int operator()(int** src, ushort* dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
if (!haveSSE)
|
||||
return x;
|
||||
|
||||
const int *row0 = src[0], *row1 = src[1], *row2 = src[2], *row3 = src[3], *row4 = src[4];
|
||||
__m128i v_delta = _mm_set1_epi32(128);
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
__m128i v_r00 = _mm_loadu_si128((__m128i const *)(row0 + x)),
|
||||
v_r01 = _mm_loadu_si128((__m128i const *)(row0 + x + 4));
|
||||
__m128i v_r10 = _mm_loadu_si128((__m128i const *)(row1 + x)),
|
||||
v_r11 = _mm_loadu_si128((__m128i const *)(row1 + x + 4));
|
||||
__m128i v_r20 = _mm_loadu_si128((__m128i const *)(row2 + x)),
|
||||
v_r21 = _mm_loadu_si128((__m128i const *)(row2 + x + 4));
|
||||
__m128i v_r30 = _mm_loadu_si128((__m128i const *)(row3 + x)),
|
||||
v_r31 = _mm_loadu_si128((__m128i const *)(row3 + x + 4));
|
||||
__m128i v_r40 = _mm_loadu_si128((__m128i const *)(row4 + x)),
|
||||
v_r41 = _mm_loadu_si128((__m128i const *)(row4 + x + 4));
|
||||
|
||||
v_r00 = _mm_add_epi32(_mm_add_epi32(v_r00, v_r40), _mm_add_epi32(v_r20, v_r20));
|
||||
v_r10 = _mm_add_epi32(_mm_add_epi32(v_r10, v_r20), v_r30);
|
||||
|
||||
v_r10 = _mm_slli_epi32(v_r10, 2);
|
||||
__m128i v_dst0 = _mm_srli_epi32(_mm_add_epi32(_mm_add_epi32(v_r00, v_r10), v_delta), 8);
|
||||
|
||||
v_r01 = _mm_add_epi32(_mm_add_epi32(v_r01, v_r41), _mm_add_epi32(v_r21, v_r21));
|
||||
v_r11 = _mm_add_epi32(_mm_add_epi32(v_r11, v_r21), v_r31);
|
||||
v_r11 = _mm_slli_epi32(v_r11, 2);
|
||||
__m128i v_dst1 = _mm_srli_epi32(_mm_add_epi32(_mm_add_epi32(v_r01, v_r11), v_delta), 8);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(dst + x), _mm_packus_epi32(v_dst0, v_dst1));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
bool haveSSE;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
typedef PyrDownNoVec<int, ushort> PyrDownVec_32s16u;
|
||||
|
||||
#endif // CV_SSE4_1
|
||||
|
||||
struct PyrDownVec_32s16s
|
||||
{
|
||||
PyrDownVec_32s16s()
|
||||
{
|
||||
haveSSE = checkHardwareSupport(CV_CPU_SSE2);
|
||||
}
|
||||
|
||||
int operator()(int** src, short* dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
if (!haveSSE)
|
||||
return x;
|
||||
|
||||
const int *row0 = src[0], *row1 = src[1], *row2 = src[2], *row3 = src[3], *row4 = src[4];
|
||||
__m128i v_delta = _mm_set1_epi32(128);
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
__m128i v_r00 = _mm_loadu_si128((__m128i const *)(row0 + x)),
|
||||
v_r01 = _mm_loadu_si128((__m128i const *)(row0 + x + 4));
|
||||
__m128i v_r10 = _mm_loadu_si128((__m128i const *)(row1 + x)),
|
||||
v_r11 = _mm_loadu_si128((__m128i const *)(row1 + x + 4));
|
||||
__m128i v_r20 = _mm_loadu_si128((__m128i const *)(row2 + x)),
|
||||
v_r21 = _mm_loadu_si128((__m128i const *)(row2 + x + 4));
|
||||
__m128i v_r30 = _mm_loadu_si128((__m128i const *)(row3 + x)),
|
||||
v_r31 = _mm_loadu_si128((__m128i const *)(row3 + x + 4));
|
||||
__m128i v_r40 = _mm_loadu_si128((__m128i const *)(row4 + x)),
|
||||
v_r41 = _mm_loadu_si128((__m128i const *)(row4 + x + 4));
|
||||
|
||||
v_r00 = _mm_add_epi32(_mm_add_epi32(v_r00, v_r40), _mm_add_epi32(v_r20, v_r20));
|
||||
v_r10 = _mm_add_epi32(_mm_add_epi32(v_r10, v_r20), v_r30);
|
||||
|
||||
v_r10 = _mm_slli_epi32(v_r10, 2);
|
||||
__m128i v_dst0 = _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(v_r00, v_r10), v_delta), 8);
|
||||
|
||||
v_r01 = _mm_add_epi32(_mm_add_epi32(v_r01, v_r41), _mm_add_epi32(v_r21, v_r21));
|
||||
v_r11 = _mm_add_epi32(_mm_add_epi32(v_r11, v_r21), v_r31);
|
||||
v_r11 = _mm_slli_epi32(v_r11, 2);
|
||||
__m128i v_dst1 = _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(v_r01, v_r11), v_delta), 8);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(dst + x), _mm_packs_epi32(v_dst0, v_dst1));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
bool haveSSE;
|
||||
};
|
||||
|
||||
struct PyrUpVec_32s8u
|
||||
{
|
||||
int operator()(int** src, uchar** dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
if (!checkHardwareSupport(CV_CPU_SSE2))
|
||||
return x;
|
||||
|
||||
uchar *dst0 = dst[0], *dst1 = dst[1];
|
||||
const uint *row0 = (uint *)src[0], *row1 = (uint *)src[1], *row2 = (uint *)src[2];
|
||||
__m128i v_delta = _mm_set1_epi16(32), v_zero = _mm_setzero_si128();
|
||||
|
||||
for( ; x <= width - 16; x += 16 )
|
||||
{
|
||||
__m128i v_r0 = _mm_packs_epi32(_mm_loadu_si128((__m128i const *)(row0 + x)),
|
||||
_mm_loadu_si128((__m128i const *)(row0 + x + 4)));
|
||||
__m128i v_r1 = _mm_packs_epi32(_mm_loadu_si128((__m128i const *)(row1 + x)),
|
||||
_mm_loadu_si128((__m128i const *)(row1 + x + 4)));
|
||||
__m128i v_r2 = _mm_packs_epi32(_mm_loadu_si128((__m128i const *)(row2 + x)),
|
||||
_mm_loadu_si128((__m128i const *)(row2 + x + 4)));
|
||||
|
||||
__m128i v_2r1 = _mm_adds_epu16(v_r1, v_r1), v_4r1 = _mm_adds_epu16(v_2r1, v_2r1);
|
||||
__m128i v_dst00 = _mm_adds_epu16(_mm_adds_epu16(v_r0, v_r2), _mm_adds_epu16(v_2r1, v_4r1));
|
||||
__m128i v_dst10 = _mm_slli_epi16(_mm_adds_epu16(v_r1, v_r2), 2);
|
||||
|
||||
v_r0 = _mm_packs_epi32(_mm_loadu_si128((__m128i const *)(row0 + x + 8)),
|
||||
_mm_loadu_si128((__m128i const *)(row0 + x + 12)));
|
||||
v_r1 = _mm_packs_epi32(_mm_loadu_si128((__m128i const *)(row1 + x + 8)),
|
||||
_mm_loadu_si128((__m128i const *)(row1 + x + 12)));
|
||||
v_r2 = _mm_packs_epi32(_mm_loadu_si128((__m128i const *)(row2 + x + 8)),
|
||||
_mm_loadu_si128((__m128i const *)(row2 + x + 12)));
|
||||
|
||||
v_2r1 = _mm_adds_epu16(v_r1, v_r1), v_4r1 = _mm_adds_epu16(v_2r1, v_2r1);
|
||||
__m128i v_dst01 = _mm_adds_epu16(_mm_adds_epu16(v_r0, v_r2), _mm_adds_epu16(v_2r1, v_4r1));
|
||||
__m128i v_dst11 = _mm_slli_epi16(_mm_adds_epu16(v_r1, v_r2), 2);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(dst0 + x), _mm_packus_epi16(_mm_srli_epi16(_mm_adds_epu16(v_dst00, v_delta), 6),
|
||||
_mm_srli_epi16(_mm_adds_epu16(v_dst01, v_delta), 6)));
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x), _mm_packus_epi16(_mm_srli_epi16(_mm_adds_epu16(v_dst10, v_delta), 6),
|
||||
_mm_srli_epi16(_mm_adds_epu16(v_dst11, v_delta), 6)));
|
||||
}
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
__m128i v_r0 = _mm_packs_epi32(_mm_loadu_si128((__m128i const *)(row0 + x)),
|
||||
_mm_loadu_si128((__m128i const *)(row0 + x + 4)));
|
||||
__m128i v_r1 = _mm_packs_epi32(_mm_loadu_si128((__m128i const *)(row1 + x)),
|
||||
_mm_loadu_si128((__m128i const *)(row1 + x + 4)));
|
||||
__m128i v_r2 = _mm_packs_epi32(_mm_loadu_si128((__m128i const *)(row2 + x)),
|
||||
_mm_loadu_si128((__m128i const *)(row2 + x + 4)));
|
||||
|
||||
__m128i v_2r1 = _mm_adds_epu16(v_r1, v_r1), v_4r1 = _mm_adds_epu16(v_2r1, v_2r1);
|
||||
__m128i v_dst0 = _mm_adds_epu16(_mm_adds_epu16(v_r0, v_r2), _mm_adds_epu16(v_2r1, v_4r1));
|
||||
__m128i v_dst1 = _mm_slli_epi16(_mm_adds_epu16(v_r1, v_r2), 2);
|
||||
|
||||
_mm_storel_epi64((__m128i *)(dst0 + x), _mm_packus_epi16(_mm_srli_epi16(_mm_adds_epu16(v_dst0, v_delta), 6), v_zero));
|
||||
_mm_storel_epi64((__m128i *)(dst1 + x), _mm_packus_epi16(_mm_srli_epi16(_mm_adds_epu16(v_dst1, v_delta), 6), v_zero));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
struct PyrUpVec_32s16s
|
||||
{
|
||||
int operator()(int** src, short** dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
if (!checkHardwareSupport(CV_CPU_SSE2))
|
||||
return x;
|
||||
|
||||
short *dst0 = dst[0], *dst1 = dst[1];
|
||||
const uint *row0 = (uint *)src[0], *row1 = (uint *)src[1], *row2 = (uint *)src[2];
|
||||
__m128i v_delta = _mm_set1_epi32(32), v_zero = _mm_setzero_si128();
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
__m128i v_r0 = _mm_loadu_si128((__m128i const *)(row0 + x)),
|
||||
v_r1 = _mm_loadu_si128((__m128i const *)(row1 + x)),
|
||||
v_r2 = _mm_loadu_si128((__m128i const *)(row2 + x));
|
||||
__m128i v_2r1 = _mm_slli_epi32(v_r1, 1), v_4r1 = _mm_slli_epi32(v_r1, 2);
|
||||
__m128i v_dst00 = _mm_add_epi32(_mm_add_epi32(v_r0, v_r2), _mm_add_epi32(v_2r1, v_4r1));
|
||||
__m128i v_dst10 = _mm_slli_epi32(_mm_add_epi32(v_r1, v_r2), 2);
|
||||
|
||||
v_r0 = _mm_loadu_si128((__m128i const *)(row0 + x + 4));
|
||||
v_r1 = _mm_loadu_si128((__m128i const *)(row1 + x + 4));
|
||||
v_r2 = _mm_loadu_si128((__m128i const *)(row2 + x + 4));
|
||||
v_2r1 = _mm_slli_epi32(v_r1, 1);
|
||||
v_4r1 = _mm_slli_epi32(v_r1, 2);
|
||||
__m128i v_dst01 = _mm_add_epi32(_mm_add_epi32(v_r0, v_r2), _mm_add_epi32(v_2r1, v_4r1));
|
||||
__m128i v_dst11 = _mm_slli_epi32(_mm_add_epi32(v_r1, v_r2), 2);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(dst0 + x),
|
||||
_mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(v_dst00, v_delta), 6),
|
||||
_mm_srai_epi32(_mm_add_epi32(v_dst01, v_delta), 6)));
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x),
|
||||
_mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(v_dst10, v_delta), 6),
|
||||
_mm_srai_epi32(_mm_add_epi32(v_dst11, v_delta), 6)));
|
||||
}
|
||||
|
||||
for( ; x <= width - 4; x += 4 )
|
||||
{
|
||||
__m128i v_r0 = _mm_loadu_si128((__m128i const *)(row0 + x)),
|
||||
v_r1 = _mm_loadu_si128((__m128i const *)(row1 + x)),
|
||||
v_r2 = _mm_loadu_si128((__m128i const *)(row2 + x));
|
||||
__m128i v_2r1 = _mm_slli_epi32(v_r1, 1), v_4r1 = _mm_slli_epi32(v_r1, 2);
|
||||
|
||||
__m128i v_dst0 = _mm_add_epi32(_mm_add_epi32(v_r0, v_r2), _mm_add_epi32(v_2r1, v_4r1));
|
||||
__m128i v_dst1 = _mm_slli_epi32(_mm_add_epi32(v_r1, v_r2), 2);
|
||||
|
||||
_mm_storel_epi64((__m128i *)(dst0 + x),
|
||||
_mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(v_dst0, v_delta), 6), v_zero));
|
||||
_mm_storel_epi64((__m128i *)(dst1 + x),
|
||||
_mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(v_dst1, v_delta), 6), v_zero));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
#if CV_SSE4_1
|
||||
|
||||
struct PyrUpVec_32s16u
|
||||
{
|
||||
int operator()(int** src, ushort** dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
if (!checkHardwareSupport(CV_CPU_SSE4_1))
|
||||
return x;
|
||||
|
||||
ushort *dst0 = dst[0], *dst1 = dst[1];
|
||||
const uint *row0 = (uint *)src[0], *row1 = (uint *)src[1], *row2 = (uint *)src[2];
|
||||
__m128i v_delta = _mm_set1_epi32(32), v_zero = _mm_setzero_si128();
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
__m128i v_r0 = _mm_loadu_si128((__m128i const *)(row0 + x)),
|
||||
v_r1 = _mm_loadu_si128((__m128i const *)(row1 + x)),
|
||||
v_r2 = _mm_loadu_si128((__m128i const *)(row2 + x));
|
||||
__m128i v_2r1 = _mm_slli_epi32(v_r1, 1), v_4r1 = _mm_slli_epi32(v_r1, 2);
|
||||
__m128i v_dst00 = _mm_add_epi32(_mm_add_epi32(v_r0, v_r2), _mm_add_epi32(v_2r1, v_4r1));
|
||||
__m128i v_dst10 = _mm_slli_epi32(_mm_add_epi32(v_r1, v_r2), 2);
|
||||
|
||||
v_r0 = _mm_loadu_si128((__m128i const *)(row0 + x + 4));
|
||||
v_r1 = _mm_loadu_si128((__m128i const *)(row1 + x + 4));
|
||||
v_r2 = _mm_loadu_si128((__m128i const *)(row2 + x + 4));
|
||||
v_2r1 = _mm_slli_epi32(v_r1, 1);
|
||||
v_4r1 = _mm_slli_epi32(v_r1, 2);
|
||||
__m128i v_dst01 = _mm_add_epi32(_mm_add_epi32(v_r0, v_r2), _mm_add_epi32(v_2r1, v_4r1));
|
||||
__m128i v_dst11 = _mm_slli_epi32(_mm_add_epi32(v_r1, v_r2), 2);
|
||||
|
||||
_mm_storeu_si128((__m128i *)(dst0 + x),
|
||||
_mm_packus_epi32(_mm_srli_epi32(_mm_add_epi32(v_dst00, v_delta), 6),
|
||||
_mm_srli_epi32(_mm_add_epi32(v_dst01, v_delta), 6)));
|
||||
_mm_storeu_si128((__m128i *)(dst1 + x),
|
||||
_mm_packus_epi32(_mm_srli_epi32(_mm_add_epi32(v_dst10, v_delta), 6),
|
||||
_mm_srli_epi32(_mm_add_epi32(v_dst11, v_delta), 6)));
|
||||
}
|
||||
|
||||
for( ; x <= width - 4; x += 4 )
|
||||
{
|
||||
__m128i v_r0 = _mm_loadu_si128((__m128i const *)(row0 + x)),
|
||||
v_r1 = _mm_loadu_si128((__m128i const *)(row1 + x)),
|
||||
v_r2 = _mm_loadu_si128((__m128i const *)(row2 + x));
|
||||
__m128i v_2r1 = _mm_slli_epi32(v_r1, 1), v_4r1 = _mm_slli_epi32(v_r1, 2);
|
||||
|
||||
__m128i v_dst0 = _mm_add_epi32(_mm_add_epi32(v_r0, v_r2), _mm_add_epi32(v_2r1, v_4r1));
|
||||
__m128i v_dst1 = _mm_slli_epi32(_mm_add_epi32(v_r1, v_r2), 2);
|
||||
|
||||
_mm_storel_epi64((__m128i *)(dst0 + x),
|
||||
_mm_packus_epi32(_mm_srli_epi32(_mm_add_epi32(v_dst0, v_delta), 6), v_zero));
|
||||
_mm_storel_epi64((__m128i *)(dst1 + x),
|
||||
_mm_packus_epi32(_mm_srli_epi32(_mm_add_epi32(v_dst1, v_delta), 6), v_zero));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
typedef PyrUpNoVec<int, uchar> PyrUpVec_32s8u;
|
||||
typedef PyrUpNoVec<int, short> PyrUpVec_32s16s;
|
||||
typedef PyrUpNoVec<int, ushort> PyrUpVec_32s16u;
|
||||
typedef PyrUpNoVec<float, float> PyrUpVec_32f;
|
||||
|
||||
#endif // CV_SSE4_1
|
||||
|
||||
struct PyrUpVec_32f
|
||||
{
|
||||
int operator()(float** src, float** dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
if (!checkHardwareSupport(CV_CPU_SSE2))
|
||||
return x;
|
||||
|
||||
const float *row0 = src[0], *row1 = src[1], *row2 = src[2];
|
||||
float *dst0 = dst[0], *dst1 = dst[1];
|
||||
__m128 v_6 = _mm_set1_ps(6.0f), v_scale = _mm_set1_ps(1.f/64.0f),
|
||||
v_scale4 = _mm_mul_ps(v_scale, _mm_set1_ps(4.0f));
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
__m128 v_r0 = _mm_loadu_ps(row0 + x);
|
||||
__m128 v_r1 = _mm_loadu_ps(row1 + x);
|
||||
__m128 v_r2 = _mm_loadu_ps(row2 + x);
|
||||
|
||||
_mm_storeu_ps(dst1 + x, _mm_mul_ps(v_scale4, _mm_add_ps(v_r1, v_r2)));
|
||||
_mm_storeu_ps(dst0 + x, _mm_mul_ps(v_scale, _mm_add_ps(_mm_add_ps(v_r0, _mm_mul_ps(v_6, v_r1)), v_r2)));
|
||||
|
||||
v_r0 = _mm_loadu_ps(row0 + x + 4);
|
||||
v_r1 = _mm_loadu_ps(row1 + x + 4);
|
||||
v_r2 = _mm_loadu_ps(row2 + x + 4);
|
||||
|
||||
_mm_storeu_ps(dst1 + x + 4, _mm_mul_ps(v_scale4, _mm_add_ps(v_r1, v_r2)));
|
||||
_mm_storeu_ps(dst0 + x + 4, _mm_mul_ps(v_scale, _mm_add_ps(_mm_add_ps(v_r0, _mm_mul_ps(v_6, v_r1)), v_r2)));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
#elif CV_NEON
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014-2015, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -713,6 +714,156 @@ struct ColumnSum<int, ushort> :
|
||||
std::vector<int> sum;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ColumnSum<int, int> :
|
||||
public BaseColumnFilter
|
||||
{
|
||||
ColumnSum( int _ksize, int _anchor, double _scale ) :
|
||||
BaseColumnFilter()
|
||||
{
|
||||
ksize = _ksize;
|
||||
anchor = _anchor;
|
||||
scale = _scale;
|
||||
sumCount = 0;
|
||||
}
|
||||
|
||||
virtual void reset() { sumCount = 0; }
|
||||
|
||||
virtual void operator()(const uchar** src, uchar* dst, int dststep, int count, int width)
|
||||
{
|
||||
int i;
|
||||
int* SUM;
|
||||
bool haveScale = scale != 1;
|
||||
double _scale = scale;
|
||||
|
||||
#if CV_SSE2
|
||||
bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2);
|
||||
#endif
|
||||
|
||||
if( width != (int)sum.size() )
|
||||
{
|
||||
sum.resize(width);
|
||||
sumCount = 0;
|
||||
}
|
||||
SUM = &sum[0];
|
||||
if( sumCount == 0 )
|
||||
{
|
||||
memset((void*)SUM, 0, width*sizeof(int));
|
||||
for( ; sumCount < ksize - 1; sumCount++, src++ )
|
||||
{
|
||||
const int* Sp = (const int*)src[0];
|
||||
i = 0;
|
||||
#if CV_SSE2
|
||||
if(haveSSE2)
|
||||
{
|
||||
for( ; i <= width-4; i+=4 )
|
||||
{
|
||||
__m128i _sum = _mm_loadu_si128((const __m128i*)(SUM+i));
|
||||
__m128i _sp = _mm_loadu_si128((const __m128i*)(Sp+i));
|
||||
_mm_storeu_si128((__m128i*)(SUM+i),_mm_add_epi32(_sum, _sp));
|
||||
}
|
||||
}
|
||||
#elif CV_NEON
|
||||
for( ; i <= width - 4; i+=4 )
|
||||
vst1q_s32(SUM + i, vaddq_s32(vld1q_s32(SUM + i), vld1q_s32(Sp + i)));
|
||||
#endif
|
||||
for( ; i < width; i++ )
|
||||
SUM[i] += Sp[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert( sumCount == ksize-1 );
|
||||
src += ksize-1;
|
||||
}
|
||||
|
||||
for( ; count--; src++ )
|
||||
{
|
||||
const int* Sp = (const int*)src[0];
|
||||
const int* Sm = (const int*)src[1-ksize];
|
||||
int* D = (int*)dst;
|
||||
if( haveScale )
|
||||
{
|
||||
i = 0;
|
||||
#if CV_SSE2
|
||||
if(haveSSE2)
|
||||
{
|
||||
const __m128 scale4 = _mm_set1_ps((float)_scale);
|
||||
for( ; i <= width-4; i+=4 )
|
||||
{
|
||||
__m128i _sm = _mm_loadu_si128((const __m128i*)(Sm+i));
|
||||
|
||||
__m128i _s0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i)),
|
||||
_mm_loadu_si128((const __m128i*)(Sp+i)));
|
||||
|
||||
__m128i _s0T = _mm_cvtps_epi32(_mm_mul_ps(scale4, _mm_cvtepi32_ps(_s0)));
|
||||
|
||||
_mm_storeu_si128((__m128i*)(D+i), _s0T);
|
||||
_mm_storeu_si128((__m128i*)(SUM+i),_mm_sub_epi32(_s0,_sm));
|
||||
}
|
||||
}
|
||||
#elif CV_NEON
|
||||
float32x4_t v_scale = vdupq_n_f32((float)_scale);
|
||||
for( ; i <= width-4; i+=4 )
|
||||
{
|
||||
int32x4_t v_s0 = vaddq_s32(vld1q_s32(SUM + i), vld1q_s32(Sp + i));
|
||||
|
||||
int32x4_t v_s0d = cv_vrndq_s32_f32(vmulq_f32(vcvtq_f32_s32(v_s0), v_scale));
|
||||
vst1q_s32(D + i, v_s0d);
|
||||
|
||||
vst1q_s32(SUM + i, vsubq_s32(v_s0, vld1q_s32(Sm + i)));
|
||||
}
|
||||
#endif
|
||||
for( ; i < width; i++ )
|
||||
{
|
||||
int s0 = SUM[i] + Sp[i];
|
||||
D[i] = saturate_cast<int>(s0*_scale);
|
||||
SUM[i] = s0 - Sm[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
#if CV_SSE2
|
||||
if(haveSSE2)
|
||||
{
|
||||
for( ; i <= width-4; i+=4 )
|
||||
{
|
||||
__m128i _sm = _mm_loadu_si128((const __m128i*)(Sm+i));
|
||||
__m128i _s0 = _mm_add_epi32(_mm_loadu_si128((const __m128i*)(SUM+i)),
|
||||
_mm_loadu_si128((const __m128i*)(Sp+i)));
|
||||
|
||||
_mm_storeu_si128((__m128i*)(D+i), _s0);
|
||||
_mm_storeu_si128((__m128i*)(SUM+i), _mm_sub_epi32(_s0,_sm));
|
||||
}
|
||||
}
|
||||
#elif CV_NEON
|
||||
for( ; i <= width-4; i+=4 )
|
||||
{
|
||||
int32x4_t v_s0 = vaddq_s32(vld1q_s32(SUM + i), vld1q_s32(Sp + i));
|
||||
|
||||
vst1q_s32(D + i, v_s0);
|
||||
vst1q_s32(SUM + i, vsubq_s32(v_s0, vld1q_s32(Sm + i)));
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; i < width; i++ )
|
||||
{
|
||||
int s0 = SUM[i] + Sp[i];
|
||||
D[i] = s0;
|
||||
SUM[i] = s0 - Sm[i];
|
||||
}
|
||||
}
|
||||
dst += dststep;
|
||||
}
|
||||
}
|
||||
|
||||
double scale;
|
||||
int sumCount;
|
||||
std::vector<int> sum;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct ColumnSum<int, float> :
|
||||
public BaseColumnFilter
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
|
||||
Reference in New Issue
Block a user