Browse Source

Replaced bit count lookup table to lzcnt implementation, Added MinimimBitsToStore to Numberics.cs

pull/1632/head
Dmitry Pentin 5 years ago
parent
commit
0664f298d9
  1. 12
      src/ImageSharp/Common/Helpers/Numerics.cs
  2. 34
      src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs

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

@ -825,5 +825,17 @@ namespace SixLabors.ImageSharp
return Sse2.ConvertToInt32(vsum); return Sse2.ConvertToInt32(vsum);
} }
#endif #endif
/// <summary>
/// Calculates how many minimum bits needed to store given value.
/// </summary>
/// <param name="number">Unsigned integer to store</param>
/// <returns>Minimum number of bits needed to store given value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int MinimumBitsToStore(uint number)
{
const int bitInUnsignedInteger = sizeof(uint) * 8;
return bitInUnsignedInteger - BitOperations.LeadingZeroCount(number);
}
} }
} }

34
src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs

@ -3,6 +3,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
@ -54,29 +55,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
this.target = outputStream; this.target = outputStream;
} }
/// <summary>
/// Gets the counts the number of bits needed to hold an integer.
/// </summary>
// The C# compiler emits this as a compile-time constant embedded in the PE file.
// This is effectively compiled down to: return new ReadOnlySpan<byte>(&data, length)
// More details can be found: https://github.com/dotnet/roslyn/pull/24621
private static ReadOnlySpan<byte> BitCountLut => new byte[]
{
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8,
};
/// <summary> /// <summary>
/// Encodes the image with no subsampling. /// Encodes the image with no subsampling.
/// </summary> /// </summary>
@ -394,15 +372,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
b = value - 1; b = value - 1;
} }
uint bt; uint bt = (uint)Numerics.MinimumBitsToStore((uint)a);
if (a < 0x100)
{
bt = BitCountLut[a];
}
else
{
bt = 8 + (uint)BitCountLut[a >> 8];
}
this.EmitHuff(index, (int)((uint)(runLength << 4) | bt)); this.EmitHuff(index, (int)((uint)(runLength << 4) | bt));
if (bt > 0) if (bt > 0)

Loading…
Cancel
Save