From f872a81117a435a3b2224379f88fe728a67c1944 Mon Sep 17 00:00:00 2001 From: winscripter <142818255+winscripter@users.noreply.github.com> Date: Wed, 9 Sep 2026 21:29:30 +0400 Subject: [PATCH] Remove SIMD vectors from FJXL, add some ANS symbol reader work --- .../Decoder/Ans/JxlAnsSymbolReader.cs | 5 + .../Encoder/JxlFastLosslessEncoder.cs | 254 ------------------ 2 files changed, 5 insertions(+), 254 deletions(-) diff --git a/src/ImageSharp/Formats/Jxl/Processing/Decoder/Ans/JxlAnsSymbolReader.cs b/src/ImageSharp/Formats/Jxl/Processing/Decoder/Ans/JxlAnsSymbolReader.cs index 115b4fad68..2de97c74f7 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/Decoder/Ans/JxlAnsSymbolReader.cs +++ b/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 configs = []; + private int logAlphaSize; + private int logEntrySize; + private int entrySizeMinus1; + } diff --git a/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs b/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs index bea22c76a3..5a4c57bdbf 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs @@ -583,260 +583,6 @@ internal sealed class JxlFastLosslessEncoder } } - /// - /// SIMD Mask32 - /// - private struct Mask32 - { - /// - /// Actual mask. - /// - public ushort Mask; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly uint CountPrefix() => CtzNonZero(~(uint)this.Mask); - } - - /// - /// Wrapper over a 32-bit integer vector. - /// - /// Underlying vector. - private struct SimdVec32(Vector vector) - { - /// - /// The actual vector for this simd vector. - /// - public Vector Vec = vector; - - /// - /// Adds both vectors. - /// - /// First vector - /// Second vector - /// a + b - public static SimdVec32 operator +(SimdVec32 a, SimdVec32 b) => new(a.Vec + b.Vec); - - /// - /// Subtracts both vectors. - /// - /// First vector - /// Second vector - /// a - b - public static SimdVec32 operator -(SimdVec32 a, SimdVec32 b) => new(a.Vec - b.Vec); - - /// - /// XORs both vectors. - /// - /// First vector - /// Second vector - /// a ^ b - public static SimdVec32 operator ^(SimdVec32 a, SimdVec32 b) => new(a.Vec ^ b.Vec); - - /// - /// 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}. - /// - /// First vector - /// Second vector - /// a == b - 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)); - - /// - /// 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}. - /// - /// First vector - /// Second vector - /// a > b - public static SimdVec32 operator >(SimdVec32 a, SimdVec32 b) => new(Vector.GreaterThan(a.Vec, b.Vec)); - - /// - /// 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}. - /// - /// First vector - /// Second vector - /// a < b - public static SimdVec32 operator <(SimdVec32 a, SimdVec32 b) => new(Vector.LessThan(a.Vec, b.Vec)); - - /// - /// Converts this vector to a mask. - /// - /// - /// Mask where bits are 1 if the item - /// at the index is set to all 1, otherwise 0. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly Mask32 ToMask() - { - int mask = 0; - - for (int i = 0; i < 16 && i < Vector.Count; i++) - { - if (this.Vec[i] == uint.MaxValue) - { - mask |= 1 << i; - } - } - - return new() { Mask = (ushort)mask }; - } - - public static SimdVec32 Load(Span data) => new(new Vector(data)); - - public static SimdVec32 Value(uint value) => new(new Vector(value)); - - public readonly SimdVec32 ValueToToken() => new(new Vector(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.One, unchecked((int)this.Vec[0]))); - - public readonly void Store(Span 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(); - } - - /// - /// SIMD Mask16 - /// - private struct Mask16 - { - /// - /// Actual mask. - /// - public uint Mask; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly uint CountPrefix() => CtzNonZero(~this.Mask); - } - - /// - /// Wrapper over a 16-bit integer vector. - /// - /// Underlying vector. - private struct SimdVec16(Vector vector) - { - /// - /// The actual vector for this simd vector. - /// - public Vector Vec = vector; - - /// - /// Adds both vectors. - /// - /// First vector - /// Second vector - /// a + b - public static SimdVec16 operator +(SimdVec16 a, SimdVec16 b) => new(a.Vec + b.Vec); - - /// - /// Subtracts both vectors. - /// - /// First vector - /// Second vector - /// a - b - public static SimdVec16 operator -(SimdVec16 a, SimdVec16 b) => new(a.Vec - b.Vec); - - /// - /// XORs both vectors. - /// - /// First vector - /// Second vector - /// a ^ b - public static SimdVec16 operator ^(SimdVec16 a, SimdVec16 b) => new(a.Vec ^ b.Vec); - - /// - /// 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}. - /// - /// First vector - /// Second vector - /// a == b - 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)); - - /// - /// 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}. - /// - /// First vector - /// Second vector - /// a > b - public static SimdVec16 operator >(SimdVec16 a, SimdVec16 b) => new(Vector.GreaterThan(a.Vec, b.Vec)); - - /// - /// 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}. - /// - /// First vector - /// Second vector - /// a < b - public static SimdVec16 operator <(SimdVec16 a, SimdVec16 b) => new(Vector.LessThan(a.Vec, b.Vec)); - - /// - /// Converts this vector to a mask. - /// - /// - /// Mask where bits are 1 if the item - /// at the index is set to all 1, otherwise 0. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly Mask16 ToMask() - { - uint mask = 0; - - for (int i = 0; i < 32 && i < Vector.Count; i++) - { - if (this.Vec[i] == ushort.MaxValue) - { - mask |= 1u << i; - } - } - - return new() { Mask = mask }; - } - - public static SimdVec16 FromTwo32(SimdVec32 lo, SimdVec32 hi) - { - Vector narrow = Vector.Narrow(lo.Vec, hi.Vec); - return new(narrow); - } - - public static SimdVec16 Load(Span data) => new(new Vector(data)); - - public static SimdVec16 Value(ushort value) => new(new Vector(value)); - - public readonly SimdVec16 ValueToToken() => new(new Vector(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.One, unchecked(this.Vec[0]))); - - public readonly void Store(Span 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(); - } - /// /// Pair of two vectors. ///