8#ifndef META_OCEAN_CV_SSE_H
9#define META_OCEAN_CV_SSE_H
17#if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
45#if !defined(OCEAN_COMPILER_MSC)
65 static_assert(
sizeof(
M128i) == 16,
"Invalid data type!");
76 static_assert(
sizeof(
M128) == 16,
"Invalid data type!");
87 static_assert(
sizeof(
M128d) == 16,
"Invalid data type!");
97 static inline void prefetchT0(
const void*
const data);
103 static inline void prefetchT1(
const void*
const data);
109 static inline void prefetchT2(
const void*
const data);
115 static inline void prefetchNTA(
const void*
const data);
123 template <
unsigned int tIndex>
124 static inline uint8_t
value_u8(
const __m128i& value);
132 static inline uint8_t
value_u8(
const __m128i& value,
const unsigned int index);
140 template <
unsigned int tIndex>
141 static inline uint16_t
value_u16(
const __m128i& value);
149 template <
unsigned int tIndex>
150 static inline unsigned int value_u32(
const __m128i& value);
157 static OCEAN_FORCE_INLINE
unsigned int sum_u32_4(
const __m128i& value);
178 static OCEAN_FORCE_INLINE
float sum_f32_4(
const __m128& value);
185 static OCEAN_FORCE_INLINE
double sum_f64_2(
const __m128d& value);
223 template <
bool tBufferHas16Bytes>
244 template <
bool tBufferHas16Bytes>
426 static inline void average30Elements1Channel8Bit3x3(
const uint8_t*
const image0,
const uint8_t*
const image1,
const uint8_t*
const image2, uint8_t*
const result);
535 template <
bool tBufferHas16Bytes>
546 template <
bool tBufferHas16Bytes>
564 static inline __m128i
interpolation1Channel8Bit8Elements(
const __m128i& values0,
const __m128i& values1,
const __m128i& fx_fy_,
const __m128i& fxfy_,
const __m128i& fx_fy,
const __m128i& fxfy);
581 static inline __m128i
interpolation2Channel16Bit8Elements(
const __m128i& values0,
const __m128i& values1,
const __m128i& fx_fy_,
const __m128i& fxfy_,
const __m128i& fx_fy,
const __m128i& fxfy);
598 static inline __m128i
interpolation3Channel24Bit8Elements(
const __m128i& values0,
const __m128i& values1,
const __m128i& fx_fy_,
const __m128i& fxfy_,
const __m128i& fx_fy,
const __m128i& fxfy);
637 static inline __m128i
interpolation4Channel32Bit8Elements(
const __m128i& values0,
const __m128i& values1,
const __m128i& fx_fy_,
const __m128i& fxfy_,
const __m128i& fx_fy,
const __m128i& fxfy);
654 static inline __m128i
interpolation4Channel32Bit2x4Elements(
const __m128i& values0,
const __m128i& values1,
const __m128i& fx_fy_,
const __m128i& fxfy_,
const __m128i& fx_fy,
const __m128i& fxfy);
668 static inline unsigned int ssd2Channel16Bit1x1(
const uint8_t*
const pixel0,
const uint8_t*
const pixel1,
const unsigned int size0,
const unsigned int size1,
const unsigned int f1x_y_,
const unsigned int f1xy_,
const unsigned int f1x_y,
const unsigned int f1xy);
686 static inline unsigned int ssd2Channel16Bit1x1(
const uint8_t*
const pixel0,
const uint8_t*
const pixel1,
const unsigned int size0,
const unsigned int size1,
const unsigned int f0x_y_,
const unsigned int f0xy_,
const unsigned int f0x_y,
const unsigned int f0xy,
const unsigned int f1x_y_,
const unsigned int f1xy_,
const unsigned int f1x_y,
const unsigned int f1xy);
725 static OCEAN_FORCE_INLINE
void deInterleave3Channel8Bit48Elements(
const __m128i& interleavedA,
const __m128i& interleavedB,
const __m128i& interleavedC, __m128i& channel0, __m128i& channel1, __m128i& channel2);
764 OCEAN_FORCE_INLINE
static void interleave3Channel8Bit48Elements(
const __m128i& channel0,
const __m128i& channel1,
const __m128i& channel2, __m128i& interleavedA, __m128i& interleavedB, __m128i& interleavedC);
773 static OCEAN_FORCE_INLINE
void interleave3Channel8Bit48Elements(
const uint8_t*
const channel0,
const uint8_t*
const channel1,
const uint8_t*
const channel2, uint8_t*
const interleaved);
808 static OCEAN_FORCE_INLINE
void reverseChannelOrder3Channel8Bit48Elements(
const __m128i& interleaved0,
const __m128i& interleaved1,
const __m128i& interleaved2, __m128i& reversedInterleaved0, __m128i& reversedInterleaved1, __m128i& reversedInterleaved2);
846 static inline void reverseElements8Bit48Elements(
const __m128i& elements0,
const __m128i& elements1,
const __m128i& elements2, __m128i& reversedElements0, __m128i& reversedElements1, __m128i& reversedElements2);
923 template <
bool tBufferHas16Bytes>
975 static inline __m128i
load128i(
const void*
const buffer);
985 template <
bool tBufferHas16Bytes>
996 template <
bool tBufferHas16Bytes>
1007 template <
bool tBufferHas16Bytes>
1018 template <
bool tBufferHas16Bytes>
1029 template <
bool tBufferHas16Bytes>
1043 template <
unsigned int tShiftBytes>
1051 static inline void store128i(
const __m128i& value, uint8_t*
const buffer);
1059 static inline __m128i
set128i(
const unsigned long long high64,
const unsigned long long low64);
1257 static OCEAN_FORCE_INLINE
void multiplyInt8x16ToInt32x8(
const __m128i& values0,
const __m128i& values1, __m128i& products0, __m128i& products1);
1290 static inline unsigned int interpolation2Channel16Bit1x1(
const uint8_t*
const pixel,
const unsigned int size,
const unsigned int fx_y_,
const unsigned int fxy_,
const unsigned int fx_y,
const unsigned int fxy);
1295 _mm_prefetch((
char*)data, _MM_HINT_T0);
1300 _mm_prefetch((
char*)data, _MM_HINT_T1);
1305 _mm_prefetch((
char*)data, _MM_HINT_T2);
1310 _mm_prefetch((
char*)data, _MM_HINT_NTA);
1313template <
unsigned int tIndex>
1316 static_assert(tIndex <= 15u,
"Invalid index!");
1318#ifdef OCEAN_COMPILER_MSC
1319 return value.m128i_u8[tIndex];
1321 return ((
const M128i*)(&value))->m128i_u8[tIndex];
1327 ocean_assert(index <= 15u);
1329#ifdef OCEAN_COMPILER_MSC
1330 return value.m128i_u8[index];
1332 return ((
const M128i*)(&value))->m128i_u8[index];
1336template <
unsigned int tIndex>
1339 static_assert(tIndex <= 7u,
"Invalid index!");
1341#ifdef OCEAN_COMPILER_MSC
1342 return value.m128i_u16[tIndex];
1344 return ((
const M128i*)(&value))->m128i_u16[tIndex];
1348template <
unsigned int tIndex>
1351 static_assert(tIndex <= 3u,
"Invalid index!");
1353#ifdef OCEAN_COMPILER_MSC
1354 return value.m128i_u32[tIndex];
1356 return ((
const M128i*)(&value))->m128i_u32[tIndex];
1362#ifdef OCEAN_COMPILER_MSC
1363 return value.m128i_u32[0] + value.m128i_u32[1] + value.m128i_u32[2] + value.m128i_u32[3];
1365 return ((
const M128i*)(&value))->m128i_u32[0] + ((
const M128i*)(&value))->m128i_u32[1] + ((
const M128i*)(&value))->m128i_u32[2] + ((
const M128i*)(&value))->m128i_u32[3];
1371#ifdef OCEAN_COMPILER_MSC
1372 return value.m128i_u32[0] + value.m128i_u32[1];
1374 return ((
const M128i*)(&value))->m128i_u32[0] + ((
const M128i*)(&value))->m128i_u32[1];
1380#ifdef OCEAN_COMPILER_MSC
1381 return value.m128i_u32[0] + value.m128i_u32[2];
1383 return ((
const M128i*)(&value))->m128i_u32[0] + ((
const M128i*)(&value))->m128i_u32[2];
1389#ifdef OCEAN_COMPILER_MSC
1390 return value.m128_f32[0] + value.m128_f32[1] + value.m128_f32[2] + value.m128_f32[3];
1392 return ((
const M128*)(&value))->m128_f32[0] + ((
const M128*)(&value))->m128_f32[1] + ((
const M128*)(&value))->m128_f32[2] + ((
const M128*)(&value))->m128_f32[3];
1398#ifdef OCEAN_COMPILER_MSC
1399 return value.m128d_f64[0] + value.m128d_f64[1];
1401 return ((
const M128d*)(&value))->m128d_f64[0] + ((
const M128d*)(&value))->m128d_f64[1];
1407 ocean_assert(image0 && image1);
1414 ocean_assert(image0 && image1);
1421 ocean_assert(image0 && image1);
1423 const __m128i row0 = _mm_lddqu_si128((__m128i*)image0);
1424 const __m128i row1 = _mm_lddqu_si128((__m128i*)image1);
1427 const __m128i subtract = _mm_or_si128(_mm_subs_epu8(row0, row1), _mm_subs_epu8(row1, row0));
1431 const __m128i subtractLow = _mm_shuffle_epi8(subtract,
set128i(0xA0A0A0A0A00AA008ull, 0xA006A004A002A000ull));
1432 const __m128i subtractHigh = _mm_shuffle_epi8(subtract,
set128i(0xA0A0A0A0A00BA009ull, 0xA007A005A003A001ull));
1435 const __m128i squareLow = _mm_mullo_epi16(subtractLow, subtractLow);
1436 const __m128i squareHigh = _mm_mullo_epi16(subtractHigh, subtractHigh);
1443 return _mm_add_epi32(sumSquareLow, sumSquareHigh);
1448 ocean_assert(image0 && image1);
1450 const __m128i row0 = _mm_lddqu_si128((__m128i*)image0);
1451 const __m128i row1 = _mm_lddqu_si128((__m128i*)image1);
1454 const __m128i subtract = _mm_or_si128(_mm_subs_epu8(row0, row1), _mm_subs_epu8(row1, row0));
1458 const __m128i subtractLow = _mm_shuffle_epi8(subtract,
set128i(0xA0A0A0A0A00EA00Cull, 0xA00AA008A006A004ull));
1459 const __m128i subtractHigh = _mm_shuffle_epi8(subtract,
set128i(0xA0A0A0A0A00FA00Dull, 0xA00BA009A007A005ull));
1462 const __m128i squareLow = _mm_mullo_epi16(subtractLow, subtractLow);
1463 const __m128i squareHigh = _mm_mullo_epi16(subtractHigh, subtractHigh);
1470 return _mm_add_epi32(sumSquareLow, sumSquareHigh);
1473template <
bool tBufferHas16Bytes>
1476 ocean_assert(image0 && image1);
1478 const __m128i row0 = load_u8_13_lower_random<tBufferHas16Bytes>(image0);
1479 const __m128i row1 = load_u8_13_lower_random<tBufferHas16Bytes>(image1);
1482 const __m128i subtract = _mm_or_si128(_mm_subs_epu8(row0, row1), _mm_subs_epu8(row1, row0));
1486 const __m128i subtractLow = _mm_shuffle_epi8(subtract,
set128i(0xA0A0A00CA00AA008ull, 0xA006A004A002A000ull));
1487 const __m128i subtractHigh = _mm_shuffle_epi8(subtract,
set128i(0xA0A0A0A0A00BA009ull, 0xA007A005A003A001ull));
1490 const __m128i squareLow = _mm_mullo_epi16(subtractLow, subtractLow);
1491 const __m128i squareHigh = _mm_mullo_epi16(subtractHigh, subtractHigh);
1498 return _mm_add_epi32(sumSquareLow, sumSquareHigh);
1503 ocean_assert(image0 && image1);
1505 const __m128i row0 = _mm_lddqu_si128((__m128i*)image0);
1506 const __m128i row1 = _mm_lddqu_si128((__m128i*)image1);
1509 const __m128i subtract = _mm_or_si128(_mm_subs_epu8(row0, row1), _mm_subs_epu8(row1, row0));
1513 const __m128i subtractLow = _mm_shuffle_epi8(subtract,
set128i(0xA0A0A00FA00DA00Bull, 0xA009A007A005A003ull));
1514 const __m128i subtractHigh = _mm_shuffle_epi8(subtract,
set128i(0xA0A0A0A0A00EA00Cull, 0xA00AA008A006A004ull));
1517 const __m128i squareLow = _mm_mullo_epi16(subtractLow, subtractLow);
1518 const __m128i squareHigh = _mm_mullo_epi16(subtractHigh, subtractHigh);
1525 return _mm_add_epi32(sumSquareLow, sumSquareHigh);
1528template <
bool tBufferHas16Bytes>
1531 ocean_assert(image0 && image1);
1533 const __m128i row0 = load_u8_15_lower_random<tBufferHas16Bytes>(image0);
1534 const __m128i row1 = load_u8_15_lower_random<tBufferHas16Bytes>(image1);
1537 const __m128i subtract = _mm_or_si128(_mm_subs_epu8(row0, row1), _mm_subs_epu8(row1, row0));
1544 const __m128i squareLow = _mm_mullo_epi16(subtractLow, subtractLow);
1545 const __m128i squareHigh = _mm_mullo_epi16(subtractHigh, subtractHigh);
1552 return _mm_add_epi32(sumSquareLow, sumSquareHigh);
1555template <
bool tBufferHas16Bytes>
1558 ocean_assert(image0 && image1);
1560 return _mm_sad_epu8(load_u8_10_upper_zero<tBufferHas16Bytes>(image0), load_u8_10_upper_zero<tBufferHas16Bytes>(image1));
1563template <
bool tBufferHas16Bytes>
1566 ocean_assert(image0 && image1);
1568 return _mm_sad_epu8(load_u8_15_upper_zero<tBufferHas16Bytes>(image0), load_u8_15_upper_zero<tBufferHas16Bytes>(image1));
1573 ocean_assert(image0 && image1);
1575 const __m128i row0 = _mm_lddqu_si128((__m128i*)image0);
1576 const __m128i row1 = _mm_lddqu_si128((__m128i*)image1);
1583 ocean_assert(image0 && image1);
1590 ocean_assert(image0 && image1);
1591 ocean_assert((
unsigned long long)image0 % 16ll == 0ll);
1592 ocean_assert((
unsigned long long)image1 % 16ll == 0ll);
1594 const __m128i row0 = _mm_load_si128((__m128i*)image0);
1595 const __m128i row1 = _mm_load_si128((__m128i*)image1);
1603 const __m128i subtract = _mm_or_si128(_mm_subs_epu8(row0, row1), _mm_subs_epu8(row1, row0));
1610 const __m128i squareLow = _mm_mullo_epi16(subtractLow, subtractLow);
1611 const __m128i squareHigh = _mm_mullo_epi16(subtractHigh, subtractHigh);
1618 return _mm_add_epi32(sumSquareLow, sumSquareHigh);
1633#ifdef OCEAN_COMPILER_MSC
1635 ocean_assert(fx_fy_.m128i_u16[0] == fx_fy_.m128i_u16[1]);
1636 ocean_assert(fx_fy_.m128i_u16[1] == fx_fy_.m128i_u16[2]);
1637 ocean_assert(fx_fy_.m128i_u16[2] == fx_fy_.m128i_u16[3]);
1638 ocean_assert(fx_fy_.m128i_u16[3] == fx_fy_.m128i_u16[4]);
1639 ocean_assert(fx_fy_.m128i_u16[4] == fx_fy_.m128i_u16[5]);
1640 ocean_assert(fx_fy_.m128i_u16[5] == fx_fy_.m128i_u16[6]);
1641 ocean_assert(fx_fy_.m128i_u16[6] == fx_fy_.m128i_u16[7]);
1643 ocean_assert(fxfy_.m128i_u16[0] == fxfy_.m128i_u16[1]);
1644 ocean_assert(fxfy_.m128i_u16[1] == fxfy_.m128i_u16[2]);
1645 ocean_assert(fxfy_.m128i_u16[2] == fxfy_.m128i_u16[3]);
1646 ocean_assert(fxfy_.m128i_u16[3] == fxfy_.m128i_u16[4]);
1647 ocean_assert(fxfy_.m128i_u16[4] == fxfy_.m128i_u16[5]);
1648 ocean_assert(fxfy_.m128i_u16[5] == fxfy_.m128i_u16[6]);
1649 ocean_assert(fxfy_.m128i_u16[6] == fxfy_.m128i_u16[7]);
1651 ocean_assert(fx_fy.m128i_u16[0] == fx_fy.m128i_u16[1]);
1652 ocean_assert(fx_fy.m128i_u16[1] == fx_fy.m128i_u16[2]);
1653 ocean_assert(fx_fy.m128i_u16[2] == fx_fy.m128i_u16[3]);
1654 ocean_assert(fx_fy.m128i_u16[3] == fx_fy.m128i_u16[4]);
1655 ocean_assert(fx_fy.m128i_u16[4] == fx_fy.m128i_u16[5]);
1656 ocean_assert(fx_fy.m128i_u16[5] == fx_fy.m128i_u16[6]);
1657 ocean_assert(fx_fy.m128i_u16[6] == fx_fy.m128i_u16[7]);
1659 ocean_assert(fxfy.m128i_u16[0] == fxfy.m128i_u16[1]);
1660 ocean_assert(fxfy.m128i_u16[1] == fxfy.m128i_u16[2]);
1661 ocean_assert(fxfy.m128i_u16[2] == fxfy.m128i_u16[3]);
1662 ocean_assert(fxfy.m128i_u16[3] == fxfy.m128i_u16[4]);
1663 ocean_assert(fxfy.m128i_u16[4] == fxfy.m128i_u16[5]);
1664 ocean_assert(fxfy.m128i_u16[5] == fxfy.m128i_u16[6]);
1665 ocean_assert(fxfy.m128i_u16[6] == fxfy.m128i_u16[7]);
1667 ocean_assert(fx_fy_.m128i_u16[0] + fxfy_.m128i_u16[0] + fx_fy.m128i_u16[0] + fxfy.m128i_u16[0] == 128u * 128u);
1673 const M128i& debug_fx_fy_ = *(
const M128i*)(&fx_fy_);
1674 const M128i& debug_fx_fy = *(
const M128i*)(&fx_fy);
1675 const M128i& debug_fxfy_ = *(
const M128i*)(&fxfy_);
1676 const M128i& debug_fxfy = *(
const M128i*)(&fxfy);
1716 __m128i shuffle =
set128i(0xA007A006A005A004ull, 0xA003A002A001A000ull);
1719 __m128i row = _mm_shuffle_epi8(values0, shuffle);
1721 __m128i multiLow = _mm_mullo_epi16(row, fx_fy_);
1722 __m128i multiHigh = _mm_mulhi_epu16(row, fx_fy_);
1724 __m128i resultEven = _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA);
1725 __m128i resultOdd = _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA);
1728 row = _mm_shuffle_epi8(values1, shuffle);
1730 multiLow = _mm_mullo_epi16(row, fx_fy);
1731 multiHigh = _mm_mulhi_epu16(row, fx_fy);
1733 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
1734 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
1738 shuffle =
set128i(0xA008A007A006A005ull, 0xA004A003A002A001ull);
1741 row = _mm_shuffle_epi8(values0, shuffle);
1743 multiLow = _mm_mullo_epi16(row, fxfy_);
1744 multiHigh = _mm_mulhi_epu16(row, fxfy_);
1746 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
1747 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
1751 row = _mm_shuffle_epi8(values1, shuffle);
1753 multiLow = _mm_mullo_epi16(row, fxfy);
1754 multiHigh = _mm_mulhi_epu16(row, fxfy);
1756 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
1757 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
1761 resultEven = _mm_add_epi32(resultEven, _mm_set1_epi32(8192));
1762 resultEven = _mm_srli_epi32(resultEven, 14);
1764 resultOdd = _mm_add_epi32(resultOdd, _mm_set1_epi32(8192));
1765 resultOdd = _mm_srli_epi32(resultOdd, 14);
1783#ifdef OCEAN_COMPILER_MSC
1785 ocean_assert(fx_fy_.m128i_u16[0] == fx_fy_.m128i_u16[1]);
1786 ocean_assert(fx_fy_.m128i_u16[1] == fx_fy_.m128i_u16[2]);
1787 ocean_assert(fx_fy_.m128i_u16[2] == fx_fy_.m128i_u16[3]);
1788 ocean_assert(fx_fy_.m128i_u16[3] == fx_fy_.m128i_u16[4]);
1789 ocean_assert(fx_fy_.m128i_u16[4] == fx_fy_.m128i_u16[5]);
1790 ocean_assert(fx_fy_.m128i_u16[5] == fx_fy_.m128i_u16[6]);
1791 ocean_assert(fx_fy_.m128i_u16[6] == fx_fy_.m128i_u16[7]);
1793 ocean_assert(fxfy_.m128i_u16[0] == fxfy_.m128i_u16[1]);
1794 ocean_assert(fxfy_.m128i_u16[1] == fxfy_.m128i_u16[2]);
1795 ocean_assert(fxfy_.m128i_u16[2] == fxfy_.m128i_u16[3]);
1796 ocean_assert(fxfy_.m128i_u16[3] == fxfy_.m128i_u16[4]);
1797 ocean_assert(fxfy_.m128i_u16[4] == fxfy_.m128i_u16[5]);
1798 ocean_assert(fxfy_.m128i_u16[5] == fxfy_.m128i_u16[6]);
1799 ocean_assert(fxfy_.m128i_u16[6] == fxfy_.m128i_u16[7]);
1801 ocean_assert(fx_fy.m128i_u16[0] == fx_fy.m128i_u16[1]);
1802 ocean_assert(fx_fy.m128i_u16[1] == fx_fy.m128i_u16[2]);
1803 ocean_assert(fx_fy.m128i_u16[2] == fx_fy.m128i_u16[3]);
1804 ocean_assert(fx_fy.m128i_u16[3] == fx_fy.m128i_u16[4]);
1805 ocean_assert(fx_fy.m128i_u16[4] == fx_fy.m128i_u16[5]);
1806 ocean_assert(fx_fy.m128i_u16[5] == fx_fy.m128i_u16[6]);
1807 ocean_assert(fx_fy.m128i_u16[6] == fx_fy.m128i_u16[7]);
1809 ocean_assert(fxfy.m128i_u16[0] == fxfy.m128i_u16[1]);
1810 ocean_assert(fxfy.m128i_u16[1] == fxfy.m128i_u16[2]);
1811 ocean_assert(fxfy.m128i_u16[2] == fxfy.m128i_u16[3]);
1812 ocean_assert(fxfy.m128i_u16[3] == fxfy.m128i_u16[4]);
1813 ocean_assert(fxfy.m128i_u16[4] == fxfy.m128i_u16[5]);
1814 ocean_assert(fxfy.m128i_u16[5] == fxfy.m128i_u16[6]);
1815 ocean_assert(fxfy.m128i_u16[6] == fxfy.m128i_u16[7]);
1821 const M128i& debug_fx_fy_ = *(
const M128i*)(&fx_fy_);
1822 const M128i& debug_fx_fy = *(
const M128i*)(&fx_fy);
1823 const M128i& debug_fxfy_ = *(
const M128i*)(&fxfy_);
1824 const M128i& debug_fxfy = *(
const M128i*)(&fxfy);
1862 __m128i shuffle =
set128i(0xA007A006A005A004ull, 0xA003A002A001A000ull);
1865 __m128i row = _mm_shuffle_epi8(values0, shuffle);
1867 __m128i multiLow = _mm_mullo_epi16(row, fx_fy_);
1868 __m128i multiHigh = _mm_mulhi_epu16(row, fx_fy_);
1870 __m128i resultEven = _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA);
1871 __m128i resultOdd = _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA);
1874 row = _mm_shuffle_epi8(values1, shuffle);
1876 multiLow = _mm_mullo_epi16(row, fx_fy);
1877 multiHigh = _mm_mulhi_epu16(row, fx_fy);
1879 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
1880 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
1884 shuffle =
set128i(0xA009A008A007A006ull, 0xA005A004A003A002ull);
1887 row = _mm_shuffle_epi8(values0, shuffle);
1889 multiLow = _mm_mullo_epi16(row, fxfy_);
1890 multiHigh = _mm_mulhi_epu16(row, fxfy_);
1892 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
1893 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
1897 row = _mm_shuffle_epi8(values1, shuffle);
1899 multiLow = _mm_mullo_epi16(row, fxfy);
1900 multiHigh = _mm_mulhi_epu16(row, fxfy);
1902 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
1903 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
1907 resultEven = _mm_add_epi32(resultEven, _mm_set1_epi32(8192));
1908 resultEven = _mm_srli_epi32(resultEven, 14);
1910 resultOdd = _mm_add_epi32(resultOdd, _mm_set1_epi32(8192));
1911 resultOdd = _mm_srli_epi32(resultOdd, 14);
1929#ifdef OCEAN_COMPILER_MSC
1931 ocean_assert(fx_fy_.m128i_u16[0] == fx_fy_.m128i_u16[1]);
1932 ocean_assert(fx_fy_.m128i_u16[1] == fx_fy_.m128i_u16[2]);
1933 ocean_assert(fx_fy_.m128i_u16[2] == fx_fy_.m128i_u16[3]);
1934 ocean_assert(fx_fy_.m128i_u16[3] == fx_fy_.m128i_u16[4]);
1935 ocean_assert(fx_fy_.m128i_u16[4] == fx_fy_.m128i_u16[5]);
1936 ocean_assert(fx_fy_.m128i_u16[5] == fx_fy_.m128i_u16[6]);
1937 ocean_assert(fx_fy_.m128i_u16[6] == fx_fy_.m128i_u16[7]);
1939 ocean_assert(fxfy_.m128i_u16[0] == fxfy_.m128i_u16[1]);
1940 ocean_assert(fxfy_.m128i_u16[1] == fxfy_.m128i_u16[2]);
1941 ocean_assert(fxfy_.m128i_u16[2] == fxfy_.m128i_u16[3]);
1942 ocean_assert(fxfy_.m128i_u16[3] == fxfy_.m128i_u16[4]);
1943 ocean_assert(fxfy_.m128i_u16[4] == fxfy_.m128i_u16[5]);
1944 ocean_assert(fxfy_.m128i_u16[5] == fxfy_.m128i_u16[6]);
1945 ocean_assert(fxfy_.m128i_u16[6] == fxfy_.m128i_u16[7]);
1947 ocean_assert(fx_fy.m128i_u16[0] == fx_fy.m128i_u16[1]);
1948 ocean_assert(fx_fy.m128i_u16[1] == fx_fy.m128i_u16[2]);
1949 ocean_assert(fx_fy.m128i_u16[2] == fx_fy.m128i_u16[3]);
1950 ocean_assert(fx_fy.m128i_u16[3] == fx_fy.m128i_u16[4]);
1951 ocean_assert(fx_fy.m128i_u16[4] == fx_fy.m128i_u16[5]);
1952 ocean_assert(fx_fy.m128i_u16[5] == fx_fy.m128i_u16[6]);
1953 ocean_assert(fx_fy.m128i_u16[6] == fx_fy.m128i_u16[7]);
1955 ocean_assert(fxfy.m128i_u16[0] == fxfy.m128i_u16[1]);
1956 ocean_assert(fxfy.m128i_u16[1] == fxfy.m128i_u16[2]);
1957 ocean_assert(fxfy.m128i_u16[2] == fxfy.m128i_u16[3]);
1958 ocean_assert(fxfy.m128i_u16[3] == fxfy.m128i_u16[4]);
1959 ocean_assert(fxfy.m128i_u16[4] == fxfy.m128i_u16[5]);
1960 ocean_assert(fxfy.m128i_u16[5] == fxfy.m128i_u16[6]);
1961 ocean_assert(fxfy.m128i_u16[6] == fxfy.m128i_u16[7]);
1967 const M128i& debug_fx_fy_ = *(
const M128i*)(&fx_fy_);
1968 const M128i& debug_fx_fy = *(
const M128i*)(&fx_fy);
1969 const M128i& debug_fxfy_ = *(
const M128i*)(&fxfy_);
1970 const M128i& debug_fxfy = *(
const M128i*)(&fxfy);
2008 __m128i shuffle =
set128i(0xA007A006A005A004ull, 0xA003A002A001A000ull);
2011 __m128i row = _mm_shuffle_epi8(values0, shuffle);
2013 __m128i multiLow = _mm_mullo_epi16(row, fx_fy_);
2014 __m128i multiHigh = _mm_mulhi_epu16(row, fx_fy_);
2016 __m128i resultEven = _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA);
2017 __m128i resultOdd = _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA);
2020 row = _mm_shuffle_epi8(values1, shuffle);
2022 multiLow = _mm_mullo_epi16(row, fx_fy);
2023 multiHigh = _mm_mulhi_epu16(row, fx_fy);
2025 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
2026 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
2030 shuffle =
set128i(0xA00AA009A008A007ull, 0xA006A005A004A003ull);
2033 row = _mm_shuffle_epi8(values0, shuffle);
2035 multiLow = _mm_mullo_epi16(row, fxfy_);
2036 multiHigh = _mm_mulhi_epu16(row, fxfy_);
2038 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
2039 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
2043 row = _mm_shuffle_epi8(values1, shuffle);
2045 multiLow = _mm_mullo_epi16(row, fxfy);
2046 multiHigh = _mm_mulhi_epu16(row, fxfy);
2048 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
2049 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
2053 resultEven = _mm_add_epi32(resultEven, _mm_set1_epi32(8192));
2054 resultEven = _mm_srli_epi32(resultEven, 14);
2056 resultOdd = _mm_add_epi32(resultOdd, _mm_set1_epi32(8192));
2057 resultOdd = _mm_srli_epi32(resultOdd, 14);
2065 __m128i row0_a = _mm_shuffle_epi8(values0,
set128i(0xFF04FF03FF03FF02ull, 0xFF02FF01FF01FF00ull));
2066 __m128i row1_a = _mm_shuffle_epi8(values1,
set128i(0xFF04FF03FF03FF02ull, 0xFF02FF01FF01FF00ull));
2068 __m128i row0_b = _mm_shuffle_epi8(values0,
set128i(0xFF08FF07FF07FF06ull, 0xFF06FF05FF05FF04ull));
2069 __m128i row1_b = _mm_shuffle_epi8(values1,
set128i(0xFF08FF07FF07FF06ull, 0xFF06FF05FF05FF04ull));
2071 __m128i row0_c = _mm_shuffle_epi8(values0,
set128i(0xFF0cFF0bFF0bFF0aull, 0xFF0aFF09FF09FF08ull));
2072 __m128i row1_c = _mm_shuffle_epi8(values1,
set128i(0xFF0cFF0bFF0bFF0aull, 0xFF0aFF09FF09FF08ull));
2074 __m128i row0_d = _mm_shuffle_epi8(values0,
set128i(0xFFFFFFFFFF0fFF0eull, 0xFF0eFF0dFF0dFF0cull));
2075 __m128i row1_d = _mm_shuffle_epi8(values1,
set128i(0xFFFFFFFFFF0fFF0eull, 0xFF0eFF0dFF0dFF0cull));
2077 row0_a = _mm_madd_epi16(row0_a, fx_fy_fxfy_);
2078 row0_b = _mm_madd_epi16(row0_b, fx_fy_fxfy_);
2079 row0_c = _mm_madd_epi16(row0_c, fx_fy_fxfy_);
2080 row0_d = _mm_madd_epi16(row0_d, fx_fy_fxfy_);
2082 row1_a = _mm_madd_epi16(row1_a, fx_fyfxfy);
2083 row1_b = _mm_madd_epi16(row1_b, fx_fyfxfy);
2084 row1_c = _mm_madd_epi16(row1_c, fx_fyfxfy);
2085 row1_d = _mm_madd_epi16(row1_d, fx_fyfxfy);
2087 const __m128i rounding = _mm_set1_epi32(8192);
2089 __m128i row_a = _mm_add_epi32(row0_a, row1_a);
2090 __m128i row_b = _mm_add_epi32(row0_b, row1_b);
2091 __m128i row_c = _mm_add_epi32(row0_c, row1_c);
2092 __m128i row_d = _mm_add_epi32(row0_d, row1_d);
2094 row_a = _mm_add_epi32(row_a, rounding);
2095 row_b = _mm_add_epi32(row_b, rounding);
2096 row_c = _mm_add_epi32(row_c, rounding);
2097 row_d = _mm_add_epi32(row_d, rounding);
2099 row_a = _mm_srli_epi32(row_a, 14);
2100 row_b = _mm_srli_epi32(row_b, 14);
2101 row_c = _mm_srli_epi32(row_c, 14);
2102 row_d = _mm_srli_epi32(row_d, 14);
2104 row_a = _mm_shuffle_epi8(row_a,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF0c080400ull));
2105 row_b = _mm_shuffle_epi8(row_b,
set128i(0xFFFFFFFFFFFFFFFFull, 0x0c080400FFFFFFFFull));
2106 row_c = _mm_shuffle_epi8(row_c,
set128i(0xFFFFFFFF0c080400ull, 0xFFFFFFFFFFFFFFFFull));
2107 row_d = _mm_shuffle_epi8(row_d,
set128i(0xFF080400FFFFFFFFull, 0xFFFFFFFFFFFFFFFFull));
2109 row_a = _mm_or_si128(row_a, row_b);
2110 row_c = _mm_or_si128(row_c, row_d);
2112 return _mm_or_si128(row_a, row_c);
2117 __m128i row0_a = _mm_shuffle_epi8(values0,
set128i(0xFF0cFF09FF09FF06ull, 0xFF06FF03FF03FF00ull));
2118 __m128i row1_a = _mm_shuffle_epi8(values1,
set128i(0xFF0cFF09FF09FF06ull, 0xFF06FF03FF03FF00ull));
2120 __m128i row0_b = _mm_shuffle_epi8(values0,
set128i(0xFF0dFF0aFF0aFF07ull, 0xFF07FF04FF04FF01ull));
2121 __m128i row1_b = _mm_shuffle_epi8(values1,
set128i(0xFF0dFF0aFF0aFF07ull, 0xFF07FF04FF04FF01ull));
2123 __m128i row0_c = _mm_shuffle_epi8(values0,
set128i(0xFF0eFF0bFF0bFF08ull, 0xFF08FF05FF05FF02ull));
2124 __m128i row1_c = _mm_shuffle_epi8(values1,
set128i(0xFF0eFF0bFF0bFF08ull, 0xFF08FF05FF05FF02ull));
2126 row0_a = _mm_madd_epi16(row0_a, fx_fy_fxfy_);
2127 row0_b = _mm_madd_epi16(row0_b, fx_fy_fxfy_);
2128 row0_c = _mm_madd_epi16(row0_c, fx_fy_fxfy_);
2130 row1_a = _mm_madd_epi16(row1_a, fx_fyfxfy);
2131 row1_b = _mm_madd_epi16(row1_b, fx_fyfxfy);
2132 row1_c = _mm_madd_epi16(row1_c, fx_fyfxfy);
2134 const __m128i rounding = _mm_set1_epi32(8192);
2136 __m128i row_a = _mm_add_epi32(row0_a, row1_a);
2137 __m128i row_b = _mm_add_epi32(row0_b, row1_b);
2138 __m128i row_c = _mm_add_epi32(row0_c, row1_c);
2140 row_a = _mm_add_epi32(row_a, rounding);
2141 row_b = _mm_add_epi32(row_b, rounding);
2142 row_c = _mm_add_epi32(row_c, rounding);
2144 row_a = _mm_srli_epi32(row_a, 14);
2145 row_b = _mm_srli_epi32(row_b, 14);
2146 row_c = _mm_srli_epi32(row_c, 14);
2148 row_a = _mm_shuffle_epi8(row_a,
set128i(0xFFFFFFFFFFFF0cFFull, 0xFF08FFFF04FFFF00ull));
2149 row_b = _mm_shuffle_epi8(row_b,
set128i(0xFFFFFFFFFF0cFFFFull, 0x08FFFF04FFFF00FFull));
2150 row_c = _mm_shuffle_epi8(row_c,
set128i(0xFFFFFFFF0cFFFF08ull, 0xFFFF04FFFF00FFFFull));
2152 return _mm_or_si128(row_a, _mm_or_si128(row_b, row_c));
2167#ifdef OCEAN_COMPILER_MSC
2169 ocean_assert(fx_fy_.m128i_u16[0] == fx_fy_.m128i_u16[1]);
2170 ocean_assert(fx_fy_.m128i_u16[1] == fx_fy_.m128i_u16[2]);
2171 ocean_assert(fx_fy_.m128i_u16[2] == fx_fy_.m128i_u16[3]);
2172 ocean_assert(fx_fy_.m128i_u16[3] == fx_fy_.m128i_u16[4]);
2173 ocean_assert(fx_fy_.m128i_u16[4] == fx_fy_.m128i_u16[5]);
2174 ocean_assert(fx_fy_.m128i_u16[5] == fx_fy_.m128i_u16[6]);
2175 ocean_assert(fx_fy_.m128i_u16[6] == fx_fy_.m128i_u16[7]);
2177 ocean_assert(fxfy_.m128i_u16[0] == fxfy_.m128i_u16[1]);
2178 ocean_assert(fxfy_.m128i_u16[1] == fxfy_.m128i_u16[2]);
2179 ocean_assert(fxfy_.m128i_u16[2] == fxfy_.m128i_u16[3]);
2180 ocean_assert(fxfy_.m128i_u16[3] == fxfy_.m128i_u16[4]);
2181 ocean_assert(fxfy_.m128i_u16[4] == fxfy_.m128i_u16[5]);
2182 ocean_assert(fxfy_.m128i_u16[5] == fxfy_.m128i_u16[6]);
2183 ocean_assert(fxfy_.m128i_u16[6] == fxfy_.m128i_u16[7]);
2185 ocean_assert(fx_fy.m128i_u16[0] == fx_fy.m128i_u16[1]);
2186 ocean_assert(fx_fy.m128i_u16[1] == fx_fy.m128i_u16[2]);
2187 ocean_assert(fx_fy.m128i_u16[2] == fx_fy.m128i_u16[3]);
2188 ocean_assert(fx_fy.m128i_u16[3] == fx_fy.m128i_u16[4]);
2189 ocean_assert(fx_fy.m128i_u16[4] == fx_fy.m128i_u16[5]);
2190 ocean_assert(fx_fy.m128i_u16[5] == fx_fy.m128i_u16[6]);
2191 ocean_assert(fx_fy.m128i_u16[6] == fx_fy.m128i_u16[7]);
2193 ocean_assert(fxfy.m128i_u16[0] == fxfy.m128i_u16[1]);
2194 ocean_assert(fxfy.m128i_u16[1] == fxfy.m128i_u16[2]);
2195 ocean_assert(fxfy.m128i_u16[2] == fxfy.m128i_u16[3]);
2196 ocean_assert(fxfy.m128i_u16[3] == fxfy.m128i_u16[4]);
2197 ocean_assert(fxfy.m128i_u16[4] == fxfy.m128i_u16[5]);
2198 ocean_assert(fxfy.m128i_u16[5] == fxfy.m128i_u16[6]);
2199 ocean_assert(fxfy.m128i_u16[6] == fxfy.m128i_u16[7]);
2205 const M128i& debug_fx_fy_ = *(
const M128i*)(&fx_fy_);
2206 const M128i& debug_fx_fy = *(
const M128i*)(&fx_fy);
2207 const M128i& debug_fxfy_ = *(
const M128i*)(&fxfy_);
2208 const M128i& debug_fxfy = *(
const M128i*)(&fxfy);
2246 __m128i shuffle =
set128i(0xA007A006A005A004ull, 0xA003A002A001A000ull);
2249 __m128i row = _mm_shuffle_epi8(values0, shuffle);
2251 __m128i multiLow = _mm_mullo_epi16(row, fx_fy_);
2252 __m128i multiHigh = _mm_mulhi_epu16(row, fx_fy_);
2254 __m128i resultEven = _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA);
2255 __m128i resultOdd = _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA);
2258 row = _mm_shuffle_epi8(values1, shuffle);
2260 multiLow = _mm_mullo_epi16(row, fx_fy);
2261 multiHigh = _mm_mulhi_epu16(row, fx_fy);
2263 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
2264 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
2268 shuffle =
set128i(0xA00BA00AA009A008ull, 0xA007A006A005A004ull);
2271 row = _mm_shuffle_epi8(values0, shuffle);
2273 multiLow = _mm_mullo_epi16(row, fxfy_);
2274 multiHigh = _mm_mulhi_epu16(row, fxfy_);
2276 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
2277 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
2281 row = _mm_shuffle_epi8(values1, shuffle);
2283 multiLow = _mm_mullo_epi16(row, fxfy);
2284 multiHigh = _mm_mulhi_epu16(row, fxfy);
2286 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
2287 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
2291 resultEven = _mm_add_epi32(resultEven, _mm_set1_epi32(8192));
2292 resultEven = _mm_srli_epi32(resultEven, 14);
2294 resultOdd = _mm_add_epi32(resultOdd, _mm_set1_epi32(8192));
2295 resultOdd = _mm_srli_epi32(resultOdd, 14);
2314#ifdef OCEAN_COMPILER_MSC
2316 ocean_assert(fx_fy_.m128i_u16[0] == fx_fy_.m128i_u16[1]);
2317 ocean_assert(fx_fy_.m128i_u16[1] == fx_fy_.m128i_u16[2]);
2318 ocean_assert(fx_fy_.m128i_u16[2] == fx_fy_.m128i_u16[3]);
2319 ocean_assert(fx_fy_.m128i_u16[3] == fx_fy_.m128i_u16[4]);
2320 ocean_assert(fx_fy_.m128i_u16[4] == fx_fy_.m128i_u16[5]);
2321 ocean_assert(fx_fy_.m128i_u16[5] == fx_fy_.m128i_u16[6]);
2322 ocean_assert(fx_fy_.m128i_u16[6] == fx_fy_.m128i_u16[7]);
2324 ocean_assert(fxfy_.m128i_u16[0] == fxfy_.m128i_u16[1]);
2325 ocean_assert(fxfy_.m128i_u16[1] == fxfy_.m128i_u16[2]);
2326 ocean_assert(fxfy_.m128i_u16[2] == fxfy_.m128i_u16[3]);
2327 ocean_assert(fxfy_.m128i_u16[3] == fxfy_.m128i_u16[4]);
2328 ocean_assert(fxfy_.m128i_u16[4] == fxfy_.m128i_u16[5]);
2329 ocean_assert(fxfy_.m128i_u16[5] == fxfy_.m128i_u16[6]);
2330 ocean_assert(fxfy_.m128i_u16[6] == fxfy_.m128i_u16[7]);
2332 ocean_assert(fx_fy.m128i_u16[0] == fx_fy.m128i_u16[1]);
2333 ocean_assert(fx_fy.m128i_u16[1] == fx_fy.m128i_u16[2]);
2334 ocean_assert(fx_fy.m128i_u16[2] == fx_fy.m128i_u16[3]);
2335 ocean_assert(fx_fy.m128i_u16[3] == fx_fy.m128i_u16[4]);
2336 ocean_assert(fx_fy.m128i_u16[4] == fx_fy.m128i_u16[5]);
2337 ocean_assert(fx_fy.m128i_u16[5] == fx_fy.m128i_u16[6]);
2338 ocean_assert(fx_fy.m128i_u16[6] == fx_fy.m128i_u16[7]);
2340 ocean_assert(fxfy.m128i_u16[0] == fxfy.m128i_u16[1]);
2341 ocean_assert(fxfy.m128i_u16[1] == fxfy.m128i_u16[2]);
2342 ocean_assert(fxfy.m128i_u16[2] == fxfy.m128i_u16[3]);
2343 ocean_assert(fxfy.m128i_u16[3] == fxfy.m128i_u16[4]);
2344 ocean_assert(fxfy.m128i_u16[4] == fxfy.m128i_u16[5]);
2345 ocean_assert(fxfy.m128i_u16[5] == fxfy.m128i_u16[6]);
2346 ocean_assert(fxfy.m128i_u16[6] == fxfy.m128i_u16[7]);
2352 const M128i& debug_fx_fy_ = *(
const M128i*)(&fx_fy_);
2353 const M128i& debug_fx_fy = *(
const M128i*)(&fx_fy);
2354 const M128i& debug_fxfy_ = *(
const M128i*)(&fxfy_);
2355 const M128i& debug_fxfy = *(
const M128i*)(&fxfy);
2393 __m128i shuffle =
set128i(0xA00BA00AA009A008ull, 0xA003A002A001A000ull);
2396 __m128i row = _mm_shuffle_epi8(values0, shuffle);
2398 __m128i multiLow = _mm_mullo_epi16(row, fx_fy_);
2399 __m128i multiHigh = _mm_mulhi_epu16(row, fx_fy_);
2401 __m128i resultEven = _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA);
2402 __m128i resultOdd = _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA);
2405 row = _mm_shuffle_epi8(values1, shuffle);
2407 multiLow = _mm_mullo_epi16(row, fx_fy);
2408 multiHigh = _mm_mulhi_epu16(row, fx_fy);
2410 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
2411 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
2415 shuffle =
set128i(0xA00FA00EA00DA00Cull, 0xA007A006A005A004ull);
2418 row = _mm_shuffle_epi8(values0, shuffle);
2420 multiLow = _mm_mullo_epi16(row, fxfy_);
2421 multiHigh = _mm_mulhi_epu16(row, fxfy_);
2423 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
2424 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
2428 row = _mm_shuffle_epi8(values1, shuffle);
2430 multiLow = _mm_mullo_epi16(row, fxfy);
2431 multiHigh = _mm_mulhi_epu16(row, fxfy);
2433 resultEven = _mm_add_epi32(resultEven, _mm_blend_epi16(multiLow, _mm_slli_si128(multiHigh, 2), 0xAA));
2434 resultOdd = _mm_add_epi32(resultOdd, _mm_blend_epi16(_mm_srli_si128(multiLow, 2), multiHigh, 0xAA));
2438 resultEven = _mm_add_epi32(resultEven, _mm_set1_epi32(8192));
2439 resultEven = _mm_srli_epi32(resultEven, 14);
2441 resultOdd = _mm_add_epi32(resultOdd, _mm_set1_epi32(8192));
2442 resultOdd = _mm_srli_epi32(resultOdd, 14);
2450 ocean_assert(image0 && image1);
2453 const __m128 row0 = _mm_loadu_ps(image0);
2454 const __m128 row1 = _mm_loadu_ps(image1);
2457 const __m128 sumFirst = _mm_add_ps(row0, row1);
2460 const __m128 rowSecond0 = _mm_loadu_ps(image0 + 4);
2461 const __m128 rowSecond1 = _mm_loadu_ps(image1 + 4);
2464 const __m128 sumSecond = _mm_add_ps(rowSecond0, rowSecond1);
2467 const __m128 sumAdjacent = _mm_hadd_ps(sumFirst, sumSecond);
2476 const __m128 division = _mm_mul_ps(sumAdjacent, _mm_set_ps1(0.25f));
2479 _mm_storeu_ps(result, division);
2484 ocean_assert(image0 && image1);
2487 const __m128i row0 = _mm_loadl_epi64((__m128i*)image0);
2488 const __m128i row1 = _mm_loadl_epi64((__m128i*)image1);
2495 const __m128i sum = _mm_add_epi16(sumLow, _mm_add_epi16(sumHigh, _mm_set1_epi32(
int(0x00020002))));
2498 const __m128i division16 = _mm_srli_epi16(sum, 2);
2503 memcpy(result, &division8,
sizeof(uint8_t) * 4);
2508 ocean_assert(image0 !=
nullptr && image1 !=
nullptr);
2509 ocean_assert(threshold >= 1u);
2512 const __m128i row0_u_8x8 = _mm_loadl_epi64((__m128i*)image0);
2513 const __m128i row1_u_8x8 = _mm_loadl_epi64((__m128i*)image1);
2515 const __m128i row0_u_16x8 = _mm_cvtepu8_epi16(row0_u_8x8);
2516 const __m128i row1_u_16x8 = _mm_cvtepu8_epi16(row1_u_8x8);
2518 const __m128i verticalSum_u_16x8 = _mm_adds_epu16(row0_u_16x8, row1_u_16x8);
2519 const __m128i sum_u_16x8 = _mm_hadd_epi16(verticalSum_u_16x8, verticalSum_u_16x8);
2521 const __m128i mask_u_16x8 = _mm_cmpgt_epi16(sum_u_16x8, _mm_set1_epi16(
short(threshold - 1u)));
2525 memcpy(result, &mask_u_8x8,
sizeof(uint8_t) * 4);
2530 ocean_assert(image0 && image1);
2533 const __m128i row0 = _mm_lddqu_si128((__m128i*)image0);
2534 const __m128i row1 = _mm_lddqu_si128((__m128i*)image1);
2541 const __m128i sum = _mm_add_epi16(sumLow, _mm_add_epi16(sumHigh, _mm_set1_epi32(
int(0x00020002))));
2544 const __m128i division16 = _mm_srli_epi16(sum, 2);
2550 _mm_storel_epi64((__m128i*)result, division8);
2565 ocean_assert(image0 !=
nullptr && image1 !=
nullptr);
2566 ocean_assert(threshold >= 1u);
2569 const __m128i row0_u_8x16 = _mm_lddqu_si128((__m128i*)image0);
2570 const __m128i row1_u_8x16 = _mm_lddqu_si128((__m128i*)image1);
2572 const __m128i horizontalSum0_u_16x8 = _mm_maddubs_epi16(row0_u_8x16, _mm_set1_epi8(1));
2573 const __m128i horizontalSum1_u_16x8 = _mm_maddubs_epi16(row1_u_8x16, _mm_set1_epi8(1));
2575 const __m128i sum_u_16x8 = _mm_add_epi16(horizontalSum0_u_16x8, horizontalSum1_u_16x8);
2577 const __m128i mask_u_16x8 = _mm_cmpgt_epi16(sum_u_16x8, _mm_set1_epi16(
short(threshold - 1u)));
2582 _mm_storel_epi64((__m128i*)result, mask_u_8x8);
2587 ocean_assert(image0 && image1);
2590 const __m128i firstRow0 = _mm_lddqu_si128((__m128i*)image0);
2591 const __m128i firstRow1 = _mm_lddqu_si128((__m128i*)image1);
2598 const __m128i firstSum = _mm_add_epi16(firstSumLow, _mm_add_epi16(firstSumHigh, _mm_set1_epi32(
int(0x00020002))));
2601 const __m128i firstDivision16 = _mm_srli_epi16(firstSum, 2);
2607 const __m128i secondRow0 = _mm_lddqu_si128((__m128i*)(image0 + 16));
2608 const __m128i secondRow1 = _mm_lddqu_si128((__m128i*)(image1 + 16));
2615 const __m128i secondSum = _mm_add_epi16(secondSumLow, _mm_add_epi16(secondSumHigh, _mm_set1_epi32(
int(0x00020002))));
2618 const __m128i secondDivision16 = _mm_srli_epi16(secondSum, 2);
2625 const __m128i division8 = _mm_or_si128(firstDivision8, secondDivision8);
2628 _mm_storeu_si128((__m128i*)result, division8);
2653 ocean_assert(image0 !=
nullptr && image1 !=
nullptr);
2654 ocean_assert(threshold >= 1u);
2657 const __m128i row0A_u_8x16 = _mm_lddqu_si128((__m128i*)image0);
2658 const __m128i row1A_u_8x16 = _mm_lddqu_si128((__m128i*)image1);
2660 const __m128i horizontalSum0A_u_16x8 = _mm_maddubs_epi16(row0A_u_8x16, _mm_set1_epi8(1));
2661 const __m128i horizontalSum1A_u_16x8 = _mm_maddubs_epi16(row1A_u_8x16, _mm_set1_epi8(1));
2663 const __m128i sumA_u_16x8 = _mm_add_epi16(horizontalSum0A_u_16x8, horizontalSum1A_u_16x8);
2665 const __m128i maskA_u_16x8 = _mm_cmpgt_epi16(sumA_u_16x8, _mm_set1_epi16(
short(threshold - 1)));
2667 const __m128i row0B_u_8x16 = _mm_lddqu_si128((__m128i*)(image0 + 16));
2668 const __m128i row1B_u_8x16 = _mm_lddqu_si128((__m128i*)(image1 + 16));
2670 const __m128i horizontalSum0B_u_16x8 = _mm_maddubs_epi16(row0B_u_8x16, _mm_set1_epi8(1));
2671 const __m128i horizontalSum1B_u_16x8 = _mm_maddubs_epi16(row1B_u_8x16, _mm_set1_epi8(1));
2673 const __m128i sumB_u_16x8 = _mm_add_epi16(horizontalSum0B_u_16x8, horizontalSum1B_u_16x8);
2675 const __m128i maskB_u_16x8 = _mm_cmpgt_epi16(sumB_u_16x8, _mm_set1_epi16(
short(threshold - 1u)));
2680 _mm_storeu_si128((__m128i*)result, mask_u_8x16);
2685 ocean_assert(image0 && image1);
2688 const __m128i row0 = _mm_loadl_epi64((__m128i*)image0);
2689 const __m128i row1 = _mm_loadl_epi64((__m128i*)image1);
2696 const __m128i sumLow = _mm_add_epi16(shuffledRow0, shuffledRow1);
2697 const __m128i sum = _mm_add_epi16(_mm_hadd_epi16(sumLow, sumLow), _mm_set1_epi32(
int(0x00020002)));
2700 const __m128i division16 = _mm_srli_epi16(sum, 2);
2705 memcpy(result, &division8,
sizeof(uint8_t) * 4);
2710 ocean_assert(image0 && image1);
2713 const __m128 row0 = _mm_loadu_ps(image0);
2714 const __m128 row1 = _mm_loadu_ps(image1);
2717 const __m128 sumFirst = _mm_add_ps(row0, row1);
2720 const __m128 rowSecond0 = _mm_loadu_ps(image0 + 4);
2721 const __m128 rowSecond1 = _mm_loadu_ps(image1 + 4);
2724 const __m128 sumSecond = _mm_add_ps(rowSecond0, rowSecond1);
2729 const __m128 sumComponents = _mm_add_ps(_mm_shuffle_ps(sumFirst, sumSecond, 68u), _mm_shuffle_ps(sumFirst, sumSecond, 238u));
2732 const __m128 division = _mm_mul_ps(sumComponents, _mm_set_ps1(0.25f));
2735 _mm_storeu_ps(result, division);
2740 ocean_assert(image0 && image1);
2743 const __m128i row0 = _mm_lddqu_si128((__m128i*)image0);
2744 const __m128i row1 = _mm_lddqu_si128((__m128i*)image1);
2751 const __m128i sum = _mm_add_epi16(_mm_hadd_epi16(sumLow, sumHigh), _mm_set1_epi32(
int(0x00020002)));
2754 const __m128i division16 = _mm_srli_epi16(sum, 2);
2760 _mm_storel_epi64((__m128i*)result, division8);
2765 ocean_assert(image0 && image1);
2768 const __m128i row0 = _mm_lddqu_si128((__m128i*)image0);
2769 const __m128i row1 = _mm_lddqu_si128((__m128i*)image1);
2776 const __m128i sum = _mm_add_epi16(_mm_hadd_epi16(sumLow, sumHigh), _mm_set1_epi32(
int(0x00020002)));
2779 const __m128i division16 = _mm_srli_epi16(sum, 2);
2785 const __m128i secondRow0 = _mm_lddqu_si128((__m128i*)(image0 + 16));
2786 const __m128i secondRow1 = _mm_lddqu_si128((__m128i*)(image1 + 16));
2793 const __m128i secondSum = _mm_add_epi16(_mm_hadd_epi16(secondSumLow, secondSumHigh), _mm_set1_epi32(
int(0x00020002)));
2796 const __m128i secondDivision16 = _mm_srli_epi16(secondSum, 2);
2803 const __m128i division8 = _mm_or_si128(firstDivision8, secondDivision8);
2806 _mm_storeu_si128((__m128i*)result, division8);
2811 ocean_assert(image0 && image1 && result);
2816 const __m128 row0 = _mm_loadu_ps(image0);
2817 const __m128 row1 = _mm_loadu_ps(image1);
2820 const __m128 sumFirst = _mm_add_ps(row0, row1);
2823 const __m128 rowSecond0 = _mm_loadu_ps(image0 + 2);
2824 const __m128 rowSecond1 = _mm_loadu_ps(image1 + 2);
2827 const __m128 sumSecond = _mm_add_ps(rowSecond0, rowSecond1);
2832 const __m128 sumComponents = _mm_add_ps(sumFirst, _mm_shuffle_ps(sumSecond, sumSecond, 57u));
2835 const __m128 division = _mm_mul_ps(sumComponents, _mm_set_ps1(0.25f));
2839#ifdef OCEAN_COMPILER_MSC
2840 memcpy(result, &division.m128_f32[0],
sizeof(
float) * 3);
2842 memcpy(result, &division,
sizeof(
float) * 3);
2848 ocean_assert(image0 && image1 && result);
2850 __m128i row0 = _mm_lddqu_si128((__m128i*)image0);
2851 __m128i row1 = _mm_lddqu_si128((__m128i*)image1);
2859 __m128i shuffleMaskLow =
set128i(0xA0A0A0A0A008A007ull, 0xA006A002A001A000ull);
2860 __m128i shuffleMaskHigh =
set128i(0xA0A0A0A0A00BA00Aull, 0xA009A005A004A003ull);
2862 __m128i sumLow = _mm_add_epi16(_mm_shuffle_epi8(row0, shuffleMaskLow), _mm_shuffle_epi8(row1, shuffleMaskLow));
2863 __m128i sumHigh = _mm_add_epi16(_mm_shuffle_epi8(row0, shuffleMaskHigh), _mm_shuffle_epi8(row1, shuffleMaskHigh));
2866 __m128i sum = _mm_add_epi16(_mm_add_epi16(sumLow, sumHigh), _mm_set1_epi32(
int(0x00020002)));
2869 __m128i division16 = _mm_srli_epi16(sum, 2);
2872 __m128i division8 = _mm_shuffle_epi8(division16,
set128i(0xA0A0A0A0A0A0A0A0ull, 0xA0A00A0806040200ull));
2881 row0 = _mm_lddqu_si128((__m128i*)(image0 + 8));
2882 row1 = _mm_lddqu_si128((__m128i*)(image1 + 8));
2884 shuffleMaskLow =
set128i(0xA0A0A0A0A00CA00Bull, 0xA00AA006A005A004ull);
2885 shuffleMaskHigh =
set128i(0xA0A0A0A0A00FA00Eull, 0xA00DA009A008A007ull);
2887 sumLow = _mm_add_epi16(_mm_shuffle_epi8(row0, shuffleMaskLow), _mm_shuffle_epi8(row1, shuffleMaskLow));
2888 sumHigh = _mm_add_epi16(_mm_shuffle_epi8(row0, shuffleMaskHigh), _mm_shuffle_epi8(row1, shuffleMaskHigh));
2891 sum = _mm_add_epi16(_mm_add_epi16(sumLow, sumHigh), _mm_set1_epi32(
int(0x00020002)));
2894 division16 = _mm_srli_epi16(sum, 2);
2897 division8 = _mm_or_si128(division8, _mm_shuffle_epi8(division16,
set128i(0xA0A0A0A00A080604ull, 0x0200A0A0A0A0A0A0ull)));
2899#ifdef OCEAN_COMPILER_MSC
2900 memcpy(result, &division8.m128i_u8[0], 12);
2902 memcpy(result, &division8, 12);
2908 ocean_assert(image0 && image1);
2911 const __m128 row0 = _mm_loadu_ps(image0);
2912 const __m128 row1 = _mm_loadu_ps(image1);
2915 const __m128 sumFirstPixel = _mm_add_ps(row0, row1);
2918 const __m128 rowSecond0 = _mm_loadu_ps(image0 + 4);
2919 const __m128 rowSecond1 = _mm_loadu_ps(image1 + 4);
2922 const __m128 sumSecondPixel = _mm_add_ps(rowSecond0, rowSecond1);
2925 const __m128 sumComponents = _mm_add_ps(sumFirstPixel, sumSecondPixel);
2928 const __m128 division = _mm_mul_ps(sumComponents, _mm_set_ps1(0.25f));
2931 _mm_storeu_ps(result, division);
2936 ocean_assert(image0 && image1);
2938 const __m128i row0 = _mm_lddqu_si128((__m128i*)image0);
2939 const __m128i row1 = _mm_lddqu_si128((__m128i*)image1);
2946 const __m128i sum = _mm_add_epi16(_mm_hadd_epi16(sumLow, sumHigh), _mm_set1_epi32(
int(0x00020002)));
2949 const __m128i division16 = _mm_srli_epi16(sum, 2);
2955 _mm_storel_epi64((__m128i*)result, division8);
2960 ocean_assert(image0 && image1);
2963 const __m128i firstRow0 = _mm_lddqu_si128((__m128i*)image0);
2964 const __m128i firstRow1 = _mm_lddqu_si128((__m128i*)image1);
2971 const __m128i firstSum = _mm_add_epi16(_mm_hadd_epi16(firstSumLow, firstSumHigh), _mm_set1_epi32(
int(0x00020002)));
2974 const __m128i firstDivision16 = _mm_srli_epi16(firstSum, 2);
2981 const __m128i secondRow0 = _mm_lddqu_si128((__m128i*)(image0 + 16));
2982 const __m128i secondRow1 = _mm_lddqu_si128((__m128i*)(image1 + 16));
2989 const __m128i secondSum = _mm_add_epi16(_mm_hadd_epi16(secondSumLow, secondSumHigh), _mm_set1_epi32(
int(0x00020002)));
2992 const __m128i secondDivision16 = _mm_srli_epi16(secondSum, 2);
2999 const __m128i division8 = _mm_or_si128(firstDivision8, secondDivision8);
3002 _mm_storeu_si128((__m128i*)result, division8);
3007 ocean_assert(image0 && image1 && image2);
3016 const __m128i firstRow0 = _mm_lddqu_si128((__m128i*)image0);
3017 const __m128i firstRow1 = _mm_lddqu_si128((__m128i*)image1);
3018 const __m128i firstRow2 = _mm_lddqu_si128((__m128i*)image2);
3025 const __m128i secondRow0 = _mm_lddqu_si128((__m128i*)(image0 + 14));
3026 const __m128i secondRow1 = _mm_lddqu_si128((__m128i*)(image1 + 14));
3027 const __m128i secondRow2 = _mm_lddqu_si128((__m128i*)(image2 + 14));
3035 const __m128i firstSum = _mm_add_epi16(firstSumEven, _mm_add_epi16(firstSumOdd, _mm_set1_epi32(
int(0x00080008))));
3037 const __m128i firstSumWithEven = _mm_add_epi16(firstSum, _mm_shuffle_epi8(firstSumEven,
set128i(0xFFFF0F0E0B0AFFFFull, 0x09080504FFFF0302ull)));
3039 const __m128i firstSumWithBoth = _mm_add_epi16(firstSumWithEven, _mm_shuffle_epi8(firstSumOdd,
set128i(0xFFFF0D0C0908FFFFull, 0x07060302FFFF0100ull)));
3043 const __m128i secondSum = _mm_add_epi16(secondSumEven, _mm_add_epi16(secondSumOdd, _mm_set1_epi32(
int(0x00080008))));
3044 const __m128i secondSumWithEven = _mm_add_epi16(secondSum, _mm_shuffle_epi8(secondSumEven,
set128i(0x0F0EFFFF0D0C0908ull, 0xFFFF07060302FFFFull)));
3045 const __m128i secondSumWithBoth = _mm_add_epi16(secondSumWithEven, _mm_shuffle_epi8(secondSumOdd,
set128i(0x0D0CFFFF0B0A0706ull, 0xFFFF05040100FFFFull)));
3048 const __m128i firstDivision16 = _mm_srli_epi16(firstSumWithBoth, 4);
3049 const __m128i secondDivision16 = _mm_srli_epi16(secondSumWithBoth, 4);
3052 const __m128i firstDivision8 = _mm_shuffle_epi8(firstDivision16,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFFFF0C0A060400ull));
3053 const __m128i secondDivision8 = _mm_shuffle_epi8(secondDivision16,
set128i(0xFFFFFFFFFFFF0E0Aull, 0x080402FFFFFFFFFFull));
3056 const __m128i division8 = _mm_or_si128(firstDivision8, secondDivision8);
3059#ifdef OCEAN_COMPILER_MSC
3060 memcpy(result, &division8.m128i_u8[0], 10);
3062 memcpy(result, &division8, 10);
3075 const __m128i maskOdds = _mm_and_si128(value,
CV::SSE::set128i(0x0001000100010001ull, 0x0001000100010001ull));
3078 const __m128i maskNegatives = _mm_srli_epi16(_mm_and_si128(value,
CV::SSE::set128i(0x8000800080008000ull, 0x8000800080008000ull)), 15);
3082 return _mm_add_epi16(value, _mm_and_si128(maskNegatives, maskOdds));
3087 ocean_assert(rightShifts < 16u);
3090 const __m128i offsetForNegatives_s_16x8 = _mm_set1_epi16(
short((1u << rightShifts) - 1u));
3093 const __m128i maskHigh_s_16x8 =
CV::SSE::set128i(0x8000800080008000ull, 0x8000800080008000ull);
3096 const __m128i maskNegativeValues_s_16x8 = _mm_cmpeq_epi16(_mm_and_si128(value, maskHigh_s_16x8), maskHigh_s_16x8);
3099 const __m128i offset_s_16x8 = _mm_and_si128(offsetForNegatives_s_16x8, maskNegativeValues_s_16x8);
3101 return _mm_add_epi16(value, offset_s_16x8);
3111 ocean_assert(rightShifts >= 1 && rightShifts <= 15);
3113 const __m128i signMask_s16x8 = _mm_srai_epi16(value_s16x8, 15);
3115 const __m128i absValue_s16x8 = _mm_abs_epi16(value_s16x8);
3116 const __m128i offset_s16x8 = _mm_set1_epi16(1 << (rightShifts - 1));
3118 const __m128i absValueWithOffset_s16x8 = _mm_add_epi16(absValue_s16x8, offset_s16x8);
3120 const __m128i shifted_s16x8 = _mm_srai_epi16(absValueWithOffset_s16x8, rightShifts);
3122 return _mm_sub_epi16(_mm_xor_si128(shifted_s16x8, signMask_s16x8), signMask_s16x8);
3127 ocean_assert(rightShifts >= 1 && rightShifts <= 15);
3129 const int32_t maxValue = 32767 - (1 << (rightShifts - 1));
3133 return int16_t(maxValue);
3145 const __m128i maskOdds = _mm_and_si128(value,
CV::SSE::set128i(0x0000000100000001ull, 0x0000000100000001ull));
3148 const __m128i maskNegatives = _mm_srli_epi32(_mm_and_si128(value,
CV::SSE::set128i(0x8000000080000000ull, 0x8000000080000000ull)), 31);
3151 return _mm_add_epi32(value, _mm_and_si128(maskNegatives, maskOdds));
3156 ocean_assert(rightShifts < 32u);
3159 const __m128i offsetForNegatives_s_32x4 = _mm_set1_epi32(
int((1u << rightShifts) - 1u));
3162 const __m128i maskHigh_s_32x4 =
CV::SSE::set128i(0x8000000080000000ull, 0x8000000080000000ull);
3165 const __m128i maskNegativeValues_s_32x4 = _mm_cmpeq_epi32(_mm_and_si128(value, maskHigh_s_32x4), maskHigh_s_32x4);
3168 const __m128i offset_s_32x4 = _mm_and_si128(offsetForNegatives_s_32x4, maskNegativeValues_s_32x4);
3170 return _mm_add_epi32(value, offset_s_32x4);
3180 ocean_assert(source && response && width >= 10u);
3183 const __m128i horizontalMinus = _mm_lddqu_si128((__m128i*)(source - 1));
3184 const __m128i horizontalPlus = _mm_lddqu_si128((__m128i*)(source + 1));
3186 const __m128i verticalMinus = _mm_lddqu_si128((__m128i*)(source - width));
3187 const __m128i verticalPlus = _mm_lddqu_si128((__m128i*)(source + width));
3190 const __m128i horizontalMinusLo = _mm_cvtepu8_epi16(horizontalMinus);
3192 const __m128i horizontalMinusHi = _mm_shuffle_epi8(horizontalMinus,
set128i(0x800F800E800D800Cull, 0x800B800A80098008ull));
3194 const __m128i horizontalPlusLo = _mm_cvtepu8_epi16(horizontalPlus);
3196 const __m128i horizontalPlusHi = _mm_shuffle_epi8(horizontalPlus,
set128i(0x800F800E800D800Cull, 0x800B800A80098008ull));
3203 const __m128i horizontalGradient = _mm_or_si128(
3204 _mm_shuffle_epi8(horizontalGradientLo,
set128i(0x8080808080808080ull, 0x0E0C0A0806040200ull)),
3205 _mm_shuffle_epi8(horizontalGradientHi,
set128i(0x0E0C0A0806040200ull, 0x8080808080808080ull)));
3208 const __m128i verticalMinusLo = _mm_cvtepu8_epi16(verticalMinus);
3210 const __m128i verticalMinusHi = _mm_shuffle_epi8(verticalMinus,
set128i(0x800F800E800D800Cull, 0x800B800A80098008ull));
3212 const __m128i verticalPlusLo = _mm_cvtepu8_epi16(verticalPlus);
3214 const __m128i verticalPlusHi = _mm_shuffle_epi8(verticalPlus,
set128i(0x800F800E800D800Cull, 0x800B800A80098008ull));
3221 const __m128i verticalGradient = _mm_or_si128(
3222 _mm_shuffle_epi8(verticalGradientLo,
set128i(0x8080808080808080ull, 0x0E0C0A0806040200ull)),
3223 _mm_shuffle_epi8(verticalGradientHi,
set128i(0x0E0C0A0806040200ull, 0x8080808080808080ull)));
3226 const __m128i interleavedResponseLo = _mm_unpacklo_epi8(horizontalGradient, verticalGradient);
3227 const __m128i interleavedResponseHi = _mm_unpackhi_epi8(horizontalGradient, verticalGradient);
3229 ocean_assert(
sizeof(
char) == 1ull);
3230 _mm_storeu_si128((__m128i*)response, interleavedResponseLo);
3231 _mm_storeu_si128((__m128i*)(response + 16ull), interleavedResponseHi);
3236 ocean_assert(source && response && width >= 10u);
3239 const __m128i horizontalMinus = _mm_lddqu_si128((__m128i*)(source - 1));
3240 const __m128i horizontalPlus = _mm_lddqu_si128((__m128i*)(source + 1));
3242 const __m128i verticalMinus = _mm_lddqu_si128((__m128i*)(source - width));
3243 const __m128i verticalPlus = _mm_lddqu_si128((__m128i*)(source + width));
3246 const __m128i horizontalMinusLo = _mm_cvtepu8_epi16(horizontalMinus);
3247 const __m128i horizontalMinusHi = _mm_shuffle_epi8(horizontalMinus,
set128i(0x800F800E800D800Cull, 0x800B800A80098008ull));
3249 const __m128i horizontalPlusLo = _mm_cvtepu8_epi16(horizontalPlus);
3250 const __m128i horizontalPlusHi = _mm_shuffle_epi8(horizontalPlus,
set128i(0x800F800E800D800Cull, 0x800B800A80098008ull));
3257 const __m128i verticalMinusLo = _mm_cvtepu8_epi16(verticalMinus);
3258 const __m128i verticalMinusHi = _mm_shuffle_epi8(verticalMinus,
set128i(0x800F800E800D800Cull, 0x800B800A80098008ull));
3260 const __m128i verticalPlusLo = _mm_cvtepu8_epi16(verticalPlus);
3261 const __m128i verticalPlusHi = _mm_shuffle_epi8(verticalPlus,
set128i(0x800F800E800D800Cull, 0x800B800A80098008ull));
3268 const __m128i horizontalHorizontalLo = _mm_mullo_epi16(horizontalGradientLo, horizontalGradientLo);
3269 const __m128i horizontalHorizontalHi = _mm_mullo_epi16(horizontalGradientHi, horizontalGradientHi);
3271 const __m128i verticalVerticalLo = _mm_mullo_epi16(verticalGradientLo, verticalGradientLo);
3272 const __m128i verticalVerticalHi = _mm_mullo_epi16(verticalGradientHi, verticalGradientHi);
3274 const __m128i horzontalVerticalLo = _mm_mullo_epi16(horizontalGradientLo, verticalGradientLo);
3275 const __m128i horzontalVerticalHi = _mm_mullo_epi16(horizontalGradientHi, verticalGradientHi);
3298 const __m128i block0Lo = _mm_or_si128(
3300 _mm_shuffle_epi8(horizontalHorizontalLo,
set128i(0xFFFF0504FFFFFFFFull, 0x0302FFFFFFFF0100ull)),
3301 _mm_shuffle_epi8(verticalVerticalLo,
set128i(0x0504FFFFFFFF0302ull, 0xFFFFFFFF0100FFFFull))),
3302 _mm_shuffle_epi8(horzontalVerticalLo,
set128i(0xFFFFFFFF0302FFFFull, 0xFFFF0100FFFFFFFFull)));
3304 const __m128i block1Lo = _mm_or_si128(
3306 _mm_shuffle_epi8(horizontalHorizontalLo,
set128i(0x0B0AFFFFFFFF0908ull, 0xFFFFFFFF0706FFFFull)),
3307 _mm_shuffle_epi8(verticalVerticalLo,
set128i(0xFFFFFFFF0908FFFFull, 0xFFFF0706FFFFFFFFull))),
3308 _mm_shuffle_epi8(horzontalVerticalLo,
set128i(0xFFFF0908FFFFFFFFull, 0x0706FFFFFFFF0504ull)));
3310 const __m128i block2Lo = _mm_or_si128(
3312 _mm_shuffle_epi8(horizontalHorizontalLo,
set128i(0xFFFFFFFF0F0EFFFFull, 0xFFFF0D0CFFFFFFFFull)),
3313 _mm_shuffle_epi8(verticalVerticalLo,
set128i(0xFFFF0F0EFFFFFFFFull, 0x0D0CFFFFFFFF0B0Aull))),
3314 _mm_shuffle_epi8(horzontalVerticalLo,
set128i(0x0F0EFFFFFFFF0D0Cull, 0xFFFFFFFF0B0AFFFFull)));
3316 const __m128i block0Hi = _mm_or_si128(
3318 _mm_shuffle_epi8(horizontalHorizontalHi,
set128i(0xFFFF0504FFFFFFFFull, 0x0302FFFFFFFF0100ull)),
3319 _mm_shuffle_epi8(verticalVerticalHi,
set128i(0x0504FFFFFFFF0302ull, 0xFFFFFFFF0100FFFFull))),
3320 _mm_shuffle_epi8(horzontalVerticalHi,
set128i(0xFFFFFFFF0302FFFFull, 0xFFFF0100FFFFFFFFull)));
3322 const __m128i block1Hi = _mm_or_si128(
3324 _mm_shuffle_epi8(horizontalHorizontalHi,
set128i(0x0B0AFFFFFFFF0908ull, 0xFFFFFFFF0706FFFFull)),
3325 _mm_shuffle_epi8(verticalVerticalHi,
set128i(0xFFFFFFFF0908FFFFull, 0xFFFF0706FFFFFFFFull))),
3326 _mm_shuffle_epi8(horzontalVerticalHi,
set128i(0xFFFF0908FFFFFFFFull, 0x0706FFFFFFFF0504ull)));
3328 const __m128i block2Hi = _mm_or_si128(
3330 _mm_shuffle_epi8(horizontalHorizontalHi,
set128i(0xFFFFFFFF0F0EFFFFull, 0xFFFF0D0CFFFFFFFFull)),
3331 _mm_shuffle_epi8(verticalVerticalHi,
set128i(0xFFFF0F0EFFFFFFFFull, 0x0D0CFFFFFFFF0B0Aull))),
3332 _mm_shuffle_epi8(horzontalVerticalHi,
set128i(0x0F0EFFFFFFFF0D0Cull, 0xFFFFFFFF0B0AFFFFull)));
3334 _mm_storeu_si128((__m128i*)response, block0Lo);
3335 _mm_storeu_si128((__m128i*)(response + 8ull), block1Lo);
3336 _mm_storeu_si128((__m128i*)(response + 16ull), block2Lo);
3337 _mm_storeu_si128((__m128i*)(response + 24ull), block0Hi);
3338 _mm_storeu_si128((__m128i*)(response + 32ull), block1Hi);
3339 _mm_storeu_si128((__m128i*)(response + 40ull), block2Hi);
3349 channel01 = _mm_shuffle_epi8(interleaved,
set128i(0xFFFFFF0d0a070401ull, 0xFFFFFF0c09060300ull));
3351 channel2 = _mm_shuffle_epi8(interleaved,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFFFF0e0b080502ull));
3362 channel01 = _mm_or_si128(_mm_shuffle_epi8(interleavedA,
set128i(0xFFFFFF0d0a070401ull, 0xFFFF0f0c09060300ull)),
3363 _mm_shuffle_epi8(interleavedB,
set128i(0x060300FFFFFFFFFFull, 0x0502FFFFFFFFFFFFull)));
3365 channel2 = _mm_or_si128(_mm_shuffle_epi8(interleavedA,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFFFF0e0b080502ull)),
3366 _mm_shuffle_epi8(interleavedB,
set128i(0xFFFFFFFFFFFFFFFFull, 0x070401FFFFFFFFFFull)));
3371 channel0 = _mm_or_si128(_mm_shuffle_epi8(interleavedA,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFF0f0c09060300ull)),
3372 _mm_or_si128(_mm_shuffle_epi8(interleavedB,
set128i(0xFFFFFFFFFF0e0b08ull, 0x0502FFFFFFFFFFFFull)),
3373 _mm_shuffle_epi8(interleavedC,
set128i(0x0d0a070401FFFFFFull, 0xFFFFFFFFFFFFFFFFull))));
3375 channel1 = _mm_or_si128(_mm_shuffle_epi8(interleavedA,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFFFF0d0a070401ull)),
3376 _mm_or_si128(_mm_shuffle_epi8(interleavedB,
set128i(0xFFFFFFFFFF0f0c09ull, 0x060300FFFFFFFFFFull)),
3377 _mm_shuffle_epi8(interleavedC,
set128i(0x0e0b080502FFFFFFull, 0xFFFFFFFFFFFFFFFFull))));
3379 channel2 = _mm_or_si128(_mm_shuffle_epi8(interleavedA,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFFFF0e0b080502ull)),
3380 _mm_or_si128(_mm_shuffle_epi8(interleavedB,
set128i(0xFFFFFFFFFFFF0d0aull, 0x070401FFFFFFFFFFull)),
3381 _mm_shuffle_epi8(interleavedC,
set128i(0x0f0c09060300FFFFull, 0xFFFFFFFFFFFFFFFFull))));
3386 ocean_assert(interleaved !=
nullptr);
3393 ocean_assert(interleaved && channel0 && channel1 && channel2);
3395 __m128i channel0_128, channel1_128, channel2_128;
3405 ocean_assert(interleaved !=
nullptr);
3410OCEAN_FORCE_INLINE
void SSE::interleave3Channel8Bit48Elements(
const __m128i& channel0,
const __m128i& channel1,
const __m128i& channel2, __m128i& interleavedA, __m128i& interleavedB, __m128i& interleavedC)
3412 interleavedA = _mm_or_si128(_mm_shuffle_epi8(channel0,
set128i(0x05FFFF04FFFF03FFull, 0xFF02FFFF01FFFF00ull)),
3413 _mm_or_si128(_mm_shuffle_epi8(channel1,
set128i(0xFFFF04FFFF03FFFFull, 0x02FFFF01FFFF00FFull)),
3414 _mm_shuffle_epi8(channel2,
set128i(0xFF04FFFF03FFFF02ull, 0xFFFF01FFFF00FFFFull))));
3416 interleavedB = _mm_or_si128(_mm_shuffle_epi8(channel0,
set128i(0xFF0AFFFF09FFFF08ull, 0xFFFF07FFFF06FFFFull)),
3417 _mm_or_si128(_mm_shuffle_epi8(channel1,
set128i(0x0AFFFF09FFFF08FFull, 0xFF07FFFF06FFFF05ull)),
3418 _mm_shuffle_epi8(channel2,
set128i(0xFFFF09FFFF08FFFFull, 0x07FFFF06FFFF05FFull))));
3420 interleavedC = _mm_or_si128(_mm_shuffle_epi8(channel0,
set128i(0xFFFF0FFFFF0EFFFFull, 0x0DFFFF0CFFFF0BFFull)),
3421 _mm_or_si128(_mm_shuffle_epi8(channel1,
set128i(0xFF0FFFFF0EFFFF0Dull, 0xFFFF0CFFFF0BFFFFull)),
3422 _mm_shuffle_epi8(channel2,
set128i(0x0FFFFF0EFFFF0DFFull, 0xFF0CFFFF0BFFFF0Aull))));
3427 ocean_assert(channel0 && channel1 && channel2 && interleaved);
3429 __m128i interleavedA_128, interleavedB_128, interleavedC_128;
3432 store128i(interleavedA_128, interleaved + 0);
3433 store128i(interleavedB_128, interleaved + 16);
3434 store128i(interleavedC_128, interleaved + 32);
3439 ocean_assert(interleaved !=
nullptr);
3443 const __m128i shuffleMask0 = _mm_set_epi8(5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0);
3444 const __m128i interleaved0 = _mm_shuffle_epi8(singleChannel_u_8x8, shuffleMask0);
3446 const __m128i shuffleMask1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 6, 6, 6, 5, 5);
3447 const __m128i interleaved1 = _mm_shuffle_epi8(singleChannel_u_8x8, shuffleMask1);
3449 _mm_storeu_si128((__m128i*)(interleaved + 0), interleaved0);
3450 _mm_storel_epi64((__m128i*)(interleaved + 16), interleaved1);
3455 ocean_assert(interleaved !=
nullptr);
3459 const __m128i shuffleMask0 = _mm_set_epi8(-128, 3, 3, 3, -128, 2, 2, 2, -128, 1, 1, 1, -128, 0, 0, 0);
3460 const __m128i shuffleMask1 = _mm_set_epi8(-128, 7, 7, 7, -128, 6, 6, 6, -128, 5, 5, 5, -128, 4, 4, 4);
3463 __m128i result0 = _mm_shuffle_epi8(singleChannel_u_8x8, shuffleMask0);
3464 __m128i result1 = _mm_shuffle_epi8(singleChannel_u_8x8, shuffleMask1);
3466 const __m128i channel4Mask = _mm_set_epi8(-1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0);
3468 const __m128i lastChannelValue_u_8x16 = _mm_set1_epi8(
char(lastChannelValue));
3470 result0 = _mm_blendv_epi8(result0, lastChannelValue_u_8x16, channel4Mask);
3471 result1 = _mm_blendv_epi8(result1, lastChannelValue_u_8x16, channel4Mask);
3473 _mm_storeu_si128((__m128i*)(interleaved + 0), result0);
3474 _mm_storeu_si128((__m128i*)(interleaved + 16), result1);
3479 ocean_assert(interleaved !=
nullptr && reversedInterleaved !=
nullptr);
3486 const __m128i shuffleMask_u_16x8 =
set128i(0x0E0F0C0D0A0B0809ull, 0x0607040502030001ull);
3488 store128i(_mm_shuffle_epi8(
load128i(interleaved + 0), shuffleMask_u_16x8), reversedInterleaved + 0);
3489 store128i(_mm_shuffle_epi8(
load128i(interleaved + 16), shuffleMask_u_16x8), reversedInterleaved + 16);
3492OCEAN_FORCE_INLINE
void SSE::reverseChannelOrder3Channel8Bit48Elements(
const __m128i& interleaved0,
const __m128i& interleaved1,
const __m128i& interleaved2, __m128i& reversedInterleaved0, __m128i& reversedInterleaved1, __m128i& reversedInterleaved2)
3494 reversedInterleaved0 = _mm_or_si128(_mm_shuffle_epi8(interleaved0,
set128i(0xFF0c0d0e090a0b06ull, 0x0708030405000102ull)),
3495 _mm_shuffle_epi8(interleaved1,
set128i(0x01FFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull)));
3497 reversedInterleaved1 = _mm_or_si128(_mm_shuffle_epi8(interleaved0,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFF0fFFull)),
3498 _mm_or_si128(_mm_shuffle_epi8(interleaved1,
set128i(0x0fFF0b0c0d08090aull, 0x050607020304FF00ull)),
3499 _mm_shuffle_epi8(interleaved2,
set128i(0xFF00FFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull))));
3501 reversedInterleaved2 = _mm_or_si128(_mm_shuffle_epi8(interleaved1,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFF0eull)),
3502 _mm_shuffle_epi8(interleaved2,
set128i(0x0d0e0f0a0b0c0708ull, 0x09040506010203FFull)));
3507 ocean_assert(interleaved !=
nullptr && reversedInterleaved !=
nullptr);
3509 __m128i reversedInterleaved0, reversedInterleaved1, reversedInterleaved2;
3512 store128i(reversedInterleaved0, reversedInterleaved);
3513 store128i(reversedInterleaved1, reversedInterleaved + 16);
3514 store128i(reversedInterleaved2, reversedInterleaved + 32);
3519 ocean_assert(interleaved !=
nullptr && reversedInterleaved !=
nullptr);
3526 const __m128i shuffleMask_u_16x8 =
set128i(0x0C0D0E0F08090A0Bull, 0x0405060700010203ull);
3528 store128i(_mm_shuffle_epi8(
load128i(interleaved + 0), shuffleMask_u_16x8), reversedInterleaved + 0);
3529 store128i(_mm_shuffle_epi8(
load128i(interleaved + 16), shuffleMask_u_16x8), reversedInterleaved + 16);
3530 store128i(_mm_shuffle_epi8(
load128i(interleaved + 32), shuffleMask_u_16x8), reversedInterleaved + 32);
3531 store128i(_mm_shuffle_epi8(
load128i(interleaved + 48), shuffleMask_u_16x8), reversedInterleaved + 48);
3536 ocean_assert(interleaved);
3538 __m128i reversedInterleaved0, reversedInterleaved1, reversedInterleaved2;
3541 store128i(reversedInterleaved0, interleaved);
3542 store128i(reversedInterleaved1, interleaved + 16);
3543 store128i(reversedInterleaved2, interleaved + 32);
3548 ocean_assert(first && second && first != second);
3550 __m128i first0, first1, first2;
3553 __m128i second0, second1, second2;
3565inline void SSE::reverseElements8Bit48Elements(
const __m128i& elements0,
const __m128i& elements1,
const __m128i& elements2, __m128i& reversedElements0, __m128i& reversedElements1, __m128i& reversedElements2)
3567 const __m128i mask =
set128i(0x0001020304050607ull, 0x08090a0b0c0d0e0full);
3569 reversedElements0 = _mm_shuffle_epi8(elements2, mask);
3570 reversedElements1 = _mm_shuffle_epi8(elements1, mask);
3571 reversedElements2 = _mm_shuffle_epi8(elements0, mask);
3576 ocean_assert(elements && reversedElements);
3578 __m128i reversedElements0, reversedElements1, reversedElements2;
3581 store128i(reversedElements0, reversedElements);
3582 store128i(reversedElements1, reversedElements + 16);
3583 store128i(reversedElements2, reversedElements + 32);
3588 ocean_assert(elements);
3590 __m128i reversedElements0, reversedElements1, reversedElements2;
3594 store128i(reversedElements1, elements + 16);
3595 store128i(reversedElements2, elements + 32);
3600 ocean_assert(first && second && first != second);
3602 __m128i first0, first1, first2;
3605 __m128i second0, second1, second2;
3619 ocean_assert(elements && shiftedElements);
3621 store128i(_mm_shuffle_epi8(
load128i(elements),
set128i(0x0c0f0e0d080b0a09ull, 0x0407060500030201ull)), shiftedElements);
3626 ocean_assert(elements && shiftedElements);
3628 store128i(_mm_shuffle_epi8(
load128i(elements),
set128i(0x0003020104070605ull, 0x080b0a090c0f0e0dull)), shiftedElements);
3633 ocean_assert(elements && shiftedElements);
3635 store128i(_mm_shuffle_epi8(
load128i(elements),
set128i(0x0e0d0c0f0a09080bull, 0x0605040702010003ull)), shiftedElements);
3640 ocean_assert(elements && shiftedElements);
3642 store128i(_mm_shuffle_epi8(
load128i(elements),
set128i(0x0201000306050407ull, 0x0a09080b0e0d0c0full)), shiftedElements);
3647 const __m128i zero = _mm_setzero_si128();
3648 const __m128i sum = _mm_sad_epu8(elements, zero);
3650 return _mm_add_epi32(_mm_srli_si128(sum, 8), sum);
3655 ocean_assert(elements !=
nullptr);
3660template <
bool tBufferHas16Bytes>
3663 ocean_assert(elements !=
nullptr);
3669 ocean_assert(elements !=
nullptr);
3680 const __m128i channel0_2First = _mm_or_si128(_mm_shuffle_epi8(interleaved0,
set128i(0xFFFFFF0e0b080502ull, 0xFFFF0f0c09060300ull)),
3681 _mm_shuffle_epi8(interleaved1,
set128i(0x070401FFFFFFFFFFull, 0x0502FFFFFFFFFFFFull)));
3684 const __m128i channel0_2Second = _mm_or_si128(_mm_shuffle_epi8(interleaved1,
set128i(0xFFFFFFFFFFFF0d0aull, 0xFFFFFFFFFF0e0b08ull)),
3685 _mm_shuffle_epi8(interleaved2,
set128i(0x0f0c09060300FFFFull, 0x0d0a070401FFFFFFull)));
3688 const __m128i channel1 = _mm_or_si128(_mm_shuffle_epi8(interleaved0,
set128i(0xFFFFFFFFFFFFFFFFull, 0xFFFFFF0d0a070401ull)),
3689 _mm_or_si128(_mm_shuffle_epi8(interleaved1,
set128i(0xFFFFFFFFFF0f0c09ull, 0x060300FFFFFFFFFFull)),
3690 _mm_shuffle_epi8(interleaved2,
set128i(0x0e0b080502FFFFFFull, 0xFFFFFFFFFFFFFFFFull))));
3692 const __m128i zero = _mm_setzero_si128();
3695 const __m128i sum0_2 = _mm_add_epi32(_mm_sad_epu8(channel0_2First, zero), _mm_sad_epu8(channel0_2Second, zero));
3698 const __m128i sum1 = _mm_sad_epu8(channel1, zero);
3701 return _mm_blend_epi16(sum0_2, _mm_add_epi32(_mm_slli_si128(sum1, 4), _mm_srli_si128(sum1, 4)),
int(0xC));
3706 ocean_assert(interleaved !=
nullptr);
3713 ocean_assert(interleaved !=
nullptr);
3720 ocean_assert(buffer !=
nullptr);
3721 return _mm_loadl_epi64((
const __m128i*)(buffer));
3726 ocean_assert(buffer !=
nullptr);
3727 return _mm_lddqu_si128((
const __m128i*)(buffer));
3730template <
bool tBufferHas16Bytes>
3733 ocean_assert(buffer !=
nullptr);
3737#ifdef OCEAN_COMPILER_MSC
3739 result.m128i_u64[0] = uint64_t(0);
3740 memcpy(result.m128i_u16 + 3, buffer + 0,
sizeof(uint16_t));
3741 memcpy(result.m128i_u64 + 1, buffer + 2,
sizeof(uint64_t));
3748 memcpy(ourResult.
m128i_u16 + 3, buffer + 0,
sizeof(uint16_t));
3749 memcpy(ourResult.
m128i_u64 + 1, buffer + 2,
sizeof(uint64_t));
3757inline __m128i SSE::load_u8_10_upper_zero<true>(
const uint8_t*
const buffer)
3759 ocean_assert(buffer !=
nullptr);
3765template <
bool tBufferHas16Bytes>
3768 ocean_assert(buffer !=
nullptr);
3770 __m128i intermediate;
3771 memcpy(&intermediate, buffer, 15);
3774 return _mm_slli_si128(intermediate, 1);
3778inline __m128i SSE::load_u8_15_upper_zero<true>(
const uint8_t*
const buffer)
3780 ocean_assert(buffer !=
nullptr);
3783 return _mm_slli_si128(_mm_lddqu_si128((__m128i*)(buffer)), 1);
3786template <
bool tBufferHas16Bytes>
3789 ocean_assert(buffer !=
nullptr);
3792 memcpy(&result, buffer, 13);
3798inline __m128i SSE::load_u8_13_lower_random<true>(
const uint8_t*
const buffer)
3800 ocean_assert(buffer !=
nullptr);
3803 return _mm_lddqu_si128((__m128i*)(buffer));
3806template <
bool tBufferHas16Bytes>
3809 ocean_assert(buffer !=
nullptr);
3812 memcpy(&result, buffer, 15);
3814#ifdef OCEAN_COMPILER_MSC
3815 result.m128i_u8[15] = 0u;
3817 ((
M128i&)result).m128i_u8[15] = 0u;
3824inline __m128i SSE::load_u8_15_lower_zero<true>(
const uint8_t*
const buffer)
3826 ocean_assert(buffer !=
nullptr);
3829 __m128i result = _mm_lddqu_si128((__m128i*)(buffer));
3831#ifdef OCEAN_COMPILER_MSC
3832 result.m128i_u8[15] = 0u;
3834 ((
M128i&)result).m128i_u8[15] = 0u;
3840template <
bool tBufferHas16Bytes>
3843 ocean_assert(buffer !=
nullptr);
3846 memcpy(&result, buffer, 15);
3852inline __m128i SSE::load_u8_15_lower_random<true>(
const uint8_t*
const buffer)
3854 ocean_assert(buffer !=
nullptr);
3857 return _mm_lddqu_si128((__m128i*)(buffer));
3860template <
unsigned int tShiftBytes>
3863 static_assert(tShiftBytes <= 16u,
"Invalid shift!");
3865 ocean_assert(buffer !=
nullptr);
3866 return _mm_srli_si128(_mm_lddqu_si128((__m128i*)(buffer)), tShiftBytes);
3871 ocean_assert(buffer !=
nullptr);
3872 _mm_storeu_si128((__m128i*)(buffer), value);
3875inline __m128i
SSE::set128i(
const unsigned long long high64,
const unsigned long long low64)
3881 return _mm_set_epi64x(high64, low64);
3883 return _mm_set_epi32(*(((
int*)&high64) + 1), *((
int*)&high64), *(((
int*)&low64) + 1), *((
int*)&low64));
3888 return _mm_set_epi64x(high64, low64);
3896 return _mm_and_si128(value, _mm_set1_epi32(
int(0x0000FFFFu)));
3901 return _mm_and_si128(value, _mm_set1_epi32(
int(0xFFFF0000u)));
3906 return _mm_and_si128(value, _mm_set1_epi32(
int(0x00FF00FFu)));
3911 return _mm_and_si128(value,
set128i(0x000000FF00FF00FFull, 0x00FF00FF00FF00FFull));
3916 return _mm_and_si128(value,
set128i(0x00FF00FF00FF00FFull, 0x00FF00FF00FF0000ull));
3921 return _mm_shuffle_epi8(value,
set128i(0xA0A0A0A0A0A0A0A0ull, 0x0E0C0A0806040200ull));
3926 return _mm_shuffle_epi8(value,
set128i(0xA0A0A0A0A0A0A0A0ull, 0xA0A0A0A00C080400ull));
3931 return _mm_shuffle_epi8(value,
set128i(0xA0A0A0A0A0A0A0A0ull, 0x0D0C090805040100ull));
3936 return _mm_shuffle_epi8(value,
set128i(0x0E0C0A0806040200ull, 0xA0A0A0A0A0A0A0A0ull));
3942 return _mm_srli_epi32(value, 16);
3947 return _mm_shuffle_epi8(value,
set128i(0xA00FA00DA00BA009ull, 0xA007A005A003A001ull));
3952 return _mm_shuffle_epi8(value,
set128i(0xA0A0A0A0A0A0A009ull, 0xA007A005A003A001ull));
3957 return _mm_shuffle_epi8(value,
set128i(0xFFFFFFFFFF0bFF09ull, 0xFF07FF05FF03FF01ull));
3962 return _mm_shuffle_epi8(value,
set128i(0xA0A0A00DA00BA009ull, 0xA007A005A003A001ull));
3967 return _mm_shuffle_epi8(value,
set128i(0xA0A0A003A0A0A002ull, 0xA0A0A001A0A0A000ull));
3977 return _mm_shuffle_epi8(value,
set128i(0xA007A003A006A002ull, 0xA005A001A004A000ull));
3982 return _mm_shuffle_epi8(value,
set128i(0xA00FA00BA00EA00Aull, 0xA00DA009A00CA008ull));
3987 return _mm_shuffle_epi8(value,
set128i(0xFF07FF05FF06FF04ull, 0xFF03FF01FF02FF00ull));
3992 return _mm_shuffle_epi8(value,
set128i(0xFF0FFF0DFF0EFF0Cull, 0xFF0BFF09FF0AFF08ull));
3997 return _mm_set1_epi32(
int(0x00FF00FFu));
4002 return _mm_set1_epi32(
int(0x0000FFFFu));
4007 const __m128i lowProducts = _mm_mullo_epi16(values0, values1);
4008 const __m128i highProducts = _mm_mulhi_epi16(values0, values1);
4010 products0 = _mm_unpacklo_epi16(lowProducts, highProducts);
4011 products1 = _mm_unpackhi_epi16(lowProducts, highProducts);
4020 results0 = _mm_add_epi32(results0, products0);
4021 results1 = _mm_add_epi32(results1, products1);
4024inline unsigned int SSE::interpolation2Channel16Bit1x1(
const uint8_t*
const pixel,
const unsigned int size,
const unsigned int fx_y_,
const unsigned int fxy_,
const unsigned int fx_y,
const unsigned int fxy)
4026 ocean_assert(pixel);
4027 ocean_assert(fx_y_ + fxy_ + fx_y + fxy == 128u * 128u);
4029 return (pixel[0] * fx_y_ + pixel[2] * fxy_ + pixel[size] * fx_y + pixel[size + 2u] * fxy + 8192u) / 16384u;
4032inline unsigned int SSE::ssd2Channel16Bit1x1(
const uint8_t*
const pixel0,
const uint8_t*
const pixel1,
const unsigned int ,
const unsigned int size1,
const unsigned int f1x_y_,
const unsigned int f1xy_,
const unsigned int f1x_y,
const unsigned int f1xy)
4034 ocean_assert(pixel0 && pixel1);
4036 ocean_assert(f1x_y_ + f1xy_ + f1x_y + f1xy == 128u * 128u);
4041inline unsigned int SSE::ssd2Channel16Bit1x1(
const uint8_t*
const pixel0,
const uint8_t*
const pixel1,
const unsigned int size0,
const unsigned int size1,
const unsigned int f0x_y_,
const unsigned int f0xy_,
const unsigned int f0x_y,
const unsigned int f0xy,
const unsigned int f1x_y_,
const unsigned int f1xy_,
const unsigned int f1x_y,
const unsigned int f1xy)
4043 ocean_assert(pixel0 && pixel1);
4045 ocean_assert(f0x_y_ + f0xy_ + f0x_y + f0xy == 128u * 128u);
4046 ocean_assert(f1x_y_ + f1xy_ + f1x_y + f1xy == 128u * 128u);
4048 return sqrDistance(
interpolation2Channel16Bit1x1(pixel0, size0, f0x_y_, f0xy_, f0x_y, f0xy),
interpolation2Channel16Bit1x1(pixel1, size1, f1x_y_, f1xy_, f1x_y, f1xy));
This class implements computer vision functions using SSE extensions.
Definition SSE.h:42
static __m128i divideByRightShiftSigned32Bit(const __m128i &value, const unsigned int rightShifts)
Divides eight signed 32 bit values by applying a right shift.
Definition SSE.h:3173
static void average32Elements2Channel16Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result)
Averages 32 elements of 2x2 blocks for 2 channel 16 bit frames.
Definition SSE.h:2763
static void gradientHorizontalVertical8Elements1Channel8Bit(const uint8_t *source, int8_t *response, const unsigned int width)
Determines the horizontal and the vertical gradients for 16 following pixels for a given 1 channel 8 ...
Definition SSE.h:3178
static unsigned int sum_u32_first_2(const __m128i &value)
Adds the first two individual 32 bit unsigned integer values of a m128i value and returns the result.
Definition SSE.h:1369
static void average24Elements3Channel24Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result)
Averages 24 elements of 2x2 blocks for 3 channel 24 bit frames.
Definition SSE.h:2846
static void prefetchT2(const void *const data)
Prefetches a block of temporal memory in all cache levels, except 0th and 1st cache levels.
Definition SSE.h:1303
static void reverseElements8Bit48Elements(const __m128i &elements0, const __m128i &elements1, const __m128i &elements2, __m128i &reversedElements0, __m128i &reversedElements1, __m128i &reversedElements2)
Reverses the order of 48 elements with 8 bit per element.
Definition SSE.h:3565
static __m128i load128i(const void *const buffer)
Loads a 128i value from the memory.
Definition SSE.h:3724
static void average16Elements2Channel16Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result)
Averages 16 elements of 2x2 blocks for 2 channel 16 bit frames.
Definition SSE.h:2738
static __m128i load_u8_16_and_shift_right(const uint8_t *const buffer)
Loads 16 bytes from memory which is at least 16 bytes large and shifts the 128i value by a specified ...
Definition SSE.h:3861
static __m128i moveLowBits32_16ToLow64(const __m128i &value)
Moves the lower 16 bits of four 32 bit elements to the lower 64 bits and fills the high 64 bits with ...
Definition SSE.h:3929
static __m128i moveLowBits32_8ToLow32(const __m128i &value)
Moves the lower 8 bits of four 32 bit elements to the lower 32 bits and fills the high 96 bits with 0...
Definition SSE.h:3924
static __m128i moveHighBits16_8_6(const __m128i &value)
Moves the higher 8 bits of six 16 bit elements to the lower 8 bits and fills the high bits with 0.
Definition SSE.h:3955
static __m128i addOffsetBeforeRightShiftDivisionByTwoSigned32Bit(const __m128i &value)
Adds 1 to each signed 32 bit value which is both, negative and odd, so that each value can be right s...
Definition SSE.h:3136
static OCEAN_FORCE_INLINE double sum_f64_2(const __m128d &value)
Adds the two (all two) individual 64 bit float of a m128 value and returns the result.
Definition SSE.h:1396
static OCEAN_FORCE_INLINE void deInterleave3Channel8Bit15Elements(const __m128i &interleaved, __m128i &channel01, __m128i &channel2)
Deinterleaves 15 elements of e.g., an image with 3 channels and 8 bit per element.
Definition SSE.h:3342
static void store128i(const __m128i &value, uint8_t *const buffer)
Stores a 128i value to the memory.
Definition SSE.h:3869
static __m128i sumSquareDifference8BitFront13Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum square difference determination for the first 13 elements of a buffer with 8 bit precision.
Definition SSE.h:1474
static __m128i sumInterleave3Channel8Bit45Elements(const uint8_t *interleaved)
Sums 15 elements individually for an interleaved pixel format with 3 channels and 8 bit per channel a...
Definition SSE.h:3711
static __m128i moveLowBits16_8ToHigh64(const __m128i &value)
Moves the lower 8 bits of eight 16 bit elements to the higher 64 bits and fills the low 64 bits with ...
Definition SSE.h:3934
static __m128i divideByRightShiftSigned16Bit(const __m128i &value, const unsigned int rightShifts)
Divides eight int16_t values by applying a right shift.
Definition SSE.h:3104
static __m128i shuffleNeighbor4High64BitsToLow16_8(const __m128i &value)
Shuffles pairs of four neighbors of the high 64 bits to the low 8 bits of eight 16 bit elements.
Definition SSE.h:3980
static void swapReversedElements8Bit48Elements(uint8_t *first, uint8_t *second)
Reverses the order of two sets of 48 elements with 8 bit per element and further swaps both sets.
Definition SSE.h:3598
static __m128i sumAbsoluteDifferences8BitBack11Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum absolute differences determination for the last 11 elements of a 16 elements buffer with 8 bit pr...
Definition SSE.h:1412
static void average8ElementsBinary1Channel8Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result, const uint16_t threshold=776u)
Averages 8 elements of 2x2 blocks for 1 binary (x00 or 0xFF) frames.
Definition SSE.h:2506
static __m128i interpolation1Channel8Bit8Elements(const __m128i &values0, const __m128i &values1, const __m128i &fx_fy_, const __m128i &fxfy_, const __m128i &fx_fy, const __m128i &fxfy)
Interpolates 8 elements of 2x2 blocks for 1 channel 8 bit frames.
Definition SSE.h:1621
static OCEAN_FORCE_INLINE void multiplyInt8x16ToInt32x8AndAccumulate(const __m128i &values0, const __m128i &values1, __m128i &results0, __m128i &results1)
Multiplies 8 int16_t values with 8 int16_t values and adds the products to 8 int32_t values.
Definition SSE.h:4014
static __m128i sumSquareDifference8BitBack13Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum square difference determination for the last 13 elements of an 16 elements buffer with 8 bit prec...
Definition SSE.h:1501
static unsigned int sum_u32_first_third(const __m128i &value)
Adds the first and the second 32 bit unsigned integer values of a m128i value and returns the result.
Definition SSE.h:1378
static __m128i sumSquareDifference8BitFront12Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum square difference determination for the first 12 elements of an 16 elements buffer with 8 bit pre...
Definition SSE.h:1419
static void average16ElementsBinary1Channel8Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result, const uint16_t threshold=776u)
Averages 16 elements of 2x2 blocks for 1 binary (x00 or 0xFF) frames.
Definition SSE.h:2563
static __m128i moveHighBits16_8_5(const __m128i &value)
Moves the higher 8 bits of five 16 bit elements to the lower 8 bits and fills the high bits with 0.
Definition SSE.h:3950
static int16_t maximalValueForRoundedDivisionByRightShiftSigned16Bit(const unsigned int rightShifts)
Returns the maximal value for which the function roundedDivideByRightShiftSigned16Bit() can be applie...
Definition SSE.h:3125
static __m128i shuffleLow32ToLow32_8(const __m128i &value)
Shuffles the lower four 8 bits to the low 8 bits of four 32 bit elements.
Definition SSE.h:3965
static void shiftChannelToFront4Channel32Bit(const uint8_t *elements, uint8_t *shiftedElements)
Shifts the channels of a 4 channel 32 bit pixels to the front and moves the front channel to the back...
Definition SSE.h:3617
static __m128i moveHighBits16_8(const __m128i &value)
Moves the higher 8 bits of eight 16 bit elements to the lower 8 bits and fills the high bits with 0.
Definition SSE.h:3945
static __m128i removeHighBits16_8_7_upper(const __m128i &value)
Removes the higher 8 bits of eight 16 bit elements and sets the lower two bytes to zero.
Definition SSE.h:3914
static void deInterleave3Channel8Bit45Elements(const uint8_t *interleaved, __m128i &channel0, __m128i &channel1, __m128i &channel2)
Deinterleaves 45 elements of e.g., an image with 3 channels and 8 bit per element.
Definition SSE.h:3403
static unsigned int value_u32(const __m128i &value)
Returns one specific 32 bit unsigned integer value of a m128i value object.
Definition SSE.h:1349
static OCEAN_FORCE_INLINE void interleave3Channel8Bit48Elements(const __m128i &channel0, const __m128i &channel1, const __m128i &channel2, __m128i &interleavedA, __m128i &interleavedB, __m128i &interleavedC)
Interleaves 48 elements of e.g., an image with 3 channels and 8 bit per element.
Definition SSE.h:3410
static __m128i load_u8_15_upper_zero(const uint8_t *const buffer)
Loads 15 bytes from memory, which holds either at least 16 bytes or exactly 15 bytes,...
Definition SSE.h:3766
static __m128i shuffleNeighbor2Low64BitsToLow16_8(const __m128i &value)
Shuffles pairs of two neighbors of the low 64 bits to the low 8 bits of eight 16 bit elements.
Definition SSE.h:3985
static void prefetchT1(const void *const data)
Prefetches a block of temporal memory in all cache levels except 0th cache level.
Definition SSE.h:1298
static __m128i sum1Channel8Bit16Elements(const __m128i &elements)
Sums 16 elements with 8 bit per element.
Definition SSE.h:3645
static __m128i shuffleNeighbor4Low64BitsToLow16_8(const __m128i &value)
Shuffles pairs of four neighbors of the low 64 bits to the low 8 bits of eight 16 bit elements.
Definition SSE.h:3970
static void average8Elements2Channel64Bit2x2(const float *const image0, const float *const image1, float *const result)
Averages 8 elements of 2x2 blocks for 2 channel 64 bit frames.
Definition SSE.h:2708
static __m128i addOffsetBeforeRightShiftDivisionSigned16Bit(const __m128i &value, const unsigned int rightShifts)
Adds 2^shifts - 1 to each negative int16_t value, so that each value can be right shifted to allow a ...
Definition SSE.h:3085
static __m128i load_u8_15_lower_random(const uint8_t *const buffer)
Loads 15 bytes from memory, which holds either at least 16 bytes or exactly 15 bytes,...
Definition SSE.h:3841
static __m128i removeHighBits16_8_7_lower(const __m128i &value)
Removes the higher 8 bits of eight 16 bit elements and sets the upper two bytes to zero.
Definition SSE.h:3909
static void average8Elements4Channel128Bit2x2(const float *const image0, const float *const image1, float *const result)
Averages 8 elements of 2x2 blocks for 4 channel 128 bit frames.
Definition SSE.h:2906
static __m128i load_u8_10_upper_zero(const uint8_t *const buffer)
Loads 10 bytes from memory, which holds either at least 16 bytes or exactly 10 bytes,...
Definition SSE.h:3731
static __m128i sumAbsoluteDifferences8Bit16Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum absolute differences determination for 16 elements of an 16 elements buffer with 8 bit precision.
Definition SSE.h:1581
static __m128i moveHighBits32_16(const __m128i &value)
Moves the higher 16 bits of four 32 bit elements to the lower 16 bits and fills the high bits with 0.
Definition SSE.h:3939
static void average16Elements4Channel32Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result)
Averages 16 elements of 2x2 blocks for 4 channel 32 bit frames.
Definition SSE.h:2934
static __m128i moveHighBits16_8_7(const __m128i &value)
Moves the higher 8 bits of seven 16 bit elements to the lower 8 bits and fills the high bits with 0.
Definition SSE.h:3960
static __m128i roundedDivideByRightShiftSigned16Bit(const __m128i &value_s16x8, const unsigned int rightShifts)
Applies a rounded division by a right shift for eight int16_t values.
Definition SSE.h:3109
static __m128i bitMaskRemoveHigh32_16()
Returns the following 128 bit mask: 0x0000FFFF-0000FFFF-0000FFFF-0000FFFF.
Definition SSE.h:4000
static __m128i sumSquareDifference8Bit16ElementsAligned16(const uint8_t *const image0, const uint8_t *const image1)
Sum square difference determination for 16 elements with 8 bit precision.
Definition SSE.h:1588
static __m128i removeHighBits32_16(const __m128i &value)
Removes the higher 16 bits of four 32 bit elements.
Definition SSE.h:3894
static __m128i shuffleNeighbor2High64BitsToLow16_8(const __m128i &value)
Shuffles pairs of two neighbors of the high 64 bits to the low 8 bits of eight 16 bit elements.
Definition SSE.h:3990
static void average6Elements3Channel96Bit2x2(const float *const image0, const float *const image1, float *const result)
Averages 6 elements of 2x2 blocks for 3 channel 96 bit frames.
Definition SSE.h:2809
static __m128i interpolation4Channel32Bit2x4Elements(const __m128i &values0, const __m128i &values1, const __m128i &fx_fy_, const __m128i &fxfy_, const __m128i &fx_fy, const __m128i &fxfy)
Interpolates 2x4 elements (two separated blocks of 4 elements) of 2x2 blocks for 4 channel 32 bit fra...
Definition SSE.h:2302
static __m128i interpolation3Channel24Bit12Elements(const __m128i &values0, const __m128i &values1, const __m128i &fx_fy_fxfy_, const __m128i &fx_fyfxfy)
Interpolates 12 elements of 2x2 blocks for 3 channel 24 bit frames.
Definition SSE.h:2115
static __m128i addOffsetBeforeRightShiftDivisionSigned32Bit(const __m128i &value, const unsigned int rightShifts)
Adds 2^shifts - 1 to each negative signed 32 bit value, so they each value can be right shifted to al...
Definition SSE.h:3154
static __m128i interpolation4Channel32Bit8Elements(const __m128i &values0, const __m128i &values1, const __m128i &fx_fy_, const __m128i &fxfy_, const __m128i &fx_fy, const __m128i &fxfy)
Interpolates 8 elements of 2x2 blocks for 4 channel 32 bit frames.
Definition SSE.h:2155
static void average8Elements1Channel32Bit2x2(const float *const image0, const float *const image1, float *const result)
Averages 8 elements of 2x2 blocks for 1 channel 32 bit frames.
Definition SSE.h:2448
static OCEAN_FORCE_INLINE void store1Channel8Bit8ElementsTo4Channels32ElementsWithConstantLastChannel(const __m128i &singleChannel_u_8x8, const uint8_t lastChannelValue, uint8_t *interleaved)
Stores 8 single-channel 8-bit elements as 32 interleaved 4-channel elements (8 elements -> 8×4 = 32 b...
Definition SSE.h:3453
static void shiftChannelToBack4Channel32Bit(const uint8_t *elements, uint8_t *shiftedElements)
Shifts the channels of a 4 channel 32 bit pixels to the back and moves the back channel to the front ...
Definition SSE.h:3631
static void average8Elements1Channel8Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result)
Averages 8 elements of 2x2 blocks for 1 channel 8 bit frames.
Definition SSE.h:2482
static OCEAN_FORCE_INLINE void deInterleave3Channel8Bit24Elements(const __m128i &interleavedA, const __m128i &interleavedB, __m128i &channel01, __m128i &channel2)
Deinterleaves 24 elements of e.g., an image with 3 channels and 8 bit per element.
Definition SSE.h:3354
static void prefetchT0(const void *const data)
Prefetches a block of temporal memory into all cache levels.
Definition SSE.h:1293
static __m128i interpolation1Channel8Bit15Elements(const __m128i &values0, const __m128i &values1, const __m128i &fx_fy_fxfy_, const __m128i &fx_fyfxfy)
Interpolates 15 elements of 2x2 blocks for 1 channel 8 bit frames.
Definition SSE.h:2063
static uint16_t value_u16(const __m128i &value)
Returns one specific 16 bit unsigned integer value of a m128i value object.
Definition SSE.h:1337
static OCEAN_FORCE_INLINE void reverseChannelOrder3Channel8Bit48Elements(const __m128i &interleaved0, const __m128i &interleaved1, const __m128i &interleaved2, __m128i &reversedInterleaved0, __m128i &reversedInterleaved1, __m128i &reversedInterleaved2)
Reverses the order of the first and last channel of 48 elements of an image with 3 interleaved channe...
Definition SSE.h:3492
static __m128i sumSquareDifferences8BitBack11Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum square differences determination for the last 11 elements of an 16 elements buffer with 8 bit pre...
Definition SSE.h:1405
static __m128i removeLowBits32_16(const __m128i &value)
Removes the lower 16 bits of four 32 bit elements.
Definition SSE.h:3899
static __m128i interpolation2Channel16Bit8Elements(const __m128i &values0, const __m128i &values1, const __m128i &fx_fy_, const __m128i &fxfy_, const __m128i &fx_fy, const __m128i &fxfy)
Interpolates 8 elements of 2x2 blocks for 2 channel 16 bit frames.
Definition SSE.h:1771
static uint8_t value_u8(const __m128i &value)
Returns one specific 8 bit unsigned integer value of a m128i value object.
Definition SSE.h:1314
static void gradientHorizontalVertical8Elements3Products1Channel8Bit(const uint8_t *source, int16_t *response, const unsigned int width)
Determines the squared horizontal and vertical gradients and the product of both gradients for 16 fol...
Definition SSE.h:3234
static __m128i bitMaskRemoveHigh16_8()
Returns the following 128 bit mask: 0x00FF00FF-00FF00FF-00FF00FF-00FF00FF.
Definition SSE.h:3995
static __m128i removeHighBits16_8(const __m128i &value)
Removes the higher 8 bits of eight 16 bit elements.
Definition SSE.h:3904
static __m128i sum1Channel8BitBack15Elements(const uint8_t *elements)
Sums the last 15 elements of a 16 elements buffer with 8 bit per element, the beginning 1 element is ...
Definition SSE.h:3667
static OCEAN_FORCE_INLINE void store1Channel8Bit8ElementsTo3Channels24Elements(const __m128i &singleChannel_u_8x8, uint8_t *interleaved)
Stores 8 single-channel 8-bit elements as 24 interleaved 3-channel elements (8 elements -> 8×3 = 24 b...
Definition SSE.h:3437
static __m128i load_u8_15_lower_zero(const uint8_t *const buffer)
Loads 15 bytes from memory, which holds either at least 16 bytes or exactly 15 bytes,...
Definition SSE.h:3807
static OCEAN_FORCE_INLINE void deInterleave3Channel8Bit48Elements(const __m128i &interleavedA, const __m128i &interleavedB, const __m128i &interleavedC, __m128i &channel0, __m128i &channel1, __m128i &channel2)
Deinterleaves 48 elements of e.g., an image with 3 channels and 8 bit per element.
Definition SSE.h:3369
static __m128i sumSquareDifference8Bit16Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum square difference determination for 16 elements with 8 bit precision.
Definition SSE.h:1571
static __m128i sumInterleave3Channel8Bit48Elements(const __m128i &interleaved0, const __m128i &interleaved1, const __m128i &interleaved2)
Sums 16 elements individually for an interleaved pixel format with 3 channels and 8 bit per channel a...
Definition SSE.h:3673
static void average32Elements4Channel32Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result)
Averages 32 elements of 2x2 blocks for 4 channel 32 bit frames.
Definition SSE.h:2958
static void average30Elements1Channel8Bit3x3(const uint8_t *const image0, const uint8_t *const image1, const uint8_t *const image2, uint8_t *const result)
Averages 30 elements of 3x3 blocks for 1 channel 8 bit frames.
Definition SSE.h:3005
static __m128i sumSquareDifference8BitFront15Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum square difference determination for the first 15 elements of a buffer with 8 bit precision.
Definition SSE.h:1529
static __m128i sum1Channel8BitFront15Elements(const uint8_t *elements)
Sums the first 15 elements of a buffer with 8 bit per element.
Definition SSE.h:3661
static void average32ElementsBinary1Channel8Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result, const uint16_t threshold=776u)
Averages 32 elements of 2x2 blocks for 1 binary (0x00 or 0xFF) frames.
Definition SSE.h:2651
static void average32Elements1Channel8Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result)
Averages 32 elements of 2x2 blocks for 1 channel 8 bit frames.
Definition SSE.h:2585
static __m128i sumSquareDifference8BitBack12Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum square difference determination for the last 12 elements of an 16 elements buffer with 8 bit prec...
Definition SSE.h:1446
static OCEAN_FORCE_INLINE float sum_f32_4(const __m128 &value)
Adds the four (all four) individual 32 bit float of a m128 value and returns the result.
Definition SSE.h:1387
static __m128i load_u8_13_lower_random(const uint8_t *const buffer)
Loads 13 bytes from memory, which holds either at least 16 bytes or exactly 13 bytes,...
Definition SSE.h:3787
static void swapReversedChannelOrder3Channel8Bit48Elements(uint8_t *first, uint8_t *second)
Reverses the order of the first and last channel of two sets of 48 elements of an image with 3 interl...
Definition SSE.h:3546
static OCEAN_FORCE_INLINE unsigned int sum_u32_4(const __m128i &value)
Adds the four (all four) individual 32 bit unsigned integer values of a m128i value and returns the r...
Definition SSE.h:1360
static void prefetchNTA(const void *const data)
Prefetches a block of non-temporal memory into non-temporal cache structure.
Definition SSE.h:1308
static __m128i moveLowBits16_8ToLow64(const __m128i &value)
Moves the lower 8 bits of eight 16 bit elements to the lower 64 bits and fills the high 64 bits with ...
Definition SSE.h:3919
static __m128i sumAbsoluteDifferences8BitFront10Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum absolute differences determination for the first 10 elements of a buffer with 8 bit precision.
Definition SSE.h:1556
static unsigned int interpolation2Channel16Bit1x1(const uint8_t *const pixel, const unsigned int size, const unsigned int fx_y_, const unsigned int fxy_, const unsigned int fx_y, const unsigned int fxy)
Returns the interpolated pixel values for one 2 channel 16 bit pixel.
Definition SSE.h:4024
static void shiftAndMirrorChannelToBack4Channel32Bit(const uint8_t *elements, uint8_t *shiftedElements)
Shifts the channels of a 4 channel 32 bit pixels to the back and moves the back channel to the front ...
Definition SSE.h:3638
static __m128i load128iLower64(const void *const buffer)
Loads the lower 64 bit of a 128i value from the memory.
Definition SSE.h:3718
static unsigned int ssd2Channel16Bit1x1(const uint8_t *const pixel0, const uint8_t *const pixel1, const unsigned int size0, const unsigned int size1, const unsigned int f1x_y_, const unsigned int f1xy_, const unsigned int f1x_y, const unsigned int f1xy)
Returns the interpolated sum of square difference for one 2 channel 16 bit pixel.
Definition SSE.h:4032
static __m128i set128i(const unsigned long long high64, const unsigned long long low64)
Sets a 128i value by two 64 bit values.
Definition SSE.h:3875
static OCEAN_FORCE_INLINE void reverseChannelOrder4Channel8Bit64Elements(const uint8_t *interleaved, uint8_t *reversedInterleaved)
Reverses the order of the channels of 16 pixels (64 elements) of an image with 4 interleaved channels...
Definition SSE.h:3517
static __m128i addOffsetBeforeRightShiftDivisionByTwoSigned16Bit(const __m128i &value)
Adds 1 to each signed 16 bit value which is both, negative and odd, so that each value can be right s...
Definition SSE.h:3066
static void average8Elements2Channel16Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result)
Averages 8 elements of 2x2 blocks for 2 channel 16 bit frames.
Definition SSE.h:2683
static void shiftAndMirrorChannelToFront4Channel32Bit(const uint8_t *elements, uint8_t *shiftedElements)
Shifts the channels of a 4 channel 32 bit pixels to the front and moves the front channel to the back...
Definition SSE.h:3624
static __m128i sumAbsoluteDifferences8BitFront15Elements(const uint8_t *const image0, const uint8_t *const image1)
Sum absolute differences determination for the first 15 elements of a buffer with 8 bit precision.
Definition SSE.h:1564
static void average16Elements1Channel8Bit2x2(const uint8_t *const image0, const uint8_t *const image1, uint8_t *const result)
Averages 16 elements of 2x2 blocks for 1 channel 8 bit frames.
Definition SSE.h:2528
static OCEAN_FORCE_INLINE void multiplyInt8x16ToInt32x8(const __m128i &values0, const __m128i &values1, __m128i &products0, __m128i &products1)
Multiplies 8 int16_t values with 8 int16_t values and returns the products as 8 int32_t results.
Definition SSE.h:4005
static OCEAN_FORCE_INLINE void reverseChannelOrder2Channel8Bit32Elements(const uint8_t *interleaved, uint8_t *reversedInterleaved)
Reverses the order of the channels of 16 pixels (32 elements) of an image with 2 interleaved channels...
Definition SSE.h:3477
static __m128i interpolation3Channel24Bit8Elements(const __m128i &values0, const __m128i &values1, const __m128i &fx_fy_, const __m128i &fxfy_, const __m128i &fx_fy, const __m128i &fxfy)
Interpolates 8 elements of 2x2 blocks for 3 channel 24 bit frames.
Definition SSE.h:1917
This class provides basic numeric functionalities.
Definition Numeric.h:57
unsigned int sqrDistance(const char first, const char second)
Returns the square distance between two values.
Definition base/Utilities.h:1159
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
This union defines a wrapper for the __m128 SSE intrinsic data type.
Definition SSE.h:71
float m128_f32[4]
The four 32 bit elements.
Definition SSE.h:73
This union defines a wrapper for the __m128 SSE intrinsic data type.
Definition SSE.h:82
double m128d_f64[2]
The two 64 bit elements.
Definition SSE.h:84
This union defines a wrapper for the __m128i SSE intrinsic data type.
Definition SSE.h:51
uint64_t m128i_u64[2]
The two 64 bit elements.
Definition SSE.h:53
uint16_t m128i_u16[8]
The eight 16 bit elements.
Definition SSE.h:59
uint32_t m128i_u32[4]
The four 32 bit elements.
Definition SSE.h:56
uint8_t m128i_u8[16]
The sixteen 8 bit elements.
Definition SSE.h:62