diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs
index a318d1941..6accad43f 100644
--- a/src/ImageSharp/Common/Helpers/ImageMaths.cs
+++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs
@@ -298,5 +298,24 @@ namespace SixLabors.ImageSharp
v *= s;
}
}
+
+ ///
+ /// Revers
+ ///
+ ///
+ /// The span of vectors
+ public static void UnPremultiply(Span vectors)
+ {
+ // TODO: This method can be AVX2 optimized using Vector
+ ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
+
+ for (int i = 0; i < vectors.Length; i++)
+ {
+ ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
+ var s = new Vector4(1 / v.W);
+ s.W = 1;
+ v *= s;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs
index f149523fc..a69ceea5c 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs
@@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// The source row position.
/// The weighted sum
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector4 ConvolvePremultipliedRows(Span rowSpan, int sourceX)
+ public Vector4 ConvolveRows(Span rowSpan, int sourceX)
{
ref float horizontalValues = ref this.GetStartReference();
int left = this.Left;
@@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
float weight = Unsafe.Add(ref horizontalValues, i);
Vector4 v = Unsafe.Add(ref vecPtr, i);
- result += v.Premultiply() * weight;
+ result += v * weight;
}
return result;
@@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// The source row position.
/// The weighted sum
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector4 ConvolvePremultipliedExpandedRows(Span rowSpan, int sourceX)
+ public Vector4 ConvolveExpandRows(Span rowSpan, int sourceX)
{
ref float horizontalValues = ref this.GetStartReference();
int left = this.Left;
@@ -118,10 +118,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
float weight = Unsafe.Add(ref horizontalValues, i);
Vector4 v = Unsafe.Add(ref vecPtr, i);
- result += v.Premultiply().Expand() * weight;
+ result += v.Expand() * weight;
}
- return result.UnPremultiply();
+ return result;
}
///
diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs
index 52ed222ca..2643206b4 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs
@@ -142,7 +142,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
public bool Compand { get; }
-
///
protected override Image CreateDestination(Image source, Rectangle sourceRectangle)
{
@@ -254,6 +253,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
Span tempRowSpan = tempRowBuffer.Span;
PixelOperations.Instance.ToVector4(sourceRow, tempRowSpan, sourceRow.Length);
+ ImageMaths.Premultiply(tempRowSpan);
if (this.Compand)
{
@@ -261,7 +261,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
ResizeKernel window = this.horizontalKernelMap.Kernels[x - startX];
Unsafe.Add(ref firstPassRow, x) =
- window.ConvolvePremultipliedExpandedRows(tempRowSpan, sourceX);
+ window.ConvolveExpandRows(tempRowSpan, sourceX).UnPremultiply();
}
}
else
@@ -270,7 +270,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
ResizeKernel window = this.horizontalKernelMap.Kernels[x - startX];
Unsafe.Add(ref firstPassRow, x) =
- window.ConvolvePremultipliedRows(tempRowSpan, sourceX);
+ window.ConvolveRows(tempRowSpan, sourceX);
}
}
}
diff --git a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs
index 51b407f86..3f41a9955 100644
--- a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs
+++ b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs
@@ -54,6 +54,21 @@ namespace SixLabors.ImageSharp.Tests.Helpers
Assert.Equal(expected, source, new ApproximateFloatComparer(1e-6f));
}
+ [Theory]
+ [InlineData(0)]
+ [InlineData(1)]
+ [InlineData(30)]
+ public void UnPremultiply_VectorSpan(int length)
+ {
+ var rnd = new Random(42);
+ Vector4[] source = rnd.GenerateRandomVectorArray(length, 0, 1);
+ Vector4[] expected = source.Select(v => v.UnPremultiply()).ToArray();
+
+ ImageMaths.UnPremultiply(source);
+
+ Assert.Equal(expected, source, new ApproximateFloatComparer(1e-6f));
+ }
+
// TODO: We need to test all ImageMaths methods!
}
}
\ No newline at end of file