Browse Source

Add Ssse3 variant for substract green transform

pull/1552/head
Brian Popow 5 years ago
parent
commit
d0550a4d14
  1. 60
      src/ImageSharp/Formats/WebP/Lossless/LosslessUtils.cs

60
src/ImageSharp/Formats/WebP/Lossless/LosslessUtils.cs

@ -103,7 +103,29 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
public static void AddGreenToBlueAndRed(Span<uint> pixelData)
{
#if SUPPORTS_RUNTIME_INTRINSICS
if (Sse.IsSupported)
if (Ssse3.IsSupported)
{
var mask = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255);
int numPixels = pixelData.Length;
int i;
fixed (uint* p = pixelData)
{
for (i = 0; i + 4 <= numPixels; i += 4)
{
var idx = p + i;
Vector128<byte> input = Sse2.LoadVector128((ushort*)idx).AsByte();
Vector128<byte> in0g0g = Ssse3.Shuffle(input, mask);
Vector128<byte> output = Sse2.Add(input, in0g0g);
Sse2.Store((byte*)idx, output.AsByte());
}
if (i != numPixels)
{
AddGreenToBlueAndRedNoneVectorized(pixelData.Slice(i));
}
}
}
else if (Sse.IsSupported)
{
var mask = SimdUtils.Shuffle.MmShuffle(2, 2, 0, 0);
int numPixels = pixelData.Length;
@ -123,18 +145,18 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
if (i != numPixels)
{
AddGreenToBlueAndRedSequential(pixelData.Slice(i));
AddGreenToBlueAndRedNoneVectorized(pixelData.Slice(i));
}
}
}
else
#endif
{
AddGreenToBlueAndRedSequential(pixelData);
AddGreenToBlueAndRedNoneVectorized(pixelData);
}
}
private static void AddGreenToBlueAndRedSequential(Span<uint> pixelData)
private static void AddGreenToBlueAndRedNoneVectorized(Span<uint> pixelData)
{
int numPixels = pixelData.Length;
for (int i = 0; i < numPixels; i++)
@ -151,7 +173,29 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
public static void SubtractGreenFromBlueAndRed(Span<uint> pixelData)
{
#if SUPPORTS_RUNTIME_INTRINSICS
if (Sse.IsSupported)
if (Ssse3.IsSupported)
{
var mask = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255);
int numPixels = pixelData.Length;
int i;
fixed (uint* p = pixelData)
{
for (i = 0; i + 4 <= numPixels; i += 4)
{
var idx = p + i;
Vector128<byte> input = Sse2.LoadVector128((ushort*)idx).AsByte();
Vector128<byte> in0g0g = Ssse3.Shuffle(input, mask);
Vector128<byte> output = Sse2.Subtract(input, in0g0g);
Sse2.Store((byte*)idx, output.AsByte());
}
if (i != numPixels)
{
SubtractGreenFromBlueAndRedNoneVectorized(pixelData.Slice(i));
}
}
}
else if (Sse.IsSupported)
{
var mask = SimdUtils.Shuffle.MmShuffle(2, 2, 0, 0);
int numPixels = pixelData.Length;
@ -171,18 +215,18 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
if (i != numPixels)
{
SubtractGreenFromBlueAndRedSequential(pixelData.Slice(i));
SubtractGreenFromBlueAndRedNoneVectorized(pixelData.Slice(i));
}
}
}
else
#endif
{
SubtractGreenFromBlueAndRedSequential(pixelData);
SubtractGreenFromBlueAndRedNoneVectorized(pixelData);
}
}
private static void SubtractGreenFromBlueAndRedSequential(Span<uint> pixelData)
private static void SubtractGreenFromBlueAndRedNoneVectorized(Span<uint> pixelData)
{
int numPixels = pixelData.Length;
for (int i = 0; i < numPixels; i++)

Loading…
Cancel
Save