/src/Simd/src/Simd/SimdAvx2BgrToBgra.cpp
Line | Count | Source |
1 | | /* |
2 | | * Simd Library (http://ermig1979.github.io/Simd). |
3 | | * |
4 | | * Copyright (c) 2011-2020 Yermalayeu Ihar. |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | | * of this software and associated documentation files (the "Software"), to deal |
8 | | * in the Software without restriction, including without limitation the rights |
9 | | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
10 | | * copies of the Software, and to permit persons to whom the Software is |
11 | | * furnished to do so, subject to the following conditions: |
12 | | * |
13 | | * The above copyright notice and this permission notice shall be included in |
14 | | * all copies or substantial portions of the Software. |
15 | | * |
16 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
21 | | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
22 | | * SOFTWARE. |
23 | | */ |
24 | | #include "Simd/SimdStore.h" |
25 | | #include "Simd/SimdMemory.h" |
26 | | #include "Simd/SimdConversion.h" |
27 | | |
28 | | namespace Simd |
29 | | { |
30 | | #ifdef SIMD_AVX2_ENABLE |
31 | | namespace Avx2 |
32 | | { |
33 | | template <bool align> SIMD_INLINE void BgrToBgra(const uint8_t * bgr, uint8_t * bgra, __m256i alpha) |
34 | 6.23k | { |
35 | 6.23k | Store<align>((__m256i*)bgra + 0, BgrToBgra<false>(Load<align>((__m256i*)(bgr + 0)), alpha)); |
36 | 6.23k | Store<align>((__m256i*)bgra + 1, BgrToBgra<false>(Load<false>((__m256i*)(bgr + 24)), alpha)); |
37 | 6.23k | Store<align>((__m256i*)bgra + 2, BgrToBgra<false>(Load<false>((__m256i*)(bgr + 48)), alpha)); |
38 | 6.23k | Store<align>((__m256i*)bgra + 3, BgrToBgra<true >(Load<align>((__m256i*)(bgr + 64)), alpha)); |
39 | 6.23k | } void Simd::Avx2::BgrToBgra<true>(unsigned char const*, unsigned char*, long long __vector(4)) Line | Count | Source | 34 | 120 | { | 35 | 120 | Store<align>((__m256i*)bgra + 0, BgrToBgra<false>(Load<align>((__m256i*)(bgr + 0)), alpha)); | 36 | 120 | Store<align>((__m256i*)bgra + 1, BgrToBgra<false>(Load<false>((__m256i*)(bgr + 24)), alpha)); | 37 | 120 | Store<align>((__m256i*)bgra + 2, BgrToBgra<false>(Load<false>((__m256i*)(bgr + 48)), alpha)); | 38 | 120 | Store<align>((__m256i*)bgra + 3, BgrToBgra<true >(Load<align>((__m256i*)(bgr + 64)), alpha)); | 39 | 120 | } |
void Simd::Avx2::BgrToBgra<false>(unsigned char const*, unsigned char*, long long __vector(4)) Line | Count | Source | 34 | 6.11k | { | 35 | 6.11k | Store<align>((__m256i*)bgra + 0, BgrToBgra<false>(Load<align>((__m256i*)(bgr + 0)), alpha)); | 36 | 6.11k | Store<align>((__m256i*)bgra + 1, BgrToBgra<false>(Load<false>((__m256i*)(bgr + 24)), alpha)); | 37 | 6.11k | Store<align>((__m256i*)bgra + 2, BgrToBgra<false>(Load<false>((__m256i*)(bgr + 48)), alpha)); | 38 | 6.11k | Store<align>((__m256i*)bgra + 3, BgrToBgra<true >(Load<align>((__m256i*)(bgr + 64)), alpha)); | 39 | 6.11k | } |
|
40 | | |
41 | | template <bool align> void BgrToBgra(const uint8_t * bgr, size_t width, size_t height, size_t bgrStride, uint8_t * bgra, size_t bgraStride, uint8_t alpha) |
42 | 1.26k | { |
43 | 1.26k | assert(width >= A); |
44 | 1.26k | if (align) |
45 | 1.26k | assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(bgr) && Aligned(bgrStride)); |
46 | | |
47 | 1.26k | size_t alignedWidth = AlignLo(width, A); |
48 | | |
49 | 1.26k | __m256i _alpha = _mm256_slli_si256(_mm256_set1_epi32(alpha), 3); |
50 | | |
51 | 3.18k | for (size_t row = 0; row < height; ++row) |
52 | 1.91k | { |
53 | 7.12k | for (size_t col = 0; col < alignedWidth; col += A) |
54 | 5.20k | BgrToBgra<align>(bgr + 3 * col, bgra + 4 * col, _alpha); |
55 | 1.91k | if (width != alignedWidth) |
56 | 1.02k | BgrToBgra<false>(bgr + 3 * (width - A), bgra + 4 * (width - A), _alpha); |
57 | 1.91k | bgr += bgrStride; |
58 | 1.91k | bgra += bgraStride; |
59 | 1.91k | } |
60 | 1.26k | } void Simd::Avx2::BgrToBgra<true>(unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned char*, unsigned long, unsigned char) Line | Count | Source | 42 | 13 | { | 43 | 13 | assert(width >= A); | 44 | 13 | if (align) | 45 | 13 | assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(bgr) && Aligned(bgrStride)); | 46 | | | 47 | 13 | size_t alignedWidth = AlignLo(width, A); | 48 | | | 49 | 13 | __m256i _alpha = _mm256_slli_si256(_mm256_set1_epi32(alpha), 3); | 50 | | | 51 | 87 | for (size_t row = 0; row < height; ++row) | 52 | 74 | { | 53 | 194 | for (size_t col = 0; col < alignedWidth; col += A) | 54 | 120 | BgrToBgra<align>(bgr + 3 * col, bgra + 4 * col, _alpha); | 55 | 74 | if (width != alignedWidth) | 56 | 0 | BgrToBgra<false>(bgr + 3 * (width - A), bgra + 4 * (width - A), _alpha); | 57 | 74 | bgr += bgrStride; | 58 | 74 | bgra += bgraStride; | 59 | 74 | } | 60 | 13 | } |
void Simd::Avx2::BgrToBgra<false>(unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned char*, unsigned long, unsigned char) Line | Count | Source | 42 | 1.25k | { | 43 | 1.25k | assert(width >= A); | 44 | 1.25k | if (align) | 45 | 1.25k | assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(bgr) && Aligned(bgrStride)); | 46 | | | 47 | 1.25k | size_t alignedWidth = AlignLo(width, A); | 48 | | | 49 | 1.25k | __m256i _alpha = _mm256_slli_si256(_mm256_set1_epi32(alpha), 3); | 50 | | | 51 | 3.09k | for (size_t row = 0; row < height; ++row) | 52 | 1.84k | { | 53 | 6.93k | for (size_t col = 0; col < alignedWidth; col += A) | 54 | 5.08k | BgrToBgra<align>(bgr + 3 * col, bgra + 4 * col, _alpha); | 55 | 1.84k | if (width != alignedWidth) | 56 | 1.02k | BgrToBgra<false>(bgr + 3 * (width - A), bgra + 4 * (width - A), _alpha); | 57 | 1.84k | bgr += bgrStride; | 58 | 1.84k | bgra += bgraStride; | 59 | 1.84k | } | 60 | 1.25k | } |
|
61 | | |
62 | | void BgrToBgra(const uint8_t * bgr, size_t width, size_t height, size_t bgrStride, uint8_t * bgra, size_t bgraStride, uint8_t alpha) |
63 | 1.26k | { |
64 | 1.26k | if (Aligned(bgra) && Aligned(bgraStride) && Aligned(bgr) && Aligned(bgrStride)) |
65 | 13 | BgrToBgra<true>(bgr, width, height, bgrStride, bgra, bgraStride, alpha); |
66 | 1.25k | else |
67 | 1.25k | BgrToBgra<false>(bgr, width, height, bgrStride, bgra, bgraStride, alpha); |
68 | 1.26k | } |
69 | | |
70 | | //--------------------------------------------------------------------- |
71 | | |
72 | | template <bool align> SIMD_INLINE void Bgr48pToBgra32(uint8_t * bgra, |
73 | | const uint8_t * blue, const uint8_t * green, const uint8_t * red, size_t offset, __m256i alpha) |
74 | 0 | { |
75 | 0 | __m256i _blue = _mm256_and_si256(LoadPermuted<align>((__m256i*)(blue + offset)), K16_00FF); |
76 | 0 | __m256i _green = _mm256_and_si256(LoadPermuted<align>((__m256i*)(green + offset)), K16_00FF); |
77 | 0 | __m256i _red = _mm256_and_si256(LoadPermuted<align>((__m256i*)(red + offset)), K16_00FF); |
78 | |
|
79 | 0 | __m256i bg = _mm256_or_si256(_blue, _mm256_slli_si256(_green, 1)); |
80 | 0 | __m256i ra = _mm256_or_si256(_red, alpha); |
81 | |
|
82 | 0 | Store<align>((__m256i*)bgra + 0, _mm256_unpacklo_epi16(bg, ra)); |
83 | 0 | Store<align>((__m256i*)bgra + 1, _mm256_unpackhi_epi16(bg, ra)); |
84 | 0 | } Unexecuted instantiation: void Simd::Avx2::Bgr48pToBgra32<true>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, long long __vector(4)) Unexecuted instantiation: void Simd::Avx2::Bgr48pToBgra32<false>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, long long __vector(4)) |
85 | | |
86 | | template <bool align> void Bgr48pToBgra32(const uint8_t * blue, size_t blueStride, size_t width, size_t height, |
87 | | const uint8_t * green, size_t greenStride, const uint8_t * red, size_t redStride, uint8_t * bgra, size_t bgraStride, uint8_t alpha) |
88 | 0 | { |
89 | 0 | assert(width >= HA); |
90 | 0 | if (align) |
91 | 0 | { |
92 | 0 | assert(Aligned(blue) && Aligned(blueStride)); |
93 | 0 | assert(Aligned(green) && Aligned(greenStride)); |
94 | 0 | assert(Aligned(red) && Aligned(redStride)); |
95 | 0 | assert(Aligned(bgra) && Aligned(bgraStride)); |
96 | 0 | } |
97 | |
|
98 | 0 | __m256i _alpha = _mm256_slli_si256(_mm256_set1_epi16(alpha), 1); |
99 | 0 | size_t alignedWidth = AlignLo(width, HA); |
100 | 0 | for (size_t row = 0; row < height; ++row) |
101 | 0 | { |
102 | 0 | for (size_t col = 0, srcOffset = 0, dstOffset = 0; col < alignedWidth; col += HA, srcOffset += A, dstOffset += DA) |
103 | 0 | Bgr48pToBgra32<align>(bgra + dstOffset, blue, green, red, srcOffset, _alpha); |
104 | 0 | if (width != alignedWidth) |
105 | 0 | Bgr48pToBgra32<false>(bgra + (width - HA) * 4, blue, green, red, (width - HA) * 2, _alpha); |
106 | 0 | blue += blueStride; |
107 | 0 | green += greenStride; |
108 | 0 | red += redStride; |
109 | 0 | bgra += bgraStride; |
110 | 0 | } |
111 | 0 | } Unexecuted instantiation: void Simd::Avx2::Bgr48pToBgra32<true>(unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned char) Unexecuted instantiation: void Simd::Avx2::Bgr48pToBgra32<false>(unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned char) |
112 | | |
113 | | void Bgr48pToBgra32(const uint8_t * blue, size_t blueStride, size_t width, size_t height, |
114 | | const uint8_t * green, size_t greenStride, const uint8_t * red, size_t redStride, uint8_t * bgra, size_t bgraStride, uint8_t alpha) |
115 | 0 | { |
116 | 0 | if (Aligned(blue) && Aligned(blueStride) && Aligned(green) && Aligned(greenStride) && |
117 | 0 | Aligned(red) && Aligned(redStride) && Aligned(bgra) && Aligned(bgraStride)) |
118 | 0 | Bgr48pToBgra32<true>(blue, blueStride, width, height, green, greenStride, red, redStride, bgra, bgraStride, alpha); |
119 | 0 | else |
120 | 0 | Bgr48pToBgra32<false>(blue, blueStride, width, height, green, greenStride, red, redStride, bgra, bgraStride, alpha); |
121 | 0 | } |
122 | | |
123 | | //--------------------------------------------------------------------- |
124 | | |
125 | | template <bool align> SIMD_INLINE void RgbToBgra(const uint8_t* rgb, uint8_t* bgra, __m256i alpha) |
126 | 6.23k | { |
127 | 6.23k | Store<align>((__m256i*)bgra + 0, RgbToBgra<false>(Load<align>((__m256i*)(rgb + 0)), alpha)); |
128 | 6.23k | Store<align>((__m256i*)bgra + 1, RgbToBgra<false>(Load<false>((__m256i*)(rgb + 24)), alpha)); |
129 | 6.23k | Store<align>((__m256i*)bgra + 2, RgbToBgra<false>(Load<false>((__m256i*)(rgb + 48)), alpha)); |
130 | 6.23k | Store<align>((__m256i*)bgra + 3, RgbToBgra<true >(Load<align>((__m256i*)(rgb + 64)), alpha)); |
131 | 6.23k | } void Simd::Avx2::RgbToBgra<true>(unsigned char const*, unsigned char*, long long __vector(4)) Line | Count | Source | 126 | 120 | { | 127 | 120 | Store<align>((__m256i*)bgra + 0, RgbToBgra<false>(Load<align>((__m256i*)(rgb + 0)), alpha)); | 128 | 120 | Store<align>((__m256i*)bgra + 1, RgbToBgra<false>(Load<false>((__m256i*)(rgb + 24)), alpha)); | 129 | 120 | Store<align>((__m256i*)bgra + 2, RgbToBgra<false>(Load<false>((__m256i*)(rgb + 48)), alpha)); | 130 | 120 | Store<align>((__m256i*)bgra + 3, RgbToBgra<true >(Load<align>((__m256i*)(rgb + 64)), alpha)); | 131 | 120 | } |
void Simd::Avx2::RgbToBgra<false>(unsigned char const*, unsigned char*, long long __vector(4)) Line | Count | Source | 126 | 6.11k | { | 127 | 6.11k | Store<align>((__m256i*)bgra + 0, RgbToBgra<false>(Load<align>((__m256i*)(rgb + 0)), alpha)); | 128 | 6.11k | Store<align>((__m256i*)bgra + 1, RgbToBgra<false>(Load<false>((__m256i*)(rgb + 24)), alpha)); | 129 | 6.11k | Store<align>((__m256i*)bgra + 2, RgbToBgra<false>(Load<false>((__m256i*)(rgb + 48)), alpha)); | 130 | 6.11k | Store<align>((__m256i*)bgra + 3, RgbToBgra<true >(Load<align>((__m256i*)(rgb + 64)), alpha)); | 131 | 6.11k | } |
|
132 | | |
133 | | template <bool align> void RgbToBgra(const uint8_t* rgb, size_t width, size_t height, size_t rgbStride, uint8_t* bgra, size_t bgraStride, uint8_t alpha) |
134 | 1.26k | { |
135 | 1.26k | assert(width >= A); |
136 | 1.26k | if (align) |
137 | 1.26k | assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(rgb) && Aligned(rgbStride)); |
138 | | |
139 | 1.26k | size_t alignedWidth = AlignLo(width, A); |
140 | | |
141 | 1.26k | __m256i _alpha = _mm256_slli_si256(_mm256_set1_epi32(alpha), 3); |
142 | | |
143 | 3.18k | for (size_t row = 0; row < height; ++row) |
144 | 1.91k | { |
145 | 7.12k | for (size_t col = 0; col < alignedWidth; col += A) |
146 | 5.20k | RgbToBgra<align>(rgb + 3 * col, bgra + 4 * col, _alpha); |
147 | 1.91k | if (width != alignedWidth) |
148 | 1.02k | RgbToBgra<false>(rgb + 3 * (width - A), bgra + 4 * (width - A), _alpha); |
149 | 1.91k | rgb += rgbStride; |
150 | 1.91k | bgra += bgraStride; |
151 | 1.91k | } |
152 | 1.26k | } void Simd::Avx2::RgbToBgra<true>(unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned char*, unsigned long, unsigned char) Line | Count | Source | 134 | 13 | { | 135 | 13 | assert(width >= A); | 136 | 13 | if (align) | 137 | 13 | assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(rgb) && Aligned(rgbStride)); | 138 | | | 139 | 13 | size_t alignedWidth = AlignLo(width, A); | 140 | | | 141 | 13 | __m256i _alpha = _mm256_slli_si256(_mm256_set1_epi32(alpha), 3); | 142 | | | 143 | 87 | for (size_t row = 0; row < height; ++row) | 144 | 74 | { | 145 | 194 | for (size_t col = 0; col < alignedWidth; col += A) | 146 | 120 | RgbToBgra<align>(rgb + 3 * col, bgra + 4 * col, _alpha); | 147 | 74 | if (width != alignedWidth) | 148 | 0 | RgbToBgra<false>(rgb + 3 * (width - A), bgra + 4 * (width - A), _alpha); | 149 | 74 | rgb += rgbStride; | 150 | 74 | bgra += bgraStride; | 151 | 74 | } | 152 | 13 | } |
void Simd::Avx2::RgbToBgra<false>(unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned char*, unsigned long, unsigned char) Line | Count | Source | 134 | 1.25k | { | 135 | 1.25k | assert(width >= A); | 136 | 1.25k | if (align) | 137 | 1.25k | assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(rgb) && Aligned(rgbStride)); | 138 | | | 139 | 1.25k | size_t alignedWidth = AlignLo(width, A); | 140 | | | 141 | 1.25k | __m256i _alpha = _mm256_slli_si256(_mm256_set1_epi32(alpha), 3); | 142 | | | 143 | 3.09k | for (size_t row = 0; row < height; ++row) | 144 | 1.84k | { | 145 | 6.93k | for (size_t col = 0; col < alignedWidth; col += A) | 146 | 5.08k | RgbToBgra<align>(rgb + 3 * col, bgra + 4 * col, _alpha); | 147 | 1.84k | if (width != alignedWidth) | 148 | 1.02k | RgbToBgra<false>(rgb + 3 * (width - A), bgra + 4 * (width - A), _alpha); | 149 | 1.84k | rgb += rgbStride; | 150 | 1.84k | bgra += bgraStride; | 151 | 1.84k | } | 152 | 1.25k | } |
|
153 | | |
154 | | void RgbToBgra(const uint8_t* rgb, size_t width, size_t height, size_t rgbStride, uint8_t* bgra, size_t bgraStride, uint8_t alpha) |
155 | 1.26k | { |
156 | 1.26k | if (Aligned(bgra) && Aligned(bgraStride) && Aligned(rgb) && Aligned(rgbStride)) |
157 | 13 | RgbToBgra<true>(rgb, width, height, rgbStride, bgra, bgraStride, alpha); |
158 | 1.25k | else |
159 | 1.25k | RgbToBgra<false>(rgb, width, height, rgbStride, bgra, bgraStride, alpha); |
160 | 1.26k | } |
161 | | } |
162 | | #endif//SIMD_AVX2_ENABLE |
163 | | } |