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/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/RgbWorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/RgbWorkingSpace.cs
index 19c0ad0ba8..ef86e20901 100644
--- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/RgbWorkingSpace.cs
+++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/RgbWorkingSpace.cs
@@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation
///
/// 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 40dce5207c..ed0ef64879 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/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/Configuration.cs b/src/ImageSharp/Configuration.cs
index 34bbb61e0b..d41e48678b 100644
--- a/src/ImageSharp/Configuration.cs
+++ b/src/ImageSharp/Configuration.cs
@@ -1,272 +1,145 @@
-// 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);
-
- ///
- /// 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();
-
- ///
- /// 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.imageFormats;
-
- ///
- /// Gets or sets the position in a stream to use for reading when using a seekable stream as an image data source.
- ///
- public ReadOrigin ReadOrigin { get; set; } = ReadOrigin.Current;
-
- ///
- /// 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 { get; private set; }
-
- ///
- /// 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;
-
-#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)
- {
- 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;
- }
-
- ///
- /// 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());
- }
-
- ///
- /// Sets the max header size.
- ///
- private void SetMaxHeaderSize()
- {
- this.MaxHeaderSize = this.imageFormatDetectors.Max(x => x.HeaderSize);
- }
- }
-}
+// 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; private set; } = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
+
+ ///
+ /// 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.
+ ///
+ public ReadOrigin ReadOrigin { get; set; } = ReadOrigin.Current;
+
+ ///
+ /// Gets or sets the that is currently in use.
+ ///
+ public ImageFormatManager ImageFormatsManager { get; set; } = new ImageFormatManager();
+
+ ///
+ /// 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.ImageFormatsManager.MaxHeaderSize;
+
+#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);
+ }
+
+ ///
+ /// Creates a shallow copy of the
+ ///
+ /// A new configuration instance
+ public Configuration ShallowCopy()
+ {
+ return new Configuration
+ {
+ ParallelOptions = this.ParallelOptions,
+ ImageFormatsManager = this.ImageFormatsManager,
+ MemoryManager = this.MemoryManager,
+ ImageOperationsProvider = this.ImageOperationsProvider,
+ ReadOrigin = this.ReadOrigin,
+
+#if !NETSTANDARD1_1
+ FileSystem = this.FileSystem
+#endif
+ };
+ }
+
+ ///
+ /// 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());
+ }
+ }
+}
\ No newline at end of file
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/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/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs
new file mode 100644
index 0000000000..67ba111474
--- /dev/null
+++ b/src/ImageSharp/Formats/ImageFormatManager.cs
@@ -0,0 +1,186 @@
+// 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.Text;
+
+namespace SixLabors.ImageSharp.Formats
+{
+ ///
+ /// Collection of Image Formats to be used in class.
+ ///
+ public class ImageFormatManager
+ {
+ ///
+ /// 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();
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ImageFormatManager()
+ {
+ }
+
+ ///
+ /// 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);
+ }
+ }
+}
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/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/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..187b65f72b 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs
+++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs
@@ -66,7 +66,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
///
/// A stack-only struct to reference the input buffers using -s.
///
- public 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
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/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/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs
index 88599808fc..cb4b63cffd 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
{
///
@@ -382,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 67abba9f33..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,100 +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)
{
- // 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.
- 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)
- {
- 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/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/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.
///
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/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/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/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/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/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/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/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/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/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/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/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/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs
index 9553ec82d6..9505ee6cf7 100644
--- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs
+++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs
@@ -6,7 +6,8 @@ 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/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt
index aa88b6606c..365f5cb514 100644
--- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt
+++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt
@@ -7,6 +7,7 @@
<#@ 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 +25,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 +65,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 +102,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 659e702281..edf6a88e1f 100644
--- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs
+++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs
@@ -6,9 +6,9 @@ namespace SixLabors.ImageSharp
{
using System;
using System.Runtime.CompilerServices;
-
+ using System.Runtime.InteropServices;
using SixLabors.ImageSharp.PixelFormats;
-
+
///
/// Provides optimized overrides for bulk operations.
///
@@ -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/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.
///
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/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
{
///
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/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 ceec8f6fb2..62fd11e8e4 100644
--- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
+++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
@@ -23,7 +23,12 @@
+
+
+
+
+
diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs
index 06f02fcf16..cf348569ce 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();
}
@@ -32,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.
@@ -78,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/Formats/ImageFormatManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
new file mode 100644
index 0000000000..a6f6600f05
--- /dev/null
+++ b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
@@ -0,0 +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 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(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 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));
+ }
+ }
+}
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/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/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));
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/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/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())
//{
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