|
3 | 3 |
|
4 | 4 | using System.Numerics; |
5 | 5 | using System.Runtime.CompilerServices; |
6 | | -using System.Runtime.InteropServices; |
7 | 6 |
|
8 | 7 | // ReSharper disable MemberHidesStaticFromOuterClass |
9 | 8 | namespace SixLabors.ImageSharp; |
@@ -35,148 +34,5 @@ internal static void ConvertToSingle( |
35 | 34 | dest1 = Vector.ConvertToSingle(i1); |
36 | 35 | dest2 = Vector.ConvertToSingle(i2); |
37 | 36 | } |
38 | | - |
39 | | - /// <summary> |
40 | | - /// <see cref="ByteToNormalizedFloat"/> as many elements as possible, slicing them down (keeping the remainder). |
41 | | - /// </summary> |
42 | | - [MethodImpl(InliningOptions.ShortMethod)] |
43 | | - internal static void ByteToNormalizedFloatReduce( |
44 | | - ref ReadOnlySpan<byte> source, |
45 | | - ref Span<float> dest) |
46 | | - { |
47 | | - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); |
48 | | - |
49 | | - if (!IsAvailable) |
50 | | - { |
51 | | - return; |
52 | | - } |
53 | | - |
54 | | - int remainder = Numerics.ModuloP2(source.Length, Vector<byte>.Count); |
55 | | - int adjustedCount = source.Length - remainder; |
56 | | - |
57 | | - if (adjustedCount > 0) |
58 | | - { |
59 | | - ByteToNormalizedFloat(source[..adjustedCount], dest[..adjustedCount]); |
60 | | - |
61 | | - source = source[adjustedCount..]; |
62 | | - dest = dest[adjustedCount..]; |
63 | | - } |
64 | | - } |
65 | | - |
66 | | - /// <summary> |
67 | | - /// <see cref="NormalizedFloatToByteSaturate"/> as many elements as possible, slicing them down (keeping the remainder). |
68 | | - /// </summary> |
69 | | - [MethodImpl(InliningOptions.ShortMethod)] |
70 | | - internal static void NormalizedFloatToByteSaturateReduce( |
71 | | - ref ReadOnlySpan<float> source, |
72 | | - ref Span<byte> dest) |
73 | | - { |
74 | | - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); |
75 | | - |
76 | | - if (!IsAvailable) |
77 | | - { |
78 | | - return; |
79 | | - } |
80 | | - |
81 | | - int remainder = Numerics.ModuloP2(source.Length, Vector<byte>.Count); |
82 | | - int adjustedCount = source.Length - remainder; |
83 | | - |
84 | | - if (adjustedCount > 0) |
85 | | - { |
86 | | - NormalizedFloatToByteSaturate(source[..adjustedCount], dest[..adjustedCount]); |
87 | | - |
88 | | - source = source[adjustedCount..]; |
89 | | - dest = dest[adjustedCount..]; |
90 | | - } |
91 | | - } |
92 | | - |
93 | | - /// <summary> |
94 | | - /// Implementation <see cref="SimdUtils.ByteToNormalizedFloat"/>, which is faster on new RyuJIT runtime. |
95 | | - /// </summary> |
96 | | - internal static void ByteToNormalizedFloat(ReadOnlySpan<byte> source, Span<float> dest) |
97 | | - { |
98 | | - DebugVerifySpanInput(source, dest, Vector<byte>.Count); |
99 | | - |
100 | | - nuint n = dest.VectorCount<byte>(); |
101 | | - |
102 | | - ref Vector<byte> sourceBase = ref Unsafe.As<byte, Vector<byte>>(ref MemoryMarshal.GetReference(source)); |
103 | | - ref Vector<float> destBase = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(dest)); |
104 | | - |
105 | | - for (nuint i = 0; i < n; i++) |
106 | | - { |
107 | | - Vector<byte> b = Unsafe.Add(ref sourceBase, i); |
108 | | - |
109 | | - Vector.Widen(b, out Vector<ushort> s0, out Vector<ushort> s1); |
110 | | - Vector.Widen(s0, out Vector<uint> w0, out Vector<uint> w1); |
111 | | - Vector.Widen(s1, out Vector<uint> w2, out Vector<uint> w3); |
112 | | - |
113 | | - Vector<float> f0 = ConvertToSingle(w0); |
114 | | - Vector<float> f1 = ConvertToSingle(w1); |
115 | | - Vector<float> f2 = ConvertToSingle(w2); |
116 | | - Vector<float> f3 = ConvertToSingle(w3); |
117 | | - |
118 | | - ref Vector<float> d = ref Unsafe.Add(ref destBase, i * 4); |
119 | | - d = f0; |
120 | | - Unsafe.Add(ref d, 1) = f1; |
121 | | - Unsafe.Add(ref d, 2) = f2; |
122 | | - Unsafe.Add(ref d, 3) = f3; |
123 | | - } |
124 | | - } |
125 | | - |
126 | | - /// <summary> |
127 | | - /// Implementation of <see cref="SimdUtils.NormalizedFloatToByteSaturate"/>, which is faster on new .NET runtime. |
128 | | - /// </summary> |
129 | | - internal static void NormalizedFloatToByteSaturate( |
130 | | - ReadOnlySpan<float> source, |
131 | | - Span<byte> dest) |
132 | | - { |
133 | | - DebugVerifySpanInput(source, dest, Vector<byte>.Count); |
134 | | - |
135 | | - nuint n = dest.VectorCount<byte>(); |
136 | | - |
137 | | - ref Vector<float> sourceBase = |
138 | | - ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(source)); |
139 | | - ref Vector<byte> destBase = ref Unsafe.As<byte, Vector<byte>>(ref MemoryMarshal.GetReference(dest)); |
140 | | - |
141 | | - for (nuint i = 0; i < n; i++) |
142 | | - { |
143 | | - ref Vector<float> s = ref Unsafe.Add(ref sourceBase, i * 4); |
144 | | - |
145 | | - Vector<float> f0 = s; |
146 | | - Vector<float> f1 = Unsafe.Add(ref s, 1); |
147 | | - Vector<float> f2 = Unsafe.Add(ref s, 2); |
148 | | - Vector<float> f3 = Unsafe.Add(ref s, 3); |
149 | | - |
150 | | - Vector<uint> w0 = ConvertToUInt32(f0); |
151 | | - Vector<uint> w1 = ConvertToUInt32(f1); |
152 | | - Vector<uint> w2 = ConvertToUInt32(f2); |
153 | | - Vector<uint> w3 = ConvertToUInt32(f3); |
154 | | - |
155 | | - var u0 = Vector.Narrow(w0, w1); |
156 | | - var u1 = Vector.Narrow(w2, w3); |
157 | | - |
158 | | - Unsafe.Add(ref destBase, i) = Vector.Narrow(u0, u1); |
159 | | - } |
160 | | - } |
161 | | - |
162 | | - [MethodImpl(MethodImplOptions.AggressiveInlining)] |
163 | | - private static Vector<uint> ConvertToUInt32(Vector<float> vf) |
164 | | - { |
165 | | - var maxBytes = new Vector<float>(255f); |
166 | | - vf *= maxBytes; |
167 | | - vf += new Vector<float>(0.5f); |
168 | | - vf = Vector.Min(Vector.Max(vf, Vector<float>.Zero), maxBytes); |
169 | | - var vi = Vector.ConvertToInt32(vf); |
170 | | - return Vector.AsVectorUInt32(vi); |
171 | | - } |
172 | | - |
173 | | - [MethodImpl(MethodImplOptions.AggressiveInlining)] |
174 | | - private static Vector<float> ConvertToSingle(Vector<uint> u) |
175 | | - { |
176 | | - var vi = Vector.AsVectorInt32(u); |
177 | | - var v = Vector.ConvertToSingle(vi); |
178 | | - v *= new Vector<float>(1f / 255f); |
179 | | - return v; |
180 | | - } |
181 | 37 | } |
182 | 38 | } |
0 commit comments