From c1eaf6e5da94e190ef3ac1f8001257e142c8ea63 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 27 Feb 2018 18:42:31 -0800 Subject: [PATCH 01/20] Update System.Memory --- .../Advanced/AdvancedImageExtensions.cs | 3 +- src/ImageSharp/Common/Extensions/SimdUtils.cs | 8 ++--- .../Formats/Jpeg/Common/Block8x8.cs | 5 +-- .../Formats/Jpeg/Common/Block8x8F.cs | 4 +-- .../JpegColorConverter.FromYCbCrSimd.cs | 9 ++--- .../JpegColorConverter.FromYCbCrSimdAvx2.cs | 9 ++--- .../ColorConverters/JpegColorConverter.cs | 2 +- .../Formats/Jpeg/Common/GenericBlock8x8.cs | 2 +- .../Formats/Png/Filters/AverageFilter.cs | 11 ++++--- .../Formats/Png/Filters/PaethFilter.cs | 11 ++++--- .../Formats/Png/Filters/SubFilter.cs | 7 ++-- .../Formats/Png/Filters/UpFilter.cs | 11 ++++--- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 4 +-- src/ImageSharp/ImageSharp.csproj | 6 ++-- src/ImageSharp/Memory/BufferExtensions.cs | 3 +- src/ImageSharp/Memory/SpanHelper.cs | 7 ++-- .../PixelOperations{TPixel}.Generated.cs | 33 ++++++++++--------- .../Rgba32.PixelOperations.Generated.cs | 26 +++++++-------- .../PixelFormats/PixelOperations{TPixel}.cs | 9 ++--- .../PixelFormats/Rgba32.PixelOperations.cs | 4 +-- .../Processors/Transforms/WeightsWindow.cs | 6 ++-- .../ImageSharp.Benchmarks.csproj | 4 +-- .../ImageSharp.Tests/ImageSharp.Tests.csproj | 3 +- .../Memory/ArrayPoolMemoryManagerTests.cs | 2 +- .../ImageSharp.Tests/Memory/Buffer2DTests.cs | 4 +-- .../Memory/BufferTestSuite.cs | 7 ++-- .../Memory/SpanUtilityTests.cs | 20 +++++------ 27 files changed, 116 insertions(+), 104 deletions(-) diff --git a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs index 612ced5d8d..24d2dd4cc4 100644 --- a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs +++ b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -148,6 +149,6 @@ namespace SixLabors.ImageSharp.Advanced /// A reference to the element. private static ref TPixel DangerousGetPinnableReferenceToPixelBuffer(IPixelSource source) where TPixel : struct, IPixel - => ref source.PixelBuffer.Span.DangerousGetPinnableReference(); + => ref MemoryMarshal.GetReference(source.PixelBuffer.Span); } } diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.cs b/src/ImageSharp/Common/Extensions/SimdUtils.cs index 7f46b7a847..7b77fefcac 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.cs +++ b/src/ImageSharp/Common/Extensions/SimdUtils.cs @@ -76,8 +76,8 @@ namespace SixLabors.ImageSharp return; } - ref Vector srcBase = ref Unsafe.As>(ref source.DangerousGetPinnableReference()); - ref Octet.OfByte destBase = ref Unsafe.As(ref dest.DangerousGetPinnableReference()); + ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); + ref Octet.OfByte destBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); int n = source.Length / 8; Vector magick = new Vector(32768.0f); @@ -117,8 +117,8 @@ namespace SixLabors.ImageSharp return; } - ref Vector srcBase = ref Unsafe.As>(ref source.DangerousGetPinnableReference()); - ref Octet.OfByte destBase = ref Unsafe.As(ref dest.DangerousGetPinnableReference()); + ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); + ref Octet.OfByte destBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); int n = source.Length / 8; Vector magick = new Vector(32768.0f); diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs b/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs index 1066cfa808..11a456ef9b 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; namespace SixLabors.ImageSharp.Formats.Jpeg.Common @@ -34,7 +35,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common public Block8x8(Span coefficients) { ref byte selfRef = ref Unsafe.As(ref this); - ref byte sourceRef = ref coefficients.NonPortableCast().DangerousGetPinnableReference(); + ref byte sourceRef = ref MemoryMarshal.GetReference(coefficients.NonPortableCast()); Unsafe.CopyBlock(ref selfRef, ref sourceRef, Size * sizeof(short)); } @@ -204,7 +205,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common public void CopyTo(Span destination) { ref byte selfRef = ref Unsafe.As(ref this); - ref byte destRef = ref destination.NonPortableCast().DangerousGetPinnableReference(); + ref byte destRef = ref MemoryMarshal.GetReference(destination.NonPortableCast()); Unsafe.CopyBlock(ref destRef, ref selfRef, Size * sizeof(short)); } diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs index 2dd42288cb..f45b5df4eb 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs @@ -163,7 +163,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common [MethodImpl(MethodImplOptions.AggressiveInlining)] public void LoadFrom(Span source) { - ref byte s = ref Unsafe.As(ref source.DangerousGetPinnableReference()); + ref byte s = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); ref byte d = ref Unsafe.As(ref this); Unsafe.CopyBlock(ref d, ref s, Size * sizeof(float)); @@ -203,7 +203,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common [MethodImpl(MethodImplOptions.AggressiveInlining)] public void CopyTo(Span dest) { - ref byte d = ref Unsafe.As(ref dest.DangerousGetPinnableReference()); + ref byte d = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); ref byte s = ref Unsafe.As(ref this); Unsafe.CopyBlock(ref d, ref s, Size * sizeof(float)); diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs index a7fc136afe..2f214f88a9 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs @@ -4,6 +4,7 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Common.Tuples; namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters @@ -37,14 +38,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters DebugGuard.IsTrue(result.Length % 8 == 0, nameof(result), "result.Length should be divisable by 8!"); ref Vector4Pair yBase = - ref Unsafe.As(ref values.Component0.DangerousGetPinnableReference()); + ref Unsafe.As(ref MemoryMarshal.GetReference(values.Component0)); ref Vector4Pair cbBase = - ref Unsafe.As(ref values.Component1.DangerousGetPinnableReference()); + ref Unsafe.As(ref MemoryMarshal.GetReference(values.Component1)); ref Vector4Pair crBase = - ref Unsafe.As(ref values.Component2.DangerousGetPinnableReference()); + ref Unsafe.As(ref MemoryMarshal.GetReference(values.Component2)); ref Vector4Octet resultBase = - ref Unsafe.As(ref result.DangerousGetPinnableReference()); + ref Unsafe.As(ref MemoryMarshal.GetReference(result)); var chromaOffset = new Vector4(-128f); diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs index 77e74c32b0..f8a4514221 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs @@ -4,6 +4,7 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Common.Tuples; // ReSharper disable ImpureMethodCallOnReadonlyValueField @@ -46,14 +47,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters } ref Vector yBase = - ref Unsafe.As>(ref values.Component0.DangerousGetPinnableReference()); + ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); ref Vector cbBase = - ref Unsafe.As>(ref values.Component1.DangerousGetPinnableReference()); + ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); ref Vector crBase = - ref Unsafe.As>(ref values.Component2.DangerousGetPinnableReference()); + ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); ref Vector4Octet resultBase = - ref Unsafe.As(ref result.DangerousGetPinnableReference()); + ref Unsafe.As(ref MemoryMarshal.GetReference(result)); var chromaOffset = new Vector(-128f); diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs index e0abc3215c..23c2071cc6 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters /// /// A stack-only struct to reference the input buffers using -s. /// - public struct ComponentValues + public ref struct ComponentValues { /// /// The component count diff --git a/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.cs b/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.cs index e20e850d74..09a7eb73aa 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.cs @@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common ref byte blockStart = ref Unsafe.As, byte>(ref this); ref byte imageStart = ref Unsafe.As( - ref Unsafe.Add(ref source.GetRowSpan(sourceY).DangerousGetPinnableReference(), sourceX)); + ref Unsafe.Add(ref MemoryMarshal.GetReference(source.GetRowSpan(sourceY)), sourceX)); int blockRowSizeInBytes = 8 * Unsafe.SizeOf(); int imageRowSizeInBytes = source.Width * Unsafe.SizeOf(); diff --git a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs index 0d3a65dbd8..de62d47029 100644 --- a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -24,8 +25,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters { DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline)); - ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference(); - ref byte prevBaseRef = ref previousScanline.DangerousGetPinnableReference(); + ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); + ref byte prevBaseRef = ref MemoryMarshal.GetReference(previousScanline); // Average(x) + floor((Raw(x-bpp)+Prior(x))/2) for (int x = 1; x < scanline.Length; x++) @@ -60,9 +61,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline)); DebugGuard.MustBeSizedAtLeast(result, scanline, nameof(result)); - ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference(); - ref byte prevBaseRef = ref previousScanline.DangerousGetPinnableReference(); - ref byte resultBaseRef = ref result.DangerousGetPinnableReference(); + ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); + ref byte prevBaseRef = ref MemoryMarshal.GetReference(previousScanline); + ref byte resultBaseRef = ref MemoryMarshal.GetReference(result); sum = 0; // Average(x) = Raw(x) - floor((Raw(x-bpp)+Prior(x))/2) diff --git a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs index 08e4938804..7e05d736f9 100644 --- a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -25,8 +26,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters { DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline)); - ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference(); - ref byte prevBaseRef = ref previousScanline.DangerousGetPinnableReference(); + ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); + ref byte prevBaseRef = ref MemoryMarshal.GetReference(previousScanline); // Paeth(x) + PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp)) int offset = bytesPerPixel + 1; @@ -61,9 +62,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline)); DebugGuard.MustBeSizedAtLeast(result, scanline, nameof(result)); - ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference(); - ref byte prevBaseRef = ref previousScanline.DangerousGetPinnableReference(); - ref byte resultBaseRef = ref result.DangerousGetPinnableReference(); + ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); + ref byte prevBaseRef = ref MemoryMarshal.GetReference(previousScanline); + ref byte resultBaseRef = ref MemoryMarshal.GetReference(result); sum = 0; // Paeth(x) = Raw(x) - PaethPredictor(Raw(x-bpp), Prior(x), Prior(x - bpp)) diff --git a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs index 5ee8664400..c0db7da935 100644 --- a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -21,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Decode(Span scanline, int bytesPerPixel) { - ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference(); + ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); // Sub(x) + Raw(x-bpp) for (int x = 1; x < scanline.Length; x++) @@ -52,8 +53,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters { DebugGuard.MustBeSizedAtLeast(result, scanline, nameof(result)); - ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference(); - ref byte resultBaseRef = ref result.DangerousGetPinnableReference(); + ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); + ref byte resultBaseRef = ref MemoryMarshal.GetReference(result); sum = 0; // Sub(x) = Raw(x) - Raw(x-bpp) diff --git a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs index 6e8f780e5c..81c063ea9e 100644 --- a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -23,8 +24,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters { DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline)); - ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference(); - ref byte prevBaseRef = ref previousScanline.DangerousGetPinnableReference(); + ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); + ref byte prevBaseRef = ref MemoryMarshal.GetReference(previousScanline); // Up(x) + Prior(x) for (int x = 1; x < scanline.Length; x++) @@ -48,9 +49,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline)); DebugGuard.MustBeSizedAtLeast(result, scanline, nameof(result)); - ref byte scanBaseRef = ref scanline.DangerousGetPinnableReference(); - ref byte prevBaseRef = ref previousScanline.DangerousGetPinnableReference(); - ref byte resultBaseRef = ref result.DangerousGetPinnableReference(); + ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); + ref byte prevBaseRef = ref MemoryMarshal.GetReference(previousScanline); + ref byte resultBaseRef = ref MemoryMarshal.GetReference(result); sum = 0; // Up(x) = Raw(x) - Prior(x) diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index fbff0ae1d9..c1dccdcafc 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -701,7 +701,7 @@ namespace SixLabors.ImageSharp.Formats.Png Span rowSpan = pixels.GetPixelRowSpan(this.currentRow); // Trim the first marker byte from the buffer - var scanlineBuffer = new Span(defilteredScanline, 1); + var scanlineBuffer = new Span(defilteredScanline, 1, defilteredScanline.Length - 1); switch (this.pngColorType) { @@ -932,7 +932,7 @@ namespace SixLabors.ImageSharp.Formats.Png var color = default(TPixel); // Trim the first marker byte from the buffer - var scanlineBuffer = new Span(defilteredScanline, 1); + var scanlineBuffer = new Span(defilteredScanline, 1, defilteredScanline.Length - 1); switch (this.pngColorType) { diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index cb0539f786..86a0ab7ea5 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -29,6 +29,7 @@ portable True IOperation + 7.2 @@ -40,12 +41,11 @@ All - - + + - diff --git a/src/ImageSharp/Memory/BufferExtensions.cs b/src/ImageSharp/Memory/BufferExtensions.cs index 919a6ef345..dd3114c21c 100644 --- a/src/ImageSharp/Memory/BufferExtensions.cs +++ b/src/ImageSharp/Memory/BufferExtensions.cs @@ -4,6 +4,7 @@ using System; using System.IO; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.Memory { @@ -53,7 +54,7 @@ namespace SixLabors.ImageSharp.Memory public static ref T DangerousGetPinnableReference(this IBuffer buffer) where T : struct => - ref buffer.Span.DangerousGetPinnableReference(); + ref MemoryMarshal.GetReference(buffer.Span); public static void Read(this Stream stream, IManagedByteBuffer buffer) { diff --git a/src/ImageSharp/Memory/SpanHelper.cs b/src/ImageSharp/Memory/SpanHelper.cs index 73bc5f55d8..0c327484a0 100644 --- a/src/ImageSharp/Memory/SpanHelper.cs +++ b/src/ImageSharp/Memory/SpanHelper.cs @@ -4,6 +4,7 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.Memory { @@ -22,7 +23,7 @@ namespace SixLabors.ImageSharp.Memory public static ref Vector FetchVector(this Span span) where T : struct { - return ref Unsafe.As>(ref span.DangerousGetPinnableReference()); + return ref Unsafe.As>(ref MemoryMarshal.GetReference(span)); } /// @@ -39,8 +40,8 @@ namespace SixLabors.ImageSharp.Memory DebugGuard.MustBeLessThanOrEqualTo(count, source.Length, nameof(count)); DebugGuard.MustBeLessThanOrEqualTo(count, destination.Length, nameof(count)); - ref byte srcRef = ref Unsafe.As(ref source.DangerousGetPinnableReference()); - ref byte destRef = ref Unsafe.As(ref destination.DangerousGetPinnableReference()); + ref byte srcRef = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); + ref byte destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destination)); int byteCount = Unsafe.SizeOf() * count; diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs index 9553ec82d6..964fa98f95 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs @@ -6,6 +6,7 @@ namespace SixLabors.ImageSharp.PixelFormats { using System; using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; public partial class PixelOperations { @@ -20,8 +21,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgba32 sourceRef = ref source.DangerousGetPinnableReference(); - ref TPixel destRef = ref destPixels.DangerousGetPinnableReference(); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(source); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); Rgba32 rgba = new Rgba32(0, 0, 0, 255); @@ -57,8 +58,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); - ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference(); - ref Rgba32 destBaseRef = ref dest.DangerousGetPinnableReference(); + ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destBaseRef = ref MemoryMarshal.GetReference(dest); for (int i = 0; i < count; i++) { @@ -91,8 +92,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Bgra32 sourceRef = ref source.DangerousGetPinnableReference(); - ref TPixel destRef = ref destPixels.DangerousGetPinnableReference(); + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); Rgba32 rgba = new Rgba32(0, 0, 0, 255); @@ -128,8 +129,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); - ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference(); - ref Bgra32 destBaseRef = ref dest.DangerousGetPinnableReference(); + ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destBaseRef = ref MemoryMarshal.GetReference(dest); for (int i = 0; i < count; i++) { @@ -162,8 +163,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgb24 sourceRef = ref source.DangerousGetPinnableReference(); - ref TPixel destRef = ref destPixels.DangerousGetPinnableReference(); + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); Rgba32 rgba = new Rgba32(0, 0, 0, 255); @@ -199,8 +200,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); - ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference(); - ref Rgb24 destBaseRef = ref dest.DangerousGetPinnableReference(); + ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destBaseRef = ref MemoryMarshal.GetReference(dest); for (int i = 0; i < count; i++) { @@ -233,8 +234,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Bgr24 sourceRef = ref source.DangerousGetPinnableReference(); - ref TPixel destRef = ref destPixels.DangerousGetPinnableReference(); + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); Rgba32 rgba = new Rgba32(0, 0, 0, 255); @@ -270,8 +271,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); - ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference(); - ref Bgr24 destBaseRef = ref dest.DangerousGetPinnableReference(); + ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destBaseRef = ref MemoryMarshal.GetReference(dest); for (int i = 0; i < count; i++) { diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs index 659e702281..43060539dc 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs @@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp { using System; using System.Runtime.CompilerServices; - + using System.Runtime.InteropServices; using SixLabors.ImageSharp.PixelFormats; /// @@ -22,8 +22,8 @@ namespace SixLabors.ImageSharp { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgb24 sourceRef = ref source.DangerousGetPinnableReference(); - ref Rgba32 destRef = ref destPixels.DangerousGetPinnableReference(); + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { @@ -38,8 +38,8 @@ namespace SixLabors.ImageSharp { GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); - ref Rgba32 sourceRef = ref sourcePixels.DangerousGetPinnableReference(); - ref Rgb24 destRef = ref dest.DangerousGetPinnableReference(); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(dest); for (int i = 0; i < count; i++) { @@ -54,8 +54,8 @@ namespace SixLabors.ImageSharp { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Bgr24 sourceRef = ref source.DangerousGetPinnableReference(); - ref Rgba32 destRef = ref destPixels.DangerousGetPinnableReference(); + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { @@ -70,8 +70,8 @@ namespace SixLabors.ImageSharp { GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); - ref Rgba32 sourceRef = ref sourcePixels.DangerousGetPinnableReference(); - ref Bgr24 destRef = ref dest.DangerousGetPinnableReference(); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(dest); for (int i = 0; i < count; i++) { @@ -86,8 +86,8 @@ namespace SixLabors.ImageSharp { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Bgra32 sourceRef = ref source.DangerousGetPinnableReference(); - ref Rgba32 destRef = ref destPixels.DangerousGetPinnableReference(); + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { @@ -102,8 +102,8 @@ namespace SixLabors.ImageSharp { GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); - ref Rgba32 sourceRef = ref sourcePixels.DangerousGetPinnableReference(); - ref Bgra32 destRef = ref dest.DangerousGetPinnableReference(); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(dest); for (int i = 0; i < count; i++) { diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 4f879fbdc7..6f79752406 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -4,6 +4,7 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.PixelFormats { @@ -30,8 +31,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(sourceVectors, nameof(sourceVectors), destColors, nameof(destColors), count); - ref Vector4 sourceRef = ref sourceVectors.DangerousGetPinnableReference(); - ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); + ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); + ref TPixel destRef = ref MemoryMarshal.GetReference(destColors); for (int i = 0; i < count; i++) { @@ -51,8 +52,8 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(sourceColors, nameof(sourceColors), destVectors, nameof(destVectors), count); - ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference(); - ref Vector4 destRef = ref destVectors.DangerousGetPinnableReference(); + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); + ref Vector4 destRef = ref MemoryMarshal.GetReference(destVectors); for (int i = 0; i < count; i++) { diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index 552ac0a018..89a4aba264 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -57,8 +57,8 @@ namespace SixLabors.ImageSharp int unpackedRawCount = count * 4; - ref uint sourceBase = ref Unsafe.As(ref sourceColors.DangerousGetPinnableReference()); - ref UnpackedRGBA destBaseAsUnpacked = ref Unsafe.As(ref destVectors.DangerousGetPinnableReference()); + ref uint sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference(sourceColors)); + ref UnpackedRGBA destBaseAsUnpacked = ref Unsafe.As(ref MemoryMarshal.GetReference(destVectors)); ref Vector destBaseAsUInt = ref Unsafe.As>(ref destBaseAsUnpacked); ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsUnpacked); diff --git a/src/ImageSharp/Processing/Processors/Transforms/WeightsWindow.cs b/src/ImageSharp/Processing/Processors/Transforms/WeightsWindow.cs index 399b3db842..26aaec502f 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/WeightsWindow.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/WeightsWindow.cs @@ -4,7 +4,7 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; - +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Processing.Processors @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Processing.Processors { ref float horizontalValues = ref this.GetStartReference(); int left = this.Left; - ref Vector4 vecPtr = ref Unsafe.Add(ref rowSpan.DangerousGetPinnableReference(), left + sourceX); + ref Vector4 vecPtr = ref Unsafe.Add(ref MemoryMarshal.GetReference(rowSpan), left + sourceX); // Destination color components Vector4 result = Vector4.Zero; @@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.Processing.Processors { ref float horizontalValues = ref this.GetStartReference(); int left = this.Left; - ref Vector4 vecPtr = ref Unsafe.Add(ref rowSpan.DangerousGetPinnableReference(), left + sourceX); + ref Vector4 vecPtr = ref Unsafe.Add(ref MemoryMarshal.GetReference(rowSpan), left + sourceX); // Destination color components Vector4 result = Vector4.Zero; diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj index 2e0b935155..021b9ead74 100644 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -19,9 +19,7 @@ - - - + diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 16f062c6ef..d6ea4a130f 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -16,7 +16,8 @@ - + + diff --git a/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs b/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs index a199bb319d..c73ce96313 100644 --- a/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs +++ b/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs @@ -133,7 +133,7 @@ namespace SixLabors.ImageSharp.Tests.Memory public void ReleaseRetainedResources_ReplacesInnerArrayPool(bool keepBufferAlive) { IBuffer buffer = this.MemoryManager.Allocate(32); - ref int ptrToPrev0 = ref buffer.Span.DangerousGetPinnableReference(); + ref int ptrToPrev0 = ref MemoryMarshal.GetReference(buffer.Span); if (!keepBufferAlive) { diff --git a/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs b/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs index 565e06572b..82163d2bb4 100644 --- a/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs +++ b/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs @@ -5,7 +5,7 @@ namespace SixLabors.ImageSharp.Tests.Memory { using System; using System.Runtime.CompilerServices; - + using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Tests.Common; using SixLabors.Primitives; @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Tests.Memory public static void SpanPointsTo(Span span, IBuffer buffer, int bufferOffset = 0) where T : struct { - ref T actual = ref span.DangerousGetPinnableReference(); + ref T actual = ref MemoryMarshal.GetReference(span); ref T expected = ref Unsafe.Add(ref buffer.DangerousGetPinnableReference(), bufferOffset); Assert.True(Unsafe.AreSame(ref expected, ref actual), "span does not point to the expected position"); diff --git a/tests/ImageSharp.Tests/Memory/BufferTestSuite.cs b/tests/ImageSharp.Tests/Memory/BufferTestSuite.cs index 50477cb5cf..eff1f197a0 100644 --- a/tests/ImageSharp.Tests/Memory/BufferTestSuite.cs +++ b/tests/ImageSharp.Tests/Memory/BufferTestSuite.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; using Xunit; // ReSharper disable InconsistentNaming @@ -165,9 +166,9 @@ namespace SixLabors.ImageSharp.Tests.Memory { using (IBuffer buffer = this.Allocate(desiredLength, false, testManagedByteBuffer)) { - ref T a = ref buffer.Span.DangerousGetPinnableReference(); - ref T b = ref buffer.Span.DangerousGetPinnableReference(); - ref T c = ref buffer.Span.DangerousGetPinnableReference(); + ref T a = ref MemoryMarshal.GetReference(buffer.Span); + ref T b = ref MemoryMarshal.GetReference(buffer.Span); + ref T c = ref MemoryMarshal.GetReference(buffer.Span); Assert.True(Unsafe.AreSame(ref a, ref b)); Assert.True(Unsafe.AreSame(ref b, ref c)); diff --git a/tests/ImageSharp.Tests/Memory/SpanUtilityTests.cs b/tests/ImageSharp.Tests/Memory/SpanUtilityTests.cs index 049c4c6ba9..23bc297436 100644 --- a/tests/ImageSharp.Tests/Memory/SpanUtilityTests.cs +++ b/tests/ImageSharp.Tests/Memory/SpanUtilityTests.cs @@ -78,8 +78,8 @@ namespace SixLabors.ImageSharp.Tests.Memory TestStructs.Foo[] source = TestStructs.Foo.CreateArray(count + 2); TestStructs.Foo[] dest = new TestStructs.Foo[count + 5]; - var apSource = new Span(source, 1); - var apDest = new Span(dest, 1); + var apSource = new Span(source, 1, source.Length - 1); + var apDest = new Span(dest, 1, dest.Length - 1); SpanHelper.Copy(apSource, apDest, count - 1); @@ -101,8 +101,8 @@ namespace SixLabors.ImageSharp.Tests.Memory TestStructs.AlignedFoo[] source = TestStructs.AlignedFoo.CreateArray(count + 2); TestStructs.AlignedFoo[] dest = new TestStructs.AlignedFoo[count + 5]; - var apSource = new Span(source, 1); - var apDest = new Span(dest, 1); + var apSource = new Span(source, 1, source.Length - 1); + var apDest = new Span(dest, 1, dest.Length - 1); SpanHelper.Copy(apSource, apDest, count - 1); @@ -124,8 +124,8 @@ namespace SixLabors.ImageSharp.Tests.Memory int[] source = CreateTestInts(count + 2); int[] dest = new int[count + 5]; - var apSource = new Span(source, 1); - var apDest = new Span(dest, 1); + var apSource = new Span(source, 1, source.Length - 1); + var apDest = new Span(dest, 1, dest.Length - 1); SpanHelper.Copy(apSource, apDest, count - 1); @@ -148,8 +148,8 @@ namespace SixLabors.ImageSharp.Tests.Memory TestStructs.Foo[] source = TestStructs.Foo.CreateArray(count + 2); byte[] dest = new byte[destCount + sizeof(TestStructs.Foo) * 2]; - var apSource = new Span(source, 1); - var apDest = new Span(dest, sizeof(TestStructs.Foo)); + var apSource = new Span(source, 1, source.Length - 1); + var apDest = new Span(dest, sizeof(TestStructs.Foo), dest.Length - sizeof(TestStructs.Foo)); SpanHelper.Copy(apSource.AsBytes(), apDest, (count - 1) * sizeof(TestStructs.Foo)); @@ -171,8 +171,8 @@ namespace SixLabors.ImageSharp.Tests.Memory TestStructs.AlignedFoo[] source = TestStructs.AlignedFoo.CreateArray(count + 2); byte[] dest = new byte[destCount + sizeof(TestStructs.AlignedFoo) * 2]; - var apSource = new Span(source, 1); - var apDest = new Span(dest, sizeof(TestStructs.AlignedFoo)); + var apSource = new Span(source, 1, source.Length - 1); + var apDest = new Span(dest, sizeof(TestStructs.AlignedFoo), dest.Length - sizeof(TestStructs.AlignedFoo)); SpanHelper.Copy(apSource.AsBytes(), apDest, (count - 1) * sizeof(TestStructs.AlignedFoo)); From a1e04d8ea9c4306704323e74187da3b38958aa49 Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Wed, 28 Feb 2018 10:10:41 +0100 Subject: [PATCH 02/20] Refactored Image Formats management into its own class --- src/ImageSharp/Configuration.cs | 94 +++------ src/ImageSharp/Formats/ImageFormatsManager.cs | 185 ++++++++++++++++++ 2 files changed, 209 insertions(+), 70 deletions(-) create mode 100644 src/ImageSharp/Formats/ImageFormatsManager.cs diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 9a627eeb77..d53d9a9a59 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -24,28 +24,8 @@ namespace SixLabors.ImageSharp /// /// A lazily initialized configuration default instance. /// - private static readonly Lazy Lazy = new Lazy(CreateDefaultInstance); - - /// - /// The list of supported keyed to mime types. - /// - private readonly ConcurrentDictionary mimeTypeEncoders = new ConcurrentDictionary(); - - /// - /// The list of supported keyed to mime types. - /// - private readonly ConcurrentDictionary mimeTypeDecoders = new ConcurrentDictionary(); - - /// - /// The list of supported s. - /// - private readonly ConcurrentBag imageFormats = new ConcurrentBag(); - - /// - /// The list of supported s. - /// - private ConcurrentBag imageFormatDetectors = new ConcurrentBag(); - + private static readonly Lazy Lazy = new Lazy(CreateDefaultInstance); + /// /// Initializes a new instance of the class. /// @@ -81,7 +61,12 @@ namespace SixLabors.ImageSharp /// /// Gets the currently registered s. /// - public IEnumerable ImageFormats => this.imageFormats; + public IEnumerable ImageFormats => this.FormatsManager.ImageFormats; + + /// + /// Gets or sets the that is currently in use. + /// + public ImageFormatsManager FormatsManager { get; set; } = new ImageFormatsManager(); /// /// Gets or sets the that is currently in use. @@ -91,22 +76,22 @@ namespace SixLabors.ImageSharp /// /// Gets the maximum header size of all the formats. /// - internal int MaxHeaderSize { get; private set; } - + internal int MaxHeaderSize => this.FormatsManager.MaxHeaderSize; + /// /// Gets the currently registered s. /// - internal IEnumerable FormatDetectors => this.imageFormatDetectors; + internal IEnumerable FormatDetectors => this.FormatsManager.FormatDetectors; /// /// Gets the currently registered s. /// - internal IEnumerable> ImageDecoders => this.mimeTypeDecoders; + internal IEnumerable> ImageDecoders => this.FormatsManager.ImageDecoders; /// /// Gets the currently registered s. /// - internal IEnumerable> ImageEncoders => this.mimeTypeEncoders; + internal IEnumerable> ImageEncoders => this.FormatsManager.ImageEncoders; #if !NETSTANDARD1_1 /// @@ -135,11 +120,8 @@ namespace SixLabors.ImageSharp /// /// The format to register as a known format. public void AddImageFormat(IImageFormat format) - { - Guard.NotNull(format, nameof(format)); - Guard.NotNull(format.MimeTypes, nameof(format.MimeTypes)); - Guard.NotNull(format.FileExtensions, nameof(format.FileExtensions)); - this.imageFormats.Add(format); + { + this.FormatsManager.AddImageFormat(format); } /// @@ -149,7 +131,7 @@ namespace SixLabors.ImageSharp /// The if found otherwise null public IImageFormat FindFormatByFileExtension(string extension) { - return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); + return this.FormatsManager.FindFormatByFileExtension(extension); } /// @@ -159,7 +141,7 @@ namespace SixLabors.ImageSharp /// The if found; otherwise null public IImageFormat FindFormatByMimeType(string mimeType) { - return this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase)); + return this.FormatsManager.FindFormatByMimeType(mimeType); } /// @@ -169,10 +151,7 @@ namespace SixLabors.ImageSharp /// The encoder to use, public void SetEncoder(IImageFormat imageFormat, IImageEncoder encoder) { - Guard.NotNull(imageFormat, nameof(imageFormat)); - Guard.NotNull(encoder, nameof(encoder)); - this.AddImageFormat(imageFormat); - this.mimeTypeEncoders.AddOrUpdate(imageFormat, encoder, (s, e) => encoder); + this.FormatsManager.SetEncoder(imageFormat, encoder); } /// @@ -182,10 +161,7 @@ namespace SixLabors.ImageSharp /// The decoder to use, public void SetDecoder(IImageFormat imageFormat, IImageDecoder decoder) { - Guard.NotNull(imageFormat, nameof(imageFormat)); - Guard.NotNull(decoder, nameof(decoder)); - this.AddImageFormat(imageFormat); - this.mimeTypeDecoders.AddOrUpdate(imageFormat, decoder, (s, e) => decoder); + this.FormatsManager.SetDecoder(imageFormat, decoder); } /// @@ -193,7 +169,7 @@ namespace SixLabors.ImageSharp /// public void ClearImageFormatDetectors() { - this.imageFormatDetectors = new ConcurrentBag(); + this.FormatsManager.ClearImageFormatDetectors(); } /// @@ -202,9 +178,7 @@ namespace SixLabors.ImageSharp /// The detector to add public void AddImageFormatDetector(IImageFormatDetector detector) { - Guard.NotNull(detector, nameof(detector)); - this.imageFormatDetectors.Add(detector); - this.SetMaxHeaderSize(); + this.FormatsManager.AddImageFormatDetector(detector); } /// @@ -214,13 +188,7 @@ namespace SixLabors.ImageSharp /// The if found otherwise null public IImageDecoder FindDecoder(IImageFormat format) { - Guard.NotNull(format, nameof(format)); - if (this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder decoder)) - { - return decoder; - } - - return null; + return this.FormatsManager.FindDecoder(format); } /// @@ -230,13 +198,7 @@ namespace SixLabors.ImageSharp /// The if found otherwise null public IImageEncoder FindEncoder(IImageFormat format) { - Guard.NotNull(format, nameof(format)); - if (this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder encoder)) - { - return encoder; - } - - return null; + return this.FormatsManager.FindEncoder(format); } /// @@ -254,14 +216,6 @@ namespace SixLabors.ImageSharp new JpegConfigurationModule(), new GifConfigurationModule(), new BmpConfigurationModule()); - } - - /// - /// Sets the max header size. - /// - private void SetMaxHeaderSize() - { - this.MaxHeaderSize = this.imageFormatDetectors.Max(x => x.HeaderSize); - } + } } } diff --git a/src/ImageSharp/Formats/ImageFormatsManager.cs b/src/ImageSharp/Formats/ImageFormatsManager.cs new file mode 100644 index 0000000000..b9307e4a05 --- /dev/null +++ b/src/ImageSharp/Formats/ImageFormatsManager.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SixLabors.ImageSharp.Formats +{ + /// + /// Collection of Image Formats to be used in class. + /// + public class ImageFormatsManager + { + /// + /// Initializes a new instance of the class. + /// + public ImageFormatsManager() + { + } + + /// + /// The list of supported keyed to mime types. + /// + private readonly ConcurrentDictionary mimeTypeEncoders = new ConcurrentDictionary(); + + /// + /// The list of supported keyed to mime types. + /// + private readonly ConcurrentDictionary mimeTypeDecoders = new ConcurrentDictionary(); + + /// + /// The list of supported s. + /// + private readonly ConcurrentBag imageFormats = new ConcurrentBag(); + + /// + /// The list of supported s. + /// + private ConcurrentBag imageFormatDetectors = new ConcurrentBag(); + + /// + /// Gets the maximum header size of all the formats. + /// + internal int MaxHeaderSize { get; private set; } + + /// + /// Gets the currently registered s. + /// + public IEnumerable ImageFormats => this.imageFormats; + + /// + /// Gets the currently registered s. + /// + internal IEnumerable FormatDetectors => this.imageFormatDetectors; + + /// + /// Gets the currently registered s. + /// + internal IEnumerable> ImageDecoders => this.mimeTypeDecoders; + + /// + /// Gets the currently registered s. + /// + internal IEnumerable> ImageEncoders => this.mimeTypeEncoders; + + /// + /// Registers a new format provider. + /// + /// The format to register as a known format. + public void AddImageFormat(IImageFormat format) + { + Guard.NotNull(format, nameof(format)); + Guard.NotNull(format.MimeTypes, nameof(format.MimeTypes)); + Guard.NotNull(format.FileExtensions, nameof(format.FileExtensions)); + this.imageFormats.Add(format); + } + + /// + /// For the specified file extensions type find the e . + /// + /// The extension to discover + /// The if found otherwise null + public IImageFormat FindFormatByFileExtension(string extension) + { + return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); + } + + /// + /// For the specified mime type find the . + /// + /// The mime-type to discover + /// The if found; otherwise null + public IImageFormat FindFormatByMimeType(string mimeType) + { + return this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase)); + } + + /// + /// Sets a specific image encoder as the encoder for a specific image format. + /// + /// The image format to register the encoder for. + /// The encoder to use, + public void SetEncoder(IImageFormat imageFormat, IImageEncoder encoder) + { + Guard.NotNull(imageFormat, nameof(imageFormat)); + Guard.NotNull(encoder, nameof(encoder)); + this.AddImageFormat(imageFormat); + this.mimeTypeEncoders.AddOrUpdate(imageFormat, encoder, (s, e) => encoder); + } + + /// + /// Sets a specific image decoder as the decoder for a specific image format. + /// + /// The image format to register the encoder for. + /// The decoder to use, + public void SetDecoder(IImageFormat imageFormat, IImageDecoder decoder) + { + Guard.NotNull(imageFormat, nameof(imageFormat)); + Guard.NotNull(decoder, nameof(decoder)); + this.AddImageFormat(imageFormat); + this.mimeTypeDecoders.AddOrUpdate(imageFormat, decoder, (s, e) => decoder); + } + + /// + /// Removes all the registered image format detectors. + /// + public void ClearImageFormatDetectors() + { + this.imageFormatDetectors = new ConcurrentBag(); + } + + /// + /// Adds a new detector for detecting mime types. + /// + /// The detector to add + public void AddImageFormatDetector(IImageFormatDetector detector) + { + Guard.NotNull(detector, nameof(detector)); + this.imageFormatDetectors.Add(detector); + this.SetMaxHeaderSize(); + } + + /// + /// For the specified mime type find the decoder. + /// + /// The format to discover + /// The if found otherwise null + public IImageDecoder FindDecoder(IImageFormat format) + { + Guard.NotNull(format, nameof(format)); + if (this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder decoder)) + { + return decoder; + } + + return null; + } + + /// + /// For the specified mime type find the encoder. + /// + /// The format to discover + /// The if found otherwise null + public IImageEncoder FindEncoder(IImageFormat format) + { + Guard.NotNull(format, nameof(format)); + if (this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder encoder)) + { + return encoder; + } + + return null; + } + + /// + /// Sets the max header size. + /// + private void SetMaxHeaderSize() + { + this.MaxHeaderSize = this.imageFormatDetectors.Max(x => x.HeaderSize); + } + + + } +} From 68896c7c3e4e10a64ee66925dba78f7f51b0a176 Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Wed, 28 Feb 2018 10:36:43 +0100 Subject: [PATCH 03/20] stylecop whitespaces --- src/ImageSharp/Configuration.cs | 426 +++++++++--------- src/ImageSharp/Formats/ImageFormatsManager.cs | 316 +++++++------ 2 files changed, 370 insertions(+), 372 deletions(-) diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index d53d9a9a59..65633f2c8a 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -1,221 +1,221 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using SixLabors.ImageSharp.Formats; -using SixLabors.ImageSharp.Formats.Bmp; -using SixLabors.ImageSharp.Formats.Gif; -using SixLabors.ImageSharp.Formats.Jpeg; -using SixLabors.ImageSharp.Formats.Png; -using SixLabors.ImageSharp.IO; -using SixLabors.ImageSharp.Memory; - -namespace SixLabors.ImageSharp -{ - /// - /// Provides initialization code which allows extending the library. - /// - public sealed class Configuration - { - /// - /// A lazily initialized configuration default instance. - /// +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.Formats.Bmp; +using SixLabors.ImageSharp.Formats.Gif; +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp +{ + /// + /// Provides initialization code which allows extending the library. + /// + public sealed class Configuration + { + /// + /// A lazily initialized configuration default instance. + /// private static readonly Lazy Lazy = new Lazy(CreateDefaultInstance); - /// - /// Initializes a new instance of the class. - /// - public Configuration() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A collection of configuration modules to register - public Configuration(params IConfigurationModule[] configurationModules) - { - if (configurationModules != null) - { - foreach (IConfigurationModule p in configurationModules) - { - p.Configure(this); - } - } - } - - /// - /// Gets the default instance. - /// - public static Configuration Default { get; } = Lazy.Value; - - /// - /// Gets the global parallel options for processing tasks in parallel. - /// - public ParallelOptions ParallelOptions { get; } = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; - - /// - /// Gets the currently registered s. - /// + /// + /// Initializes a new instance of the class. + /// + public Configuration() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A collection of configuration modules to register + public Configuration(params IConfigurationModule[] configurationModules) + { + if (configurationModules != null) + { + foreach (IConfigurationModule p in configurationModules) + { + p.Configure(this); + } + } + } + + /// + /// Gets the default instance. + /// + public static Configuration Default { get; } = Lazy.Value; + + /// + /// Gets the global parallel options for processing tasks in parallel. + /// + public ParallelOptions ParallelOptions { get; } = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; + + /// + /// Gets the currently registered s. + /// public IEnumerable ImageFormats => this.FormatsManager.ImageFormats; - /// - /// Gets or sets the that is currently in use. - /// - public ImageFormatsManager FormatsManager { get; set; } = new ImageFormatsManager(); - - /// - /// Gets or sets the that is currently in use. - /// - public MemoryManager MemoryManager { get; set; } = ArrayPoolMemoryManager.CreateDefault(); - - /// - /// Gets the maximum header size of all the formats. - /// + /// + /// Gets or sets the that is currently in use. + /// + public ImageFormatsManager FormatsManager { get; set; } = new ImageFormatsManager(); + + /// + /// Gets or sets the that is currently in use. + /// + public MemoryManager MemoryManager { get; set; } = ArrayPoolMemoryManager.CreateDefault(); + + /// + /// Gets the maximum header size of all the formats. + /// internal int MaxHeaderSize => this.FormatsManager.MaxHeaderSize; - /// - /// Gets the currently registered s. - /// - internal IEnumerable FormatDetectors => this.FormatsManager.FormatDetectors; - - /// - /// Gets the currently registered s. - /// - internal IEnumerable> ImageDecoders => this.FormatsManager.ImageDecoders; - - /// - /// Gets the currently registered s. - /// - internal IEnumerable> ImageEncoders => this.FormatsManager.ImageEncoders; - -#if !NETSTANDARD1_1 - /// - /// Gets or sets the filesystem helper for accessing the local file system. - /// - internal IFileSystem FileSystem { get; set; } = new LocalFileSystem(); -#endif - - /// - /// Gets or sets the image operations provider factory. - /// - internal IImageProcessingContextFactory ImageOperationsProvider { get; set; } = new DefaultImageOperationsProviderFactory(); - - /// - /// Registers a new format provider. - /// - /// The configuration provider to call configure on. - public void Configure(IConfigurationModule configuration) - { - Guard.NotNull(configuration, nameof(configuration)); - configuration.Configure(this); - } - - /// - /// Registers a new format provider. - /// - /// The format to register as a known format. - public void AddImageFormat(IImageFormat format) + /// + /// Gets the currently registered s. + /// + internal IEnumerable FormatDetectors => this.FormatsManager.FormatDetectors; + + /// + /// Gets the currently registered s. + /// + internal IEnumerable> ImageDecoders => this.FormatsManager.ImageDecoders; + + /// + /// Gets the currently registered s. + /// + internal IEnumerable> ImageEncoders => this.FormatsManager.ImageEncoders; + +#if !NETSTANDARD1_1 + /// + /// Gets or sets the filesystem helper for accessing the local file system. + /// + internal IFileSystem FileSystem { get; set; } = new LocalFileSystem(); +#endif + + /// + /// Gets or sets the image operations provider factory. + /// + internal IImageProcessingContextFactory ImageOperationsProvider { get; set; } = new DefaultImageOperationsProviderFactory(); + + /// + /// Registers a new format provider. + /// + /// The configuration provider to call configure on. + public void Configure(IConfigurationModule configuration) + { + Guard.NotNull(configuration, nameof(configuration)); + configuration.Configure(this); + } + + /// + /// Registers a new format provider. + /// + /// The format to register as a known format. + public void AddImageFormat(IImageFormat format) + { + this.FormatsManager.AddImageFormat(format); + } + + /// + /// For the specified file extensions type find the e . + /// + /// The extension to discover + /// The if found otherwise null + public IImageFormat FindFormatByFileExtension(string extension) + { + return this.FormatsManager.FindFormatByFileExtension(extension); + } + + /// + /// For the specified mime type find the . + /// + /// The mime-type to discover + /// The if found; otherwise null + public IImageFormat FindFormatByMimeType(string mimeType) + { + return this.FormatsManager.FindFormatByMimeType(mimeType); + } + + /// + /// Sets a specific image encoder as the encoder for a specific image format. + /// + /// The image format to register the encoder for. + /// The encoder to use, + public void SetEncoder(IImageFormat imageFormat, IImageEncoder encoder) + { + this.FormatsManager.SetEncoder(imageFormat, encoder); + } + + /// + /// Sets a specific image decoder as the decoder for a specific image format. + /// + /// The image format to register the encoder for. + /// The decoder to use, + public void SetDecoder(IImageFormat imageFormat, IImageDecoder decoder) + { + this.FormatsManager.SetDecoder(imageFormat, decoder); + } + + /// + /// Removes all the registered image format detectors. + /// + public void ClearImageFormatDetectors() + { + this.FormatsManager.ClearImageFormatDetectors(); + } + + /// + /// Adds a new detector for detecting mime types. + /// + /// The detector to add + public void AddImageFormatDetector(IImageFormatDetector detector) + { + this.FormatsManager.AddImageFormatDetector(detector); + } + + /// + /// For the specified mime type find the decoder. + /// + /// The format to discover + /// The if found otherwise null + public IImageDecoder FindDecoder(IImageFormat format) + { + return this.FormatsManager.FindDecoder(format); + } + + /// + /// For the specified mime type find the encoder. + /// + /// The format to discover + /// The if found otherwise null + public IImageEncoder FindEncoder(IImageFormat format) + { + return this.FormatsManager.FindEncoder(format); + } + + /// + /// Creates the default instance with the following s preregistered: + /// + /// + /// + /// + /// + /// The default configuration of + internal static Configuration CreateDefaultInstance() { - this.FormatsManager.AddImageFormat(format); - } - - /// - /// For the specified file extensions type find the e . - /// - /// The extension to discover - /// The if found otherwise null - public IImageFormat FindFormatByFileExtension(string extension) - { - return this.FormatsManager.FindFormatByFileExtension(extension); - } - - /// - /// For the specified mime type find the . - /// - /// The mime-type to discover - /// The if found; otherwise null - public IImageFormat FindFormatByMimeType(string mimeType) - { - return this.FormatsManager.FindFormatByMimeType(mimeType); - } - - /// - /// Sets a specific image encoder as the encoder for a specific image format. - /// - /// The image format to register the encoder for. - /// The encoder to use, - public void SetEncoder(IImageFormat imageFormat, IImageEncoder encoder) - { - this.FormatsManager.SetEncoder(imageFormat, encoder); - } - - /// - /// Sets a specific image decoder as the decoder for a specific image format. - /// - /// The image format to register the encoder for. - /// The decoder to use, - public void SetDecoder(IImageFormat imageFormat, IImageDecoder decoder) - { - this.FormatsManager.SetDecoder(imageFormat, decoder); - } - - /// - /// Removes all the registered image format detectors. - /// - public void ClearImageFormatDetectors() - { - this.FormatsManager.ClearImageFormatDetectors(); - } - - /// - /// Adds a new detector for detecting mime types. - /// - /// The detector to add - public void AddImageFormatDetector(IImageFormatDetector detector) - { - this.FormatsManager.AddImageFormatDetector(detector); - } - - /// - /// For the specified mime type find the decoder. - /// - /// The format to discover - /// The if found otherwise null - public IImageDecoder FindDecoder(IImageFormat format) - { - return this.FormatsManager.FindDecoder(format); - } - - /// - /// For the specified mime type find the encoder. - /// - /// The format to discover - /// The if found otherwise null - public IImageEncoder FindEncoder(IImageFormat format) - { - return this.FormatsManager.FindEncoder(format); - } - - /// - /// Creates the default instance with the following s preregistered: - /// - /// - /// - /// - /// - /// The default configuration of - internal static Configuration CreateDefaultInstance() - { - return new Configuration( - new PngConfigurationModule(), - new JpegConfigurationModule(), - new GifConfigurationModule(), - new BmpConfigurationModule()); + return new Configuration( + new PngConfigurationModule(), + new JpegConfigurationModule(), + new GifConfigurationModule(), + new BmpConfigurationModule()); } - } -} + } +} diff --git a/src/ImageSharp/Formats/ImageFormatsManager.cs b/src/ImageSharp/Formats/ImageFormatsManager.cs index b9307e4a05..3a78965612 100644 --- a/src/ImageSharp/Formats/ImageFormatsManager.cs +++ b/src/ImageSharp/Formats/ImageFormatsManager.cs @@ -6,180 +6,178 @@ using System.Text; namespace SixLabors.ImageSharp.Formats { - /// - /// Collection of Image Formats to be used in class. + /// + /// Collection of Image Formats to be used in class. /// public class ImageFormatsManager { - /// - /// Initializes a new instance of the class. - /// - public ImageFormatsManager() - { - } + /// + /// The list of supported keyed to mime types. + /// + private readonly ConcurrentDictionary mimeTypeEncoders = new ConcurrentDictionary(); + + /// + /// The list of supported keyed to mime types. + /// + private readonly ConcurrentDictionary mimeTypeDecoders = new ConcurrentDictionary(); + + /// + /// The list of supported s. + /// + private readonly ConcurrentBag imageFormats = new ConcurrentBag(); - /// - /// The list of supported keyed to mime types. - /// - private readonly ConcurrentDictionary mimeTypeEncoders = new ConcurrentDictionary(); - - /// - /// The list of supported keyed to mime types. - /// - private readonly ConcurrentDictionary mimeTypeDecoders = new ConcurrentDictionary(); - - /// - /// The list of supported s. - /// - private readonly ConcurrentBag imageFormats = new ConcurrentBag(); - - /// - /// The list of supported s. - /// + /// + /// The list of supported s. + /// private ConcurrentBag imageFormatDetectors = new ConcurrentBag(); - /// - /// Gets the maximum header size of all the formats. - /// + /// + /// Initializes a new instance of the class. + /// + public ImageFormatsManager() + { + } + + /// + /// Gets the maximum header size of all the formats. + /// internal int MaxHeaderSize { get; private set; } - /// - /// Gets the currently registered s. - /// + /// + /// Gets the currently registered s. + /// public IEnumerable ImageFormats => this.imageFormats; - /// - /// Gets the currently registered s. - /// - internal IEnumerable FormatDetectors => this.imageFormatDetectors; - - /// - /// Gets the currently registered s. - /// - internal IEnumerable> ImageDecoders => this.mimeTypeDecoders; - - /// - /// Gets the currently registered s. - /// + /// + /// Gets the currently registered s. + /// + internal IEnumerable FormatDetectors => this.imageFormatDetectors; + + /// + /// Gets the currently registered s. + /// + internal IEnumerable> ImageDecoders => this.mimeTypeDecoders; + + /// + /// Gets the currently registered s. + /// internal IEnumerable> ImageEncoders => this.mimeTypeEncoders; - /// - /// Registers a new format provider. - /// - /// The format to register as a known format. - public void AddImageFormat(IImageFormat format) - { - Guard.NotNull(format, nameof(format)); - Guard.NotNull(format.MimeTypes, nameof(format.MimeTypes)); - Guard.NotNull(format.FileExtensions, nameof(format.FileExtensions)); - this.imageFormats.Add(format); - } - - /// - /// For the specified file extensions type find the e . - /// - /// The extension to discover - /// The if found otherwise null - public IImageFormat FindFormatByFileExtension(string extension) - { - return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); - } - - /// - /// For the specified mime type find the . - /// - /// The mime-type to discover - /// The if found; otherwise null - public IImageFormat FindFormatByMimeType(string mimeType) - { - return this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase)); - } - - /// - /// Sets a specific image encoder as the encoder for a specific image format. - /// - /// The image format to register the encoder for. - /// The encoder to use, - public void SetEncoder(IImageFormat imageFormat, IImageEncoder encoder) - { - Guard.NotNull(imageFormat, nameof(imageFormat)); - Guard.NotNull(encoder, nameof(encoder)); - this.AddImageFormat(imageFormat); - this.mimeTypeEncoders.AddOrUpdate(imageFormat, encoder, (s, e) => encoder); - } - - /// - /// Sets a specific image decoder as the decoder for a specific image format. - /// - /// The image format to register the encoder for. - /// The decoder to use, - public void SetDecoder(IImageFormat imageFormat, IImageDecoder decoder) - { - Guard.NotNull(imageFormat, nameof(imageFormat)); - Guard.NotNull(decoder, nameof(decoder)); - this.AddImageFormat(imageFormat); - this.mimeTypeDecoders.AddOrUpdate(imageFormat, decoder, (s, e) => decoder); - } - - /// - /// Removes all the registered image format detectors. - /// - public void ClearImageFormatDetectors() - { - this.imageFormatDetectors = new ConcurrentBag(); - } - - /// - /// Adds a new detector for detecting mime types. - /// - /// The detector to add - public void AddImageFormatDetector(IImageFormatDetector detector) - { - Guard.NotNull(detector, nameof(detector)); - this.imageFormatDetectors.Add(detector); - this.SetMaxHeaderSize(); - } - - /// - /// For the specified mime type find the decoder. - /// - /// The format to discover - /// The if found otherwise null - public IImageDecoder FindDecoder(IImageFormat format) - { - Guard.NotNull(format, nameof(format)); - if (this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder decoder)) - { - return decoder; - } - - return null; - } - - /// - /// For the specified mime type find the encoder. - /// - /// The format to discover - /// The if found otherwise null - public IImageEncoder FindEncoder(IImageFormat format) - { - Guard.NotNull(format, nameof(format)); - if (this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder encoder)) - { - return encoder; - } - - return null; + /// + /// Registers a new format provider. + /// + /// The format to register as a known format. + public void AddImageFormat(IImageFormat format) + { + Guard.NotNull(format, nameof(format)); + Guard.NotNull(format.MimeTypes, nameof(format.MimeTypes)); + Guard.NotNull(format.FileExtensions, nameof(format.FileExtensions)); + this.imageFormats.Add(format); + } + + /// + /// For the specified file extensions type find the e . + /// + /// The extension to discover + /// The if found otherwise null + public IImageFormat FindFormatByFileExtension(string extension) + { + return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); + } + + /// + /// For the specified mime type find the . + /// + /// The mime-type to discover + /// The if found; otherwise null + public IImageFormat FindFormatByMimeType(string mimeType) + { + return this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase)); + } + + /// + /// Sets a specific image encoder as the encoder for a specific image format. + /// + /// The image format to register the encoder for. + /// The encoder to use, + public void SetEncoder(IImageFormat imageFormat, IImageEncoder encoder) + { + Guard.NotNull(imageFormat, nameof(imageFormat)); + Guard.NotNull(encoder, nameof(encoder)); + this.AddImageFormat(imageFormat); + this.mimeTypeEncoders.AddOrUpdate(imageFormat, encoder, (s, e) => encoder); + } + + /// + /// Sets a specific image decoder as the decoder for a specific image format. + /// + /// The image format to register the encoder for. + /// The decoder to use, + public void SetDecoder(IImageFormat imageFormat, IImageDecoder decoder) + { + Guard.NotNull(imageFormat, nameof(imageFormat)); + Guard.NotNull(decoder, nameof(decoder)); + this.AddImageFormat(imageFormat); + this.mimeTypeDecoders.AddOrUpdate(imageFormat, decoder, (s, e) => decoder); + } + + /// + /// Removes all the registered image format detectors. + /// + public void ClearImageFormatDetectors() + { + this.imageFormatDetectors = new ConcurrentBag(); + } + + /// + /// Adds a new detector for detecting mime types. + /// + /// The detector to add + public void AddImageFormatDetector(IImageFormatDetector detector) + { + Guard.NotNull(detector, nameof(detector)); + this.imageFormatDetectors.Add(detector); + this.SetMaxHeaderSize(); + } + + /// + /// For the specified mime type find the decoder. + /// + /// The format to discover + /// The if found otherwise null + public IImageDecoder FindDecoder(IImageFormat format) + { + Guard.NotNull(format, nameof(format)); + if (this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder decoder)) + { + return decoder; + } + + return null; } - /// - /// Sets the max header size. - /// - private void SetMaxHeaderSize() - { - this.MaxHeaderSize = this.imageFormatDetectors.Max(x => x.HeaderSize); + /// + /// For the specified mime type find the encoder. + /// + /// The format to discover + /// The if found otherwise null + public IImageEncoder FindEncoder(IImageFormat format) + { + Guard.NotNull(format, nameof(format)); + if (this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder encoder)) + { + return encoder; + } + + return null; } - + /// + /// Sets the max header size. + /// + private void SetMaxHeaderSize() + { + this.MaxHeaderSize = this.imageFormatDetectors.Max(x => x.HeaderSize); + } } } From 02dee3cad964ef5db5e6583f92c11b5e3b7d0ec8 Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Wed, 28 Feb 2018 11:49:27 +0100 Subject: [PATCH 04/20] Coverage test --- src/ImageSharp/Formats/ImageFormatsManager.cs | 5 +- .../Formats/ImageFormatsManagerTests.cs | 117 ++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 tests/ImageSharp.Tests/Formats/ImageFormatsManagerTests.cs diff --git a/src/ImageSharp/Formats/ImageFormatsManager.cs b/src/ImageSharp/Formats/ImageFormatsManager.cs index 3a78965612..350c28b0a3 100644 --- a/src/ImageSharp/Formats/ImageFormatsManager.cs +++ b/src/ImageSharp/Formats/ImageFormatsManager.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; diff --git a/tests/ImageSharp.Tests/Formats/ImageFormatsManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatsManagerTests.cs new file mode 100644 index 0000000000..3aeeff9379 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/ImageFormatsManagerTests.cs @@ -0,0 +1,117 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.PixelFormats; +using Moq; +using Xunit; + +namespace SixLabors.ImageSharp.Tests +{ + public class ImageFormatsManagerTests + { + public ImageFormatsManager FormatsManagerEmpty { get; private set; } + public ImageFormatsManager DefaultFormatsManager { get; private set; } + + public ImageFormatsManagerTests() + { + this.DefaultFormatsManager = Configuration.Default.FormatsManager; + this.FormatsManagerEmpty = new ImageFormatsManager(); + } + + [Fact] + public void IfAutoloadWellknownFormatsIsTrueAllFormatsAreLoaded() + { + Assert.Equal(4, this.DefaultFormatsManager.ImageEncoders.Count()); + Assert.Equal(4, this.DefaultFormatsManager.ImageDecoders.Count()); + } + + [Fact] + public void AddImageFormatDetectorNullthrows() + { + Assert.Throws(() => + { + this.DefaultFormatsManager.AddImageFormatDetector(null); + }); + } + + [Fact] + public void RegisterNullMimeTypeEncoder() + { + Assert.Throws(() => + { + this.DefaultFormatsManager.SetEncoder(null, new Mock().Object); + }); + Assert.Throws(() => + { + this.DefaultFormatsManager.SetEncoder(ImageFormats.Bmp, null); + }); + Assert.Throws(() => + { + this.DefaultFormatsManager.SetEncoder(null, null); + }); + } + + [Fact] + public void RegisterNullSetDecoder() + { + Assert.Throws(() => + { + this.DefaultFormatsManager.SetDecoder(null, new Mock().Object); + }); + Assert.Throws(() => + { + this.DefaultFormatsManager.SetDecoder(ImageFormats.Bmp, null); + }); + Assert.Throws(() => + { + this.DefaultFormatsManager.SetDecoder(null, null); + }); + } + + [Fact] + public void RegisterMimeTypeEncoderReplacesLast() + { + IImageEncoder encoder1 = new Mock().Object; + this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder1); + IImageEncoder found = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat); + Assert.Equal(encoder1, found); + + IImageEncoder encoder2 = new Mock().Object; + this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder2); + IImageEncoder found2 = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat); + Assert.Equal(encoder2, found2); + Assert.NotEqual(found, found2); + } + + [Fact] + public void RegisterMimeTypeDecoderReplacesLast() + { + IImageDecoder decoder1 = new Mock().Object; + this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder1); + IImageDecoder found = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat); + Assert.Equal(decoder1, found); + + IImageDecoder decoder2 = new Mock().Object; + this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder2); + IImageDecoder found2 = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat); + Assert.Equal(decoder2, found2); + Assert.NotEqual(found, found2); + } + + [Fact] + public void AddFormatCallsConfig() + { + var provider = new Mock(); + var config = new Configuration(); + config.Configure(provider.Object); + + provider.Verify(x => x.Configure(config)); + } + } +} From 08fbee99faea9d49d18ae3d046081dda89c086d9 Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Wed, 28 Feb 2018 12:50:55 +0100 Subject: [PATCH 05/20] renaming ImageFormatsManager to ImageFormatManager --- src/ImageSharp/Configuration.cs | 32 +++++++++---------- ...ormatsManager.cs => ImageFormatManager.cs} | 6 ++-- ...gerTests.cs => ImageFormatManagerTests.cs} | 14 ++++---- 3 files changed, 26 insertions(+), 26 deletions(-) rename src/ImageSharp/Formats/{ImageFormatsManager.cs => ImageFormatManager.cs} (96%) rename tests/ImageSharp.Tests/Formats/{ImageFormatsManagerTests.cs => ImageFormatManagerTests.cs} (89%) diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 65633f2c8a..0f69194f2d 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -61,12 +61,12 @@ namespace SixLabors.ImageSharp /// /// Gets the currently registered s. /// - public IEnumerable ImageFormats => this.FormatsManager.ImageFormats; + public IEnumerable ImageFormats => this.ImageFormatsManager.ImageFormats; /// - /// Gets or sets the that is currently in use. + /// Gets or sets the that is currently in use. /// - public ImageFormatsManager FormatsManager { get; set; } = new ImageFormatsManager(); + public ImageFormatManager ImageFormatsManager { get; set; } = new ImageFormatManager(); /// /// Gets or sets the that is currently in use. @@ -76,22 +76,22 @@ namespace SixLabors.ImageSharp /// /// Gets the maximum header size of all the formats. /// - internal int MaxHeaderSize => this.FormatsManager.MaxHeaderSize; + internal int MaxHeaderSize => this.ImageFormatsManager.MaxHeaderSize; /// /// Gets the currently registered s. /// - internal IEnumerable FormatDetectors => this.FormatsManager.FormatDetectors; + internal IEnumerable FormatDetectors => this.ImageFormatsManager.FormatDetectors; /// /// Gets the currently registered s. /// - internal IEnumerable> ImageDecoders => this.FormatsManager.ImageDecoders; + internal IEnumerable> ImageDecoders => this.ImageFormatsManager.ImageDecoders; /// /// Gets the currently registered s. /// - internal IEnumerable> ImageEncoders => this.FormatsManager.ImageEncoders; + internal IEnumerable> ImageEncoders => this.ImageFormatsManager.ImageEncoders; #if !NETSTANDARD1_1 /// @@ -121,7 +121,7 @@ namespace SixLabors.ImageSharp /// The format to register as a known format. public void AddImageFormat(IImageFormat format) { - this.FormatsManager.AddImageFormat(format); + this.ImageFormatsManager.AddImageFormat(format); } /// @@ -131,7 +131,7 @@ namespace SixLabors.ImageSharp /// The if found otherwise null public IImageFormat FindFormatByFileExtension(string extension) { - return this.FormatsManager.FindFormatByFileExtension(extension); + return this.ImageFormatsManager.FindFormatByFileExtension(extension); } /// @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp /// The if found; otherwise null public IImageFormat FindFormatByMimeType(string mimeType) { - return this.FormatsManager.FindFormatByMimeType(mimeType); + return this.ImageFormatsManager.FindFormatByMimeType(mimeType); } /// @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp /// The encoder to use, public void SetEncoder(IImageFormat imageFormat, IImageEncoder encoder) { - this.FormatsManager.SetEncoder(imageFormat, encoder); + this.ImageFormatsManager.SetEncoder(imageFormat, encoder); } /// @@ -161,7 +161,7 @@ namespace SixLabors.ImageSharp /// The decoder to use, public void SetDecoder(IImageFormat imageFormat, IImageDecoder decoder) { - this.FormatsManager.SetDecoder(imageFormat, decoder); + this.ImageFormatsManager.SetDecoder(imageFormat, decoder); } /// @@ -169,7 +169,7 @@ namespace SixLabors.ImageSharp /// public void ClearImageFormatDetectors() { - this.FormatsManager.ClearImageFormatDetectors(); + this.ImageFormatsManager.ClearImageFormatDetectors(); } /// @@ -178,7 +178,7 @@ namespace SixLabors.ImageSharp /// The detector to add public void AddImageFormatDetector(IImageFormatDetector detector) { - this.FormatsManager.AddImageFormatDetector(detector); + this.ImageFormatsManager.AddImageFormatDetector(detector); } /// @@ -188,7 +188,7 @@ namespace SixLabors.ImageSharp /// The if found otherwise null public IImageDecoder FindDecoder(IImageFormat format) { - return this.FormatsManager.FindDecoder(format); + return this.ImageFormatsManager.FindDecoder(format); } /// @@ -198,7 +198,7 @@ namespace SixLabors.ImageSharp /// The if found otherwise null public IImageEncoder FindEncoder(IImageFormat format) { - return this.FormatsManager.FindEncoder(format); + return this.ImageFormatsManager.FindEncoder(format); } /// diff --git a/src/ImageSharp/Formats/ImageFormatsManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs similarity index 96% rename from src/ImageSharp/Formats/ImageFormatsManager.cs rename to src/ImageSharp/Formats/ImageFormatManager.cs index 350c28b0a3..67ba111474 100644 --- a/src/ImageSharp/Formats/ImageFormatsManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Formats /// /// Collection of Image Formats to be used in class. /// - public class ImageFormatsManager + public class ImageFormatManager { /// /// The list of supported keyed to mime types. @@ -35,9 +35,9 @@ namespace SixLabors.ImageSharp.Formats private ConcurrentBag imageFormatDetectors = new ConcurrentBag(); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public ImageFormatsManager() + public ImageFormatManager() { } diff --git a/tests/ImageSharp.Tests/Formats/ImageFormatsManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs similarity index 89% rename from tests/ImageSharp.Tests/Formats/ImageFormatsManagerTests.cs rename to tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs index 3aeeff9379..bfaf26c6ac 100644 --- a/tests/ImageSharp.Tests/Formats/ImageFormatsManagerTests.cs +++ b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs @@ -13,19 +13,19 @@ using Xunit; namespace SixLabors.ImageSharp.Tests { - public class ImageFormatsManagerTests + public class ImageFormatManagerTests { - public ImageFormatsManager FormatsManagerEmpty { get; private set; } - public ImageFormatsManager DefaultFormatsManager { get; private set; } + public ImageFormatManager FormatsManagerEmpty { get; private set; } + public ImageFormatManager DefaultFormatsManager { get; private set; } - public ImageFormatsManagerTests() + public ImageFormatManagerTests() { - this.DefaultFormatsManager = Configuration.Default.FormatsManager; - this.FormatsManagerEmpty = new ImageFormatsManager(); + this.DefaultFormatsManager = Configuration.Default.ImageFormatsManager; + this.FormatsManagerEmpty = new ImageFormatManager(); } [Fact] - public void IfAutoloadWellknownFormatsIsTrueAllFormatsAreLoaded() + public void IfAutoloadWellKnownFormatsIsTrueAllFormatsAreLoaded() { Assert.Equal(4, this.DefaultFormatsManager.ImageEncoders.Count()); Assert.Equal(4, this.DefaultFormatsManager.ImageDecoders.Count()); From dad8b1bed50cf62a82f5a3cce8b9a15b183067bf Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Wed, 28 Feb 2018 13:52:03 +0100 Subject: [PATCH 06/20] changed test to ensure proper encoders/decoders are set --- .../Formats/ImageFormatManagerTests.cs | 222 +++++++++--------- 1 file changed, 117 insertions(+), 105 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs index bfaf26c6ac..a6f6600f05 100644 --- a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs +++ b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs @@ -1,117 +1,129 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using SixLabors.ImageSharp.Formats; -using SixLabors.ImageSharp.IO; -using SixLabors.ImageSharp.PixelFormats; -using Moq; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.Formats.Bmp; +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.Formats.Gif; +using Moq; using Xunit; + namespace SixLabors.ImageSharp.Tests { public class ImageFormatManagerTests { - public ImageFormatManager FormatsManagerEmpty { get; private set; } - public ImageFormatManager DefaultFormatsManager { get; private set; } - - public ImageFormatManagerTests() - { - this.DefaultFormatsManager = Configuration.Default.ImageFormatsManager; - this.FormatsManagerEmpty = new ImageFormatManager(); - } - - [Fact] - public void IfAutoloadWellKnownFormatsIsTrueAllFormatsAreLoaded() - { - Assert.Equal(4, this.DefaultFormatsManager.ImageEncoders.Count()); - Assert.Equal(4, this.DefaultFormatsManager.ImageDecoders.Count()); + public ImageFormatManager FormatsManagerEmpty { get; private set; } + public ImageFormatManager DefaultFormatsManager { get; private set; } + + public ImageFormatManagerTests() + { + this.DefaultFormatsManager = Configuration.Default.ImageFormatsManager; + this.FormatsManagerEmpty = new ImageFormatManager(); + } + + [Fact] + public void IfAutoloadWellKnownFormatsIsTrueAllFormatsAreLoaded() + { + Assert.Equal(1, this.DefaultFormatsManager.ImageEncoders.Select(item => item.Value).OfType().Count()); + Assert.Equal(1, this.DefaultFormatsManager.ImageEncoders.Select(item => item.Value).OfType().Count()); + Assert.Equal(1, this.DefaultFormatsManager.ImageEncoders.Select(item => item.Value).OfType().Count()); + Assert.Equal(1, this.DefaultFormatsManager.ImageEncoders.Select(item => item.Value).OfType().Count()); + + Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); + Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); + Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); + Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); + } + + [Fact] + public void AddImageFormatDetectorNullthrows() + { + Assert.Throws(() => + { + this.DefaultFormatsManager.AddImageFormatDetector(null); + }); } - [Fact] - public void AddImageFormatDetectorNullthrows() - { - Assert.Throws(() => - { - this.DefaultFormatsManager.AddImageFormatDetector(null); - }); - } - - [Fact] - public void RegisterNullMimeTypeEncoder() - { - Assert.Throws(() => + [Fact] + public void RegisterNullMimeTypeEncoder() + { + Assert.Throws(() => + { + this.DefaultFormatsManager.SetEncoder(null, new Mock().Object); + }); + Assert.Throws(() => { - this.DefaultFormatsManager.SetEncoder(null, new Mock().Object); - }); - Assert.Throws(() => - { - this.DefaultFormatsManager.SetEncoder(ImageFormats.Bmp, null); - }); - Assert.Throws(() => - { - this.DefaultFormatsManager.SetEncoder(null, null); - }); - } - - [Fact] - public void RegisterNullSetDecoder() - { - Assert.Throws(() => - { - this.DefaultFormatsManager.SetDecoder(null, new Mock().Object); - }); - Assert.Throws(() => - { - this.DefaultFormatsManager.SetDecoder(ImageFormats.Bmp, null); - }); - Assert.Throws(() => - { - this.DefaultFormatsManager.SetDecoder(null, null); - }); - } - - [Fact] - public void RegisterMimeTypeEncoderReplacesLast() - { - IImageEncoder encoder1 = new Mock().Object; - this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder1); - IImageEncoder found = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat); - Assert.Equal(encoder1, found); - - IImageEncoder encoder2 = new Mock().Object; - this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder2); - IImageEncoder found2 = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat); - Assert.Equal(encoder2, found2); - Assert.NotEqual(found, found2); - } - - [Fact] - public void RegisterMimeTypeDecoderReplacesLast() - { - IImageDecoder decoder1 = new Mock().Object; - this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder1); - IImageDecoder found = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat); - Assert.Equal(decoder1, found); - - IImageDecoder decoder2 = new Mock().Object; - this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder2); - IImageDecoder found2 = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat); - Assert.Equal(decoder2, found2); - Assert.NotEqual(found, found2); - } - - [Fact] - public void AddFormatCallsConfig() - { - var provider = new Mock(); - var config = new Configuration(); - config.Configure(provider.Object); - - provider.Verify(x => x.Configure(config)); + this.DefaultFormatsManager.SetEncoder(ImageFormats.Bmp, null); + }); + Assert.Throws(() => + { + this.DefaultFormatsManager.SetEncoder(null, null); + }); + } + + [Fact] + public void RegisterNullSetDecoder() + { + Assert.Throws(() => + { + this.DefaultFormatsManager.SetDecoder(null, new Mock().Object); + }); + Assert.Throws(() => + { + this.DefaultFormatsManager.SetDecoder(ImageFormats.Bmp, null); + }); + Assert.Throws(() => + { + this.DefaultFormatsManager.SetDecoder(null, null); + }); + } + + [Fact] + public void RegisterMimeTypeEncoderReplacesLast() + { + IImageEncoder encoder1 = new Mock().Object; + this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder1); + IImageEncoder found = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat); + Assert.Equal(encoder1, found); + + IImageEncoder encoder2 = new Mock().Object; + this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder2); + IImageEncoder found2 = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat); + Assert.Equal(encoder2, found2); + Assert.NotEqual(found, found2); + } + + [Fact] + public void RegisterMimeTypeDecoderReplacesLast() + { + IImageDecoder decoder1 = new Mock().Object; + this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder1); + IImageDecoder found = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat); + Assert.Equal(decoder1, found); + + IImageDecoder decoder2 = new Mock().Object; + this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder2); + IImageDecoder found2 = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat); + Assert.Equal(decoder2, found2); + Assert.NotEqual(found, found2); + } + + [Fact] + public void AddFormatCallsConfig() + { + var provider = new Mock(); + var config = new Configuration(); + config.Configure(provider.Object); + + provider.Verify(x => x.Configure(config)); } } } From 2064002b20ca5051bd363ecd0753d067f17526bb Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 28 Feb 2018 10:05:04 -0800 Subject: [PATCH 07/20] Fix breaking changes from System.Memory in benchmarks --- tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs | 6 +++--- tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index 7d8519875b..7bac44a982 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -3,7 +3,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk { using System.Numerics; using System.Runtime.CompilerServices; - + using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Memory; @@ -37,8 +37,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk [Benchmark(Baseline = true)] public void PerElement() { - ref Vector4 s = ref this.source.Span.DangerousGetPinnableReference(); - ref TPixel d = ref this.destination.Span.DangerousGetPinnableReference(); + ref Vector4 s = ref MemoryMarshal.GetReference(this.source.Span); + ref TPixel d = ref MemoryMarshal.GetReference(this.destination.Span); for (int i = 0; i < this.Count; i++) { diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj index 021b9ead74..6dcfbaf818 100644 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -17,7 +17,9 @@ - + + + From 862998974b6e694fcf00aecbc76c8b2e118ce271 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 28 Feb 2018 10:17:23 -0800 Subject: [PATCH 08/20] Annotate readonly structs --- src/ImageSharp/ColorSpaces/CieLab.cs | 2 +- src/ImageSharp/ColorSpaces/CieLch.cs | 2 +- src/ImageSharp/ColorSpaces/CieLchuv.cs | 2 +- src/ImageSharp/ColorSpaces/CieLuv.cs | 2 +- src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs | 2 +- src/ImageSharp/ColorSpaces/CieXyy.cs | 2 +- src/ImageSharp/ColorSpaces/CieXyz.cs | 2 +- src/ImageSharp/ColorSpaces/Cmyk.cs | 2 +- .../Conversion/Implementation/Rgb/RgbWorkingSpace.cs | 2 +- src/ImageSharp/ColorSpaces/Hsl.cs | 2 +- src/ImageSharp/ColorSpaces/Hsv.cs | 2 +- src/ImageSharp/ColorSpaces/HunterLab.cs | 2 +- src/ImageSharp/ColorSpaces/LinearRgb.cs | 2 +- src/ImageSharp/ColorSpaces/Lms.cs | 2 +- src/ImageSharp/ColorSpaces/Rgb.cs | 2 +- src/ImageSharp/ColorSpaces/YCbCr.cs | 2 +- src/ImageSharp/Formats/Gif/PackedField.cs | 2 +- src/ImageSharp/Formats/Jpeg/Common/Decoder/AdobeMarker.cs | 2 +- src/ImageSharp/Formats/Jpeg/Common/Decoder/JFifMarker.cs | 2 +- .../Jpeg/GolangPort/Components/Decoder/InputProcessor.cs | 2 -- .../Formats/Jpeg/GolangPort/Components/Encoder/HuffmanLut.cs | 2 +- .../Formats/Jpeg/GolangPort/Components/Encoder/HuffmanSpec.cs | 2 +- .../Formats/Jpeg/PdfJsPort/Components/PdfJsYCbCrToRgbTables.cs | 2 +- src/ImageSharp/Memory/BufferArea{T}.cs | 2 +- .../MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs | 2 +- src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs | 2 +- .../MetaData/Profiles/ICC/Various/IccPositionNumber.cs | 2 +- src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs | 2 +- .../MetaData/Profiles/ICC/Various/IccResponseNumber.cs | 2 +- .../MetaData/Profiles/ICC/Various/IccScreeningChannel.cs | 2 +- .../MetaData/Profiles/ICC/Various/IccTagTableEntry.cs | 2 +- src/ImageSharp/Numerics/ValueSize.cs | 2 +- src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs | 2 +- 33 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/ImageSharp/ColorSpaces/CieLab.cs b/src/ImageSharp/ColorSpaces/CieLab.cs index 107be4cb2b..cb08d08bf9 100644 --- a/src/ImageSharp/ColorSpaces/CieLab.cs +++ b/src/ImageSharp/ColorSpaces/CieLab.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// Represents a CIE L*a*b* 1976 color. /// /// - internal struct CieLab : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct CieLab : IColorVector, IEquatable, IAlmostEquatable { /// /// D50 standard illuminant. diff --git a/src/ImageSharp/ColorSpaces/CieLch.cs b/src/ImageSharp/ColorSpaces/CieLch.cs index 834ef56a89..94443fd863 100644 --- a/src/ImageSharp/ColorSpaces/CieLch.cs +++ b/src/ImageSharp/ColorSpaces/CieLch.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// Represents the CIE L*C*h°, cylindrical form of the CIE L*a*b* 1976 color. /// /// - internal struct CieLch : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct CieLch : IColorVector, IEquatable, IAlmostEquatable { /// /// D50 standard illuminant. diff --git a/src/ImageSharp/ColorSpaces/CieLchuv.cs b/src/ImageSharp/ColorSpaces/CieLchuv.cs index f35914d641..705b770d35 100644 --- a/src/ImageSharp/ColorSpaces/CieLchuv.cs +++ b/src/ImageSharp/ColorSpaces/CieLchuv.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// Represents the CIE L*C*h°, cylindrical form of the CIE L*u*v* 1976 color. /// /// - internal struct CieLchuv : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct CieLchuv : IColorVector, IEquatable, IAlmostEquatable { /// /// D50 standard illuminant. diff --git a/src/ImageSharp/ColorSpaces/CieLuv.cs b/src/ImageSharp/ColorSpaces/CieLuv.cs index 9b52517083..b0ae048ab7 100644 --- a/src/ImageSharp/ColorSpaces/CieLuv.cs +++ b/src/ImageSharp/ColorSpaces/CieLuv.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// attempted perceptual uniformity /// /// - internal struct CieLuv : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct CieLuv : IColorVector, IEquatable, IAlmostEquatable { /// /// D65 standard illuminant. diff --git a/src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs b/src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs index 487f464d8e..d0a70dd191 100644 --- a/src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs +++ b/src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// Represents the coordinates of CIEXY chromaticity space /// - internal struct CieXyChromaticityCoordinates : IEquatable, IAlmostEquatable + internal readonly struct CieXyChromaticityCoordinates : IEquatable, IAlmostEquatable { /// /// Represents a that has X, Y values set to zero. diff --git a/src/ImageSharp/ColorSpaces/CieXyy.cs b/src/ImageSharp/ColorSpaces/CieXyy.cs index d5ef4b15d3..751830a0ba 100644 --- a/src/ImageSharp/ColorSpaces/CieXyy.cs +++ b/src/ImageSharp/ColorSpaces/CieXyy.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// Represents an CIE xyY 1931 color /// /// - internal struct CieXyy : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct CieXyy : IColorVector, IEquatable, IAlmostEquatable { /// /// Represents a that has X, Y, and Y values set to zero. diff --git a/src/ImageSharp/ColorSpaces/CieXyz.cs b/src/ImageSharp/ColorSpaces/CieXyz.cs index 908408000a..0f1866009b 100644 --- a/src/ImageSharp/ColorSpaces/CieXyz.cs +++ b/src/ImageSharp/ColorSpaces/CieXyz.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// Represents an CIE XYZ 1931 color /// /// - internal struct CieXyz : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct CieXyz : IColorVector, IEquatable, IAlmostEquatable { /// /// Represents a that has X, Y, and Z values set to zero. diff --git a/src/ImageSharp/ColorSpaces/Cmyk.cs b/src/ImageSharp/ColorSpaces/Cmyk.cs index 2a58a5762a..2eb148a8c3 100644 --- a/src/ImageSharp/ColorSpaces/Cmyk.cs +++ b/src/ImageSharp/ColorSpaces/Cmyk.cs @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// Represents an CMYK (cyan, magenta, yellow, keyline) color. /// - internal struct Cmyk : IEquatable, IAlmostEquatable + internal readonly struct Cmyk : IEquatable, IAlmostEquatable { /// /// Represents a that has C, M, Y, and K values set to zero. diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbWorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbWorkingSpace.cs index 8a2c66a80c..5a5c39647f 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbWorkingSpace.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbWorkingSpace.cs @@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSap /// /// Trivial implementation of /// - internal struct RgbWorkingSpace : IRgbWorkingSpace + internal readonly struct RgbWorkingSpace : IRgbWorkingSpace { /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/ColorSpaces/Hsl.cs b/src/ImageSharp/ColorSpaces/Hsl.cs index cf880f1548..1944ac0c6b 100644 --- a/src/ImageSharp/ColorSpaces/Hsl.cs +++ b/src/ImageSharp/ColorSpaces/Hsl.cs @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// Represents a Hsl (hue, saturation, lightness) color. /// - internal struct Hsl : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct Hsl : IColorVector, IEquatable, IAlmostEquatable { /// /// Represents a that has H, S, and L values set to zero. diff --git a/src/ImageSharp/ColorSpaces/Hsv.cs b/src/ImageSharp/ColorSpaces/Hsv.cs index 9f47393792..45ffd7f121 100644 --- a/src/ImageSharp/ColorSpaces/Hsv.cs +++ b/src/ImageSharp/ColorSpaces/Hsv.cs @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// Represents a HSV (hue, saturation, value) color. Also known as HSB (hue, saturation, brightness). /// - internal struct Hsv : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct Hsv : IColorVector, IEquatable, IAlmostEquatable { /// /// Represents a that has H, S, and V values set to zero. diff --git a/src/ImageSharp/ColorSpaces/HunterLab.cs b/src/ImageSharp/ColorSpaces/HunterLab.cs index b5ba7c86c7..de42518d76 100644 --- a/src/ImageSharp/ColorSpaces/HunterLab.cs +++ b/src/ImageSharp/ColorSpaces/HunterLab.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// Represents an Hunter LAB color. /// /// - internal struct HunterLab : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct HunterLab : IColorVector, IEquatable, IAlmostEquatable { /// /// D50 standard illuminant. diff --git a/src/ImageSharp/ColorSpaces/LinearRgb.cs b/src/ImageSharp/ColorSpaces/LinearRgb.cs index 07889c3529..b8c446285a 100644 --- a/src/ImageSharp/ColorSpaces/LinearRgb.cs +++ b/src/ImageSharp/ColorSpaces/LinearRgb.cs @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// Represents an linear Rgb color with specified working space /// - internal struct LinearRgb : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct LinearRgb : IColorVector, IEquatable, IAlmostEquatable { /// /// Represents a that has R, G, and B values set to zero. diff --git a/src/ImageSharp/ColorSpaces/Lms.cs b/src/ImageSharp/ColorSpaces/Lms.cs index 82c291de3d..72ac16f213 100644 --- a/src/ImageSharp/ColorSpaces/Lms.cs +++ b/src/ImageSharp/ColorSpaces/Lms.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// named after their responsivity (sensitivity) at long, medium and short wavelengths. /// /// - internal struct Lms : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct Lms : IColorVector, IEquatable, IAlmostEquatable { /// /// Represents a that has L, M, and S values set to zero. diff --git a/src/ImageSharp/ColorSpaces/Rgb.cs b/src/ImageSharp/ColorSpaces/Rgb.cs index 8ac8411b20..53fa6086df 100644 --- a/src/ImageSharp/ColorSpaces/Rgb.cs +++ b/src/ImageSharp/ColorSpaces/Rgb.cs @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// Represents an RGB color with specified working space /// - internal struct Rgb : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct Rgb : IColorVector, IEquatable, IAlmostEquatable { /// /// Represents a that has R, G, and B values set to zero. diff --git a/src/ImageSharp/ColorSpaces/YCbCr.cs b/src/ImageSharp/ColorSpaces/YCbCr.cs index 708a74308a..44a0b245d5 100644 --- a/src/ImageSharp/ColorSpaces/YCbCr.cs +++ b/src/ImageSharp/ColorSpaces/YCbCr.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// /// - internal struct YCbCr : IColorVector, IEquatable, IAlmostEquatable + internal readonly struct YCbCr : IColorVector, IEquatable, IAlmostEquatable { /// /// Represents a that has Y, Cb, and Cr values set to zero. diff --git a/src/ImageSharp/Formats/Gif/PackedField.cs b/src/ImageSharp/Formats/Gif/PackedField.cs index 962e2082bf..28a415e2b8 100644 --- a/src/ImageSharp/Formats/Gif/PackedField.cs +++ b/src/ImageSharp/Formats/Gif/PackedField.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// Represents a byte of data in a GIF data stream which contains a number /// of data items. /// - internal struct PackedField : IEquatable + internal readonly struct PackedField : IEquatable { /// /// The individual bits representing the packed byte. diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/AdobeMarker.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/AdobeMarker.cs index 0ec2297d76..d55e36bd48 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/AdobeMarker.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/AdobeMarker.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder /// Provides information about the Adobe marker segment. /// /// See the included 5116.DCT.pdf file in the source for more information. - internal struct AdobeMarker : IEquatable + internal readonly struct AdobeMarker : IEquatable { /// /// Gets the length of an adobe marker segment. diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JFifMarker.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JFifMarker.cs index cba7be5539..c856fd04a6 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JFifMarker.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JFifMarker.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder /// Provides information about the JFIF marker segment /// TODO: Thumbnail? /// - internal struct JFifMarker : IEquatable + internal readonly struct JFifMarker : IEquatable { /// /// Gets the length of an JFIF marker segment. diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs index 88599808fc..fd6a7833a7 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs @@ -5,8 +5,6 @@ using System; using System.IO; using System.Runtime.CompilerServices; -using SixLabors.ImageSharp.Memory; - namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder { /// diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanLut.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanLut.cs index 2fb01c5c8c..7756a7e3ba 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanLut.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanLut.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder /// codeword size in bits and the 24 least significant bits hold the codeword. /// The maximum codeword size is 16 bits. /// - internal struct HuffmanLut + internal readonly struct HuffmanLut { /// /// The compiled representations of theHuffmanSpec. diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanSpec.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanSpec.cs index 8e40cb3689..1c8228aaa2 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanSpec.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanSpec.cs @@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder /// /// The Huffman encoding specifications. /// - internal struct HuffmanSpec + internal readonly struct HuffmanSpec { #pragma warning disable SA1118 // ParameterMustNotSpanMultipleLines diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsYCbCrToRgbTables.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsYCbCrToRgbTables.cs index ddc577270b..203a7b1eb2 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsYCbCrToRgbTables.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsYCbCrToRgbTables.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components /// Provides 8-bit lookup tables for converting from YCbCr to Rgb colorspace. /// Methods to build the tables are based on libjpeg implementation. /// - internal struct PdfJsYCbCrToRgbTables + internal readonly struct PdfJsYCbCrToRgbTables { /// /// The red red-chrominance table diff --git a/src/ImageSharp/Memory/BufferArea{T}.cs b/src/ImageSharp/Memory/BufferArea{T}.cs index 588eae483d..990b494fc7 100644 --- a/src/ImageSharp/Memory/BufferArea{T}.cs +++ b/src/ImageSharp/Memory/BufferArea{T}.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Memory /// This type is kind-of 2D Span, but it can live on heap. /// /// The element type - internal struct BufferArea + internal readonly struct BufferArea where T : struct { /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs index 17127110d6..c5b005ea09 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// Entry of ICC colorant table /// - internal struct IccColorantTableEntry : IEquatable + internal readonly struct IccColorantTableEntry : IEquatable { /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs index 98107e8281..22916c1344 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// A specific color with a name /// - internal struct IccNamedColor : IEquatable + internal readonly struct IccNamedColor : IEquatable { /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs index 6258ca2f36..d886dc099c 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// Position of an object within an ICC profile /// - internal struct IccPositionNumber : IEquatable + internal readonly struct IccPositionNumber : IEquatable { /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs index 1f96540df3..4070f835d6 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// ICC Profile ID /// - public struct IccProfileId : IEquatable + public readonly struct IccProfileId : IEquatable { /// /// A profile ID with all values set to zero diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs index a10c55f4e4..c786a0fd45 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// Associates a normalized device code with a measurement value /// - internal struct IccResponseNumber : IEquatable + internal readonly struct IccResponseNumber : IEquatable { /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs index f41858f303..e1f1bb32fe 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// A single channel of a /// - internal struct IccScreeningChannel : IEquatable + internal readonly struct IccScreeningChannel : IEquatable { /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs index 5464de9c5f..7cb5c7901e 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// Entry of ICC tag table /// - internal struct IccTagTableEntry : IEquatable + internal readonly struct IccTagTableEntry : IEquatable { /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/Numerics/ValueSize.cs b/src/ImageSharp/Numerics/ValueSize.cs index 659e0ebfe1..fcf61a586d 100644 --- a/src/ImageSharp/Numerics/ValueSize.cs +++ b/src/ImageSharp/Numerics/ValueSize.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp /// /// Represents a value in relation to a value on the image /// - internal struct ValueSize : IEquatable + internal readonly struct ValueSize : IEquatable { /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs b/src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs index e3b9c11bdf..07045bb5ab 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Processing.Processors /// Represents a composite pair of pixels. Used for caching color distance lookups. /// /// The pixel format. - internal struct PixelPair : IEquatable> + internal readonly struct PixelPair : IEquatable> where TPixel : struct, IPixel { /// From 7e02d037fb98d9e6c3cfd1a790a860fd121e3a40 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 28 Feb 2018 10:42:24 -0800 Subject: [PATCH 09/20] Work around compiler bug --- .../Common/Decoder/ColorConverters/JpegColorConverter.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs index 23c2071cc6..0427289061 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs @@ -63,10 +63,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters private static JpegColorConverter GetYCbCrConverter() => FromYCbCrSimdAvx2.IsAvailable ? (JpegColorConverter)new FromYCbCrSimdAvx2() : new FromYCbCrSimd(); + /// /// A stack-only struct to reference the input buffers using -s. /// - public ref struct ComponentValues +#pragma warning disable SA1206 // Declaration keywords should follow order + public readonly ref struct ComponentValues +#pragma warning restore SA1206 // Declaration keywords should follow order { /// /// The component count From f6c55f33f7f28e51b018e282fbe8b6eb49c7212a Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 28 Feb 2018 11:38:48 -0800 Subject: [PATCH 10/20] Remove rouge blank line --- .../Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs index 0427289061..187b65f72b 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs @@ -63,7 +63,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters private static JpegColorConverter GetYCbCrConverter() => FromYCbCrSimdAvx2.IsAvailable ? (JpegColorConverter)new FromYCbCrSimdAvx2() : new FromYCbCrSimd(); - /// /// A stack-only struct to reference the input buffers using -s. /// From 924c77f9736de8de6bb4271ab3b74a5b44f6ab4b Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 28 Feb 2018 17:19:51 -0800 Subject: [PATCH 11/20] Update T4 templates --- .../Generated/PixelOperations{TPixel}.Generated.cs | 2 +- .../Generated/PixelOperations{TPixel}.Generated.tt | 13 ++++++++----- .../Generated/Rgba32.PixelOperations.Generated.cs | 2 +- .../Generated/Rgba32.PixelOperations.Generated.tt | 12 ++++++------ 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs index 964fa98f95..9505ee6cf7 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs @@ -7,7 +7,7 @@ namespace SixLabors.ImageSharp.PixelFormats using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - + public partial class PixelOperations { diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt index aa88b6606c..e23f196212 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt @@ -4,9 +4,11 @@ #> <#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> +<#@ assembly name="$(NuGetPackageRoot)/system.memory/4.5.0-preview1-26216-02/lib/netstandard2.0/System.Memory.dll" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Runtime.InteropServices" #> <#@ output extension=".cs" #> <# void GenerateToDestFormatMethods(string pixelType) @@ -24,8 +26,8 @@ { GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); - ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference(); - ref <#=pixelType#> destBaseRef = ref dest.DangerousGetPinnableReference(); + ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destBaseRef = ref MemoryMarshal.GetReference(dest); for (int i = 0; i < count; i++) { @@ -64,8 +66,8 @@ { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref <#=pixelType#> sourceRef = ref source.DangerousGetPinnableReference(); - ref TPixel destRef = ref destPixels.DangerousGetPinnableReference(); + ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); Rgba32 rgba = new Rgba32(0, 0, 0, 255); @@ -101,7 +103,8 @@ namespace SixLabors.ImageSharp.PixelFormats { using System; using System.Runtime.CompilerServices; - + using System.Runtime.InteropServices; + public partial class PixelOperations { <# diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs index 43060539dc..edf6a88e1f 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.ImageSharp.PixelFormats; - + /// /// Provides optimized overrides for bulk operations. /// diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt index 9d22293947..d83e49f770 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt @@ -18,8 +18,8 @@ { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref <#=pixelType#> sourceRef = ref source.DangerousGetPinnableReference(); - ref Rgba32 destRef = ref destPixels.DangerousGetPinnableReference(); + ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { @@ -40,8 +40,8 @@ { GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); - ref Rgba32 sourceRef = ref sourcePixels.DangerousGetPinnableReference(); - ref <#=pixelType#> destRef = ref dest.DangerousGetPinnableReference(); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(dest); for (int i = 0; i < count; i++) { @@ -61,9 +61,9 @@ namespace SixLabors.ImageSharp { using System; using System.Runtime.CompilerServices; - + using System.Runtime.InteropServices; using SixLabors.ImageSharp.PixelFormats; - + /// /// Provides optimized overrides for bulk operations. /// From 72e5e51ed80bd2a4f21abb0da9b2428d81be2c6a Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 28 Feb 2018 17:24:50 -0800 Subject: [PATCH 12/20] Remove T4 reference --- .../PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt index e23f196212..365f5cb514 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt @@ -4,7 +4,6 @@ #> <#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> -<#@ assembly name="$(NuGetPackageRoot)/system.memory/4.5.0-preview1-26216-02/lib/netstandard2.0/System.Memory.dll" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> From 7e8e78070f19acaf3e674c857dab89257b75cbb1 Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Thu, 1 Mar 2018 09:39:05 +0100 Subject: [PATCH 13/20] Added a convenience copy constructor. --- src/ImageSharp/Configuration.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 0f69194f2d..771e2007fd 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -33,6 +33,18 @@ namespace SixLabors.ImageSharp { } + /// + /// Initializes a new instance of the class. + /// + /// A configuration instance to be copied + public Configuration(Configuration configuration) + { + this.ParallelOptions = configuration.ParallelOptions; + this.ImageFormatsManager = configuration.ImageFormatsManager; + this.MemoryManager = configuration.MemoryManager; + this.ImageOperationsProvider = configuration.ImageOperationsProvider; + } + /// /// Initializes a new instance of the class. /// From 53f40b0f396278bee43ed3541566179c70d9944c Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Thu, 1 Mar 2018 13:33:10 +0100 Subject: [PATCH 14/20] added missing property in copy constructor. --- src/ImageSharp/Configuration.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 771e2007fd..afa63dacbf 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -43,6 +43,10 @@ namespace SixLabors.ImageSharp this.ImageFormatsManager = configuration.ImageFormatsManager; this.MemoryManager = configuration.MemoryManager; this.ImageOperationsProvider = configuration.ImageOperationsProvider; + + #if !NETSTANDARD1_1 + this.FileSystem = configuration.FileSystem; + #endif } /// From 2cb62b84d90bad5c1ff9fd33b4c4e00916bf0ace Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Thu, 1 Mar 2018 15:43:36 +0100 Subject: [PATCH 15/20] whitespaces removed --- src/ImageSharp/Configuration.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index b0e414c2fe..5912ac6309 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp #if !NETSTANDARD1_1 this.FileSystem = configuration.FileSystem; #endif - + this.ReadOrigin = configuration.ReadOrigin; } @@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp /// Gets the currently registered s. /// public IEnumerable ImageFormats => this.ImageFormatsManager.ImageFormats; - + /// /// Gets or sets the position in a stream to use for reading when using a seekable stream as an image data source. /// From 37d8c479237182372551b4a97f63d7c2e18f25dc Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 2 Mar 2018 17:19:51 +1100 Subject: [PATCH 16/20] Can now read padded RSTn markers. Fix #481 --- .../Components/Decoder/OrigJpegScanDecoder.cs | 28 ++++++++++++++++--- .../PdfJsPort/Components/PdfJsScanDecoder.cs | 2 +- .../Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs | 2 +- .../Formats/Jpg/JpegDecoderTests.cs | 6 ++-- tests/ImageSharp.Tests/TestImages.cs | 1 + tests/Images/External | 2 +- tests/Images/Input/Jpg/baseline/badrst.jpg | 3 ++ 7 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 tests/Images/Input/Jpg/baseline/badrst.jpg diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs index 67abba9f33..7d58d168a6 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs @@ -197,16 +197,36 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder if (decoder.RestartInterval > 0 && mcu % decoder.RestartInterval == 0 && mcu < decoder.TotalMCUCount) { - // A more sophisticated decoder could use RST[0-7] markers to resynchronize from corrupt input, - // but this one assumes well-formed input, and hence the restart marker follows immediately. + // Attempt to look for RST[0-7] markers to resynchronize from corrupt input. if (!decoder.InputProcessor.ReachedEOF) { decoder.InputProcessor.ReadFullUnsafe(decoder.Temp, 0, 2); if (decoder.InputProcessor.CheckEOFEnsureNoError()) { - if (decoder.Temp[0] != 0xff || decoder.Temp[1] != expectedRst) + if (decoder.Temp[0] != 0xFF || decoder.Temp[1] != expectedRst) { - throw new ImageFormatException("Bad RST marker"); + bool invalidRst = true; + + // Most jpeg's containing well-formed input will have a RST[0-7] marker following immediately + // but some, see Issue #481, contain padding bytes "0xFF" before the RST[0-7] marker. + // If we identify that case we attempt to read until we have bypassed the padded bytes. + // We then check again for our RST marker and throw if invalid. + // No other methods are attempted to resynchronize from corrupt input. + if (decoder.Temp[0] == 0xFF && decoder.Temp[1] == 0xFF) + { + while (decoder.Temp[0] == 0xFF && decoder.InputProcessor.CheckEOFEnsureNoError()) + { + decoder.InputProcessor.ReadFullUnsafe(decoder.Temp, 0, 1); + } + + // Have we found a valid restart marker? + invalidRst = decoder.Temp[0] != expectedRst; + } + + if (invalidRst) + { + throw new ImageFormatException("Bad RST marker"); + } } expectedRst++; diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs index 9e245ea2c6..c6f6ac270f 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs @@ -154,7 +154,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components ushort marker = fileMarker.Marker; - // RSTn - We've alread read the bytes and altered the position so no need to skip + // RSTn - We've already read the bytes and altered the position so no need to skip if (marker >= PdfJsJpegConstants.Markers.RST0 && marker <= PdfJsJpegConstants.Markers.RST7) { continue; diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs index 4fa0bc281d..54e2833b11 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs @@ -137,7 +137,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort return new PdfJsFileMarker(PdfJsJpegConstants.Markers.EOI, (int)stream.Length - 2); } - marker[1] = (byte)value; + marker[1] = (byte)suffix; } return new PdfJsFileMarker((ushort)((marker[0] << 8) | marker[1]), (int)(stream.Position - 2)); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 139fa351bb..95ee40e807 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -42,7 +42,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Baseline.Jpeg444, TestImages.Jpeg.Baseline.Bad.BadEOF, TestImages.Jpeg.Issues.MultiHuffmanBaseline394, - TestImages.Jpeg.Baseline.MultiScanBaselineCMYK + TestImages.Jpeg.Baseline.MultiScanBaselineCMYK, + TestImages.Jpeg.Baseline.Bad.BadRST }; public static string[] ProgressiveTestJpegs = @@ -61,6 +62,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [TestImages.Jpeg.Baseline.Calliphora] = 0.00002f / 100, [TestImages.Jpeg.Baseline.Bad.BadEOF] = 0.38f / 100, [TestImages.Jpeg.Baseline.Testorig420] = 0.38f / 100, + [TestImages.Jpeg.Baseline.Bad.BadRST] = 0.0589f / 100, // Progressive: [TestImages.Jpeg.Issues.MissingFF00ProgressiveGirl159] = 0.34f / 100, @@ -119,7 +121,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } public const string DecodeBaselineJpegOutputName = "DecodeBaselineJpeg"; - + [Theory] [WithFile(TestImages.Jpeg.Baseline.Calliphora, CommonNonDefaultPixelTypes, false)] [WithFile(TestImages.Jpeg.Baseline.Calliphora, CommonNonDefaultPixelTypes, true)] diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index f1f989581f..db469f87e1 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -96,6 +96,7 @@ namespace SixLabors.ImageSharp.Tests public static class Bad { public const string BadEOF = "Jpg/baseline/badeof.jpg"; + public const string BadRST = "Jpg/baseline/badrst.jpg"; } public const string Cmyk = "Jpg/baseline/cmyk.jpg"; diff --git a/tests/Images/External b/tests/Images/External index 8714b94dc4..653f0c7e3c 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 8714b94dc4bab6788fcbb6254174db2b9c8f69c9 +Subproject commit 653f0c7e3c84657f68dd46e5a380186b3696b956 diff --git a/tests/Images/Input/Jpg/baseline/badrst.jpg b/tests/Images/Input/Jpg/baseline/badrst.jpg new file mode 100644 index 0000000000..61805b42d3 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/badrst.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af18f0bf30231d2c4c0e6b80d4636237c2851f67763788de12931fd1960c4ff3 +size 74497 From 1ce9342d229b6fb779c83c369fe6dc91944ae923 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 2 Mar 2018 17:32:29 +1100 Subject: [PATCH 17/20] Check and ensure no error --- .../Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs index 7d58d168a6..2e1372c564 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs @@ -217,6 +217,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder while (decoder.Temp[0] == 0xFF && decoder.InputProcessor.CheckEOFEnsureNoError()) { decoder.InputProcessor.ReadFullUnsafe(decoder.Temp, 0, 1); + if (!decoder.InputProcessor.CheckEOFEnsureNoError()) + { + break; + } } // Have we found a valid restart marker? From ce62a947d9b6a362bcc252c9aa0080a5402d7399 Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Fri, 2 Mar 2018 10:00:41 +0100 Subject: [PATCH 18/20] replaced Configuration copy constructor with a ShallowCopy method. --- src/ImageSharp/Configuration.cs | 42 +++++++++++--------- tests/ImageSharp.Tests/ConfigurationTests.cs | 6 ++- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 5912ac6309..8d3811a974 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -33,24 +33,6 @@ namespace SixLabors.ImageSharp { } - /// - /// Initializes a new instance of the class. - /// - /// A configuration instance to be copied - public Configuration(Configuration configuration) - { - this.ParallelOptions = configuration.ParallelOptions; - this.ImageFormatsManager = configuration.ImageFormatsManager; - this.MemoryManager = configuration.MemoryManager; - this.ImageOperationsProvider = configuration.ImageOperationsProvider; - - #if !NETSTANDARD1_1 - this.FileSystem = configuration.FileSystem; - #endif - - this.ReadOrigin = configuration.ReadOrigin; - } - /// /// Initializes a new instance of the class. /// @@ -74,7 +56,7 @@ namespace SixLabors.ImageSharp /// /// Gets the global parallel options for processing tasks in parallel. /// - public ParallelOptions ParallelOptions { get; } = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; + public ParallelOptions ParallelOptions { get; private set; } = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; /// /// Gets the currently registered s. @@ -138,6 +120,28 @@ namespace SixLabors.ImageSharp configuration.Configure(this); } + /// + /// Creates a shallow copy of the + /// + /// A new configuration instance + public Configuration ShallowCopy() + { + Configuration cfg = new Configuration(); + + cfg.ParallelOptions = this.ParallelOptions; + cfg.ImageFormatsManager = this.ImageFormatsManager; + cfg.MemoryManager = this.MemoryManager; + cfg.ImageOperationsProvider = this.ImageOperationsProvider; + +#if !NETSTANDARD1_1 + cfg.FileSystem = this.FileSystem; +#endif + + cfg.ReadOrigin = this.ReadOrigin; + + return cfg; + } + /// /// Registers a new format provider. /// diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs index 06f02fcf16..d38556fa9e 100644 --- a/tests/ImageSharp.Tests/ConfigurationTests.cs +++ b/tests/ImageSharp.Tests/ConfigurationTests.cs @@ -22,8 +22,10 @@ namespace SixLabors.ImageSharp.Tests public Configuration DefaultConfiguration { get; private set; } public ConfigurationTests() - { - this.DefaultConfiguration = Configuration.CreateDefaultInstance(); + { + // the shallow copy of configuration should behave exactly like the default configuration, + // so by using the copy, we test both the default and the copy. + this.DefaultConfiguration = Configuration.CreateDefaultInstance().ShallowCopy(); this.ConfigurationEmpty = new Configuration(); } From 1f2b2b8a7a82e6c970ed43a9708af196a88088c7 Mon Sep 17 00:00:00 2001 From: Vicente Penades Date: Fri, 2 Mar 2018 10:15:42 +0100 Subject: [PATCH 19/20] removed ImageFormat redirect methods from Configuration. --- src/ImageSharp/Configuration.cs | 121 ++---------------- .../Formats/Bmp/BmpConfigurationModule.cs | 6 +- src/ImageSharp/Formats/Bmp/ImageExtensions.cs | 2 +- .../Formats/Gif/GifConfigurationModule.cs | 6 +- src/ImageSharp/Formats/Gif/ImageExtensions.cs | 2 +- .../Formats/Jpeg/ImageExtensions.cs | 2 +- .../Formats/Jpeg/JpegConfigurationModule.cs | 6 +- src/ImageSharp/Formats/Png/ImageExtensions.cs | 2 +- .../Formats/Png/PngConfigurationModule.cs | 6 +- src/ImageSharp/Image/Image.Decode.cs | 4 +- src/ImageSharp/Image/Image.FromStream.cs | 2 +- src/ImageSharp/Image/ImageExtensions.cs | 10 +- tests/ImageSharp.Tests/ConfigurationTests.cs | 83 +----------- .../Image/ImageDiscoverMimeType.cs | 2 +- .../ImageSharp.Tests/Image/ImageLoadTests.cs | 4 +- .../ImageSharp.Tests/Image/ImageSaveTests.cs | 4 +- tests/ImageSharp.Tests/TestFormat.cs | 6 +- .../TestUtilities/TestEnvironment.Formats.cs | 12 +- .../TestUtilities/TestImageExtensions.cs | 2 +- 19 files changed, 49 insertions(+), 233 deletions(-) diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 8d3811a974..d41e48678b 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -83,21 +83,6 @@ namespace SixLabors.ImageSharp /// internal int MaxHeaderSize => this.ImageFormatsManager.MaxHeaderSize; - /// - /// Gets the currently registered s. - /// - internal IEnumerable FormatDetectors => this.ImageFormatsManager.FormatDetectors; - - /// - /// Gets the currently registered s. - /// - internal IEnumerable> ImageDecoders => this.ImageFormatsManager.ImageDecoders; - - /// - /// Gets the currently registered s. - /// - internal IEnumerable> ImageEncoders => this.ImageFormatsManager.ImageEncoders; - #if !NETSTANDARD1_1 /// /// Gets or sets the filesystem helper for accessing the local file system. @@ -126,106 +111,18 @@ namespace SixLabors.ImageSharp /// A new configuration instance public Configuration ShallowCopy() { - Configuration cfg = new Configuration(); - - cfg.ParallelOptions = this.ParallelOptions; - cfg.ImageFormatsManager = this.ImageFormatsManager; - cfg.MemoryManager = this.MemoryManager; - cfg.ImageOperationsProvider = this.ImageOperationsProvider; + return new Configuration + { + ParallelOptions = this.ParallelOptions, + ImageFormatsManager = this.ImageFormatsManager, + MemoryManager = this.MemoryManager, + ImageOperationsProvider = this.ImageOperationsProvider, + ReadOrigin = this.ReadOrigin, #if !NETSTANDARD1_1 - cfg.FileSystem = this.FileSystem; + FileSystem = this.FileSystem #endif - - cfg.ReadOrigin = this.ReadOrigin; - - return cfg; - } - - /// - /// Registers a new format provider. - /// - /// The format to register as a known format. - public void AddImageFormat(IImageFormat format) - { - this.ImageFormatsManager.AddImageFormat(format); - } - - /// - /// For the specified file extensions type find the e . - /// - /// The extension to discover - /// The if found otherwise null - public IImageFormat FindFormatByFileExtension(string extension) - { - return this.ImageFormatsManager.FindFormatByFileExtension(extension); - } - - /// - /// For the specified mime type find the . - /// - /// The mime-type to discover - /// The if found; otherwise null - public IImageFormat FindFormatByMimeType(string mimeType) - { - return this.ImageFormatsManager.FindFormatByMimeType(mimeType); - } - - /// - /// Sets a specific image encoder as the encoder for a specific image format. - /// - /// The image format to register the encoder for. - /// The encoder to use, - public void SetEncoder(IImageFormat imageFormat, IImageEncoder encoder) - { - this.ImageFormatsManager.SetEncoder(imageFormat, encoder); - } - - /// - /// Sets a specific image decoder as the decoder for a specific image format. - /// - /// The image format to register the encoder for. - /// The decoder to use, - public void SetDecoder(IImageFormat imageFormat, IImageDecoder decoder) - { - this.ImageFormatsManager.SetDecoder(imageFormat, decoder); - } - - /// - /// Removes all the registered image format detectors. - /// - public void ClearImageFormatDetectors() - { - this.ImageFormatsManager.ClearImageFormatDetectors(); - } - - /// - /// Adds a new detector for detecting mime types. - /// - /// The detector to add - public void AddImageFormatDetector(IImageFormatDetector detector) - { - this.ImageFormatsManager.AddImageFormatDetector(detector); - } - - /// - /// For the specified mime type find the decoder. - /// - /// The format to discover - /// The if found otherwise null - public IImageDecoder FindDecoder(IImageFormat format) - { - return this.ImageFormatsManager.FindDecoder(format); - } - - /// - /// For the specified mime type find the encoder. - /// - /// The format to discover - /// The if found otherwise null - public IImageEncoder FindEncoder(IImageFormat format) - { - return this.ImageFormatsManager.FindEncoder(format); + }; } /// diff --git a/src/ImageSharp/Formats/Bmp/BmpConfigurationModule.cs b/src/ImageSharp/Formats/Bmp/BmpConfigurationModule.cs index b091467bf5..956acc1578 100644 --- a/src/ImageSharp/Formats/Bmp/BmpConfigurationModule.cs +++ b/src/ImageSharp/Formats/Bmp/BmpConfigurationModule.cs @@ -11,9 +11,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// public void Configure(Configuration config) { - config.SetEncoder(ImageFormats.Bmp, new BmpEncoder()); - config.SetDecoder(ImageFormats.Bmp, new BmpDecoder()); - config.AddImageFormatDetector(new BmpImageFormatDetector()); + config.ImageFormatsManager.SetEncoder(ImageFormats.Bmp, new BmpEncoder()); + config.ImageFormatsManager.SetDecoder(ImageFormats.Bmp, new BmpDecoder()); + config.ImageFormatsManager.AddImageFormatDetector(new BmpImageFormatDetector()); } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Bmp/ImageExtensions.cs b/src/ImageSharp/Formats/Bmp/ImageExtensions.cs index 935ce8f4ad..35e168e278 100644 --- a/src/ImageSharp/Formats/Bmp/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Bmp/ImageExtensions.cs @@ -36,6 +36,6 @@ namespace SixLabors.ImageSharp /// Thrown if the stream is null. public static void SaveAsBmp(this Image source, Stream stream, BmpEncoder encoder) where TPixel : struct, IPixel - => source.Save(stream, encoder ?? source.GetConfiguration().FindEncoder(ImageFormats.Bmp)); + => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(ImageFormats.Bmp)); } } diff --git a/src/ImageSharp/Formats/Gif/GifConfigurationModule.cs b/src/ImageSharp/Formats/Gif/GifConfigurationModule.cs index 4c42a833c0..0bb62779eb 100644 --- a/src/ImageSharp/Formats/Gif/GifConfigurationModule.cs +++ b/src/ImageSharp/Formats/Gif/GifConfigurationModule.cs @@ -11,10 +11,10 @@ namespace SixLabors.ImageSharp.Formats.Gif /// public void Configure(Configuration config) { - config.SetEncoder(ImageFormats.Gif, new GifEncoder()); - config.SetDecoder(ImageFormats.Gif, new GifDecoder()); + config.ImageFormatsManager.SetEncoder(ImageFormats.Gif, new GifEncoder()); + config.ImageFormatsManager.SetDecoder(ImageFormats.Gif, new GifDecoder()); - config.AddImageFormatDetector(new GifImageFormatDetector()); + config.ImageFormatsManager.AddImageFormatDetector(new GifImageFormatDetector()); } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs index 939eb456e1..78acadb4b1 100644 --- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs @@ -36,6 +36,6 @@ namespace SixLabors.ImageSharp /// Thrown if the stream is null. public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder) where TPixel : struct, IPixel - => source.Save(stream, encoder ?? source.GetConfiguration().FindEncoder(ImageFormats.Gif)); + => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(ImageFormats.Gif)); } } diff --git a/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs b/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs index 9cd7b3a8bd..d3f95e40c0 100644 --- a/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs @@ -36,6 +36,6 @@ namespace SixLabors.ImageSharp /// Thrown if the stream is null. public static void SaveAsJpeg(this Image source, Stream stream, JpegEncoder encoder) where TPixel : struct, IPixel - => source.Save(stream, encoder ?? source.GetConfiguration().FindEncoder(ImageFormats.Jpeg)); + => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(ImageFormats.Jpeg)); } } diff --git a/src/ImageSharp/Formats/Jpeg/JpegConfigurationModule.cs b/src/ImageSharp/Formats/Jpeg/JpegConfigurationModule.cs index 1ab5093398..23cef59273 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegConfigurationModule.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegConfigurationModule.cs @@ -11,10 +11,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// public void Configure(Configuration config) { - config.SetEncoder(ImageFormats.Jpeg, new JpegEncoder()); - config.SetDecoder(ImageFormats.Jpeg, new JpegDecoder()); + config.ImageFormatsManager.SetEncoder(ImageFormats.Jpeg, new JpegEncoder()); + config.ImageFormatsManager.SetDecoder(ImageFormats.Jpeg, new JpegDecoder()); - config.AddImageFormatDetector(new JpegImageFormatDetector()); + config.ImageFormatsManager.AddImageFormatDetector(new JpegImageFormatDetector()); } } } diff --git a/src/ImageSharp/Formats/Png/ImageExtensions.cs b/src/ImageSharp/Formats/Png/ImageExtensions.cs index 10970fc16a..f25d2bffe2 100644 --- a/src/ImageSharp/Formats/Png/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Png/ImageExtensions.cs @@ -35,6 +35,6 @@ namespace SixLabors.ImageSharp /// Thrown if the stream is null. public static void SaveAsPng(this Image source, Stream stream, PngEncoder encoder) where TPixel : struct, IPixel - => source.Save(stream, encoder ?? source.GetConfiguration().FindEncoder(ImageFormats.Png)); + => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(ImageFormats.Png)); } } diff --git a/src/ImageSharp/Formats/Png/PngConfigurationModule.cs b/src/ImageSharp/Formats/Png/PngConfigurationModule.cs index ab6f31d49a..0036280a83 100644 --- a/src/ImageSharp/Formats/Png/PngConfigurationModule.cs +++ b/src/ImageSharp/Formats/Png/PngConfigurationModule.cs @@ -11,9 +11,9 @@ namespace SixLabors.ImageSharp.Formats.Png /// public void Configure(Configuration config) { - config.SetEncoder(ImageFormats.Png, new PngEncoder()); - config.SetDecoder(ImageFormats.Png, new PngDecoder()); - config.AddImageFormatDetector(new PngImageFormatDetector()); + config.ImageFormatsManager.SetEncoder(ImageFormats.Png, new PngEncoder()); + config.ImageFormatsManager.SetDecoder(ImageFormats.Png, new PngDecoder()); + config.ImageFormatsManager.AddImageFormatDetector(new PngImageFormatDetector()); } } } \ No newline at end of file diff --git a/src/ImageSharp/Image/Image.Decode.cs b/src/ImageSharp/Image/Image.Decode.cs index 72492a494b..6b44c893bc 100644 --- a/src/ImageSharp/Image/Image.Decode.cs +++ b/src/ImageSharp/Image/Image.Decode.cs @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp long startPosition = stream.Position; stream.Read(buffer.Array, 0, maxHeaderSize); stream.Position = startPosition; - return config.FormatDetectors.Select(x => x.DetectFormat(buffer.Span)).LastOrDefault(x => x != null); + return config.ImageFormatsManager.FormatDetectors.Select(x => x.DetectFormat(buffer.Span)).LastOrDefault(x => x != null); } } @@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp format = InternalDetectFormat(stream, config); if (format != null) { - return config.FindDecoder(format); + return config.ImageFormatsManager.FindDecoder(format); } return null; diff --git a/src/ImageSharp/Image/Image.FromStream.cs b/src/ImageSharp/Image/Image.FromStream.cs index 4e294260aa..9061c334dc 100644 --- a/src/ImageSharp/Image/Image.FromStream.cs +++ b/src/ImageSharp/Image/Image.FromStream.cs @@ -186,7 +186,7 @@ namespace SixLabors.ImageSharp var stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Image cannot be loaded. Available decoders:"); - foreach (KeyValuePair val in config.ImageDecoders) + foreach (KeyValuePair val in config.ImageFormatsManager.ImageDecoders) { stringBuilder.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}"); } diff --git a/src/ImageSharp/Image/ImageExtensions.cs b/src/ImageSharp/Image/ImageExtensions.cs index c4de1c2988..7d23d95d9c 100644 --- a/src/ImageSharp/Image/ImageExtensions.cs +++ b/src/ImageSharp/Image/ImageExtensions.cs @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp Guard.NotNullOrEmpty(filePath, nameof(filePath)); string ext = Path.GetExtension(filePath).Trim('.'); - IImageFormat format = source.GetConfiguration().FindFormatByFileExtension(ext); + IImageFormat format = source.GetConfiguration().ImageFormatsManager.FindFormatByFileExtension(ext); if (format == null) { var stringBuilder = new StringBuilder(); @@ -45,13 +45,13 @@ namespace SixLabors.ImageSharp throw new NotSupportedException(stringBuilder.ToString()); } - IImageEncoder encoder = source.GetConfiguration().FindEncoder(format); + IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format); if (encoder == null) { var stringBuilder = new StringBuilder(); stringBuilder.AppendLine($"Can't find encoder for file extention '{ext}' using image format '{format.Name}'. Registered encoders include:"); - foreach (KeyValuePair enc in source.GetConfiguration().ImageEncoders) + foreach (KeyValuePair enc in source.GetConfiguration().ImageFormatsManager.ImageEncoders) { stringBuilder.AppendLine($" - {enc.Key} : {enc.Value.GetType().Name}"); } @@ -93,14 +93,14 @@ namespace SixLabors.ImageSharp where TPixel : struct, IPixel { Guard.NotNull(format, nameof(format)); - IImageEncoder encoder = source.GetConfiguration().FindEncoder(format); + IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format); if (encoder == null) { var stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Can't find encoder for provided mime type. Available encoded:"); - foreach (KeyValuePair val in source.GetConfiguration().ImageEncoders) + foreach (KeyValuePair val in source.GetConfiguration().ImageFormatsManager.ImageEncoders) { stringBuilder.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}"); } diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs index d38556fa9e..cf348569ce 100644 --- a/tests/ImageSharp.Tests/ConfigurationTests.cs +++ b/tests/ImageSharp.Tests/ConfigurationTests.cs @@ -34,14 +34,7 @@ namespace SixLabors.ImageSharp.Tests { Assert.IsType(this.DefaultConfiguration.FileSystem); Assert.IsType(this.ConfigurationEmpty.FileSystem); - } - - [Fact] - public void IfAutoloadWellknwonFormatesIsTrueAllFormateAreLoaded() - { - Assert.Equal(4, this.DefaultConfiguration.ImageEncoders.Count()); - Assert.Equal(4, this.DefaultConfiguration.ImageDecoders.Count()); - } + } /// /// Test that the default configuration is not null. @@ -80,80 +73,6 @@ namespace SixLabors.ImageSharp.Tests Assert.True(Configuration.Default.ParallelOptions.MaxDegreeOfParallelism == Environment.ProcessorCount); } - [Fact] - public void AddImageFormatDetectorNullthrows() - { - Assert.Throws(() => - { - this.DefaultConfiguration.AddImageFormatDetector(null); - }); - } - - [Fact] - public void RegisterNullMimeTypeEncoder() - { - Assert.Throws(() => - { - this.DefaultConfiguration.SetEncoder(null, new Mock().Object); - }); - Assert.Throws(() => - { - this.DefaultConfiguration.SetEncoder(ImageFormats.Bmp, null); - }); - Assert.Throws(() => - { - this.DefaultConfiguration.SetEncoder(null, null); - }); - } - - [Fact] - public void RegisterNullSetDecoder() - { - Assert.Throws(() => - { - this.DefaultConfiguration.SetDecoder(null, new Mock().Object); - }); - Assert.Throws(() => - { - this.DefaultConfiguration.SetDecoder(ImageFormats.Bmp, null); - }); - Assert.Throws(() => - { - this.DefaultConfiguration.SetDecoder(null, null); - }); - } - - [Fact] - public void RegisterMimeTypeEncoderReplacesLast() - { - IImageEncoder encoder1 = new Mock().Object; - this.ConfigurationEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder1); - IImageEncoder found = this.ConfigurationEmpty.FindEncoder(TestFormat.GlobalTestFormat); - Assert.Equal(encoder1, found); - - IImageEncoder encoder2 = new Mock().Object; - this.ConfigurationEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder2); - IImageEncoder found2 = this.ConfigurationEmpty.FindEncoder(TestFormat.GlobalTestFormat); - Assert.Equal(encoder2, found2); - Assert.NotEqual(found, found2); - } - - [Fact] - public void RegisterMimeTypeDecoderReplacesLast() - { - IImageDecoder decoder1 = new Mock().Object; - this.ConfigurationEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder1); - IImageDecoder found = this.ConfigurationEmpty.FindDecoder(TestFormat.GlobalTestFormat); - Assert.Equal(decoder1, found); - - IImageDecoder decoder2 = new Mock().Object; - this.ConfigurationEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder2); - IImageDecoder found2 = this.ConfigurationEmpty.FindDecoder(TestFormat.GlobalTestFormat); - Assert.Equal(decoder2, found2); - Assert.NotEqual(found, found2); - } - - [Fact] public void ConstructorCallConfigureOnFormatProvider() { diff --git a/tests/ImageSharp.Tests/Image/ImageDiscoverMimeType.cs b/tests/ImageSharp.Tests/Image/ImageDiscoverMimeType.cs index f19fa1990c..1a2275062e 100644 --- a/tests/ImageSharp.Tests/Image/ImageDiscoverMimeType.cs +++ b/tests/ImageSharp.Tests/Image/ImageDiscoverMimeType.cs @@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp.Tests FileSystem = this.fileSystem.Object }; - this.LocalConfiguration.AddImageFormatDetector(this.localMimeTypeDetector); + this.LocalConfiguration.ImageFormatsManager.AddImageFormatDetector(this.localMimeTypeDetector); TestFormat.RegisterGlobalTestFormat(); this.Marker = Guid.NewGuid().ToByteArray(); diff --git a/tests/ImageSharp.Tests/Image/ImageLoadTests.cs b/tests/ImageSharp.Tests/Image/ImageLoadTests.cs index de18714e2b..97274e98b3 100644 --- a/tests/ImageSharp.Tests/Image/ImageLoadTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageLoadTests.cs @@ -54,8 +54,8 @@ namespace SixLabors.ImageSharp.Tests { FileSystem = this.fileSystem.Object }; - this.LocalConfiguration.AddImageFormatDetector(this.localMimeTypeDetector); - this.LocalConfiguration.SetDecoder(this.localImageFormatMock.Object, this.localDecoder.Object); + this.LocalConfiguration.ImageFormatsManager.AddImageFormatDetector(this.localMimeTypeDetector); + this.LocalConfiguration.ImageFormatsManager.SetDecoder(this.localImageFormatMock.Object, this.localDecoder.Object); TestFormat.RegisterGlobalTestFormat(); this.Marker = Guid.NewGuid().ToByteArray(); diff --git a/tests/ImageSharp.Tests/Image/ImageSaveTests.cs b/tests/ImageSharp.Tests/Image/ImageSaveTests.cs index 7f6e3b7dac..028313e631 100644 --- a/tests/ImageSharp.Tests/Image/ImageSaveTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageSaveTests.cs @@ -42,8 +42,8 @@ namespace SixLabors.ImageSharp.Tests { FileSystem = this.fileSystem.Object }; - config.AddImageFormatDetector(this.localMimeTypeDetector); - config.SetEncoder(this.localImageFormat.Object, this.encoder.Object); + config.ImageFormatsManager.AddImageFormatDetector(this.localMimeTypeDetector); + config.ImageFormatsManager.SetEncoder(this.localImageFormat.Object, this.encoder.Object); this.Image = new Image(config, 1, 1); } diff --git a/tests/ImageSharp.Tests/TestFormat.cs b/tests/ImageSharp.Tests/TestFormat.cs index 078b708dfd..445ace9812 100644 --- a/tests/ImageSharp.Tests/TestFormat.cs +++ b/tests/ImageSharp.Tests/TestFormat.cs @@ -116,9 +116,9 @@ namespace SixLabors.ImageSharp.Tests public void Configure(Configuration host) { - host.AddImageFormatDetector(new TestHeader(this)); - host.SetEncoder(this, new TestEncoder(this)); - host.SetDecoder(this, new TestDecoder(this)); + host.ImageFormatsManager.AddImageFormatDetector(new TestHeader(this)); + host.ImageFormatsManager.SetEncoder(this, new TestEncoder(this)); + host.ImageFormatsManager.SetDecoder(this, new TestDecoder(this)); } public struct DecodeOperation diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs index 089fed6b0a..fa9497a8f8 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs @@ -21,20 +21,20 @@ namespace SixLabors.ImageSharp.Tests internal static IImageDecoder GetReferenceDecoder(string filePath) { IImageFormat format = GetImageFormat(filePath); - return Configuration.FindDecoder(format); + return Configuration.ImageFormatsManager.FindDecoder(format); } internal static IImageEncoder GetReferenceEncoder(string filePath) { IImageFormat format = GetImageFormat(filePath); - return Configuration.FindEncoder(format); + return Configuration.ImageFormatsManager.FindEncoder(format); } internal static IImageFormat GetImageFormat(string filePath) { string extension = Path.GetExtension(filePath).ToLower(); if (extension[0] == '.') extension = extension.Substring(1); - IImageFormat format = Configuration.FindFormatByFileExtension(extension); + IImageFormat format = Configuration.ImageFormatsManager.FindFormatByFileExtension(extension); return format; } @@ -45,9 +45,9 @@ namespace SixLabors.ImageSharp.Tests IImageEncoder encoder, IImageFormatDetector detector) { - cfg.SetDecoder(imageFormat, decoder); - cfg.SetEncoder(imageFormat, encoder); - cfg.AddImageFormatDetector(detector); + cfg.ImageFormatsManager.SetDecoder(imageFormat, decoder); + cfg.ImageFormatsManager.SetEncoder(imageFormat, encoder); + cfg.ImageFormatsManager.AddImageFormatDetector(detector); } private static Configuration CreateDefaultConfiguration() diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index 6014e25334..f03f9db09a 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -360,7 +360,7 @@ namespace SixLabors.ImageSharp.Tests IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(path); IImageFormat format = TestEnvironment.GetImageFormat(path); - IImageDecoder defaultDecoder = Configuration.Default.FindDecoder(format); + IImageDecoder defaultDecoder = Configuration.Default.ImageFormatsManager.FindDecoder(format); //if (referenceDecoder.GetType() == defaultDecoder.GetType()) //{ From 0fc9002dcc83b9717d57ea62706368098507d80a Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 3 Mar 2018 01:47:44 +0100 Subject: [PATCH 20/20] sanitize MCU processing code --- .../Components/Decoder/InputProcessor.cs | 8 + .../Components/Decoder/OrigJpegScanDecoder.cs | 205 ++++++++++-------- .../Jpeg/GolangPort/OrigJpegDecoderCore.cs | 9 + 3 files changed, 133 insertions(+), 89 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs index fd6a7833a7..cb4b63cffd 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs @@ -380,5 +380,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder this.LastErrorCode = this.Bits.ReceiveExtendUnsafe(t, ref this, out x); return this.LastErrorCode; } + + /// + /// Reset the Huffman decoder. + /// + public void ResetHuffmanDecoder() + { + this.Bits = default(Bits); + } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs index 2e1372c564..d10def3ce7 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs @@ -94,6 +94,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder /// private int eobRun; + /// + /// The block counter + /// + private int blockCounter; + + /// + /// The MCU counter + /// + private int mcuCounter; + + /// + /// The expected RST marker value + /// + private byte expectedRst; + /// /// Initializes a default-constructed instance for reading data from -s stream. /// @@ -139,124 +154,136 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder { decoder.InputProcessor.ResetErrorState(); - int blockCount = 0; - int mcu = 0; - byte expectedRst = OrigJpegConstants.Markers.RST0; + this.blockCounter = 0; + this.mcuCounter = 0; + this.expectedRst = OrigJpegConstants.Markers.RST0; for (int my = 0; my < decoder.MCUCountY; my++) { for (int mx = 0; mx < decoder.MCUCountX; mx++) { - for (int scanIndex = 0; scanIndex < this.componentScanCount; scanIndex++) - { - this.ComponentIndex = this.pointers.ComponentScan[scanIndex].ComponentIndex; - OrigComponent component = decoder.Components[this.ComponentIndex]; + this.DecodeBlocksAtMcuIndex(decoder, mx, my); - this.hi = component.HorizontalSamplingFactor; - int vi = component.VerticalSamplingFactor; - - for (int j = 0; j < this.hi * vi; j++) - { - if (this.componentScanCount != 1) - { - this.bx = (this.hi * mx) + (j % this.hi); - this.by = (vi * my) + (j / this.hi); - } - else - { - int q = decoder.MCUCountX * this.hi; - this.bx = blockCount % q; - this.by = blockCount / q; - blockCount++; - if (this.bx * 8 >= decoder.ImageWidth || this.by * 8 >= decoder.ImageHeight) - { - continue; - } - } + this.mcuCounter++; - // Find the block at (bx,by) in the component's buffer: - ref Block8x8 blockRefOnHeap = ref component.GetBlockReference(this.bx, this.by); + // Handling restart intervals + // Useful info: https://stackoverflow.com/a/8751802 + if (decoder.IsAtRestartInterval(this.mcuCounter)) + { + this.ProcessRSTMarker(decoder); + this.Reset(decoder); + } + } + } + } - // Copy block to stack - this.data.Block = blockRefOnHeap; + private void DecodeBlocksAtMcuIndex(OrigJpegDecoderCore decoder, int mx, int my) + { + for (int scanIndex = 0; scanIndex < this.componentScanCount; scanIndex++) + { + this.ComponentIndex = this.pointers.ComponentScan[scanIndex].ComponentIndex; + OrigComponent component = decoder.Components[this.ComponentIndex]; - if (!decoder.InputProcessor.ReachedEOF) - { - this.DecodeBlock(decoder, scanIndex); - } + this.hi = component.HorizontalSamplingFactor; + int vi = component.VerticalSamplingFactor; - // Store the result block: - blockRefOnHeap = this.data.Block; + for (int j = 0; j < this.hi * vi; j++) + { + if (this.componentScanCount != 1) + { + this.bx = (this.hi * mx) + (j % this.hi); + this.by = (vi * my) + (j / this.hi); + } + else + { + int q = decoder.MCUCountX * this.hi; + this.bx = this.blockCounter % q; + this.by = this.blockCounter / q; + this.blockCounter++; + if (this.bx * 8 >= decoder.ImageWidth || this.by * 8 >= decoder.ImageHeight) + { + continue; } + } + + // Find the block at (bx,by) in the component's buffer: + ref Block8x8 blockRefOnHeap = ref component.GetBlockReference(this.bx, this.by); - // for j + // Copy block to stack + this.data.Block = blockRefOnHeap; + + if (!decoder.InputProcessor.ReachedEOF) + { + this.DecodeBlock(decoder, scanIndex); } - // for i - mcu++; + // Store the result block: + blockRefOnHeap = this.data.Block; + } + } + } - if (decoder.RestartInterval > 0 && mcu % decoder.RestartInterval == 0 && mcu < decoder.TotalMCUCount) + private void ProcessRSTMarker(OrigJpegDecoderCore decoder) + { + // Attempt to look for RST[0-7] markers to resynchronize from corrupt input. + if (!decoder.InputProcessor.ReachedEOF) + { + decoder.InputProcessor.ReadFullUnsafe(decoder.Temp, 0, 2); + if (decoder.InputProcessor.CheckEOFEnsureNoError()) + { + if (decoder.Temp[0] != 0xFF || decoder.Temp[1] != this.expectedRst) { - // Attempt to look for RST[0-7] markers to resynchronize from corrupt input. - if (!decoder.InputProcessor.ReachedEOF) + bool invalidRst = true; + + // Most jpeg's containing well-formed input will have a RST[0-7] marker following immediately + // but some, see Issue #481, contain padding bytes "0xFF" before the RST[0-7] marker. + // If we identify that case we attempt to read until we have bypassed the padded bytes. + // We then check again for our RST marker and throw if invalid. + // No other methods are attempted to resynchronize from corrupt input. + if (decoder.Temp[0] == 0xFF && decoder.Temp[1] == 0xFF) { - decoder.InputProcessor.ReadFullUnsafe(decoder.Temp, 0, 2); - if (decoder.InputProcessor.CheckEOFEnsureNoError()) + while (decoder.Temp[0] == 0xFF && decoder.InputProcessor.CheckEOFEnsureNoError()) { - if (decoder.Temp[0] != 0xFF || decoder.Temp[1] != expectedRst) - { - bool invalidRst = true; - - // Most jpeg's containing well-formed input will have a RST[0-7] marker following immediately - // but some, see Issue #481, contain padding bytes "0xFF" before the RST[0-7] marker. - // If we identify that case we attempt to read until we have bypassed the padded bytes. - // We then check again for our RST marker and throw if invalid. - // No other methods are attempted to resynchronize from corrupt input. - if (decoder.Temp[0] == 0xFF && decoder.Temp[1] == 0xFF) - { - while (decoder.Temp[0] == 0xFF && decoder.InputProcessor.CheckEOFEnsureNoError()) - { - decoder.InputProcessor.ReadFullUnsafe(decoder.Temp, 0, 1); - if (!decoder.InputProcessor.CheckEOFEnsureNoError()) - { - break; - } - } - - // Have we found a valid restart marker? - invalidRst = decoder.Temp[0] != expectedRst; - } - - if (invalidRst) - { - throw new ImageFormatException("Bad RST marker"); - } - } - - expectedRst++; - if (expectedRst == OrigJpegConstants.Markers.RST7 + 1) + decoder.InputProcessor.ReadFullUnsafe(decoder.Temp, 0, 1); + if (!decoder.InputProcessor.CheckEOFEnsureNoError()) { - expectedRst = OrigJpegConstants.Markers.RST0; + break; } } - } - // Reset the Huffman decoder. - decoder.InputProcessor.Bits = default(Bits); + // Have we found a valid restart marker? + invalidRst = decoder.Temp[0] != this.expectedRst; + } - // Reset the DC components, as per section F.2.1.3.1. - this.ResetDc(); + if (invalidRst) + { + throw new ImageFormatException("Bad RST marker"); + } + } - // Reset the progressive decoder state, as per section G.1.2.2. - this.eobRun = 0; + this.expectedRst++; + if (this.expectedRst == OrigJpegConstants.Markers.RST7 + 1) + { + this.expectedRst = OrigJpegConstants.Markers.RST0; } } - - // for mx } } - private void ResetDc() + private void Reset(OrigJpegDecoderCore decoder) + { + decoder.InputProcessor.ResetHuffmanDecoder(); + + this.ResetDcValues(); + + // Reset the progressive decoder state, as per section G.1.2.2. + this.eobRun = 0; + } + + /// + /// Reset the DC components, as per section F.2.1.3.1. + /// + private void ResetDcValues() { Unsafe.InitBlock(this.pointers.Dc, default(byte), sizeof(int) * OrigJpegDecoderCore.MaxComponents); } diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs index 58513fd297..6cc275d49d 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs @@ -411,6 +411,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort this.InitDerivedMetaDataProperties(); } + /// + /// Returns true if 'mcuCounter' is at restart interval + /// + public bool IsAtRestartInterval(int mcuCounter) + { + return this.RestartInterval > 0 && mcuCounter % this.RestartInterval == 0 + && mcuCounter < this.TotalMCUCount; + } + /// /// Assigns derived metadata properties to , eg. horizontal and vertical resolution if it has a JFIF header. ///