diff --git a/src/ImageSharp/Common/Helpers/DebugGuard.cs b/src/ImageSharp/Common/Helpers/DebugGuard.cs index 096f96f04b..f6941fc6fc 100644 --- a/src/ImageSharp/Common/Helpers/DebugGuard.cs +++ b/src/ImageSharp/Common/Helpers/DebugGuard.cs @@ -170,6 +170,7 @@ namespace ImageSharp /// /// is true /// + [Conditional("DEBUG")] public static void MustBeSameSized(Span target, Span other, string parameterName) where T : struct { @@ -189,6 +190,7 @@ namespace ImageSharp /// /// is true /// + [Conditional("DEBUG")] public static void MustBeSizedAtLeast(Span target, Span minSpan, string parameterName) where T : struct { diff --git a/src/ImageSharp/Common/Helpers/Guard.cs b/src/ImageSharp/Common/Helpers/Guard.cs index cf307e9365..a4b392fcf1 100644 --- a/src/ImageSharp/Common/Helpers/Guard.cs +++ b/src/ImageSharp/Common/Helpers/Guard.cs @@ -230,5 +230,24 @@ namespace ImageSharp throw new ArgumentException(message, parameterName); } } + + /// + /// Verifies, that the `target` span has the length of 'minSpan', or longer. + /// + /// The element type of the spans + /// The target span. + /// The minimum length. + /// The name of the parameter that is to be checked. + /// + /// is true + /// + public static void MustBeSizedAtLeast(Span target, int minLength, string parameterName) + where T : struct + { + if (target.Length < minLength) + { + throw new ArgumentException($"Span-s must be at least of length {minLength}!", parameterName); + } + } } } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index b92b86b410..993a11232a 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -30,6 +30,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromVector4(Span sourceVectors, Span destColors, int count) { + Guard.MustBeSizedAtLeast(sourceVectors, count, nameof(sourceVectors)); + Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + ref Vector4 sourceRef = ref sourceVectors.DangerousGetPinnableReference(); ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); @@ -49,6 +52,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void ToVector4(Span sourceColors, Span destVectors, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destVectors, count, nameof(destVectors)); + ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference(); ref Vector4 destRef = ref destVectors.DangerousGetPinnableReference(); @@ -68,6 +74,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromXyzBytes(Span sourceBytes, Span destColors, int count) { + Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes)); + Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); @@ -91,6 +100,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void ToXyzBytes(Span sourceColors, Span destBytes, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destBytes, count * 3, nameof(destBytes)); + ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference(); for (int i = 0; i < count; i++) @@ -108,6 +120,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromXyzwBytes(Span sourceBytes, Span destColors, int count) { + Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes)); + Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); @@ -131,6 +146,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void ToXyzwBytes(Span sourceColors, Span destBytes, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destBytes, count * 4, nameof(destBytes)); + ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference(); for (int i = 0; i < count; i++) @@ -148,6 +166,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromZyxBytes(Span sourceBytes, Span destColors, int count) { + Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes)); + Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); @@ -171,6 +192,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void ToZyxBytes(Span sourceColors, Span destBytes, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destBytes, count * 3, nameof(destBytes)); + ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference(); for (int i = 0; i < count; i++) @@ -188,6 +212,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromZyxwBytes(Span sourceBytes, Span destColors, int count) { + Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes)); + Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); @@ -211,6 +238,9 @@ namespace ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void ToZyxwBytes(Span sourceColors, Span destBytes, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destBytes, count * 4, nameof(destBytes)); + ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference(); for (int i = 0; i < count; i++) diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index 168787ba7c..2ba663603e 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -93,6 +93,9 @@ namespace ImageSharp /// internal override void ToVector4(Span sourceColors, Span destVectors, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destVectors, count, nameof(destVectors)); + if (count < 256 || !Vector.IsHardwareAccelerated) { // Doesn't worth to bother with SIMD: @@ -120,6 +123,9 @@ namespace ImageSharp /// internal override void PackFromXyzBytes(Span sourceBytes, Span destColors, int count) { + Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes)); + Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + ref RGB24 sourceRef = ref Unsafe.As(ref sourceBytes.DangerousGetPinnableReference()); ref Rgba32 destRef = ref destColors.DangerousGetPinnableReference(); @@ -136,6 +142,9 @@ namespace ImageSharp /// internal override void ToXyzBytes(Span sourceColors, Span destBytes, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destBytes, count * 3, nameof(destBytes)); + ref Rgba32 sourceRef = ref sourceColors.DangerousGetPinnableReference(); ref RGB24 destRef = ref Unsafe.As(ref destBytes.DangerousGetPinnableReference()); @@ -151,18 +160,27 @@ namespace ImageSharp /// internal override unsafe void PackFromXyzwBytes(Span sourceBytes, Span destColors, int count) { + Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes)); + Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + SpanHelper.Copy(sourceBytes, destColors.AsBytes(), count * sizeof(Rgba32)); } /// internal override unsafe void ToXyzwBytes(Span sourceColors, Span destBytes, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destBytes, count * 4, nameof(destBytes)); + SpanHelper.Copy(sourceColors.AsBytes(), destBytes, count * sizeof(Rgba32)); } /// internal override void PackFromZyxBytes(Span sourceBytes, Span destColors, int count) { + Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes)); + Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + ref RGB24 sourceRef = ref Unsafe.As(ref sourceBytes.DangerousGetPinnableReference()); ref Rgba32 destRef = ref destColors.DangerousGetPinnableReference(); @@ -179,6 +197,9 @@ namespace ImageSharp /// internal override void ToZyxBytes(Span sourceColors, Span destBytes, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destBytes, count * 3, nameof(destBytes)); + ref Rgba32 sourceRef = ref sourceColors.DangerousGetPinnableReference(); ref RGB24 destRef = ref Unsafe.As(ref destBytes.DangerousGetPinnableReference()); @@ -194,6 +215,9 @@ namespace ImageSharp /// internal override void PackFromZyxwBytes(Span sourceBytes, Span destColors, int count) { + Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes)); + Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + ref RGBA32 sourceRef = ref Unsafe.As(ref sourceBytes.DangerousGetPinnableReference()); ref Rgba32 destRef = ref destColors.DangerousGetPinnableReference(); @@ -209,6 +233,9 @@ namespace ImageSharp /// internal override void ToZyxwBytes(Span sourceColors, Span destBytes, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destBytes, count * 4, nameof(destBytes)); + ref Rgba32 sourceRef = ref sourceColors.DangerousGetPinnableReference(); ref RGBA32 destRef = ref Unsafe.As(ref destBytes.DangerousGetPinnableReference()); diff --git a/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs index 5c7ee17ca7..ac25b7f149 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs @@ -23,6 +23,9 @@ namespace ImageSharp.PixelFormats /// internal override unsafe void ToVector4(Span sourceColors, Span destVectors, int count) { + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destVectors, count, nameof(destVectors)); + SpanHelper.Copy(sourceColors.AsBytes(), destVectors.AsBytes(), count * sizeof(Vector4)); } }