Browse Source

Utils FTW

js/color-alpha-handling
James Jackson-South 6 years ago
parent
commit
f66fe45ac1
  1. 12
      src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs
  2. 2
      src/ImageSharp/Common/Helpers/Vector4Utils.cs
  3. 4
      src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs
  4. 2
      src/ImageSharp/Processing/Processors/Filters/FilterProcessor{TPixel}.cs
  5. 6
      src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs
  6. 6
      src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtils.cs
  7. 6
      src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs
  8. 2
      tests/ImageSharp.Benchmarks/Color/Bulk/PremultiplyVector4.cs
  9. 2
      tests/ImageSharp.Benchmarks/Color/Bulk/UnPremultiplyVector4.cs
  10. 8
      tests/ImageSharp.Tests/Helpers/Vector4UtilsTests.cs
  11. 24
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

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

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

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

@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp
/// <summary> /// <summary>
/// Utility methods for the <see cref="Vector4"/> struct. /// Utility methods for the <see cref="Vector4"/> struct.
/// </summary> /// </summary>
internal static class Vector4Utilities internal static class Vector4Utils
{ {
private const int BlendAlphaControl = 0b_10_00_10_00; private const int BlendAlphaControl = 0b_10_00_10_00;
private const int ShuffleAlphaControl = 0b_11_11_11_11; private const int ShuffleAlphaControl = 0b_11_11_11_11;

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

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

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); Span<TPixel> rowSpan = this.source.GetPixelRowSpan(y).Slice(this.startX, span.Length);
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, rowSpan, span); PixelOperations<TPixel>.Instance.ToVector4(this.configuration, rowSpan, span);
Vector4Utilities.Transform(span, ref Unsafe.AsRef(this.matrix)); Vector4Utils.Transform(span, ref Unsafe.AsRef(this.matrix));
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, span, rowSpan); PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, span, rowSpan);
} }

6
src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs

@ -80,8 +80,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
return; return;
} }
int yRadius = LinearTransformUtilities.GetSamplingRadius(in sampler, source.Height, destination.Height); int yRadius = LinearTransformUtils.GetSamplingRadius(in sampler, source.Height, destination.Height);
int xRadius = LinearTransformUtilities.GetSamplingRadius(in sampler, source.Width, destination.Width); int xRadius = LinearTransformUtils.GetSamplingRadius(in sampler, source.Width, destination.Width);
var radialExtents = new Vector2(xRadius, yRadius); var radialExtents = new Vector2(xRadius, yRadius);
int yLength = (yRadius * 2) + 1; int yLength = (yRadius * 2) + 1;
int xLength = (xRadius * 2) + 1; int xLength = (xRadius * 2) + 1;
@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Use the single precision position to calculate correct bounding pixels // Use the single precision position to calculate correct bounding pixels
// otherwise we get rogue pixels outside of the bounds. // otherwise we get rogue pixels outside of the bounds.
var point = Vector2.Transform(new Vector2(x, y), this.matrix); var point = Vector2.Transform(new Vector2(x, y), this.matrix);
LinearTransformUtilities.Convolve( LinearTransformUtils.Convolve(
in this.sampler, in this.sampler,
point, point,
sourceBuffer, sourceBuffer,

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

@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// <summary> /// <summary>
/// Utility methods for affine and projective transforms. /// Utility methods for affine and projective transforms.
/// </summary> /// </summary>
internal static class LinearTransformUtilities internal static class LinearTransformUtils
{ {
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
internal static int GetSamplingRadius<TResampler>(in TResampler sampler, int sourceSize, int destinationSize) internal static int GetSamplingRadius<TResampler>(in TResampler sampler, int sourceSize, int destinationSize)
@ -78,13 +78,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Values are first premultiplied to prevent darkening of edge pixels. // Values are first premultiplied to prevent darkening of edge pixels.
var current = sourcePixels[x, y].ToVector4(); var current = sourcePixels[x, y].ToVector4();
Vector4Utilities.Premultiply(ref current); Vector4Utils.Premultiply(ref current);
sum += current * xWeight * yWeight; sum += current * xWeight * yWeight;
} }
} }
// Reverse the premultiplication // Reverse the premultiplication
Vector4Utilities.UnPremultiply(ref sum); Vector4Utils.UnPremultiply(ref sum);
targetRow[column] = sum; targetRow[column] = sum;
} }

6
src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs

@ -80,8 +80,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
return; return;
} }
int yRadius = LinearTransformUtilities.GetSamplingRadius(in sampler, source.Height, destination.Height); int yRadius = LinearTransformUtils.GetSamplingRadius(in sampler, source.Height, destination.Height);
int xRadius = LinearTransformUtilities.GetSamplingRadius(in sampler, source.Width, destination.Width); int xRadius = LinearTransformUtils.GetSamplingRadius(in sampler, source.Width, destination.Width);
var radialExtents = new Vector2(xRadius, yRadius); var radialExtents = new Vector2(xRadius, yRadius);
int yLength = (yRadius * 2) + 1; int yLength = (yRadius * 2) + 1;
int xLength = (xRadius * 2) + 1; int xLength = (xRadius * 2) + 1;
@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Use the single precision position to calculate correct bounding pixels // Use the single precision position to calculate correct bounding pixels
// otherwise we get rogue pixels outside of the bounds. // otherwise we get rogue pixels outside of the bounds.
Vector2 point = TransformUtilities.ProjectiveTransform2D(x, y, this.matrix); Vector2 point = TransformUtilities.ProjectiveTransform2D(x, y, this.matrix);
LinearTransformUtilities.Convolve( LinearTransformUtils.Convolve(
in this.sampler, in this.sampler,
point, point,
sourceBuffer, sourceBuffer,

2
tests/ImageSharp.Benchmarks/Color/Bulk/PremultiplyVector4.cs

@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk
[Benchmark] [Benchmark]
public void Premultiply() public void Premultiply()
{ {
Vector4Utilities.Premultiply(Vectors); Vector4Utils.Premultiply(Vectors);
} }
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]

2
tests/ImageSharp.Benchmarks/Color/Bulk/UnPremultiplyVector4.cs

@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk
[Benchmark] [Benchmark]
public void UnPremultiply() public void UnPremultiply()
{ {
Vector4Utilities.UnPremultiply(Vectors); Vector4Utils.UnPremultiply(Vectors);
} }
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]

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

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

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

@ -197,7 +197,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{ {
if (this.HasUnassociatedAlpha) if (this.HasUnassociatedAlpha)
{ {
Vector4Utilities.Premultiply(ref v); Vector4Utils.Premultiply(ref v);
} }
} }
@ -205,7 +205,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{ {
if (this.HasUnassociatedAlpha) if (this.HasUnassociatedAlpha)
{ {
Vector4Utilities.UnPremultiply(ref v); Vector4Utils.UnPremultiply(ref v);
} }
} }
@ -232,7 +232,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{ {
if (this.HasUnassociatedAlpha) if (this.HasUnassociatedAlpha)
{ {
Vector4Utilities.Premultiply(ref v); Vector4Utils.Premultiply(ref v);
} }
} }
@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{ {
if (this.HasUnassociatedAlpha) if (this.HasUnassociatedAlpha)
{ {
Vector4Utilities.UnPremultiply(ref v); Vector4Utils.UnPremultiply(ref v);
} }
} }
@ -273,7 +273,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
if (this.HasUnassociatedAlpha) if (this.HasUnassociatedAlpha)
{ {
Vector4Utilities.Premultiply(ref v); Vector4Utils.Premultiply(ref v);
} }
} }
@ -281,7 +281,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{ {
if (this.HasUnassociatedAlpha) if (this.HasUnassociatedAlpha)
{ {
Vector4Utilities.UnPremultiply(ref v); Vector4Utils.UnPremultiply(ref v);
} }
SRgbCompanding.Compress(ref v); SRgbCompanding.Compress(ref v);
@ -394,12 +394,12 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{ {
void SourceAction(ref Vector4 v) void SourceAction(ref Vector4 v)
{ {
Vector4Utilities.UnPremultiply(ref v); Vector4Utils.UnPremultiply(ref v);
} }
void ExpectedAction(ref Vector4 v) void ExpectedAction(ref Vector4 v)
{ {
Vector4Utilities.Premultiply(ref v); Vector4Utils.Premultiply(ref v);
} }
TPixel[] source = CreatePixelTestData(count, (ref Vector4 v) => SourceAction(ref v)); TPixel[] source = CreatePixelTestData(count, (ref Vector4 v) => SourceAction(ref v));
@ -417,12 +417,12 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{ {
void SourceAction(ref Vector4 v) void SourceAction(ref Vector4 v)
{ {
Vector4Utilities.UnPremultiply(ref v); Vector4Utils.UnPremultiply(ref v);
} }
void ExpectedAction(ref Vector4 v) void ExpectedAction(ref Vector4 v)
{ {
Vector4Utilities.Premultiply(ref v); Vector4Utils.Premultiply(ref v);
} }
TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => SourceAction(ref v)); TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => SourceAction(ref v));
@ -444,14 +444,14 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{ {
void SourceAction(ref Vector4 v) void SourceAction(ref Vector4 v)
{ {
Vector4Utilities.UnPremultiply(ref v); Vector4Utils.UnPremultiply(ref v);
SRgbCompanding.Compress(ref v); SRgbCompanding.Compress(ref v);
} }
void ExpectedAction(ref Vector4 v) void ExpectedAction(ref Vector4 v)
{ {
SRgbCompanding.Expand(ref v); SRgbCompanding.Expand(ref v);
Vector4Utilities.Premultiply(ref v); Vector4Utils.Premultiply(ref v);
} }
TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => SourceAction(ref v)); TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => SourceAction(ref v));

Loading…
Cancel
Save