diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs index df81c39e7f..513db0c448 100644 --- a/src/ImageSharp/Common/Helpers/Numerics.cs +++ b/src/ImageSharp/Common/Helpers/Numerics.cs @@ -912,7 +912,7 @@ namespace SixLabors.ImageSharp /// Rotates the specified value left by the specified number of bits. /// /// The value to rotate. - /// The number of bits to roate with. + /// The number of bits to rotate with. /// The rotated value. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint RotateLeft(uint value, int offset) @@ -929,11 +929,39 @@ namespace SixLabors.ImageSharp /// Rotates the specified value left by the specified number of bits. /// /// The value to rotate. - /// The number of bits to roate with. + /// The number of bits to rotate with. /// The rotated value. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint RotateLeftSoftwareFallback(uint value, int offset) => (value << offset) | (value >> (32 - offset)); #endif + + /// + /// Rotates the specified value right by the specified number of bits. + /// + /// The value to rotate. + /// The number of bits to rotate with. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint RotateRight(uint value, int offset) + { +#if SUPPORTS_BITOPERATIONS + return BitOperations.RotateRight(value, offset); +#else + return RotateRightSoftwareFallback(value, offset); +#endif + } + +#if !SUPPORTS_BITOPERATIONS + /// + /// Rotates the specified value right by the specified number of bits. + /// + /// The value to rotate. + /// The number of bits to rotate with. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint RotateRightSoftwareFallback(uint value, int offset) + => (value >> offset) | (value << (32 - offset)); +#endif } } diff --git a/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs b/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs index da60928d3f..a1224a7673 100644 --- a/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs +++ b/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs @@ -3,10 +3,8 @@ using System; using System.Buffers.Binary; -using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Common.Helpers; // The JIT can detect and optimize rotation idioms ROTL (Rotate Left) // and ROTR (Rotate Right) emitting efficient CPU instructions: @@ -99,15 +97,15 @@ namespace SixLabors.ImageSharp { ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - nint n = (nint)source.Length / 4; + nuint n = (nuint)(uint)source.Length / 4; - for (nint i = 0; i < n; i++) + for (nuint i = 0; i < n; i++) { - uint packed = Unsafe.Add(ref sBase, i); + uint packed = Unsafe.Add(ref sBase, (IntPtr)(uint)i); // packed = [W Z Y X] // ROTL(8, packed) = [Z Y X W] - Unsafe.Add(ref dBase, i) = (packed << 8) | (packed >> 24); + Unsafe.Add(ref dBase, (IntPtr)(uint)i) = (packed << 8) | (packed >> 24); } } } @@ -125,15 +123,15 @@ namespace SixLabors.ImageSharp { ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - nint n = (nint)source.Length / 4; + nuint n = (nuint)(uint)source.Length / 4; - for (nint i = 0; i < n; i++) + for (nuint i = 0; i < n; i++) { - uint packed = Unsafe.Add(ref sBase, i); + uint packed = Unsafe.Add(ref sBase, (IntPtr)(uint)i); // packed = [W Z Y X] // REVERSE(packedArgb) = [X Y Z W] - Unsafe.Add(ref dBase, i) = BinaryPrimitives.ReverseEndianness(packed); + Unsafe.Add(ref dBase, (IntPtr)(uint)i) = BinaryPrimitives.ReverseEndianness(packed); } } } @@ -151,15 +149,15 @@ namespace SixLabors.ImageSharp { ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - nint n = (nint)source.Length / 4; + nuint n = (nuint)(uint)source.Length / 4; - for (nint i = 0; i < n; i++) + for (nuint i = 0; i < n; i++) { - uint packed = Unsafe.Add(ref sBase, i); + uint packed = Unsafe.Add(ref sBase, (IntPtr)(uint)i); // packed = [W Z Y X] // ROTR(8, packedArgb) = [Y Z W X] - Unsafe.Add(ref dBase, i) = (packed >> 8) | (packed << 24); + Unsafe.Add(ref dBase, (IntPtr)(uint)i) = Numerics.RotateRight(packed, 8); } } } @@ -177,11 +175,11 @@ namespace SixLabors.ImageSharp { ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - nint n = (nint)source.Length / 4; + nuint n = (nuint)(uint)source.Length / 4; - for (nint i = 0; i < n; i++) + for (nuint i = 0; i < n; i++) { - uint packed = Unsafe.Add(ref sBase, i); + uint packed = Unsafe.Add(ref sBase, (IntPtr)(uint)i); // packed = [W Z Y X] // tmp1 = [W 0 Y 0] @@ -192,7 +190,7 @@ namespace SixLabors.ImageSharp uint tmp2 = packed & 0x00FF00FF; uint tmp3 = Numerics.RotateLeft(tmp2, 16); - Unsafe.Add(ref dBase, i) = tmp1 + tmp3; + Unsafe.Add(ref dBase, (IntPtr)(uint)i) = tmp1 + tmp3; } } } @@ -210,11 +208,11 @@ namespace SixLabors.ImageSharp { ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - nint n = (nint)source.Length / 4; + nuint n = (nuint)(uint)source.Length / 4; - for (nint i = 0; i < n; i++) + for (nuint i = 0; i < n; i++) { - uint packed = Unsafe.Add(ref sBase, i); + uint packed = Unsafe.Add(ref sBase, (IntPtr)(uint)i); // packed = [W Z Y X] // tmp1 = [0 Z 0 X] @@ -225,7 +223,7 @@ namespace SixLabors.ImageSharp uint tmp2 = packed & 0xFF00FF00; uint tmp3 = Numerics.RotateLeft(tmp2, 16); - Unsafe.Add(ref dBase, i) = tmp1 + tmp3; + Unsafe.Add(ref dBase, (IntPtr)(uint)i) = tmp1 + tmp3; } } }