Browse Source

Replace Vector4.Clamp

pull/1574/head
James Jackson-South 6 years ago
parent
commit
f2aa2a7965
  1. 2
      src/ImageSharp/ColorSpaces/Cmyk.cs
  2. 12
      src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs
  3. 4
      src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs
  4. 2
      src/ImageSharp/Common/Helpers/SimdUtils.cs
  5. 18
      src/ImageSharp/Common/Helpers/Vector4Utilities.cs
  6. 32
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
  7. 2
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
  8. 2
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
  9. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs
  10. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs
  11. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs
  12. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs
  13. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs
  14. 2
      src/ImageSharp/PixelFormats/PixelImplementations/L16.cs
  15. 2
      src/ImageSharp/PixelFormats/PixelImplementations/L8.cs
  16. 2
      src/ImageSharp/PixelFormats/PixelImplementations/La16.cs
  17. 2
      src/ImageSharp/PixelFormats/PixelImplementations/La32.cs
  18. 2
      src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs
  19. 2
      src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs
  20. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs
  21. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs
  22. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs
  23. 4
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs
  24. 4
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs
  25. 2
      src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs
  26. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs
  27. 4
      src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs
  28. 2
      src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs
  29. 2
      src/ImageSharp/Processing/Processors/Filters/FilterProcessor{TPixel}.cs
  30. 6
      src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtilities.cs
  31. 60
      tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs
  32. 8
      tests/ImageSharp.Tests/Helpers/Vector4UtilsTests.cs
  33. 24
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

2
src/ImageSharp/ColorSpaces/Cmyk.cs

@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
[MethodImpl(InliningOptions.ShortMethod)]
public Cmyk(Vector4 vector)
{
vector = Vector4.Clamp(vector, Min, Max);
vector = Vector4Utilities.FastClamp(vector, Min, Max);
this.C = vector.X;
this.M = vector.Y;
this.Y = vector.Z;

12
src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs

@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
vector.W = target.W;
Vector4Utils.UnPremultiply(ref vector);
Vector4Utilities.UnPremultiply(ref vector);
target = vector;
}
@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp
out Vector4 vector);
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
Vector4Utils.UnPremultiply(ref vector);
Vector4Utilities.UnPremultiply(ref vector);
target = vector;
}
@ -140,7 +140,7 @@ namespace SixLabors.ImageSharp
{
int offsetX = (sourceOffsetColumnBase + x - radiusX).Clamp(minColumn, maxColumn);
var currentColor = sourceRowSpan[offsetX].ToVector4();
Vector4Utils.Premultiply(ref currentColor);
Vector4Utilities.Premultiply(ref currentColor);
vectorX += matrixX[y, x] * currentColor;
vectorY += matrixY[y, x] * currentColor;
@ -193,7 +193,7 @@ namespace SixLabors.ImageSharp
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
vector.W = target.W;
Vector4Utils.UnPremultiply(ref vector);
Vector4Utilities.UnPremultiply(ref vector);
target = vector;
}
@ -238,7 +238,7 @@ namespace SixLabors.ImageSharp
ref vector);
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
Vector4Utils.UnPremultiply(ref vector);
Vector4Utilities.UnPremultiply(ref vector);
target = vector;
}
@ -270,7 +270,7 @@ namespace SixLabors.ImageSharp
{
int offsetX = (sourceOffsetColumnBase + x - radiusX).Clamp(minColumn, maxColumn);
var currentColor = sourceRowSpan[offsetX].ToVector4();
Vector4Utils.Premultiply(ref currentColor);
Vector4Utilities.Premultiply(ref currentColor);
vector += matrix[y, x] * currentColor;
}
}

4
src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -125,8 +125,6 @@ namespace SixLabors.ImageSharp
Vector4 s = Unsafe.Add(ref sBase, i);
s *= maxBytes;
s += half;
// I'm not sure if Vector4.Clamp() is properly implemented with intrinsics.
s = Vector4.Max(Vector4.Zero, s);
s = Vector4.Min(maxBytes, s);

2
src/ImageSharp/Common/Helpers/SimdUtils.cs

@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static Vector4 PseudoRound(this Vector4 v)
{
var sign = Vector4.Clamp(v, new Vector4(-1), new Vector4(1));
var sign = Vector4Utilities.FastClamp(v, new Vector4(-1), new Vector4(1));
return v + (sign * 0.5f);
}

18
src/ImageSharp/Common/Helpers/Vector4Utils.cs → src/ImageSharp/Common/Helpers/Vector4Utilities.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -11,8 +11,20 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Utility methods for the <see cref="Vector4"/> struct.
/// </summary>
internal static class Vector4Utils
internal static class Vector4Utilities
{
/// <summary>
/// Restricts a vector between a minimum and a maximum value.
/// 5x Faster then <see cref="Vector4.Clamp(Vector4, Vector4, Vector4)"/>.
/// </summary>
/// <param name="x">The vector to restrict.</param>
/// <param name="min">The minimum value.</param>
/// <param name="max">The maximum value.</param>
/// <returns>The <see cref="Vector4"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static Vector4 FastClamp(Vector4 x, Vector4 min, Vector4 max)
=> Vector4.Min(Vector4.Max(min, x), max);
/// <summary>
/// Pre-multiplies the "x", "y", "z" components of a vector by its "w" component leaving the "w" component intact.
/// </summary>
@ -107,4 +119,4 @@ namespace SixLabors.ImageSharp
}
}
}
}
}

32
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs

@ -99,22 +99,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
var CMax4 = new Vector4(maximum);
var COff4 = new Vector4(MathF.Ceiling(maximum / 2));
this.V0L = Vector4.Clamp(this.V0L + COff4, CMin4, CMax4);
this.V0R = Vector4.Clamp(this.V0R + COff4, CMin4, CMax4);
this.V1L = Vector4.Clamp(this.V1L + COff4, CMin4, CMax4);
this.V1R = Vector4.Clamp(this.V1R + COff4, CMin4, CMax4);
this.V2L = Vector4.Clamp(this.V2L + COff4, CMin4, CMax4);
this.V2R = Vector4.Clamp(this.V2R + COff4, CMin4, CMax4);
this.V3L = Vector4.Clamp(this.V3L + COff4, CMin4, CMax4);
this.V3R = Vector4.Clamp(this.V3R + COff4, CMin4, CMax4);
this.V4L = Vector4.Clamp(this.V4L + COff4, CMin4, CMax4);
this.V4R = Vector4.Clamp(this.V4R + COff4, CMin4, CMax4);
this.V5L = Vector4.Clamp(this.V5L + COff4, CMin4, CMax4);
this.V5R = Vector4.Clamp(this.V5R + COff4, CMin4, CMax4);
this.V6L = Vector4.Clamp(this.V6L + COff4, CMin4, CMax4);
this.V6R = Vector4.Clamp(this.V6R + COff4, CMin4, CMax4);
this.V7L = Vector4.Clamp(this.V7L + COff4, CMin4, CMax4);
this.V7R = Vector4.Clamp(this.V7R + COff4, CMin4, CMax4);
this.V0L = Vector4Utilities.FastClamp(this.V0L + COff4, CMin4, CMax4);
this.V0R = Vector4Utilities.FastClamp(this.V0R + COff4, CMin4, CMax4);
this.V1L = Vector4Utilities.FastClamp(this.V1L + COff4, CMin4, CMax4);
this.V1R = Vector4Utilities.FastClamp(this.V1R + COff4, CMin4, CMax4);
this.V2L = Vector4Utilities.FastClamp(this.V2L + COff4, CMin4, CMax4);
this.V2R = Vector4Utilities.FastClamp(this.V2R + COff4, CMin4, CMax4);
this.V3L = Vector4Utilities.FastClamp(this.V3L + COff4, CMin4, CMax4);
this.V3R = Vector4Utilities.FastClamp(this.V3R + COff4, CMin4, CMax4);
this.V4L = Vector4Utilities.FastClamp(this.V4L + COff4, CMin4, CMax4);
this.V4R = Vector4Utilities.FastClamp(this.V4R + COff4, CMin4, CMax4);
this.V5L = Vector4Utilities.FastClamp(this.V5L + COff4, CMin4, CMax4);
this.V5R = Vector4Utilities.FastClamp(this.V5R + COff4, CMin4, CMax4);
this.V6L = Vector4Utilities.FastClamp(this.V6L + COff4, CMin4, CMax4);
this.V6R = Vector4Utilities.FastClamp(this.V6R + COff4, CMin4, CMax4);
this.V7L = Vector4Utilities.FastClamp(this.V7L + COff4, CMin4, CMax4);
this.V7R = Vector4Utilities.FastClamp(this.V7R + COff4, CMin4, CMax4);
}
/// <summary>

2
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt

@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
for (int j = 0; j < 2; j++)
{
char side = j == 0 ? 'L' : 'R';
Write($"this.V{i}{side} = Vector4.Clamp(this.V{i}{side} + COff4, CMin4, CMax4);\r\n");
Write($"this.V{i}{side} = Vector4Utilities.FastClamp(this.V{i}{side} + COff4, CMin4, CMax4);\r\n");
}
}
PopIndent();

2
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs

@ -589,7 +589,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
private static Vector4 DivideRound(Vector4 dividend, Vector4 divisor)
{
// sign(dividend) = max(min(dividend, 1), -1)
var sign = Vector4.Clamp(dividend, NegativeOne, Vector4.One);
var sign = Vector4Utilities.FastClamp(dividend, NegativeOne, Vector4.One);
// AlmostRound(dividend/divisor) = dividend/divisor + 0.5*sign(dividend)
return (dividend / divisor) + (sign * Offset);

2
src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs

@ -373,7 +373,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
vector *= MaxBytes;
vector += Half;
vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, MaxBytes);
this.R = (byte)vector.X;
this.G = (byte)vector.Y;

2
src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs

@ -296,7 +296,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
vector *= MaxBytes;
vector += Half;
vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, MaxBytes);
this.R = (byte)vector.X;
this.G = (byte)vector.Y;

2
src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs

@ -162,7 +162,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
private static ushort Pack(ref Vector4 vector)
{
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, Vector4.One);
return (ushort)((((int)Math.Round(vector.W * 15F) & 0x0F) << 12)
| (((int)Math.Round(vector.X * 15F) & 0x0F) << 8)
| (((int)Math.Round(vector.Y * 15F) & 0x0F) << 4)

2
src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs

@ -163,7 +163,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
private static ushort Pack(ref Vector4 vector)
{
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, Vector4.One);
return (ushort)(
(((int)Math.Round(vector.X * 31F) & 0x1F) << 10)
| (((int)Math.Round(vector.Y * 31F) & 0x1F) << 5)

2
src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs

@ -171,7 +171,7 @@ namespace SixLabors.ImageSharp.PixelFormats
const float Max = 255F;
// Clamp the value between min and max values
vector = Vector4.Clamp(vector, Vector4.Zero, new Vector4(Max));
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, new Vector4(Max));
uint byte4 = (uint)Math.Round(vector.X) & 0xFF;
uint byte3 = ((uint)Math.Round(vector.Y) & 0xFF) << 0x8;

2
src/ImageSharp/PixelFormats/PixelImplementations/L16.cs

@ -176,7 +176,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
internal void ConvertFromRgbaScaledVector4(Vector4 vector)
{
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, Vector4.One) * Max;
this.PackedValue = ImageMaths.Get16BitBT709Luminance(
vector.X,
vector.Y,

2
src/ImageSharp/PixelFormats/PixelImplementations/L8.cs

@ -156,7 +156,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
vector *= MaxBytes;
vector += Half;
vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, MaxBytes);
this.PackedValue = ImageMaths.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z);
}
}

2
src/ImageSharp/PixelFormats/PixelImplementations/La16.cs

@ -219,7 +219,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
vector *= MaxBytes;
vector += Half;
vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, MaxBytes);
this.L = ImageMaths.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z);
this.A = (byte)vector.W;
}

2
src/ImageSharp/PixelFormats/PixelImplementations/La32.cs

@ -233,7 +233,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
internal void ConvertFromRgbaScaledVector4(Vector4 vector)
{
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, Vector4.One) * Max;
this.L = ImageMaths.Get16BitBT709Luminance(
vector.X,
vector.Y,

2
src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs

@ -174,7 +174,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Pack(ref Vector4 vector)
{
vector = Vector4.Clamp(vector, MinusOne, Vector4.One) * Half;
vector = Vector4Utilities.FastClamp(vector, MinusOne, Vector4.One) * Half;
uint byte4 = ((uint)MathF.Round(vector.X) & 0xFF) << 0;
uint byte3 = ((uint)MathF.Round(vector.Y) & 0xFF) << 8;

2
src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs

@ -177,7 +177,7 @@ namespace SixLabors.ImageSharp.PixelFormats
private static ulong Pack(ref Vector4 vector)
{
vector *= Max;
vector = Vector4.Clamp(vector, Min, Max);
vector = Vector4Utilities.FastClamp(vector, Min, Max);
// Round rather than truncate.
ulong word4 = ((ulong)MathF.Round(vector.X) & 0xFFFF) << 0x00;

2
src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs

@ -254,7 +254,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
vector *= MaxBytes;
vector += Half;
vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, MaxBytes);
this.R = (byte)vector.X;
this.G = (byte)vector.Y;

2
src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs

@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
{
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, Vector4.One) * Max;
this.R = (ushort)MathF.Round(vector.X);
this.G = (ushort)MathF.Round(vector.Y);
this.B = (ushort)MathF.Round(vector.Z);

2
src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs

@ -163,7 +163,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Pack(ref Vector4 vector)
{
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Multiplier;
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, Vector4.One) * Multiplier;
return (uint)(
(((int)Math.Round(vector.X) & 0x03FF) << 0)

4
src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs

@ -452,7 +452,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
vector *= MaxBytes;
vector += Half;
vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, MaxBytes);
return new Rgba32((byte)vector.X, (byte)vector.Y, (byte)vector.Z, (byte)vector.W);
}
@ -491,7 +491,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
vector *= MaxBytes;
vector += Half;
vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, MaxBytes);
this.R = (byte)vector.X;
this.G = (byte)vector.Y;

4
src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs

@ -127,7 +127,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public Rgba64(Vector4 vector)
{
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, Vector4.One) * Max;
this.R = (ushort)MathF.Round(vector.X);
this.G = (ushort)MathF.Round(vector.Y);
this.B = (ushort)MathF.Round(vector.Z);
@ -209,7 +209,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
{
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, Vector4.One) * Max;
this.R = (ushort)MathF.Round(vector.X);
this.G = (ushort)MathF.Round(vector.Y);
this.B = (ushort)MathF.Round(vector.Z);

2
src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs

@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
{
vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One);
vector = Vector4Utilities.FastClamp(vector, Vector4.Zero, Vector4.One);
this.R = vector.X;
this.G = vector.Y;
this.B = vector.Z;

2
src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs

@ -183,7 +183,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
private static ulong Pack(ref Vector4 vector)
{
vector = Vector4.Clamp(vector, Min, Max);
vector = Vector4Utilities.FastClamp(vector, Min, Max);
// Clamp the value between min and max values
ulong word4 = ((ulong)Math.Round(vector.X) & 0xFFFF) << 0x00;

4
src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs

@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils
if (modifiers.IsDefined(PixelConversionModifiers.Premultiply))
{
Vector4Utils.Premultiply(vectors);
Vector4Utilities.Premultiply(vectors);
}
}
@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils
{
if (modifiers.IsDefined(PixelConversionModifiers.Premultiply))
{
Vector4Utils.UnPremultiply(vectors);
Vector4Utilities.UnPremultiply(vectors);
}
if (modifiers.IsDefined(PixelConversionModifiers.SRgbCompand))

2
src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs

@ -304,7 +304,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
for (int x = 0; x < this.bounds.Width; x++)
{
ref Vector4 v = ref Unsafe.Add(ref sourceRef, x);
var clamp = Vector4.Clamp(v, low, high);
var clamp = Vector4Utilities.FastClamp(v, low, high);
v.X = MathF.Pow(clamp.X, this.inverseGamma);
v.Y = MathF.Pow(clamp.Y, this.inverseGamma);
v.Z = MathF.Pow(clamp.Z, this.inverseGamma);

2
src/ImageSharp/Processing/Processors/Filters/FilterProcessor{TPixel}.cs

@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
Span<TPixel> rowSpan = this.source.GetPixelRowSpan(y).Slice(this.startX, span.Length);
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, rowSpan, span);
Vector4Utils.Transform(span, ref Unsafe.AsRef(this.matrix));
Vector4Utilities.Transform(span, ref Unsafe.AsRef(this.matrix));
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, span, rowSpan);
}

6
src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtilities.cs

@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
MathF.Floor(maxXY.X),
MathF.Floor(maxXY.Y));
sourceExtents = Vector4.Clamp(sourceExtents, Vector4.Zero, maxSourceExtents);
sourceExtents = Vector4Utilities.FastClamp(sourceExtents, Vector4.Zero, maxSourceExtents);
int left = (int)sourceExtents.X;
int top = (int)sourceExtents.Y;
@ -78,13 +78,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Values are first premultiplied to prevent darkening of edge pixels.
var current = sourcePixels[x, y].ToVector4();
Vector4Utils.Premultiply(ref current);
Vector4Utilities.Premultiply(ref current);
sum += current * xWeight * yWeight;
}
}
// Reverse the premultiplication
Vector4Utils.UnPremultiply(ref sum);
Vector4Utilities.UnPremultiply(ref sum);
targetRow[column] = sum;
}

60
tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using BenchmarkDotNet.Attributes;
namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath
{
public class ClampVector4
{
private readonly float min = -1.5f;
private readonly float max = 2.5f;
private static readonly float[] Values = { -10, -5, -3, -1.5f, -0.5f, 0f, 1f, 1.5f, 2.5f, 3, 10 };
[Benchmark(Baseline = true)]
public Vector4 UsingVectorClamp()
{
Vector4 acc = Vector4.Zero;
for (int i = 0; i < Values.Length; i++)
{
acc += ClampUsingVectorClamp(Values[i], this.min, this.max);
}
return acc;
}
[Benchmark]
public Vector4 UsingVectorMinMax()
{
Vector4 acc = Vector4.Zero;
for (int i = 0; i < Values.Length; i++)
{
acc += ClampUsingVectorMinMax(Values[i], this.min, this.max);
}
return acc;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 ClampUsingVectorClamp(float x, float min, float max)
{
return Vector4.Clamp(new Vector4(x), new Vector4(min), new Vector4(max));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 ClampUsingVectorMinMax(float x, float min, float max)
{
return Vector4.Min(new Vector4(max), Vector4.Max(new Vector4(min), new Vector4(x)));
}
// RESULTS
// | Method | Mean | Error | StdDev | Ratio |
// |------------------ |---------:|---------:|---------:|------:|
// | UsingVectorClamp | 75.21 ns | 1.572 ns | 4.057 ns | 1.00 |
// | UsingVectorMinMax | 15.35 ns | 0.356 ns | 0.789 ns | 0.20 |
}
}

8
tests/ImageSharp.Tests/Helpers/Vector4UtilsTests.cs

@ -23,11 +23,11 @@ namespace SixLabors.ImageSharp.Tests.Helpers
Vector4[] source = rnd.GenerateRandomVectorArray(length, 0, 1);
Vector4[] expected = source.Select(v =>
{
Vector4Utils.Premultiply(ref v);
Vector4Utilities.Premultiply(ref v);
return v;
}).ToArray();
Vector4Utils.Premultiply(source);
Vector4Utilities.Premultiply(source);
Assert.Equal(expected, source, this.approximateFloatComparer);
}
@ -42,11 +42,11 @@ namespace SixLabors.ImageSharp.Tests.Helpers
Vector4[] source = rnd.GenerateRandomVectorArray(length, 0, 1);
Vector4[] expected = source.Select(v =>
{
Vector4Utils.UnPremultiply(ref v);
Vector4Utilities.UnPremultiply(ref v);
return v;
}).ToArray();
Vector4Utils.UnPremultiply(source);
Vector4Utilities.UnPremultiply(source);
Assert.Equal(expected, source, this.approximateFloatComparer);
}

24
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

@ -170,7 +170,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasAlpha)
{
Vector4Utils.Premultiply(ref v);
Vector4Utilities.Premultiply(ref v);
}
}
@ -178,7 +178,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasAlpha)
{
Vector4Utils.UnPremultiply(ref v);
Vector4Utilities.UnPremultiply(ref v);
}
}
@ -199,7 +199,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasAlpha)
{
Vector4Utils.Premultiply(ref v);
Vector4Utilities.Premultiply(ref v);
}
}
@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasAlpha)
{
Vector4Utils.UnPremultiply(ref v);
Vector4Utilities.UnPremultiply(ref v);
}
}
@ -234,7 +234,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
if (this.HasAlpha)
{
Vector4Utils.Premultiply(ref v);
Vector4Utilities.Premultiply(ref v);
}
}
@ -242,7 +242,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasAlpha)
{
Vector4Utils.UnPremultiply(ref v);
Vector4Utilities.UnPremultiply(ref v);
}
SRgbCompanding.Compress(ref v);
@ -349,12 +349,12 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
void SourceAction(ref Vector4 v)
{
Vector4Utils.UnPremultiply(ref v);
Vector4Utilities.UnPremultiply(ref v);
}
void ExpectedAction(ref Vector4 v)
{
Vector4Utils.Premultiply(ref v);
Vector4Utilities.Premultiply(ref v);
}
TPixel[] source = CreatePixelTestData(count, (ref Vector4 v) => SourceAction(ref v));
@ -372,12 +372,12 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
void SourceAction(ref Vector4 v)
{
Vector4Utils.UnPremultiply(ref v);
Vector4Utilities.UnPremultiply(ref v);
}
void ExpectedAction(ref Vector4 v)
{
Vector4Utils.Premultiply(ref v);
Vector4Utilities.Premultiply(ref v);
}
TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => SourceAction(ref v));
@ -399,14 +399,14 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
void SourceAction(ref Vector4 v)
{
Vector4Utils.UnPremultiply(ref v);
Vector4Utilities.UnPremultiply(ref v);
SRgbCompanding.Compress(ref v);
}
void ExpectedAction(ref Vector4 v)
{
SRgbCompanding.Expand(ref v);
Vector4Utils.Premultiply(ref v);
Vector4Utilities.Premultiply(ref v);
}
TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => SourceAction(ref v));

Loading…
Cancel
Save