diff --git a/src/Simd/SimdSse41BgraToBgr.cpp b/src/Simd/SimdSse41BgraToBgr.cpp index 5c50a2e805..8168dcf846 100644 --- a/src/Simd/SimdSse41BgraToBgr.cpp +++ b/src/Simd/SimdSse41BgraToBgr.cpp @@ -30,30 +30,34 @@ namespace Simd #ifdef SIMD_SSE41_ENABLE namespace Sse41 { - template SIMD_INLINE void BgraToBgrBody(const uint8_t * bgra, uint8_t * bgr, __m128i k[3][2]) + SIMD_INLINE void BgraToBgrBody(const uint8_t * bgra, uint8_t * bgr, __m128i k[3][2]) { - Store((__m128i*)(bgr + 0), _mm_shuffle_epi8(Load((__m128i*)bgra + 0), k[0][0])); - Store((__m128i*)(bgr + 12), _mm_shuffle_epi8(Load((__m128i*)bgra + 1), k[0][0])); - Store((__m128i*)(bgr + 24), _mm_shuffle_epi8(Load((__m128i*)bgra + 2), k[0][0])); - Store((__m128i*)(bgr + 36), _mm_shuffle_epi8(Load((__m128i*)bgra + 3), k[0][0])); + _mm_storeu_si128((__m128i*)(bgr + 0), _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)bgra + 0), k[0][0])); + _mm_storeu_si128((__m128i*)(bgr + 12), _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)bgra + 1), k[0][0])); + _mm_storeu_si128((__m128i*)(bgr + 24), _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)bgra + 2), k[0][0])); + _mm_storeu_si128((__m128i*)(bgr + 36), _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)bgra + 3), k[0][0])); } - template SIMD_INLINE void BgraToBgr(const uint8_t * bgra, uint8_t * bgr, __m128i k[3][2]) + SIMD_INLINE void BgraToBgr(const uint8_t * bgra, uint8_t * bgr, __m128i k[3][2]) { - __m128i bgra0 = Load((__m128i*)bgra + 0); - __m128i bgra1 = Load((__m128i*)bgra + 1); - __m128i bgra2 = Load((__m128i*)bgra + 2); - __m128i bgra3 = Load((__m128i*)bgra + 3); - Store((__m128i*)bgr + 0, _mm_or_si128(_mm_shuffle_epi8(bgra0, k[0][0]), _mm_shuffle_epi8(bgra1, k[0][1]))); - Store((__m128i*)bgr + 1, _mm_or_si128(_mm_shuffle_epi8(bgra1, k[1][0]), _mm_shuffle_epi8(bgra2, k[1][1]))); - Store((__m128i*)bgr + 2, _mm_or_si128(_mm_shuffle_epi8(bgra2, k[2][0]), _mm_shuffle_epi8(bgra3, k[2][1]))); + __m128i bgra0 = _mm_loadu_si128((__m128i*)bgra + 0); + __m128i bgra1 = _mm_loadu_si128((__m128i*)bgra + 1); + __m128i bgra2 = _mm_loadu_si128((__m128i*)bgra + 2); + __m128i bgra3 = _mm_loadu_si128((__m128i*)bgra + 3); + _mm_storeu_si128((__m128i*)bgr + 0, _mm_or_si128(_mm_shuffle_epi8(bgra0, k[0][0]), _mm_shuffle_epi8(bgra1, k[0][1]))); + _mm_storeu_si128((__m128i*)bgr + 1, _mm_or_si128(_mm_shuffle_epi8(bgra1, k[1][0]), _mm_shuffle_epi8(bgra2, k[1][1]))); + _mm_storeu_si128((__m128i*)bgr + 2, _mm_or_si128(_mm_shuffle_epi8(bgra2, k[2][0]), _mm_shuffle_epi8(bgra3, k[2][1]))); } - template void BgraToBgr(const uint8_t * bgra, size_t width, size_t height, size_t bgraStride, uint8_t * bgr, size_t bgrStride) + void BgraToBgr(const uint8_t * bgra, size_t width, size_t height, size_t bgraStride, uint8_t * bgr, size_t bgrStride) { + if (width < A) + { + Base::BgraToBgr(bgra, width, height, bgraStride, bgr, bgrStride); + return; + } + assert(width >= A); - if (align) - assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(bgr) && Aligned(bgrStride)); size_t widthA = AlignLo(width, A) - A; @@ -68,32 +72,26 @@ namespace Simd for (size_t row = 0; row < height; ++row) { for (size_t col = 0; col < widthA; col += A) - BgraToBgrBody(bgra + 4 * col, bgr + 3 * col, k); - BgraToBgr(bgra + 4 * widthA, bgr + 3 * widthA, k); + BgraToBgrBody(bgra + 4 * col, bgr + 3 * col, k); + BgraToBgr(bgra + 4 * widthA, bgr + 3 * widthA, k); if (widthA + A != width) - BgraToBgr(bgra + 4 * (width - A), bgr + 3 * (width - A), k); + BgraToBgr(bgra + 4 * (width - A), bgr + 3 * (width - A), k); bgra += bgraStride; bgr += bgrStride; } } - void BgraToBgr(const uint8_t * bgra, size_t width, size_t height, size_t bgraStride, uint8_t * bgr, size_t bgrStride) - { - if (width < A) - Base::BgraToBgr(bgra, width, height, bgraStride, bgr, bgrStride); - else if (Aligned(bgra) && Aligned(bgraStride) && Aligned(bgr) && Aligned(bgrStride)) - BgraToBgr(bgra, width, height, bgraStride, bgr, bgrStride); - else - BgraToBgr(bgra, width, height, bgraStride, bgr, bgrStride); - } - //------------------------------------------------------------------------------------------------- - template void BgraToRgb(const uint8_t* bgra, size_t width, size_t height, size_t bgraStride, uint8_t* rgb, size_t rgbStride) + void BgraToRgb(const uint8_t* bgra, size_t width, size_t height, size_t bgraStride, uint8_t* rgb, size_t rgbStride) { + if (width < A) + { + Base::BgraToRgb(bgra, width, height, bgraStride, rgb, rgbStride); + return; + } + assert(width >= A); - if (align) - assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(rgb) && Aligned(rgbStride)); size_t widthA = AlignLo(width, A) - A; @@ -108,39 +106,33 @@ namespace Simd for (size_t row = 0; row < height; ++row) { for (size_t col = 0; col < widthA; col += A) - BgraToBgrBody(bgra + 4 * col, rgb + 3 * col, k); - BgraToBgr(bgra + 4 * widthA, rgb + 3 * widthA, k); + BgraToBgrBody(bgra + 4 * col, rgb + 3 * col, k); + BgraToBgr(bgra + 4 * widthA, rgb + 3 * widthA, k); if (widthA + A != width) - BgraToBgr(bgra + 4 * (width - A), rgb + 3 * (width - A), k); + BgraToBgr(bgra + 4 * (width - A), rgb + 3 * (width - A), k); bgra += bgraStride; rgb += rgbStride; } } - void BgraToRgb(const uint8_t* bgra, size_t width, size_t height, size_t bgraStride, uint8_t* rgb, size_t rgbStride) - { - if (width < A) - Base::BgraToRgb(bgra, width, height, bgraStride, rgb, rgbStride); - else if (Aligned(bgra) && Aligned(bgraStride) && Aligned(rgb) && Aligned(rgbStride)) - BgraToRgb(bgra, width, height, bgraStride, rgb, rgbStride); - else - BgraToRgb(bgra, width, height, bgraStride, rgb, rgbStride); - } - //------------------------------------------------------------------------------------------------- const __m128i K8_BGRA_TO_RGBA = SIMD_MM_SETR_EPI8(0x2, 0x1, 0x0, 0x3, 0x6, 0x5, 0x4, 0x7, 0xA, 0x9, 0x8, 0xB, 0xE, 0xD, 0xC, 0xF); - template SIMD_INLINE void BgraToRgba(const uint8_t* bgra, uint8_t* rgba) + SIMD_INLINE void BgraToRgba(const uint8_t* bgra, uint8_t* rgba) { - Store((__m128i*)rgba, _mm_shuffle_epi8(Load((__m128i*)bgra), K8_BGRA_TO_RGBA)); + _mm_storeu_si128((__m128i*)rgba, _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)bgra), K8_BGRA_TO_RGBA)); } - template void BgraToRgba(const uint8_t* bgra, size_t width, size_t height, size_t bgraStride, uint8_t* rgba, size_t rgbaStride) + void BgraToRgba(const uint8_t* bgra, size_t width, size_t height, size_t bgraStride, uint8_t* rgba, size_t rgbaStride) { + if(width < F) + { + Base::BgraToRgba(bgra, width, height, bgraStride, rgba, rgbaStride); + return; + } + assert(width >= F); - if (align) - assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(rgba) && Aligned(rgbaStride)); size_t size = width * 4; size_t sizeA = AlignLo(size, A); @@ -148,23 +140,13 @@ namespace Simd for (size_t row = 0; row < height; ++row) { for (size_t i = 0; i < sizeA; i += A) - BgraToRgba(bgra + i, rgba + i); + BgraToRgba(bgra + i, rgba + i); if (size != sizeA) - BgraToRgba(bgra + size - A, rgba + size - A); + BgraToRgba(bgra + size - A, rgba + size - A); bgra += bgraStride; rgba += rgbaStride; } } - - void BgraToRgba(const uint8_t* bgra, size_t width, size_t height, size_t bgraStride, uint8_t* rgba, size_t rgbaStride) - { - if(width < F) - Base::BgraToRgba(bgra, width, height, bgraStride, rgba, rgbaStride); - else if (Aligned(bgra) && Aligned(bgraStride) && Aligned(rgba) && Aligned(rgbaStride)) - BgraToRgba(bgra, width, height, bgraStride, rgba, rgbaStride); - else - BgraToRgba(bgra, width, height, bgraStride, rgba, rgbaStride); - } } #endif } diff --git a/src/Simd/SimdSse41BgraToGray.cpp b/src/Simd/SimdSse41BgraToGray.cpp index 2c191c22c0..ec85122984 100644 --- a/src/Simd/SimdSse41BgraToGray.cpp +++ b/src/Simd/SimdSse41BgraToGray.cpp @@ -49,19 +49,9 @@ namespace Simd return _mm_packus_epi16(lo, hi); } - template SIMD_INLINE void Load(const uint8_t* p, __m128i a[4]) - { - a[0] = Load((__m128i*)p + 0); - a[1] = Load((__m128i*)p + 1); - a[2] = Load((__m128i*)p + 2); - a[3] = Load((__m128i*)p + 3); - } - - template void BgraToGray(const uint8_t *bgra, size_t width, size_t height, size_t bgraStride, uint8_t *gray, size_t grayStride) + void BgraToGray(const uint8_t *bgra, size_t width, size_t height, size_t bgraStride, uint8_t *gray, size_t grayStride) { assert(width >= A); - if (align) - assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(gray) && Aligned(grayStride)); size_t alignedWidth = AlignLo(width, A); __m128i a[4]; @@ -69,27 +59,27 @@ namespace Simd { for (size_t col = 0; col < alignedWidth; col += A) { - Sse41::Load(bgra + 4 * col, a); - Store((__m128i*)(gray + col), BgraToGray(a)); + const uint8_t * p = bgra + 4 * col; + a[0] = _mm_loadu_si128((__m128i*)p + 0); + a[1] = _mm_loadu_si128((__m128i*)p + 1); + a[2] = _mm_loadu_si128((__m128i*)p + 2); + a[3] = _mm_loadu_si128((__m128i*)p + 3); + _mm_storeu_si128((__m128i*)(gray + col), BgraToGray(a)); } if (alignedWidth != width) { - Sse41::Load(bgra + 4 * (width - A), a); - Store((__m128i*)(gray + width - A), BgraToGray(a)); + const uint8_t * p = bgra + 4 * (width - A); + a[0] = _mm_loadu_si128((__m128i*)p + 0); + a[1] = _mm_loadu_si128((__m128i*)p + 1); + a[2] = _mm_loadu_si128((__m128i*)p + 2); + a[3] = _mm_loadu_si128((__m128i*)p + 3); + _mm_storeu_si128((__m128i*)(gray + width - A), BgraToGray(a)); } bgra += bgraStride; gray += grayStride; } } - void BgraToGray(const uint8_t *bgra, size_t width, size_t height, size_t bgraStride, uint8_t *gray, size_t grayStride) - { - if (Aligned(bgra) && Aligned(gray) && Aligned(bgraStride) && Aligned(grayStride)) - BgraToGray(bgra, width, height, bgraStride, gray, grayStride); - else - BgraToGray(bgra, width, height, bgraStride, gray, grayStride); - } - //----------------------------------------------------------------------------------------- const __m128i K16_RED_BLUE = SIMD_MM_SET2_EPI16(Base::RED_TO_GRAY_WEIGHT, Base::BLUE_TO_GRAY_WEIGHT); @@ -109,11 +99,15 @@ namespace Simd return _mm_packus_epi16(lo, hi); } - template void RgbaToGray(const uint8_t* rgba, size_t width, size_t height, size_t rgbaStride, uint8_t* gray, size_t grayStride) + void RgbaToGray(const uint8_t* rgba, size_t width, size_t height, size_t rgbaStride, uint8_t* gray, size_t grayStride) { + if(width < A) + { + Base::RgbaToGray(rgba, width, height, rgbaStride, gray, grayStride); + return; + } + assert(width >= A); - if (align) - assert(Aligned(rgba) && Aligned(rgbaStride) && Aligned(gray) && Aligned(grayStride)); size_t alignedWidth = AlignLo(width, A); __m128i a[4]; @@ -121,28 +115,26 @@ namespace Simd { for (size_t col = 0; col < alignedWidth; col += A) { - Load(rgba + 4 * col, a); - Store((__m128i*)(gray + col), RgbaToGray(a)); + const uint8_t* p = rgba + 4 * col; + a[0] = _mm_loadu_si128((__m128i*)p + 0); + a[1] = _mm_loadu_si128((__m128i*)p + 1); + a[2] = _mm_loadu_si128((__m128i*)p + 2); + a[3] = _mm_loadu_si128((__m128i*)p + 3); + _mm_storeu_si128((__m128i*)(gray + col), RgbaToGray(a)); } if (alignedWidth != width) { - Load(rgba + 4 * (width - A), a); - Store((__m128i*)(gray + width - A), RgbaToGray(a)); + const uint8_t* p = rgba + 4 * (width - A); + a[0] = _mm_loadu_si128((__m128i*)p + 0); + a[1] = _mm_loadu_si128((__m128i*)p + 1); + a[2] = _mm_loadu_si128((__m128i*)p + 2); + a[3] = _mm_loadu_si128((__m128i*)p + 3); + _mm_storeu_si128((__m128i*)(gray + width - A), RgbaToGray(a)); } rgba += rgbaStride; gray += grayStride; } } - - void RgbaToGray(const uint8_t* rgba, size_t width, size_t height, size_t rgbaStride, uint8_t* gray, size_t grayStride) - { - if(width < A) - Base::RgbaToGray(rgba, width, height, rgbaStride, gray, grayStride); - else if (Aligned(rgba) && Aligned(gray) && Aligned(rgbaStride) && Aligned(grayStride)) - RgbaToGray(rgba, width, height, rgbaStride, gray, grayStride); - else - RgbaToGray(rgba, width, height, rgbaStride, gray, grayStride); - } } #endif }