|
|
|
@ -2,6 +2,7 @@ |
|
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
|
|
|
|
#if SUPPORTS_RUNTIME_INTRINSICS
|
|
|
|
using System; |
|
|
|
using System.Runtime.CompilerServices; |
|
|
|
using System.Runtime.InteropServices; |
|
|
|
using System.Runtime.Intrinsics; |
|
|
|
@ -47,31 +48,33 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public override void ConvertFromRgbInplace(in ComponentValues values) |
|
|
|
public override void ConvertFromRgbInplace(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane) |
|
|
|
{ |
|
|
|
ref Vector256<float> c0Base = |
|
|
|
ref Vector256<float> destC = |
|
|
|
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component0)); |
|
|
|
ref Vector256<float> c1Base = |
|
|
|
ref Vector256<float> destM = |
|
|
|
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component1)); |
|
|
|
ref Vector256<float> c2Base = |
|
|
|
ref Vector256<float> destY = |
|
|
|
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component2)); |
|
|
|
ref Vector256<float> c3Base = |
|
|
|
ref Vector256<float> destK = |
|
|
|
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component3)); |
|
|
|
|
|
|
|
ref Vector256<float> srcR = |
|
|
|
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(rLane)); |
|
|
|
ref Vector256<float> srcG = |
|
|
|
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(gLane)); |
|
|
|
ref Vector256<float> srcB = |
|
|
|
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(bLane)); |
|
|
|
|
|
|
|
// Used for the color conversion
|
|
|
|
var scale = Vector256.Create(this.MaximumValue); |
|
|
|
|
|
|
|
nint n = values.Component0.Length / Vector256<float>.Count; |
|
|
|
for (nint i = 0; i < n; i++) |
|
|
|
{ |
|
|
|
ref Vector256<float> c0 = ref Unsafe.Add(ref c0Base, i); |
|
|
|
ref Vector256<float> c1 = ref Unsafe.Add(ref c1Base, i); |
|
|
|
ref Vector256<float> c2 = ref Unsafe.Add(ref c2Base, i); |
|
|
|
ref Vector256<float> c3 = ref Unsafe.Add(ref c3Base, i); |
|
|
|
|
|
|
|
Vector256<float> ctmp = Avx.Subtract(scale, c0); |
|
|
|
Vector256<float> mtmp = Avx.Subtract(scale, c1); |
|
|
|
Vector256<float> ytmp = Avx.Subtract(scale, c2); |
|
|
|
Vector256<float> ctmp = Avx.Subtract(scale, Unsafe.Add(ref srcR, i)); |
|
|
|
Vector256<float> mtmp = Avx.Subtract(scale, Unsafe.Add(ref srcG, i)); |
|
|
|
Vector256<float> ytmp = Avx.Subtract(scale, Unsafe.Add(ref srcB, i)); |
|
|
|
Vector256<float> ktmp = Avx.Min(ctmp, Avx.Min(mtmp, ytmp)); |
|
|
|
|
|
|
|
Vector256<float> kMask = Avx.CompareNotEqual(ktmp, scale); |
|
|
|
@ -80,10 +83,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components |
|
|
|
mtmp = Avx.And(Avx.Divide(Avx.Subtract(mtmp, ktmp), Avx.Subtract(scale, ktmp)), kMask); |
|
|
|
ytmp = Avx.And(Avx.Divide(Avx.Subtract(ytmp, ktmp), Avx.Subtract(scale, ktmp)), kMask); |
|
|
|
|
|
|
|
c0 = Avx.Subtract(scale, Avx.Multiply(ctmp, scale)); |
|
|
|
c1 = Avx.Subtract(scale, Avx.Multiply(mtmp, scale)); |
|
|
|
c2 = Avx.Subtract(scale, Avx.Multiply(ytmp, scale)); |
|
|
|
c3 = Avx.Subtract(scale, ktmp); |
|
|
|
Unsafe.Add(ref destC, i) = Avx.Subtract(scale, Avx.Multiply(ctmp, scale)); |
|
|
|
Unsafe.Add(ref destM, i) = Avx.Subtract(scale, Avx.Multiply(mtmp, scale)); |
|
|
|
Unsafe.Add(ref destY, i) = Avx.Subtract(scale, Avx.Multiply(ytmp, scale)); |
|
|
|
Unsafe.Add(ref destK, i) = Avx.Subtract(scale, ktmp); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|