Browse Source

Remove SIMD vectors from FJXL, add some ANS symbol reader work

pull/3153/head
winscripter 3 weeks ago
parent
commit
f872a81117
  1. 5
      src/ImageSharp/Formats/Jxl/Processing/Decoder/Ans/JxlAnsSymbolReader.cs
  2. 254
      src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs

5
src/ImageSharp/Formats/Jxl/Processing/Decoder/Ans/JxlAnsSymbolReader.cs

@ -27,4 +27,9 @@ internal sealed class JxlAnsSymbolReader
private JxlHuffmanDecodingData huffmanData;
private bool usePrefixCode;
private uint state = AnsSignature << 16u;
private List<JxlAnsHybridUIntConfiguration> configs = [];
private int logAlphaSize;
private int logEntrySize;
private int entrySizeMinus1;
}

254
src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs

@ -583,260 +583,6 @@ internal sealed class JxlFastLosslessEncoder
}
}
/// <summary>
/// SIMD Mask32
/// </summary>
private struct Mask32
{
/// <summary>
/// Actual mask.
/// </summary>
public ushort Mask;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly uint CountPrefix() => CtzNonZero(~(uint)this.Mask);
}
/// <summary>
/// Wrapper over a 32-bit integer vector.
/// </summary>
/// <param name="vector">Underlying vector.</param>
private struct SimdVec32(Vector<uint> vector)
{
/// <summary>
/// The actual vector for this simd vector.
/// </summary>
public Vector<uint> Vec = vector;
/// <summary>
/// Adds both vectors.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a + b</returns>
public static SimdVec32 operator +(SimdVec32 a, SimdVec32 b) => new(a.Vec + b.Vec);
/// <summary>
/// Subtracts both vectors.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a - b</returns>
public static SimdVec32 operator -(SimdVec32 a, SimdVec32 b) => new(a.Vec - b.Vec);
/// <summary>
/// XORs both vectors.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a ^ b</returns>
public static SimdVec32 operator ^(SimdVec32 a, SimdVec32 b) => new(a.Vec ^ b.Vec);
/// <summary>
/// Sets bits to all 1 if vector items are equal, otherwise to all 0.
/// For example, if vector a is {5, 2, 4, 1} and vector b is {7, 3, 4, 5}
/// the result is {0, 0, 0xFFFFFFFF, 0}.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a == b</returns>
public static SimdVec32 operator ==(SimdVec32 a, SimdVec32 b) => new(Vector.Equals(a.Vec, b.Vec));
// We don't use this. It's to remove an error where == requires !=.
public static SimdVec32 operator !=(SimdVec32 a, SimdVec32 b) => new(Vector.Equals(a.Vec, b.Vec));
/// <summary>
/// Sets bits to all 1 if vector items are larger, otherwise to all 0.
/// For example, if vector a is {5, 2, 4, 1} and vector b is {3, 3, 4, 5}
/// the result is {0xFFFFFFFF, 0, 0, 0}.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a &gt; b</returns>
public static SimdVec32 operator >(SimdVec32 a, SimdVec32 b) => new(Vector.GreaterThan(a.Vec, b.Vec));
/// <summary>
/// Sets bits to all 1 if vector items are lower, otherwise to all 0.
/// For example, if vector a is {5, 2, 4, 1} and vector b is {3, 3, 4, 5}
/// the result is {0, 0xFFFFFFFF, 0, 0xFFFFFFFF}.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a &lt; b</returns>
public static SimdVec32 operator <(SimdVec32 a, SimdVec32 b) => new(Vector.LessThan(a.Vec, b.Vec));
/// <summary>
/// Converts this vector to a mask.
/// </summary>
/// <returns>
/// Mask where bits are 1 if the item
/// at the index is set to all 1, otherwise 0.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Mask32 ToMask()
{
int mask = 0;
for (int i = 0; i < 16 && i < Vector<int>.Count; i++)
{
if (this.Vec[i] == uint.MaxValue)
{
mask |= 1 << i;
}
}
return new() { Mask = (ushort)mask };
}
public static SimdVec32 Load(Span<uint> data) => new(new Vector<uint>(data));
public static SimdVec32 Value(uint value) => new(new Vector<uint>(value));
public readonly SimdVec32 ValueToToken() => new(new Vector<uint>(32u) - GetLzcnt(this.Vec));
public readonly SimdVec32 SaturateSubtract(SimdVec32 toSubtract) => new(Vector.Max(this.Vec, toSubtract.Vec) - toSubtract.Vec);
public readonly SimdVec32 Pow2() => new(Vector.ShiftLeft(Vector<uint>.One, unchecked((int)this.Vec[0])));
public readonly void Store(Span<uint> data) => this.Vec.CopyTo(data);
// We don't use this.
public override readonly bool Equals(object? obj) => false;
// We don't use this.
public override readonly int GetHashCode() => this.Vec.GetHashCode();
}
/// <summary>
/// SIMD Mask16
/// </summary>
private struct Mask16
{
/// <summary>
/// Actual mask.
/// </summary>
public uint Mask;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly uint CountPrefix() => CtzNonZero(~this.Mask);
}
/// <summary>
/// Wrapper over a 16-bit integer vector.
/// </summary>
/// <param name="vector">Underlying vector.</param>
private struct SimdVec16(Vector<ushort> vector)
{
/// <summary>
/// The actual vector for this simd vector.
/// </summary>
public Vector<ushort> Vec = vector;
/// <summary>
/// Adds both vectors.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a + b</returns>
public static SimdVec16 operator +(SimdVec16 a, SimdVec16 b) => new(a.Vec + b.Vec);
/// <summary>
/// Subtracts both vectors.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a - b</returns>
public static SimdVec16 operator -(SimdVec16 a, SimdVec16 b) => new(a.Vec - b.Vec);
/// <summary>
/// XORs both vectors.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a ^ b</returns>
public static SimdVec16 operator ^(SimdVec16 a, SimdVec16 b) => new(a.Vec ^ b.Vec);
/// <summary>
/// Sets bits to all 1 if vector items are equal, otherwise to all 0.
/// For example, if vector a is {5, 2, 4, 1} and vector b is {7, 3, 4, 5}
/// the result is {0, 0, 0xFFFF, 0}.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a == b</returns>
public static SimdVec16 operator ==(SimdVec16 a, SimdVec16 b) => new(Vector.Equals(a.Vec, b.Vec));
// We don't use this. It's to remove an error where == requires !=.
public static SimdVec16 operator !=(SimdVec16 a, SimdVec16 b) => new(Vector.Equals(a.Vec, b.Vec));
/// <summary>
/// Sets bits to all 1 if vector items are larger, otherwise to all 0.
/// For example, if vector a is {5, 2, 4, 1} and vector b is {3, 3, 4, 5}
/// the result is {0xFFFF, 0, 0, 0}.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a &gt; b</returns>
public static SimdVec16 operator >(SimdVec16 a, SimdVec16 b) => new(Vector.GreaterThan(a.Vec, b.Vec));
/// <summary>
/// Sets bits to all 1 if vector items are lower, otherwise to all 0.
/// For example, if vector a is {5, 2, 4, 1} and vector b is {3, 3, 4, 5}
/// the result is {0, 0xFFFF, 0, 0xFFFF}.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>a &lt; b</returns>
public static SimdVec16 operator <(SimdVec16 a, SimdVec16 b) => new(Vector.LessThan(a.Vec, b.Vec));
/// <summary>
/// Converts this vector to a mask.
/// </summary>
/// <returns>
/// Mask where bits are 1 if the item
/// at the index is set to all 1, otherwise 0.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Mask16 ToMask()
{
uint mask = 0;
for (int i = 0; i < 32 && i < Vector<ushort>.Count; i++)
{
if (this.Vec[i] == ushort.MaxValue)
{
mask |= 1u << i;
}
}
return new() { Mask = mask };
}
public static SimdVec16 FromTwo32(SimdVec32 lo, SimdVec32 hi)
{
Vector<ushort> narrow = Vector.Narrow(lo.Vec, hi.Vec);
return new(narrow);
}
public static SimdVec16 Load(Span<ushort> data) => new(new Vector<ushort>(data));
public static SimdVec16 Value(ushort value) => new(new Vector<ushort>(value));
public readonly SimdVec16 ValueToToken() => new(new Vector<ushort>(16) - GetLzcnt(this.Vec));
public readonly SimdVec16 SaturateSubtract(SimdVec16 toSubtract) => new(Vector.Max(this.Vec, toSubtract.Vec) - toSubtract.Vec);
public readonly SimdVec16 Pow2() => new(Vector.ShiftLeft(Vector<ushort>.One, unchecked(this.Vec[0])));
public readonly void Store(Span<ushort> data) => this.Vec.CopyTo(data);
// We don't use this.
public override readonly bool Equals(object? obj) => false;
// We don't use this.
public override readonly int GetHashCode() => this.Vec.GetHashCode();
}
/// <summary>
/// Pair of two vectors.
/// </summary>

Loading…
Cancel
Save