Browse Source

Use Numerics class as polyfill for BitOperations

pull/1886/head
Ynse Hoornenborg 4 years ago
parent
commit
e04ea46df1
  1. 26
      src/ImageSharp/Common/Helpers/BitOperations.cs
  2. 28
      src/ImageSharp/Common/Helpers/Numerics.cs
  3. 4
      src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs

26
src/ImageSharp/Common/Helpers/BitOperations.cs

@ -1,26 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Runtime.CompilerServices;
#if !NETCOREAPP3_1_OR_GREATER
namespace SixLabors.ImageSharp.Common.Helpers
{
/// <summary>
/// Polyfill for System.Numerics.BitOperations class, introduced in .NET Core 3.0.
/// <see href="https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs"/>
/// </summary>
public static class BitOperations
{
/// <summary>
/// Rotates the specified value left by the specified number of bits.
/// </summary>
/// <param name="value">The value to rotate.</param>
/// <param name="offset">The number of bits to roate with.</param>
/// <returns>The rotated value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint RotateLeft(uint value, int offset)
=> (value << offset) | (value >> (32 - offset));
}
}
#endif

28
src/ImageSharp/Common/Helpers/Numerics.cs

@ -907,5 +907,33 @@ namespace SixLabors.ImageSharp
/// <param name="divisor">Divisor value.</param> /// <param name="divisor">Divisor value.</param>
/// <returns>Ceiled division result.</returns> /// <returns>Ceiled division result.</returns>
public static uint DivideCeil(uint value, uint divisor) => (value + divisor - 1) / divisor; public static uint DivideCeil(uint value, uint divisor) => (value + divisor - 1) / divisor;
/// <summary>
/// Rotates the specified value left by the specified number of bits.
/// </summary>
/// <param name="value">The value to rotate.</param>
/// <param name="offset">The number of bits to roate with.</param>
/// <returns>The rotated value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint RotateLeft(uint value, int offset)
{
#if SUPPORTS_BITOPERATIONS
return BitOperations.RotateLeft(value, offset);
#else
return RotateLeftSoftwareFallback(value, offset);
#endif
}
#if !SUPPORTS_BITOPERATIONS
/// <summary>
/// Rotates the specified value left by the specified number of bits.
/// </summary>
/// <param name="value">The value to rotate.</param>
/// <param name="offset">The number of bits to roate with.</param>
/// <returns>The rotated value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint RotateLeftSoftwareFallback(uint value, int offset)
=> (value << offset) | (value >> (32 - offset));
#endif
} }
} }

4
src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs

@ -190,7 +190,7 @@ namespace SixLabors.ImageSharp
// tmp1 + tmp3 = [W X Y Z] // tmp1 + tmp3 = [W X Y Z]
uint tmp1 = packed & 0xFF00FF00; uint tmp1 = packed & 0xFF00FF00;
uint tmp2 = packed & 0x00FF00FF; uint tmp2 = packed & 0x00FF00FF;
uint tmp3 = BitOperations.RotateLeft(tmp2, 16); uint tmp3 = Numerics.RotateLeft(tmp2, 16);
Unsafe.Add(ref dBase, i) = tmp1 + tmp3; Unsafe.Add(ref dBase, i) = tmp1 + tmp3;
} }
@ -223,7 +223,7 @@ namespace SixLabors.ImageSharp
// tmp1 + tmp3 = [Y Z W X] // tmp1 + tmp3 = [Y Z W X]
uint tmp1 = packed & 0x00FF00FF; uint tmp1 = packed & 0x00FF00FF;
uint tmp2 = packed & 0xFF00FF00; uint tmp2 = packed & 0xFF00FF00;
uint tmp3 = BitOperations.RotateLeft(tmp2, 16); uint tmp3 = Numerics.RotateLeft(tmp2, 16);
Unsafe.Add(ref dBase, i) = tmp1 + tmp3; Unsafe.Add(ref dBase, i) = tmp1 + tmp3;
} }

Loading…
Cancel
Save