Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
144 commits
Select commit Hold shift + click to select a range
85c851b
Add JPEG XL format
winscripter Jul 14, 2026
996e93d
Implement ac_context.h
winscripter Jul 14, 2026
d87178f
Implemented frame_dimensions.h plus part of ac_strategy.h
winscripter Jul 14, 2026
1ac6140
Implement AC strategy
winscripter Jul 15, 2026
31b5505
Implement JxlMemoryManager
winscripter Jul 15, 2026
21ff33f
Implement image and memory buffers
winscripter Jul 15, 2026
6fea920
Add metadata models
winscripter Jul 15, 2026
762edd1
Add headers & aspect ratio helpers
winscripter Jul 15, 2026
487410e
Implement field encodings, move IJxlFields
winscripter Jul 15, 2026
ac1c866
Add xorshift implemetation
winscripter Jul 15, 2026
8581222
It's Jxl not Jpeg
winscripter Jul 15, 2026
9b58f4b
Implement spline abstractions
winscripter Jul 15, 2026
064376a
Add quantized spline implementations
winscripter Jul 16, 2026
90680b7
Prefer the term "coefficient"
winscripter Jul 16, 2026
1e40482
Start work on ANS entropy
winscripter Jul 16, 2026
396cd8d
Implement JxlAnsHelper.GetPopulationCountPrecision
winscripter Jul 16, 2026
cb364fa
Turn JxlFrameDimensions into a sealed class
winscripter Jul 16, 2026
528149f
Implement CreateFlatHistogram
winscripter Jul 16, 2026
490f02f
Add ANS entropy structs
winscripter Jul 16, 2026
73941c1
Prefer byte for enums
winscripter Jul 16, 2026
20c2dd3
Implement ANS entropy helpers
winscripter Jul 16, 2026
fed0af3
Add bit-stream reader
winscripter Jul 16, 2026
25e41da
Avoid 'using static'
winscripter Jul 16, 2026
4ec9b95
Simplify
winscripter Jul 16, 2026
b716d4e
Add ANS VarLen & histogram parser
winscripter Jul 16, 2026
1381def
Fix memory leaks
winscripter Jul 16, 2026
8ffb41a
Don't use end of stream singleton
winscripter Jul 16, 2026
3ed56c9
Add ANS hybrid uint configuration & LZ77 parameters model
winscripter Jul 16, 2026
7f35b1a
Implement Lehmer codes
winscripter Jul 16, 2026
57eadbb
Implement noise shared logic
winscripter Jul 16, 2026
6de4a89
Add alpha blending
winscripter Jul 16, 2026
289fecd
Move AC strategy & Coefficients stuff into Processing
winscripter Jul 17, 2026
b15c190
Add symmetric weights; fix broken using
winscripter Jul 17, 2026
b3023f2
Add separable weights
winscripter Jul 17, 2026
73c7cec
Add DCT scales
winscripter Jul 17, 2026
7223d98
Add DCT memory, make JxlImage3<T> implement IDisposable
winscripter Jul 17, 2026
51b7765
Implement signed packing
winscripter Jul 17, 2026
446e4a5
Add loop filter
winscripter Jul 18, 2026
decc0b2
Fully implement JPEG XL fields
winscripter Jul 18, 2026
a6a0263
Implement visitor for JxlBitDepth
winscripter Jul 18, 2026
6aa313f
Add matrices
winscripter Jul 18, 2026
d401b71
Fix errors
winscripter Jul 18, 2026
a803f01
Add Y'Cb'Cr chroma subsampling as part of the frame header
winscripter Jul 18, 2026
16c55f3
Add frame header
winscripter Jul 19, 2026
ded8906
Move Metadata folder to IO
winscripter Jul 19, 2026
674f82a
Add quantizer
winscripter Jul 20, 2026
07f6be0
Fix memory leak
winscripter Jul 20, 2026
b720196
Add opsin inverse parameters, some quantizer weight work
winscripter Jul 20, 2026
2758454
Move, add entropy coding common functions
winscripter Jul 21, 2026
6eda7e2
Remove aggressive inlining attributes, fix usings
winscripter Jul 21, 2026
f71bab2
Use distinct read-only spans
winscripter Jul 21, 2026
abafaf8
Add CFL
winscripter Jul 21, 2026
9c6b4ef
Add Huffman common methods
winscripter Jul 22, 2026
3591250
Start work on Butteraugli
winscripter Jul 22, 2026
765c892
Implement Butteraugli core functions
winscripter Jul 24, 2026
0d159b9
Add CMS* prototype, XYB decoding, TOC, convolution and coefficient or…
winscripter Aug 1, 2026
083385b
Use inline arrays in quantizer
winscripter Aug 1, 2026
a1cae71
Prefer const
winscripter Aug 1, 2026
eb80187
Don't use System.Diagnostics.Debug
winscripter Aug 1, 2026
79e8ce7
Add Move to Front transform
winscripter Aug 6, 2026
d1f6646
Prefer inline arrays
winscripter Aug 6, 2026
fe41799
Prevent potential overflow
winscripter Aug 6, 2026
8209aa1
Refactor
winscripter Aug 6, 2026
074ff1b
Validate the size parameter in JxlCoefficientOrder.ReadPermutation
winscripter Aug 6, 2026
f19c879
Add more implementations and prototypes
winscripter Aug 8, 2026
ff98ffd
Add image copy operations
winscripter Aug 8, 2026
e718a4a
Implement image operations
winscripter Aug 8, 2026
048945c
Reduce number of errors
winscripter Aug 8, 2026
4f71c52
Implement JPEG XL numerics functions & reduce errors
winscripter Aug 8, 2026
4d0a468
Add rectangle support to images
winscripter Aug 8, 2026
2c517a2
Document JxlPlane<T> and JxlPlaneBase
winscripter Aug 8, 2026
50813c1
Add passes decoder state prototype & reduce errors in JxlQuantizedSpline
winscripter Aug 8, 2026
27a848c
Add DCT, transpose, and performance improvements
winscripter Aug 12, 2026
0d9aea4
Remove GC.SuppressFinalize(this)
winscripter Aug 12, 2026
20e3a34
Add image bundle
winscripter Aug 12, 2026
6e432ca
Use inline arrays in Butteraugli
winscripter Aug 12, 2026
4308af8
Merge branch 'SixLabors:main' into jxl-support
winscripter Aug 13, 2026
8b4ff41
First prototype of JxlDecoderCore
winscripter Aug 15, 2026
e03a581
Add JPEG XL container prototype & file type box
winscripter Aug 17, 2026
2d12bc6
Zero-copy input access (prototype 1)
winscripter Aug 18, 2026
08c13fc
Performance improvements
winscripter Aug 18, 2026
6ba0d37
Zero-copy input access (prototype 2)
winscripter Aug 18, 2026
c535893
Zero-copy input access (prototype 3)
winscripter Aug 18, 2026
75f676d
Add prototype of modular
winscripter Aug 24, 2026
e449656
Merge branch 'SixLabors:main' into jxl-support
winscripter Aug 24, 2026
dfd99a0
Reduce errors in AC strategy code
winscripter Aug 24, 2026
a2f8fe6
Reduce errors
winscripter Aug 24, 2026
352b14d
Reduce errors, remove unused constant
winscripter Aug 24, 2026
093d846
Finish inverse RCT
winscripter Aug 24, 2026
c5a7bb8
Complete RCT
winscripter Aug 24, 2026
c8b0a5d
Simplify decoder core & add palette shared methods
winscripter Aug 24, 2026
c079cf9
Add missing types, rename JxlBitDepth metadata to JxlBitDepthMetadata…
winscripter Aug 24, 2026
7e23670
Add CodestreamMarker, don't manually check for out-of-bounds
winscripter Aug 24, 2026
b8f4094
Reduce errors
winscripter Aug 24, 2026
2b43fd6
Simplify
winscripter Aug 24, 2026
9f8eb4a
Add box content decoder with Brotli compression & reduce errors
winscripter Aug 25, 2026
315ea0f
Reduce errors & refine documentation
winscripter Aug 25, 2026
57958f3
Reduce errors & remove unnecessary if statements
winscripter Aug 25, 2026
0678f35
Add missing types, reduce errors
winscripter Aug 25, 2026
4118c4a
Quantizer improvements, reduce errors
winscripter Aug 25, 2026
874ec5b
Complete quantizer encoding
winscripter Aug 25, 2026
acc474e
Complete modular transforms, context prediction
winscripter Aug 31, 2026
7b8749d
Don't use stackalloc for two bytes
winscripter Aug 31, 2026
15c32fe
Prefer Math.DivRem
winscripter Aug 31, 2026
de8c644
Use Math.DivRem
winscripter Aug 31, 2026
a5d5ab6
Prefer byte
winscripter Aug 31, 2026
1b6e824
Don't use GetWReference (it should return span)
winscripter Aug 31, 2026
c6c6942
Parenthesize
winscripter Aug 31, 2026
79b0113
Don't use stackalloc
winscripter Aug 31, 2026
e7d3608
Remove SuppressFinalize from sealed class
winscripter Aug 31, 2026
e6ed4ba
Use Math.Clamp
winscripter Aug 31, 2026
4858ef3
Use StartsWith
winscripter Aug 31, 2026
2835528
Remove try/finally
winscripter Aug 31, 2026
90ddb9d
Add JPEG parsed data
winscripter Aug 31, 2026
3059910
Use InlineArray for color correlation
winscripter Aug 31, 2026
a955946
Add JPEG data constants
winscripter Aug 31, 2026
497c27c
Update folder structure
winscripter Sep 1, 2026
4b9a74d
Add JPEG parser for JXL<->JPEG conversion
winscripter Sep 1, 2026
bc7e30e
Refactor & optimize
winscripter Sep 1, 2026
081384d
Optimize
winscripter Sep 1, 2026
80f1075
Make interface an abstract class
winscripter Sep 1, 2026
fad73d8
Add encoder ANS SIMD bit cost estimation
winscripter Sep 2, 2026
64bade8
Add huffman encoder, inverse Gaborish transform, gamma correction, no…
winscripter Sep 2, 2026
8345623
Refactor, optimize
winscripter Sep 2, 2026
4116e9c
Complete Edge Preserving Filter render pipeline stages
winscripter Sep 2, 2026
5874c4c
Optimize JxlNoiseHistogram
winscripter Sep 2, 2026
5f99a65
Further update folder structure, start working on write to output sta…
winscripter Sep 2, 2026
9ad0210
Add IJxlImageOutput
winscripter Sep 2, 2026
eead4a9
Add ShouldFlip methods, fix typo
winscripter Sep 2, 2026
a0feb21
Add Y'Cb'Cr stage, make Epf1Stage class sealed
winscripter Sep 2, 2026
9f3ccfa
Use primary constructor
winscripter Sep 2, 2026
76ed571
Add Gaborish stage
winscripter Sep 2, 2026
64edab5
Add patch dictionary stage
winscripter Sep 2, 2026
e0305d7
Partial adaptive quantizer encoder
winscripter Sep 2, 2026
5de2701
Add JxlToJpegDecoder static methods
winscripter Sep 2, 2026
4476abd
Add 3 missing methods to JxlFrameDecoder, add spline and spotcolor re…
winscripter Sep 2, 2026
5739218
Add a few CMS transfer functions (incomplete)
winscripter Sep 3, 2026
7880fb2
Add SIMD float->Half conversion
winscripter Sep 3, 2026
5fe70ba
Add photon noise encoder
winscripter Sep 3, 2026
bedf8ec
Add tests, complete splines, SIMD-accelerate transpose, add a few SIM…
winscripter Sep 4, 2026
eacb943
Reduce errors
winscripter Sep 4, 2026
4e929f3
Move comment
winscripter Sep 4, 2026
58c803e
Complete Butteraugli
winscripter Sep 4, 2026
b0f0d34
Complete Butteraugli and its tests
winscripter Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion src/ImageSharp/Common/Helpers/SimdUtils.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Diagnostics;
Expand Down Expand Up @@ -71,6 +71,43 @@ internal static Vector<float> FastRound(this Vector<float> v)
return val_2p23_f32 | sign;
}

/// <summary>
/// Estimates the reciprocal of this vector.
/// </summary>
/// <param name="v">The vector to get reciprocal estimate of.</param>
/// <returns>An estimated reciprocal of each element in the vector.</returns>
internal static Vector<float> ReciprocalEstimate(this Vector<float> v)
{
// TODO: System.Runtime.Intrinsics.Arm has Sve and Sve2
// support but is for evaluation purposes only; add SVE/SVE2
// support when possible
if (Avx512F.IsSupported && Vector<float>.Count == 16)
{
// x86
return Avx512F.Reciprocal14(v.AsVector512()).AsVector();
}
else if (Avx.IsSupported && Vector<float>.Count == 8)
{
// x86
return Avx.Reciprocal(v.AsVector256()).AsVector();
}
else if (AdvSimd.IsSupported && Vector<float>.Count == 4)
{
// ARM
return AdvSimd.ReciprocalEstimate(v.AsVector128()).AsVector();
}
else if (Sse.IsSupported && Vector<float>.Count == 4)
{
// x86
return Sse.Reciprocal(v.AsVector128()).AsVector();
}
else
{
// Exact reciprocal fallback (slower)
return Vector<float>.One / v;
}
}

[Conditional("DEBUG")]
private static void DebugVerifySpanInput(ReadOnlySpan<byte> source, ReadOnlySpan<float> dest, int shouldBeDivisibleBy)
{
Expand Down
80 changes: 80 additions & 0 deletions src/ImageSharp/Common/Helpers/Vector128Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -859,4 +859,84 @@ public static Vector128<sbyte> UnpackLow(Vector128<sbyte> left, Vector128<sbyte>
Vector128<sbyte> unpacked = Vector128.Create(left.GetLower(), right.GetLower());
return Vector128.ShuffleNative(unpacked, Vector128.Create(0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15));
}

/// <summary>
/// Interleaves the lower half of the vector.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>
/// <c>{ a[0], b[0], a[1], b[1] }</c>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<int> InterleaveLower(Vector128<int> a, Vector128<int> b)
{
Vector128<int> shuffledA = Vector128.Shuffle(a, Vector128.Create(0, 0, 1, 1));
Vector128<int> shuffledB = Vector128.Shuffle(b, Vector128.Create(0, 0, 1, 1));

Vector128<int> maskA = Vector128.Create(-1, 0, -1, 0);
Vector128<int> maskB = Vector128.Create(0, -1, 0, -1);

return (shuffledA & maskA) | (shuffledB & maskB);
}

/// <summary>
/// Interleaves the upper half of the vector.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>
/// <c>{ a[2], b[2], a[3], b[3] }</c>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<int> InterleaveUpper(Vector128<int> a, Vector128<int> b)
{
Vector128<int> shuffledA = Vector128.Shuffle(a, Vector128.Create(2, 2, 3, 3));
Vector128<int> shuffledB = Vector128.Shuffle(b, Vector128.Create(2, 2, 3, 3));

Vector128<int> maskA = Vector128.Create(-1, 0, -1, 0);
Vector128<int> maskB = Vector128.Create(0, -1, 0, -1);

return (shuffledA & maskA) | (shuffledB & maskB);
}

/// <summary>
/// Interleaves the lower half of the vector.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>
/// <c>{ a[0], b[0], a[1], b[1] }</c>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> InterleaveLower(Vector128<float> a, Vector128<float> b)
{
Vector128<float> shuffledA = Vector128.Shuffle(a, Vector128.Create(0, 0, 1, 1));
Vector128<float> shuffledB = Vector128.Shuffle(b, Vector128.Create(0, 0, 1, 1));

Vector128<float> maskA = Vector128.Create(-1, 0, -1, 0).AsSingle();
Vector128<float> maskB = Vector128.Create(0, -1, 0, -1).AsSingle();

return (shuffledA & maskA) | (shuffledB & maskB);
}

/// <summary>
/// Interleaves the upper half of the vector.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>
/// <c>{ a[2], b[2], a[3], b[3] }</c>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> InterleaveUpper(Vector128<float> a, Vector128<float> b)
{
Vector128<float> shuffledA = Vector128.Shuffle(a, Vector128.Create(2, 2, 3, 3));
Vector128<float> shuffledB = Vector128.Shuffle(b, Vector128.Create(2, 2, 3, 3));

Vector128<float> maskA = Vector128.Create(-1, 0, -1, 0).AsSingle();
Vector128<float> maskB = Vector128.Create(0, -1, 0, -1).AsSingle();

return (shuffledA & maskA) | (shuffledB & maskB);
}
}
206 changes: 206 additions & 0 deletions src/ImageSharp/Common/Helpers/Vector256Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,4 +397,210 @@ public static Vector256<byte> UnpackLow(Vector256<byte> left, Vector256<byte> ri

return Vector256.Create(lo, hi);
}

/// <summary>
/// Multiplies only the even indices of the two 256-bit vectors,
/// producing half as many elements of twice the element width.
/// </summary>
/// <param name="left">Left vector to multiply.</param>
/// <param name="right">Right vector to multiply</param>
/// <returns>
/// <code>
/// {
/// A[0] * B[0],
/// A[2] * B[2],
/// A[4] * B[4],
/// A[6] * B[6]
/// }
/// </code>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<long> MultiplyEven(Vector256<int> left, Vector256<int> right)
=> Vector256.Create(
left[0] * right[0],
left[2] * right[2],
left[4] * right[4],
left[6] * right[6]);

/// <summary>
/// Multiplies only the odd indices of the two 256-bit vectors,
/// producing half as many elements of twice the element width.
/// </summary>
/// <param name="left">Left vector to multiply.</param>
/// <param name="right">Right vector to multiply</param>
/// <returns>
/// <code>
/// {
/// A[1] * B[1],
/// A[3] * B[3],
/// A[5] * B[5],
/// A[7] * B[7]
/// }
/// </code>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<long> MultiplyOdd(Vector256<int> left, Vector256<int> right)
=> Vector256.Create(
left[1] * right[1],
left[3] * right[3],
left[5] * right[5],
left[7] * right[7]);

/// <summary>
/// Produces a vector by interleaving the even-indexed elements
/// of the left and right vectors.
/// </summary>
/// <param name="left">Left vector to interleave.</param>
/// <param name="right">Right vector to interleave.</param>
/// <returns>
/// <code>
/// {
/// A[0], B[0],
/// A[2], B[2],
/// A[4], B[4],
/// A[6], B[6]
/// }
/// </code>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<int> InterleaveEven(
Vector256<int> left,
Vector256<int> right)
=> Vector256.Create(
left[0],
right[0],
left[2],
right[2],
left[4],
right[4],
left[6],
right[6]);

/// <summary>
/// Produces a vector by interleaving the odd-indexed elements
/// of the left and right vectors.
/// </summary>
/// <param name="left">Left vector to interleave.</param>
/// <param name="right">Right vector to interleave.</param>
/// <returns>
/// <code>
/// {
/// A[1], B[1],
/// A[3], B[3],
/// A[5], B[5],
/// A[7], B[7]
/// }
/// </code>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<int> InterleaveOdd(
Vector256<int> left,
Vector256<int> right)
=> Vector256.Create(
left[1],
right[1],
left[3],
right[3],
left[5],
right[5],
left[7],
right[7]);

/// <summary>
/// Produces a vector with masks where 0xFFFFFFFF specifies
/// that the left value does not equal to the right value and
/// 0x00000000 specifies that the value equals to the
/// right value.
/// </summary>
/// <param name="left">Left vector to compare for inequality.</param>
/// <param name="right">Right vector to compare for inequality.</param>
/// <returns>
/// 0xFFFFFFFF for values that aren't equal, 0x00000000 for
/// values that are equal. This is essentially the inverse of
/// <see cref="Vector256.Equals{T}(Vector256{T}, Vector256{T})"/>.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<int> NotEqual(
Vector256<int> left,
Vector256<int> right) => ~Vector256.Equals(left, right);

/// <summary>
/// Interleaves the lower half of the vector.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>
/// <c>{ a[0], b[0], a[1], b[1], a[2], b[2], a[3], b[3] }</c>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<int> InterleaveLower(Vector256<int> a, Vector256<int> b)
{
Vector256<int> shuffledA = Vector256.Shuffle(a, Vector256.Create(0, 0, 1, 1, 2, 2, 3, 3));
Vector256<int> shuffledB = Vector256.Shuffle(b, Vector256.Create(0, 0, 1, 1, 2, 2, 3, 3));

Vector256<int> maskA = Vector256.Create(-1, 0, -1, 0, -1, 0, -1, 0);
Vector256<int> maskB = Vector256.Create(0, -1, 0, -1, 0, -1, 0, -1);

return (shuffledA & maskA) | (shuffledB & maskB);
}

/// <summary>
/// Interleaves the upper half of the vector.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>
/// <c>{ a[4], b[4], a[5], b[5], a[6], b[6], a[7], b[7] }</c>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<int> InterleaveUpper(Vector256<int> a, Vector256<int> b)
{
Vector256<int> shuffledA = Vector256.Shuffle(a, Vector256.Create(4, 4, 5, 5, 6, 6, 7, 7));
Vector256<int> shuffledB = Vector256.Shuffle(b, Vector256.Create(4, 4, 5, 5, 6, 6, 7, 7));

Vector256<int> maskA = Vector256.Create(-1, 0, -1, 0, -1, 0, -1, 0);
Vector256<int> maskB = Vector256.Create(0, -1, 0, -1, 0, -1, 0, -1);

return (shuffledA & maskA) | (shuffledB & maskB);
}

/// <summary>
/// Interleaves the lower half of the vector.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>
/// <c>{ a[0], b[0], a[1], b[1], a[2], b[2], a[3], b[3] }</c>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<float> InterleaveLower(Vector256<float> a, Vector256<float> b)
{
Vector256<float> shuffledA = Vector256.Shuffle(a, Vector256.Create(0, 0, 1, 1, 2, 2, 3, 3));
Vector256<float> shuffledB = Vector256.Shuffle(b, Vector256.Create(0, 0, 1, 1, 2, 2, 3, 3));

Vector256<float> maskA = Vector256.Create(-1, 0, -1, 0, -1, 0, -1, 0).AsSingle();
Vector256<float> maskB = Vector256.Create(0, -1, 0, -1, 0, -1, 0, -1).AsSingle();

return (shuffledA & maskA) | (shuffledB & maskB);
}

/// <summary>
/// Interleaves the upper half of the vector.
/// </summary>
/// <param name="a">First vector</param>
/// <param name="b">Second vector</param>
/// <returns>
/// <c>{ a[4], b[4], a[5], b[5], a[6], b[6], a[7], b[7] }</c>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<float> InterleaveUpper(Vector256<float> a, Vector256<float> b)
{
Vector256<float> shuffledA = Vector256.Shuffle(a, Vector256.Create(4, 4, 5, 5, 6, 6, 7, 7));
Vector256<float> shuffledB = Vector256.Shuffle(b, Vector256.Create(4, 4, 5, 5, 6, 6, 7, 7));

Vector256<float> maskA = Vector256.Create(-1, 0, -1, 0, -1, 0, -1, 0).AsSingle();
Vector256<float> maskB = Vector256.Create(0, -1, 0, -1, 0, -1, 0, -1).AsSingle();

return (shuffledA & maskA) | (shuffledB & maskB);
}
}
31 changes: 30 additions & 1 deletion src/ImageSharp/Common/InlineArray.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

// <auto-generated />
Expand Down Expand Up @@ -44,6 +44,15 @@ internal struct InlineArray16<T>
private T t;
}

/// <summary>
/// Represents a safe, fixed sized buffer of 17 elements.
/// </summary>
[InlineArray(17)]
internal struct InlineArray17<T>
{
private T t;
}

/// <summary>
/// Represents a safe, fixed sized buffer of 18 elements.
/// </summary>
Expand Down Expand Up @@ -71,6 +80,24 @@ internal struct InlineArray26<T>
private T t;
}

/// <summary>
/// Represents a safe, fixed sized buffer of 32 elements.
/// </summary>
[InlineArray(32)]
internal struct InlineArray32<T>
{
private T t;
}

/// <summary>
/// Represents a safe, fixed sized buffer of 33 elements.
/// </summary>
[InlineArray(33)]
internal struct InlineArray33<T>
{
private T t;
}

/// <summary>
/// Represents a safe, fixed sized buffer of 36 elements.
/// </summary>
Expand All @@ -88,3 +115,5 @@ internal struct InlineArray256<T>
{
private T t;
}


Comment thread
winscripter marked this conversation as resolved.
Loading