|
|
|
@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters |
|
|
|
|
|
|
|
// Paeth(x) + PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp))
|
|
|
|
int offset = bytesPerPixel + 1; // Add one because x starts at one.
|
|
|
|
int x = 1; |
|
|
|
nint x = 1; |
|
|
|
for (; x < offset; x++) |
|
|
|
{ |
|
|
|
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x); |
|
|
|
@ -146,9 +146,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters |
|
|
|
sum = 0; |
|
|
|
|
|
|
|
// Paeth(x) = Raw(x) - PaethPredictor(Raw(x-bpp), Prior(x), Prior(x - bpp))
|
|
|
|
resultBaseRef = 4; |
|
|
|
resultBaseRef = (byte)FilterType.Paeth; |
|
|
|
|
|
|
|
int x = 0; |
|
|
|
nint x = 0; |
|
|
|
for (; x < bytesPerPixel; /* Note: ++x happens in the body to avoid one add operation */) |
|
|
|
{ |
|
|
|
byte scan = Unsafe.Add(ref scanBaseRef, x); |
|
|
|
@ -164,7 +164,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters |
|
|
|
Vector256<byte> zero = Vector256<byte>.Zero; |
|
|
|
Vector256<int> sumAccumulator = Vector256<int>.Zero; |
|
|
|
|
|
|
|
for (int xLeft = x - bytesPerPixel; x + Vector256<byte>.Count <= scanline.Length; xLeft += Vector256<byte>.Count) |
|
|
|
for (nint xLeft = x - bytesPerPixel; x <= scanline.Length - Vector256<byte>.Count; xLeft += Vector256<byte>.Count) |
|
|
|
{ |
|
|
|
Vector256<byte> scan = Unsafe.As<byte, Vector256<byte>>(ref Unsafe.Add(ref scanBaseRef, x)); |
|
|
|
Vector256<byte> left = Unsafe.As<byte, Vector256<byte>>(ref Unsafe.Add(ref scanBaseRef, xLeft)); |
|
|
|
@ -184,7 +184,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters |
|
|
|
{ |
|
|
|
Vector<uint> sumAccumulator = Vector<uint>.Zero; |
|
|
|
|
|
|
|
for (int xLeft = x - bytesPerPixel; x + Vector<byte>.Count <= scanline.Length; xLeft += Vector<byte>.Count) |
|
|
|
for (nint xLeft = x - bytesPerPixel; x <= scanline.Length - Vector<byte>.Count; xLeft += Vector<byte>.Count) |
|
|
|
{ |
|
|
|
Vector<byte> scan = Unsafe.As<byte, Vector<byte>>(ref Unsafe.Add(ref scanBaseRef, x)); |
|
|
|
Vector<byte> left = Unsafe.As<byte, Vector<byte>>(ref Unsafe.Add(ref scanBaseRef, xLeft)); |
|
|
|
@ -204,7 +204,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) |
|
|
|
for (nint xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) |
|
|
|
{ |
|
|
|
byte scan = Unsafe.Add(ref scanBaseRef, x); |
|
|
|
byte left = Unsafe.Add(ref scanBaseRef, xLeft); |
|
|
|
@ -215,8 +215,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters |
|
|
|
res = (byte)(scan - PaethPredictor(left, above, upperLeft)); |
|
|
|
sum += Numerics.Abs(unchecked((sbyte)res)); |
|
|
|
} |
|
|
|
|
|
|
|
sum -= 4; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -250,6 +248,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters |
|
|
|
return upperLeft; |
|
|
|
} |
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
private static Vector256<byte> PaethPredictor(Vector256<byte> left, Vector256<byte> above, Vector256<byte> upleft) |
|
|
|
{ |
|
|
|
Vector256<byte> zero = Vector256<byte>.Zero; |
|
|
|
@ -282,6 +281,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters |
|
|
|
return Avx2.BlendVariable(resbc, left, Avx2.CompareEqual(Avx2.Min(minbc, pa), pa)); |
|
|
|
} |
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
private static Vector<byte> PaethPredictor(Vector<byte> left, Vector<byte> above, Vector<byte> upperLeft) |
|
|
|
{ |
|
|
|
Vector.Widen(left, out Vector<ushort> a1, out Vector<ushort> a2); |
|
|
|
@ -293,16 +293,17 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters |
|
|
|
return Vector.AsVectorByte(Vector.Narrow(p1, p2)); |
|
|
|
} |
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
private static Vector<short> PaethPredictor(Vector<short> left, Vector<short> above, Vector<short> upperLeft) |
|
|
|
{ |
|
|
|
Vector<short> p = left + above - upperLeft; |
|
|
|
var pa = Vector.Abs(p - left); |
|
|
|
var pb = Vector.Abs(p - above); |
|
|
|
var pc = Vector.Abs(p - upperLeft); |
|
|
|
Vector<short> pa = Vector.Abs(p - left); |
|
|
|
Vector<short> pb = Vector.Abs(p - above); |
|
|
|
Vector<short> pc = Vector.Abs(p - upperLeft); |
|
|
|
|
|
|
|
var pa_pb = Vector.LessThanOrEqual(pa, pb); |
|
|
|
var pa_pc = Vector.LessThanOrEqual(pa, pc); |
|
|
|
var pb_pc = Vector.LessThanOrEqual(pb, pc); |
|
|
|
Vector<short> pa_pb = Vector.LessThanOrEqual(pa, pb); |
|
|
|
Vector<short> pa_pc = Vector.LessThanOrEqual(pa, pc); |
|
|
|
Vector<short> pb_pc = Vector.LessThanOrEqual(pb, pc); |
|
|
|
|
|
|
|
return Vector.ConditionalSelect( |
|
|
|
condition: Vector.BitwiseAnd(pa_pb, pa_pc), |
|
|
|
|