Browse Source

Vectorized UpFilter

pull/1630/head
TechPizza 5 years ago
parent
commit
425e4876fa
  1. 31
      src/ImageSharp/Formats/Png/Filters/UpFilter.cs

31
src/ImageSharp/Formats/Png/Filters/UpFilter.cs

@ -1,7 +1,8 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -57,7 +58,33 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
// Up(x) = Raw(x) - Prior(x)
resultBaseRef = 2;
for (int x = 0; x < scanline.Length; /* Note: ++x happens in the body to avoid one add operation */)
int x = 0;
#if SUPPORTS_RUNTIME_INTRINSICS
if (Vector.IsHardwareAccelerated)
{
Vector<uint> sumAccumulator = Vector<uint>.Zero;
for (; x + Vector<byte>.Count <= scanline.Length;)
{
Vector<byte> scan = Unsafe.As<byte, Vector<byte>>(ref Unsafe.Add(ref scanBaseRef, x));
Vector<byte> above = Unsafe.As<byte, Vector<byte>>(ref Unsafe.Add(ref prevBaseRef, x));
Vector<byte> res = scan - above;
Unsafe.As<byte, Vector<byte>>(ref Unsafe.Add(ref resultBaseRef, x + 1)) = res; // +1 to skip filter type
x += Vector<byte>.Count;
Numerics.Accumulate(ref sumAccumulator, Vector.AsVectorByte(Vector.Abs(Vector.AsVectorSByte(res))));
}
for (int i = 0; i < Vector<uint>.Count; i++)
{
sum += (int)sumAccumulator[i];
}
}
#endif
for (; x < scanline.Length; /* Note: ++x happens in the body to avoid one add operation */)
{
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);

Loading…
Cancel
Save