Browse Source

Merge branch 'main' into js/webp-allocations

pull/2546/head
James Jackson-South 2 years ago
committed by GitHub
parent
commit
31aabcc40c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 40
      src/ImageSharp/Advanced/AdvancedImageExtensions.cs
  2. 2
      src/ImageSharp/Advanced/IConfigurationProvider.cs
  3. 2
      src/ImageSharp/Formats/Bmp/BmpEncoder.cs
  4. 2
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  5. 2
      src/ImageSharp/Formats/Gif/GifEncoder.cs
  6. 2
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  7. 4
      src/ImageSharp/Formats/ImageEncoder.cs
  8. 72
      src/ImageSharp/Formats/ImageExtensions.Save.cs
  9. 8
      src/ImageSharp/Formats/ImageExtensions.Save.tt
  10. 2
      src/ImageSharp/Formats/Jpeg/Components/Encoder/JpegFrame.cs
  11. 2
      src/ImageSharp/Formats/Jpeg/Components/Encoder/SpectralConverter{TPixel}.cs
  12. 2
      src/ImageSharp/Formats/Pbm/PbmEncoder.cs
  13. 2
      src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs
  14. 3
      src/ImageSharp/Formats/Png/PngEncoder.cs
  15. 8
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  16. 4
      src/ImageSharp/Formats/Qoi/QoiEncoder.cs
  17. 5
      src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs
  18. 6
      src/ImageSharp/Formats/Tga/TgaEncoder.cs
  19. 2
      src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
  20. 3
      src/ImageSharp/Formats/Tiff/TiffEncoder.cs
  21. 2
      src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
  22. 2
      src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs
  23. 2
      src/ImageSharp/Formats/Webp/WebpEncoder.cs
  24. 13
      src/ImageSharp/Image.cs
  25. 12
      src/ImageSharp/ImageExtensions.cs
  26. 14
      src/ImageSharp/ImageFrame.cs
  27. 20
      src/ImageSharp/ImageFrameCollection{TPixel}.cs
  28. 12
      src/ImageSharp/ImageFrame{TPixel}.cs
  29. 4
      src/ImageSharp/ImageSharp.csproj
  30. 8
      src/ImageSharp/Image{TPixel}.cs
  31. 5
      src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs
  32. 5
      src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.LongArray.cs
  33. 5
      src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.Rational.cs
  34. 13
      src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.SignedShortArray.cs
  35. 5
      src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTagValue.cs
  36. 5
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShortArray.cs
  37. 7
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs
  38. 4
      src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs
  39. 2
      src/ImageSharp/Processing/Extensions/ProcessingExtensions.IntegralImage.cs
  40. 12
      src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs
  41. 2
      src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs
  42. 4
      tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs
  43. 8
      tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs
  44. 2
      tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs
  45. 6
      tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs
  46. 13
      tests/ImageSharp.Tests/Image/ImageTests.cs
  47. 7
      tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs
  48. 24
      tests/ImageSharp.Tests/Metadata/Profiles/Exif/Values/ExifValuesTests.cs
  49. 2
      tests/ImageSharp.Tests/Processing/BaseImageOperationsExtensionTest.cs
  50. 2
      tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs
  51. 2
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs
  52. 2
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs
  53. 6
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/ImageSharpPngEncoderWithDefaultConfiguration.cs
  54. 8
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs
  55. 4
      tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs

40
src/ImageSharp/Advanced/AdvancedImageExtensions.cs

@ -27,11 +27,11 @@ public static class AdvancedImageExtensions
Guard.NotNull(filePath, nameof(filePath));
string ext = Path.GetExtension(filePath);
if (!source.GetConfiguration().ImageFormatsManager.TryFindFormatByFileExtension(ext, out IImageFormat? format))
if (!source.Configuration.ImageFormatsManager.TryFindFormatByFileExtension(ext, out IImageFormat? format))
{
StringBuilder sb = new();
sb = sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}'. Registered encoders include:");
foreach (IImageFormat fmt in source.GetConfiguration().ImageFormats)
foreach (IImageFormat fmt in source.Configuration.ImageFormats)
{
sb = sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", fmt.Name, string.Join(", ", fmt.FileExtensions), Environment.NewLine);
}
@ -39,13 +39,13 @@ public static class AdvancedImageExtensions
throw new UnknownImageFormatException(sb.ToString());
}
IImageEncoder? encoder = source.GetConfiguration().ImageFormatsManager.GetEncoder(format);
IImageEncoder? encoder = source.Configuration.ImageFormatsManager.GetEncoder(format);
if (encoder is null)
{
StringBuilder sb = new();
sb = sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}' using image format '{format.Name}'. Registered encoders include:");
foreach (KeyValuePair<IImageFormat, IImageEncoder> enc in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
foreach (KeyValuePair<IImageFormat, IImageEncoder> enc in source.Configuration.ImageFormatsManager.ImageEncoders)
{
sb = sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", enc.Key, enc.Value.GetType().Name, Environment.NewLine);
}
@ -76,30 +76,6 @@ public static class AdvancedImageExtensions
public static Task AcceptVisitorAsync(this Image source, IImageVisitorAsync visitor, CancellationToken cancellationToken = default)
=> source.AcceptAsync(visitor, cancellationToken);
/// <summary>
/// Gets the configuration for the image.
/// </summary>
/// <param name="source">The source image.</param>
/// <returns>Returns the configuration.</returns>
public static Configuration GetConfiguration(this Image source)
=> GetConfiguration((IConfigurationProvider)source);
/// <summary>
/// Gets the configuration for the image frame.
/// </summary>
/// <param name="source">The source image.</param>
/// <returns>Returns the configuration.</returns>
public static Configuration GetConfiguration(this ImageFrame source)
=> GetConfiguration((IConfigurationProvider)source);
/// <summary>
/// Gets the configuration.
/// </summary>
/// <param name="source">The source image</param>
/// <returns>Returns the bounds of the image</returns>
private static Configuration GetConfiguration(IConfigurationProvider source)
=> source?.Configuration ?? Configuration.Default;
/// <summary>
/// Gets the representation of the pixels as a <see cref="IMemoryGroup{T}"/> containing the backing pixel data of the image
/// stored in row major order, as a list of contiguous <see cref="Memory{T}"/> blocks in the source image's pixel format.
@ -167,12 +143,4 @@ public static class AdvancedImageExtensions
return source.Frames.RootFrame.PixelBuffer.GetSafeRowMemory(rowIndex);
}
/// <summary>
/// Gets the <see cref="MemoryAllocator"/> assigned to 'source'.
/// </summary>
/// <param name="source">The source image.</param>
/// <returns>Returns the configuration.</returns>
internal static MemoryAllocator GetMemoryAllocator(this IConfigurationProvider source)
=> GetConfiguration(source).MemoryAllocator;
}

2
src/ImageSharp/Advanced/IConfigurationProvider.cs

@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Advanced;
/// <summary>
/// Defines the contract for objects that can provide access to configuration.
/// </summary>
internal interface IConfigurationProvider
public interface IConfigurationProvider
{
/// <summary>
/// Gets the configuration which allows altering default behaviour or extending the library.

2
src/ImageSharp/Formats/Bmp/BmpEncoder.cs

@ -32,7 +32,7 @@ public sealed class BmpEncoder : QuantizingImageEncoder
/// <inheritdoc/>
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
BmpEncoderCore encoder = new(this, image.GetMemoryAllocator());
BmpEncoderCore encoder = new(this, image.Configuration.MemoryAllocator);
encoder.Encode(image, stream, cancellationToken);
}
}

2
src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

@ -119,7 +119,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals
Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream));
Configuration configuration = image.GetConfiguration();
Configuration configuration = image.Configuration;
ImageMetadata metadata = image.Metadata;
BmpMetadata bmpMetadata = metadata.GetBmpMetadata();
this.bitsPerPixel ??= bmpMetadata.BitsPerPixel;

2
src/ImageSharp/Formats/Gif/GifEncoder.cs

@ -18,7 +18,7 @@ public sealed class GifEncoder : QuantizingImageEncoder
/// <inheritdoc/>
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
GifEncoderCore encoder = new(image.GetConfiguration(), this);
GifEncoderCore encoder = new(image.Configuration, this);
encoder.Encode(image, stream, cancellationToken);
}
}

2
src/ImageSharp/Formats/Gif/GifEncoderCore.cs

@ -189,7 +189,7 @@ internal sealed class GifEncoderCore : IImageEncoderInternals
// This frame is reused to store de-duplicated pixel buffers.
// This is more expensive memory-wise than de-duplicating indexed buffer but allows us to deduplicate
// frames using both local and global palettes.
using ImageFrame<TPixel> encodingFrame = new(previousFrame.GetConfiguration(), previousFrame.Size());
using ImageFrame<TPixel> encodingFrame = new(previousFrame.Configuration, previousFrame.Size());
for (int i = 1; i < image.Frames.Count; i++)
{

4
src/ImageSharp/Formats/ImageEncoder.cs

@ -42,7 +42,7 @@ public abstract class ImageEncoder : IImageEncoder
private void EncodeWithSeekableStream<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
{
Configuration configuration = image.GetConfiguration();
Configuration configuration = image.Configuration;
if (stream.CanSeek)
{
this.Encode(image, stream, cancellationToken);
@ -59,7 +59,7 @@ public abstract class ImageEncoder : IImageEncoder
private async Task EncodeWithSeekableStreamAsync<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
{
Configuration configuration = image.GetConfiguration();
Configuration configuration = image.Configuration;
if (stream.CanSeek)
{
await DoEncodeAsync(stream).ConfigureAwait(false);

72
src/ImageSharp/Formats/ImageExtensions.Save.cs

@ -59,7 +59,7 @@ public static partial class ImageExtensions
public static void SaveAsBmp(this Image source, string path, BmpEncoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(BmpFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(BmpFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Bmp format.
@ -73,7 +73,7 @@ public static partial class ImageExtensions
public static Task SaveAsBmpAsync(this Image source, string path, BmpEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(BmpFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(BmpFormat.Instance),
cancellationToken);
/// <summary>
@ -106,7 +106,7 @@ public static partial class ImageExtensions
public static void SaveAsBmp(this Image source, Stream stream, BmpEncoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(BmpFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(BmpFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Bmp format.
@ -120,7 +120,7 @@ public static partial class ImageExtensions
public static Task SaveAsBmpAsync(this Image source, Stream stream, BmpEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(BmpFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(BmpFormat.Instance),
cancellationToken);
/// <summary>
@ -161,7 +161,7 @@ public static partial class ImageExtensions
public static void SaveAsGif(this Image source, string path, GifEncoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(GifFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(GifFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Gif format.
@ -175,7 +175,7 @@ public static partial class ImageExtensions
public static Task SaveAsGifAsync(this Image source, string path, GifEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(GifFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(GifFormat.Instance),
cancellationToken);
/// <summary>
@ -208,7 +208,7 @@ public static partial class ImageExtensions
public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(GifFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(GifFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Gif format.
@ -222,7 +222,7 @@ public static partial class ImageExtensions
public static Task SaveAsGifAsync(this Image source, Stream stream, GifEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(GifFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(GifFormat.Instance),
cancellationToken);
/// <summary>
@ -263,7 +263,7 @@ public static partial class ImageExtensions
public static void SaveAsJpeg(this Image source, string path, JpegEncoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(JpegFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(JpegFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Jpeg format.
@ -277,7 +277,7 @@ public static partial class ImageExtensions
public static Task SaveAsJpegAsync(this Image source, string path, JpegEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(JpegFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(JpegFormat.Instance),
cancellationToken);
/// <summary>
@ -310,7 +310,7 @@ public static partial class ImageExtensions
public static void SaveAsJpeg(this Image source, Stream stream, JpegEncoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(JpegFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(JpegFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Jpeg format.
@ -324,7 +324,7 @@ public static partial class ImageExtensions
public static Task SaveAsJpegAsync(this Image source, Stream stream, JpegEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(JpegFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(JpegFormat.Instance),
cancellationToken);
/// <summary>
@ -365,7 +365,7 @@ public static partial class ImageExtensions
public static void SaveAsPbm(this Image source, string path, PbmEncoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PbmFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(PbmFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Pbm format.
@ -379,7 +379,7 @@ public static partial class ImageExtensions
public static Task SaveAsPbmAsync(this Image source, string path, PbmEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PbmFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(PbmFormat.Instance),
cancellationToken);
/// <summary>
@ -412,7 +412,7 @@ public static partial class ImageExtensions
public static void SaveAsPbm(this Image source, Stream stream, PbmEncoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PbmFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(PbmFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Pbm format.
@ -426,7 +426,7 @@ public static partial class ImageExtensions
public static Task SaveAsPbmAsync(this Image source, Stream stream, PbmEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PbmFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(PbmFormat.Instance),
cancellationToken);
/// <summary>
@ -467,7 +467,7 @@ public static partial class ImageExtensions
public static void SaveAsPng(this Image source, string path, PngEncoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PngFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(PngFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Png format.
@ -481,7 +481,7 @@ public static partial class ImageExtensions
public static Task SaveAsPngAsync(this Image source, string path, PngEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PngFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(PngFormat.Instance),
cancellationToken);
/// <summary>
@ -514,7 +514,7 @@ public static partial class ImageExtensions
public static void SaveAsPng(this Image source, Stream stream, PngEncoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PngFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(PngFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Png format.
@ -528,7 +528,7 @@ public static partial class ImageExtensions
public static Task SaveAsPngAsync(this Image source, Stream stream, PngEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PngFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(PngFormat.Instance),
cancellationToken);
/// <summary>
@ -569,7 +569,7 @@ public static partial class ImageExtensions
public static void SaveAsQoi(this Image source, string path, QoiEncoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(QoiFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(QoiFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Qoi format.
@ -583,7 +583,7 @@ public static partial class ImageExtensions
public static Task SaveAsQoiAsync(this Image source, string path, QoiEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(QoiFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(QoiFormat.Instance),
cancellationToken);
/// <summary>
@ -616,7 +616,7 @@ public static partial class ImageExtensions
public static void SaveAsQoi(this Image source, Stream stream, QoiEncoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(QoiFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(QoiFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Qoi format.
@ -630,7 +630,7 @@ public static partial class ImageExtensions
public static Task SaveAsQoiAsync(this Image source, Stream stream, QoiEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(QoiFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(QoiFormat.Instance),
cancellationToken);
/// <summary>
@ -671,7 +671,7 @@ public static partial class ImageExtensions
public static void SaveAsTga(this Image source, string path, TgaEncoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TgaFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(TgaFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Tga format.
@ -685,7 +685,7 @@ public static partial class ImageExtensions
public static Task SaveAsTgaAsync(this Image source, string path, TgaEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TgaFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(TgaFormat.Instance),
cancellationToken);
/// <summary>
@ -718,7 +718,7 @@ public static partial class ImageExtensions
public static void SaveAsTga(this Image source, Stream stream, TgaEncoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TgaFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(TgaFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Tga format.
@ -732,7 +732,7 @@ public static partial class ImageExtensions
public static Task SaveAsTgaAsync(this Image source, Stream stream, TgaEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TgaFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(TgaFormat.Instance),
cancellationToken);
/// <summary>
@ -773,7 +773,7 @@ public static partial class ImageExtensions
public static void SaveAsTiff(this Image source, string path, TiffEncoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TiffFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(TiffFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Tiff format.
@ -787,7 +787,7 @@ public static partial class ImageExtensions
public static Task SaveAsTiffAsync(this Image source, string path, TiffEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TiffFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(TiffFormat.Instance),
cancellationToken);
/// <summary>
@ -820,7 +820,7 @@ public static partial class ImageExtensions
public static void SaveAsTiff(this Image source, Stream stream, TiffEncoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TiffFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(TiffFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Tiff format.
@ -834,7 +834,7 @@ public static partial class ImageExtensions
public static Task SaveAsTiffAsync(this Image source, Stream stream, TiffEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TiffFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(TiffFormat.Instance),
cancellationToken);
/// <summary>
@ -875,7 +875,7 @@ public static partial class ImageExtensions
public static void SaveAsWebp(this Image source, string path, WebpEncoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(WebpFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(WebpFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Webp format.
@ -889,7 +889,7 @@ public static partial class ImageExtensions
public static Task SaveAsWebpAsync(this Image source, string path, WebpEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(WebpFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(WebpFormat.Instance),
cancellationToken);
/// <summary>
@ -922,7 +922,7 @@ public static partial class ImageExtensions
public static void SaveAsWebp(this Image source, Stream stream, WebpEncoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(WebpFormat.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(WebpFormat.Instance));
/// <summary>
/// Saves the image to the given stream with the Webp format.
@ -936,7 +936,7 @@ public static partial class ImageExtensions
public static Task SaveAsWebpAsync(this Image source, Stream stream, WebpEncoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(WebpFormat.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(WebpFormat.Instance),
cancellationToken);
}

8
src/ImageSharp/Formats/ImageExtensions.Save.tt

@ -78,7 +78,7 @@ public static partial class ImageExtensions
public static void SaveAs<#= fmt #>(this Image source, string path, <#= fmt #>Encoder encoder) =>
source.Save(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(<#= fmt #>Format.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(<#= fmt #>Format.Instance));
/// <summary>
/// Saves the image to the given stream with the <#= fmt #> format.
@ -92,7 +92,7 @@ public static partial class ImageExtensions
public static Task SaveAs<#= fmt #>Async(this Image source, string path, <#= fmt #>Encoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
path,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(<#= fmt #>Format.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(<#= fmt #>Format.Instance),
cancellationToken);
/// <summary>
@ -125,7 +125,7 @@ public static partial class ImageExtensions
public static void SaveAs<#= fmt #>(this Image source, Stream stream, <#= fmt #>Encoder encoder)
=> source.Save(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(<#= fmt #>Format.Instance));
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(<#= fmt #>Format.Instance));
/// <summary>
/// Saves the image to the given stream with the <#= fmt #> format.
@ -139,7 +139,7 @@ public static partial class ImageExtensions
public static Task SaveAs<#= fmt #>Async(this Image source, Stream stream, <#= fmt #>Encoder encoder, CancellationToken cancellationToken = default)
=> source.SaveAsync(
stream,
encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(<#= fmt #>Format.Instance),
encoder ?? source.Configuration.ImageFormatsManager.GetEncoder(<#= fmt #>Format.Instance),
cancellationToken);
<#

2
src/ImageSharp/Formats/Jpeg/Components/Encoder/JpegFrame.cs

@ -20,7 +20,7 @@ internal sealed class JpegFrame : IDisposable
this.PixelWidth = image.Width;
this.PixelHeight = image.Height;
MemoryAllocator allocator = image.GetConfiguration().MemoryAllocator;
MemoryAllocator allocator = image.Configuration.MemoryAllocator;
JpegComponentConfig[] componentConfigs = frameConfig.Components;
this.Components = new Component[componentConfigs.Length];

2
src/ImageSharp/Formats/Jpeg/Components/Encoder/SpectralConverter{TPixel}.cs

@ -32,7 +32,7 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
public SpectralConverter(JpegFrame frame, Image<TPixel> image, Block8x8F[] dequantTables)
{
MemoryAllocator allocator = image.GetConfiguration().MemoryAllocator;
MemoryAllocator allocator = image.Configuration.MemoryAllocator;
// iteration data
int majorBlockWidth = frame.Components.Max((component) => component.SizeInBlocks.Width);

2
src/ImageSharp/Formats/Pbm/PbmEncoder.cs

@ -49,7 +49,7 @@ public sealed class PbmEncoder : ImageEncoder
/// <inheritdoc/>
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
PbmEncoderCore encoder = new(image.GetConfiguration(), this);
PbmEncoderCore encoder = new(image.Configuration, this);
encoder.Encode(image, stream, cancellationToken);
}
}

2
src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs

@ -78,7 +78,7 @@ internal sealed class PbmEncoderCore : IImageEncoderInternals
private void SanitizeAndSetEncoderOptions<TPixel>(Image<TPixel> image)
where TPixel : unmanaged, IPixel<TPixel>
{
this.configuration = image.GetConfiguration();
this.configuration = image.Configuration;
PbmMetadata metadata = image.Metadata.GetPbmMetadata();
this.encoding = this.encoder.Encoding ?? metadata.Encoding;
this.colorType = this.encoder.ColorType ?? metadata.ColorType;

3
src/ImageSharp/Formats/Png/PngEncoder.cs

@ -2,7 +2,6 @@
// Licensed under the Six Labors Split License.
#nullable disable
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Processing.Processors.Quantization;
namespace SixLabors.ImageSharp.Formats.Png;
@ -79,7 +78,7 @@ public class PngEncoder : QuantizingImageEncoder
/// <inheritdoc/>
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
using PngEncoderCore encoder = new(image.GetMemoryAllocator(), image.GetConfiguration(), this);
using PngEncoderCore encoder = new(image.Configuration, this);
encoder.Encode(image, stream, cancellationToken);
}
}

8
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -6,7 +6,6 @@ using System.Buffers;
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Common.Helpers;
using SixLabors.ImageSharp.Compression.Zlib;
using SixLabors.ImageSharp.Formats.Png.Chunks;
@ -116,13 +115,12 @@ internal sealed class PngEncoderCore : IImageEncoderInternals, IDisposable
/// <summary>
/// Initializes a new instance of the <see cref="PngEncoderCore" /> class.
/// </summary>
/// <param name="memoryAllocator">The <see cref="MemoryAllocator" /> to use for buffer allocations.</param>
/// <param name="configuration">The configuration.</param>
/// <param name="encoder">The encoder with options.</param>
public PngEncoderCore(MemoryAllocator memoryAllocator, Configuration configuration, PngEncoder encoder)
public PngEncoderCore(Configuration configuration, PngEncoder encoder)
{
this.memoryAllocator = memoryAllocator;
this.configuration = configuration;
this.memoryAllocator = configuration.MemoryAllocator;
this.encoder = encoder;
}
@ -1308,7 +1306,7 @@ internal sealed class PngEncoderCore : IImageEncoderInternals, IDisposable
}
// Create quantized frame returning the palette and set the bit depth.
using IQuantizer<TPixel> frameQuantizer = quantizer.CreatePixelSpecificQuantizer<TPixel>(image.GetConfiguration());
using IQuantizer<TPixel> frameQuantizer = quantizer.CreatePixelSpecificQuantizer<TPixel>(image.Configuration);
frameQuantizer.BuildPalette(encoder.PixelSamplingStrategy, image);
return frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds);

4
src/ImageSharp/Formats/Qoi/QoiEncoder.cs

@ -1,8 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Advanced;
namespace SixLabors.ImageSharp.Formats.Qoi;
/// <summary>
@ -27,7 +25,7 @@ public class QoiEncoder : ImageEncoder
/// <inheritdoc />
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
QoiEncoderCore encoder = new(this, image.GetMemoryAllocator(), image.GetConfiguration());
QoiEncoderCore encoder = new(this, image.Configuration);
encoder.Encode(image, stream, cancellationToken);
}
}

5
src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs

@ -33,13 +33,12 @@ internal class QoiEncoderCore : IImageEncoderInternals
/// Initializes a new instance of the <see cref="QoiEncoderCore"/> class.
/// </summary>
/// <param name="encoder">The encoder with options.</param>
/// <param name="memoryAllocator">The <see cref="MemoryAllocator" /> to use for buffer allocations.</param>
/// <param name="configuration">The configuration of the Encoder.</param>
public QoiEncoderCore(QoiEncoder encoder, MemoryAllocator memoryAllocator, Configuration configuration)
public QoiEncoderCore(QoiEncoder encoder, Configuration configuration)
{
this.encoder = encoder;
this.memoryAllocator = memoryAllocator;
this.configuration = configuration;
this.memoryAllocator = configuration.MemoryAllocator;
}
/// <inheritdoc />

6
src/ImageSharp/Formats/Tga/TgaEncoder.cs

@ -1,12 +1,10 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Advanced;
namespace SixLabors.ImageSharp.Formats.Tga;
/// <summary>
/// Image encoder for writing an image to a stream as a targa truevision image.
/// Image encoder for writing an image to a stream as a Targa true-vision image.
/// </summary>
public sealed class TgaEncoder : ImageEncoder
{
@ -23,7 +21,7 @@ public sealed class TgaEncoder : ImageEncoder
/// <inheritdoc/>
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
TgaEncoderCore encoder = new(this, image.GetMemoryAllocator());
TgaEncoderCore encoder = new(this, image.Configuration.MemoryAllocator);
encoder.Encode(image, stream, cancellationToken);
}
}

2
src/ImageSharp/Formats/Tga/TgaEncoderCore.cs

@ -112,7 +112,7 @@ internal sealed class TgaEncoderCore : IImageEncoderInternals
}
else
{
this.WriteImage(image.GetConfiguration(), stream, image.Frames.RootFrame);
this.WriteImage(image.Configuration, stream, image.Frames.RootFrame);
}
stream.Flush();

3
src/ImageSharp/Formats/Tiff/TiffEncoder.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Compression.Zlib;
using SixLabors.ImageSharp.Formats.Tiff.Constants;
using SixLabors.ImageSharp.Processing;
@ -48,7 +47,7 @@ public class TiffEncoder : QuantizingImageEncoder
/// <inheritdoc/>
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
TiffEncoderCore encode = new(this, image.GetMemoryAllocator());
TiffEncoderCore encode = new(this, image.Configuration.MemoryAllocator);
encode.Encode(image, stream, cancellationToken);
}
}

2
src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs

@ -128,7 +128,7 @@ internal sealed class TiffEncoderCore : IImageEncoderInternals
Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream));
this.configuration = image.GetConfiguration();
this.configuration = image.Configuration;
ImageFrameMetadata rootFrameMetaData = image.Frames.RootFrame.Metadata;
TiffFrameMetadata rootFrameTiffMetaData = rootFrameMetaData.GetTiffMetadata();

2
src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs

@ -502,7 +502,7 @@ internal class Vp8LEncoder : IDisposable
doNotCache = true;
// Go brute force on all transforms.
foreach (EntropyIx entropyIx in Enum.GetValues(typeof(EntropyIx)).Cast<EntropyIx>())
foreach (EntropyIx entropyIx in Enum.GetValues<EntropyIx>())
{
// We can only apply kPalette or kPaletteAndSpatial if we can indeed use a palette.
if ((entropyIx != EntropyIx.Palette && entropyIx != EntropyIx.PaletteAndSpatial) || usePalette)

2
src/ImageSharp/Formats/Webp/WebpEncoder.cs

@ -82,7 +82,7 @@ public sealed class WebpEncoder : ImageEncoder
/// <inheritdoc/>
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
WebpEncoderCore encoder = new(this, image.GetConfiguration());
WebpEncoderCore encoder = new(this, image.Configuration);
encoder.Encode(image, stream, cancellationToken);
}
}

13
src/ImageSharp/Image.cs

@ -17,7 +17,6 @@ namespace SixLabors.ImageSharp;
public abstract partial class Image : IDisposable, IConfigurationProvider
{
private bool isDisposed;
private readonly Configuration configuration;
/// <summary>
/// Initializes a new instance of the <see cref="Image"/> class.
@ -26,12 +25,12 @@ public abstract partial class Image : IDisposable, IConfigurationProvider
/// <param name="pixelType">The pixel type information.</param>
/// <param name="metadata">The image metadata.</param>
/// <param name="size">The size in px units.</param>
protected Image(Configuration configuration, PixelTypeInfo pixelType, ImageMetadata? metadata, Size size)
protected Image(Configuration configuration, PixelTypeInfo pixelType, ImageMetadata metadata, Size size)
{
this.configuration = configuration;
this.Configuration = configuration;
this.PixelType = pixelType;
this.Size = size;
this.Metadata = metadata ?? new ImageMetadata();
this.Metadata = metadata;
}
/// <summary>
@ -45,7 +44,7 @@ public abstract partial class Image : IDisposable, IConfigurationProvider
internal Image(
Configuration configuration,
PixelTypeInfo pixelType,
ImageMetadata? metadata,
ImageMetadata metadata,
int width,
int height)
: this(configuration, pixelType, metadata, new Size(width, height))
@ -53,7 +52,7 @@ public abstract partial class Image : IDisposable, IConfigurationProvider
}
/// <inheritdoc/>
Configuration IConfigurationProvider.Configuration => this.configuration;
public Configuration Configuration { get; }
/// <summary>
/// Gets information about the image pixels.
@ -147,7 +146,7 @@ public abstract partial class Image : IDisposable, IConfigurationProvider
/// <typeparam name="TPixel2">The pixel format.</typeparam>
/// <returns>The <see cref="Image{TPixel2}"/></returns>
public Image<TPixel2> CloneAs<TPixel2>()
where TPixel2 : unmanaged, IPixel<TPixel2> => this.CloneAs<TPixel2>(this.GetConfiguration());
where TPixel2 : unmanaged, IPixel<TPixel2> => this.CloneAs<TPixel2>(this.Configuration);
/// <summary>
/// Returns a copy of the image in the given pixel format.

12
src/ImageSharp/ImageExtensions.cs

@ -47,7 +47,7 @@ public static partial class ImageExtensions
{
Guard.NotNull(path, nameof(path));
Guard.NotNull(encoder, nameof(encoder));
using Stream fs = source.GetConfiguration().FileSystem.Create(path);
using Stream fs = source.Configuration.FileSystem.Create(path);
source.Save(fs, encoder);
}
@ -70,7 +70,7 @@ public static partial class ImageExtensions
Guard.NotNull(path, nameof(path));
Guard.NotNull(encoder, nameof(encoder));
await using Stream fs = source.GetConfiguration().FileSystem.CreateAsynchronous(path);
await using Stream fs = source.Configuration.FileSystem.CreateAsynchronous(path);
await source.SaveAsync(fs, encoder, cancellationToken).ConfigureAwait(false);
}
@ -94,14 +94,14 @@ public static partial class ImageExtensions
throw new NotSupportedException("Cannot write to the stream.");
}
IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.GetEncoder(format);
IImageEncoder encoder = source.Configuration.ImageFormatsManager.GetEncoder(format);
if (encoder is null)
{
StringBuilder sb = new();
sb.AppendLine("No encoder was found for the provided mime type. Registered encoders include:");
foreach (KeyValuePair<IImageFormat, IImageEncoder> val in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
foreach (KeyValuePair<IImageFormat, IImageEncoder> val in source.Configuration.ImageFormatsManager.ImageEncoders)
{
sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine);
}
@ -138,14 +138,14 @@ public static partial class ImageExtensions
throw new NotSupportedException("Cannot write to the stream.");
}
IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.GetEncoder(format);
IImageEncoder encoder = source.Configuration.ImageFormatsManager.GetEncoder(format);
if (encoder is null)
{
StringBuilder sb = new();
sb.AppendLine("No encoder was found for the provided mime type. Registered encoders include:");
foreach (KeyValuePair<IImageFormat, IImageEncoder> val in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
foreach (KeyValuePair<IImageFormat, IImageEncoder> val in source.Configuration.ImageFormatsManager.ImageEncoders)
{
sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine);
}

14
src/ImageSharp/ImageFrame.cs

@ -15,8 +15,6 @@ namespace SixLabors.ImageSharp;
/// </summary>
public abstract partial class ImageFrame : IConfigurationProvider, IDisposable
{
private readonly Configuration configuration;
/// <summary>
/// Initializes a new instance of the <see cref="ImageFrame"/> class.
/// </summary>
@ -26,10 +24,7 @@ public abstract partial class ImageFrame : IConfigurationProvider, IDisposable
/// <param name="metadata">The <see cref="ImageFrameMetadata"/>.</param>
protected ImageFrame(Configuration configuration, int width, int height, ImageFrameMetadata metadata)
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(metadata, nameof(metadata));
this.configuration = configuration ?? Configuration.Default;
this.Configuration = configuration;
this.Width = width;
this.Height = height;
this.Metadata = metadata;
@ -51,19 +46,19 @@ public abstract partial class ImageFrame : IConfigurationProvider, IDisposable
public ImageFrameMetadata Metadata { get; }
/// <inheritdoc/>
Configuration IConfigurationProvider.Configuration => this.configuration;
public Configuration Configuration { get; }
/// <summary>
/// Gets the size of the frame.
/// </summary>
/// <returns>The <see cref="Size"/></returns>
public Size Size() => new Size(this.Width, this.Height);
public Size Size() => new(this.Width, this.Height);
/// <summary>
/// Gets the bounds of the frame.
/// </summary>
/// <returns>The <see cref="Rectangle"/></returns>
public Rectangle Bounds() => new Rectangle(0, 0, this.Width, this.Height);
public Rectangle Bounds() => new(0, 0, this.Width, this.Height);
/// <inheritdoc />
public void Dispose()
@ -84,6 +79,7 @@ public abstract partial class ImageFrame : IConfigurationProvider, IDisposable
/// <summary>
/// Updates the size of the image frame.
/// </summary>
/// <param name="size">The size.</param>
internal void UpdateSize(Size size)
{
this.Width = size.Width;

20
src/ImageSharp/ImageFrameCollection{TPixel}.cs

@ -24,7 +24,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
this.parent = parent ?? throw new ArgumentNullException(nameof(parent));
// Frames are already cloned within the caller
this.frames.Add(new ImageFrame<TPixel>(parent.GetConfiguration(), width, height, backgroundColor));
this.frames.Add(new ImageFrame<TPixel>(parent.Configuration, width, height, backgroundColor));
}
internal ImageFrameCollection(Image<TPixel> parent, int width, int height, MemoryGroup<TPixel> memorySource)
@ -32,7 +32,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
this.parent = parent ?? throw new ArgumentNullException(nameof(parent));
// Frames are already cloned within the caller
this.frames.Add(new ImageFrame<TPixel>(parent.GetConfiguration(), width, height, memorySource));
this.frames.Add(new ImageFrame<TPixel>(parent.Configuration, width, height, memorySource));
}
internal ImageFrameCollection(Image<TPixel> parent, IEnumerable<ImageFrame<TPixel>> frames)
@ -138,7 +138,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
this.EnsureNotDisposed();
this.ValidateFrame(source);
ImageFrame<TPixel> clonedFrame = source.Clone(this.parent.GetConfiguration());
ImageFrame<TPixel> clonedFrame = source.Clone(this.parent.Configuration);
this.frames.Insert(index, clonedFrame);
return clonedFrame;
}
@ -153,7 +153,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
this.EnsureNotDisposed();
this.ValidateFrame(source);
ImageFrame<TPixel> clonedFrame = source.Clone(this.parent.GetConfiguration());
ImageFrame<TPixel> clonedFrame = source.Clone(this.parent.Configuration);
this.frames.Add(clonedFrame);
return clonedFrame;
}
@ -169,7 +169,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
this.EnsureNotDisposed();
ImageFrame<TPixel> frame = ImageFrame.LoadPixelData(
this.parent.GetConfiguration(),
this.parent.Configuration,
source,
this.RootFrame.Width,
this.RootFrame.Height);
@ -270,7 +270,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
this.frames.Remove(frame);
return new Image<TPixel>(this.parent.GetConfiguration(), this.parent.Metadata.DeepClone(), new[] { frame });
return new Image<TPixel>(this.parent.Configuration, this.parent.Metadata.DeepClone(), new[] { frame });
}
/// <summary>
@ -285,7 +285,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
ImageFrame<TPixel> frame = this[index];
ImageFrame<TPixel> clonedFrame = frame.Clone();
return new Image<TPixel>(this.parent.GetConfiguration(), this.parent.Metadata.DeepClone(), new[] { clonedFrame });
return new Image<TPixel>(this.parent.Configuration, this.parent.Metadata.DeepClone(), new[] { clonedFrame });
}
/// <summary>
@ -299,7 +299,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
this.EnsureNotDisposed();
ImageFrame<TPixel> frame = new(
this.parent.GetConfiguration(),
this.parent.Configuration,
this.RootFrame.Width,
this.RootFrame.Height);
this.frames.Add(frame);
@ -365,7 +365,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
public ImageFrame<TPixel> CreateFrame(TPixel backgroundColor)
{
ImageFrame<TPixel> frame = new(
this.parent.GetConfiguration(),
this.parent.Configuration,
this.RootFrame.Width,
this.RootFrame.Height,
backgroundColor);
@ -414,7 +414,7 @@ public sealed class ImageFrameCollection<TPixel> : ImageFrameCollection, IEnumer
private ImageFrame<TPixel> CopyNonCompatibleFrame(ImageFrame source)
{
ImageFrame<TPixel> result = new(
this.parent.GetConfiguration(),
this.parent.Configuration,
source.Size(),
source.Metadata.DeepClone());
source.CopyPixelsTo(result.PixelBuffer.FastMemoryGroup);

12
src/ImageSharp/ImageFrame{TPixel}.cs

@ -66,7 +66,7 @@ public sealed class ImageFrame<TPixel> : ImageFrame, IPixelSource<TPixel>
Guard.MustBeGreaterThan(width, 0, nameof(width));
Guard.MustBeGreaterThan(height, 0, nameof(height));
this.PixelBuffer = this.GetConfiguration().MemoryAllocator.Allocate2D<TPixel>(
this.PixelBuffer = this.Configuration.MemoryAllocator.Allocate2D<TPixel>(
width,
height,
configuration.PreferContiguousImageBuffers,
@ -99,7 +99,7 @@ public sealed class ImageFrame<TPixel> : ImageFrame, IPixelSource<TPixel>
Guard.MustBeGreaterThan(width, 0, nameof(width));
Guard.MustBeGreaterThan(height, 0, nameof(height));
this.PixelBuffer = this.GetConfiguration().MemoryAllocator.Allocate2D<TPixel>(
this.PixelBuffer = this.Configuration.MemoryAllocator.Allocate2D<TPixel>(
width,
height,
configuration.PreferContiguousImageBuffers);
@ -146,7 +146,7 @@ public sealed class ImageFrame<TPixel> : ImageFrame, IPixelSource<TPixel>
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(source, nameof(source));
this.PixelBuffer = this.GetConfiguration().MemoryAllocator.Allocate2D<TPixel>(
this.PixelBuffer = this.Configuration.MemoryAllocator.Allocate2D<TPixel>(
source.PixelBuffer.Width,
source.PixelBuffer.Height,
configuration.PreferContiguousImageBuffers);
@ -371,7 +371,7 @@ public sealed class ImageFrame<TPixel> : ImageFrame, IPixelSource<TPixel>
}
this.PixelBuffer.FastMemoryGroup.TransformTo(destination, (s, d)
=> PixelOperations<TPixel>.Instance.To(this.GetConfiguration(), s, d));
=> PixelOperations<TPixel>.Instance.To(this.Configuration, s, d));
}
/// <inheritdoc/>
@ -381,7 +381,7 @@ public sealed class ImageFrame<TPixel> : ImageFrame, IPixelSource<TPixel>
/// Clones the current instance.
/// </summary>
/// <returns>The <see cref="ImageFrame{TPixel}"/></returns>
internal ImageFrame<TPixel> Clone() => this.Clone(this.GetConfiguration());
internal ImageFrame<TPixel> Clone() => this.Clone(this.Configuration);
/// <summary>
/// Clones the current instance.
@ -396,7 +396,7 @@ public sealed class ImageFrame<TPixel> : ImageFrame, IPixelSource<TPixel>
/// <typeparam name="TPixel2">The pixel format.</typeparam>
/// <returns>The <see cref="ImageFrame{TPixel2}"/></returns>
internal ImageFrame<TPixel2>? CloneAs<TPixel2>()
where TPixel2 : unmanaged, IPixel<TPixel2> => this.CloneAs<TPixel2>(this.GetConfiguration());
where TPixel2 : unmanaged, IPixel<TPixel2> => this.CloneAs<TPixel2>(this.Configuration);
/// <summary>
/// Returns a copy of the image frame in the given pixel format.

4
src/ImageSharp/ImageSharp.csproj

@ -22,8 +22,8 @@
</PropertyGroup>
<PropertyGroup>
<!--Bump to V3 prior to tagged release.-->
<MinVerMinimumMajorMinor>3.0</MinVerMinimumMajorMinor>
<!--Bump to v3.1 prior to tagged release.-->
<MinVerMinimumMajorMinor>3.1</MinVerMinimumMajorMinor>
</PropertyGroup>
<Choose>

8
src/ImageSharp/Image{TPixel}.cs

@ -78,12 +78,12 @@ public sealed class Image<TPixel> : Image
/// <param name="height">The height of the image in pixels.</param>
/// <param name="metadata">The images metadata.</param>
internal Image(Configuration configuration, int width, int height, ImageMetadata? metadata)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata, width, height)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata ?? new(), width, height)
=> this.frames = new ImageFrameCollection<TPixel>(this, width, height, default(TPixel));
/// <summary>
/// Initializes a new instance of the <see cref="Image{TPixel}"/> class
/// wrapping an external <see cref="Buffer2D{TPixel}"/> pixel bufferx.
/// wrapping an external <see cref="Buffer2D{TPixel}"/> pixel buffer.
/// </summary>
/// <param name="configuration">The configuration providing initialization code which allows extending the library.</param>
/// <param name="pixelBuffer">Pixel buffer.</param>
@ -129,7 +129,7 @@ public sealed class Image<TPixel> : Image
int height,
TPixel backgroundColor,
ImageMetadata? metadata)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata, width, height)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata ?? new(), width, height)
=> this.frames = new ImageFrameCollection<TPixel>(this, width, height, backgroundColor);
/// <summary>
@ -328,7 +328,7 @@ public sealed class Image<TPixel> : Image
/// Clones the current image
/// </summary>
/// <returns>Returns a new image with all the same metadata as the original.</returns>
public Image<TPixel> Clone() => this.Clone(this.GetConfiguration());
public Image<TPixel> Clone() => this.Clone(this.Configuration);
/// <summary>
/// Clones the current image with the given configuration.

5
src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs

@ -117,6 +117,11 @@ internal sealed class UniformUnmanagedMemoryPoolMemoryAllocator : MemoryAllocato
AllocationOptions options = AllocationOptions.None)
{
long totalLengthInBytes = totalLength * Unsafe.SizeOf<T>();
if (totalLengthInBytes < 0)
{
throw new InvalidMemoryOperationException("Attempted to allocate a MemoryGroup of a size that is not representable.");
}
if (totalLengthInBytes <= this.sharedArrayPoolThresholdInBytes)
{
var buffer = new SharedArrayPoolBuffer<T>((int)totalLength);

5
src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.LongArray.cs

@ -56,11 +56,6 @@ public abstract partial class ExifTag
/// </summary>
public static ExifTag<uint[]> IntergraphRegisters { get; } = new ExifTag<uint[]>(ExifTagValue.IntergraphRegisters);
/// <summary>
/// Gets the TimeZoneOffset exif tag.
/// </summary>
public static ExifTag<uint[]> TimeZoneOffset { get; } = new ExifTag<uint[]>(ExifTagValue.TimeZoneOffset);
/// <summary>
/// Gets the offset to child IFDs exif tag.
/// </summary>

5
src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.Rational.cs

@ -165,4 +165,9 @@ public abstract partial class ExifTag
/// Gets the GPSDestDistance exif tag.
/// </summary>
public static ExifTag<Rational> GPSDestDistance { get; } = new ExifTag<Rational>(ExifTagValue.GPSDestDistance);
/// <summary>
/// Gets the GPSHPositioningError exif tag.
/// </summary>
public static ExifTag<Rational> GPSHPositioningError { get; } = new ExifTag<Rational>(ExifTagValue.GPSHPositioningError);
}

13
src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.SignedShortArray.cs

@ -0,0 +1,13 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.Metadata.Profiles.Exif;
/// <content/>
public abstract partial class ExifTag
{
/// <summary>
/// Gets the TimeZoneOffset exif tag.
/// </summary>
public static ExifTag<short[]> TimeZoneOffset { get; } = new ExifTag<short[]>(ExifTagValue.TimeZoneOffset);
}

5
src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTagValue.cs

@ -1691,6 +1691,11 @@ internal enum ExifTagValue
/// </summary>
GPSDifferential = 0x001E,
/// <summary>
/// GPSHPositioningError
/// </summary>
GPSHPositioningError = 0x001F,
/// <summary>
/// Used in the Oce scanning process.
/// Identifies the scanticket used in the scanning process.

5
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShortArray.cs

@ -5,6 +5,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif;
internal sealed class ExifSignedShortArray : ExifArrayValue<short>
{
public ExifSignedShortArray(ExifTag<short[]> tag)
: base(tag)
{
}
public ExifSignedShortArray(ExifTagValue tag)
: base(tag)
{

7
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs

@ -144,8 +144,6 @@ internal static partial class ExifValues
return new ExifLongArray(ExifTag.StripRowCounts);
case ExifTagValue.IntergraphRegisters:
return new ExifLongArray(ExifTag.IntergraphRegisters);
case ExifTagValue.TimeZoneOffset:
return new ExifLongArray(ExifTag.TimeZoneOffset);
case ExifTagValue.SubIFDs:
return new ExifLongArray(ExifTag.SubIFDs);
@ -243,6 +241,8 @@ internal static partial class ExifValues
return new ExifRational(ExifTag.GPSDestBearing);
case ExifTagValue.GPSDestDistance:
return new ExifRational(ExifTag.GPSDestDistance);
case ExifTagValue.GPSHPositioningError:
return new ExifRational(ExifTag.GPSHPositioningError);
case ExifTagValue.WhitePoint:
return new ExifRationalArray(ExifTag.WhitePoint);
@ -417,6 +417,9 @@ internal static partial class ExifValues
case ExifTagValue.Decode:
return new ExifSignedRationalArray(ExifTag.Decode);
case ExifTagValue.TimeZoneOffset:
return new ExifSignedShortArray(ExifTag.TimeZoneOffset);
case ExifTagValue.ImageDescription:
return new ExifString(ExifTag.ImageDescription);
case ExifTagValue.Make:

4
src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs

@ -88,9 +88,9 @@ internal sealed class IccReader
foreach (IccTagTableEntry tag in tagTable)
{
IccTagDataEntry entry;
if (store.ContainsKey(tag.Offset))
if (store.TryGetValue(tag.Offset, out IccTagDataEntry? value))
{
entry = store[tag.Offset];
entry = value;
}
else
{

2
src/ImageSharp/Processing/Extensions/ProcessingExtensions.IntegralImage.cs

@ -54,7 +54,7 @@ public static partial class ProcessingExtensions
public static Buffer2D<ulong> CalculateIntegralImage<TPixel>(this ImageFrame<TPixel> source, Rectangle bounds)
where TPixel : unmanaged, IPixel<TPixel>
{
Configuration configuration = source.GetConfiguration();
Configuration configuration = source.Configuration;
var interest = Rectangle.Intersect(bounds, source.Bounds());
int startY = interest.Y;

12
src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs

@ -22,7 +22,7 @@ public static partial class ProcessingExtensions
/// <exception cref="ObjectDisposedException">The source has been disposed.</exception>
/// <exception cref="ImageProcessingException">The processing operation failed.</exception>
public static void Mutate(this Image source, Action<IImageProcessingContext> operation)
=> Mutate(source, source.GetConfiguration(), operation);
=> Mutate(source, source.Configuration, operation);
/// <summary>
/// Mutates the source image by applying the image operation to it.
@ -57,7 +57,7 @@ public static partial class ProcessingExtensions
/// <exception cref="ImageProcessingException">The processing operation failed.</exception>
public static void Mutate<TPixel>(this Image<TPixel> source, Action<IImageProcessingContext> operation)
where TPixel : unmanaged, IPixel<TPixel>
=> Mutate(source, source.GetConfiguration(), operation);
=> Mutate(source, source.Configuration, operation);
/// <summary>
/// Mutates the source image by applying the image operation to it.
@ -97,7 +97,7 @@ public static partial class ProcessingExtensions
/// <exception cref="ImageProcessingException">The processing operation failed.</exception>
public static void Mutate<TPixel>(this Image<TPixel> source, params IImageProcessor[] operations)
where TPixel : unmanaged, IPixel<TPixel>
=> Mutate(source, source.GetConfiguration(), operations);
=> Mutate(source, source.Configuration, operations);
/// <summary>
/// Mutates the source image by applying the operations to it.
@ -135,7 +135,7 @@ public static partial class ProcessingExtensions
/// <exception cref="ObjectDisposedException">The source has been disposed.</exception>
/// <exception cref="ImageProcessingException">The processing operation failed.</exception>
public static Image Clone(this Image source, Action<IImageProcessingContext> operation)
=> Clone(source, source.GetConfiguration(), operation);
=> Clone(source, source.Configuration, operation);
/// <summary>
/// Creates a deep clone of the current image. The clone is then mutated by the given operation.
@ -174,7 +174,7 @@ public static partial class ProcessingExtensions
/// <returns>The new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Clone<TPixel>(this Image<TPixel> source, Action<IImageProcessingContext> operation)
where TPixel : unmanaged, IPixel<TPixel>
=> Clone(source, source.GetConfiguration(), operation);
=> Clone(source, source.Configuration, operation);
/// <summary>
/// Creates a deep clone of the current image. The clone is then mutated by the given operation.
@ -217,7 +217,7 @@ public static partial class ProcessingExtensions
/// <returns>The new <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> Clone<TPixel>(this Image<TPixel> source, params IImageProcessor[] operations)
where TPixel : unmanaged, IPixel<TPixel>
=> Clone(source, source.GetConfiguration(), operations);
=> Clone(source, source.Configuration, operations);
/// <summary>
/// Creates a deep clone of the current image. The clone is then mutated by the given operations.

2
src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs

@ -38,7 +38,7 @@ internal class EntropyCropProcessor<TPixel> : ImageProcessor<TPixel>
// All frames have be the same size so we only need to calculate the correct dimensions for the first frame
using (Image<TPixel> temp = new(this.Configuration, this.Source.Metadata.DeepClone(), new[] { this.Source.Frames.RootFrame.Clone() }))
{
Configuration configuration = this.Source.GetConfiguration();
Configuration configuration = this.Source.Configuration;
// Detect the edges.
new EdgeDetector2DProcessor(KnownEdgeDetectorKernels.Sobel, false).Execute(this.Configuration, temp, this.SourceRectangle);

4
tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs

@ -42,7 +42,7 @@ public class YuvConversionTests
{
// arrange
using Image<TPixel> image = provider.GetImage();
Configuration config = image.GetConfiguration();
Configuration config = image.Configuration;
MemoryAllocator memoryAllocator = config.MemoryAllocator;
int pixels = image.Width * image.Height;
int uvWidth = (image.Width + 1) >> 1;
@ -158,7 +158,7 @@ public class YuvConversionTests
{
// arrange
using Image<TPixel> image = provider.GetImage();
Configuration config = image.GetConfiguration();
Configuration config = image.Configuration;
MemoryAllocator memoryAllocator = config.MemoryAllocator;
int pixels = image.Width * image.Height;
int uvWidth = (image.Width + 1) >> 1;

8
tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs

@ -20,7 +20,7 @@ public abstract partial class ImageFrameCollectionTests
public void AddFrame_OfDifferentPixelType()
{
using (Image<Bgra32> sourceImage = new(
this.Image.GetConfiguration(),
this.Image.Configuration,
this.Image.Width,
this.Image.Height,
Color.Blue))
@ -41,7 +41,7 @@ public abstract partial class ImageFrameCollectionTests
public void InsertFrame_OfDifferentPixelType()
{
using (Image<Bgra32> sourceImage = new(
this.Image.GetConfiguration(),
this.Image.Configuration,
this.Image.Width,
this.Image.Height,
Color.Blue))
@ -278,8 +278,8 @@ public abstract partial class ImageFrameCollectionTests
where TPixel : unmanaged, IPixel<TPixel>
{
using Image source = provider.GetImage();
using Image<TPixel> dest = new(source.GetConfiguration(), source.Width, source.Height);
using Image<TPixel> dest = new(source.Configuration, source.Width, source.Height);
// Giphy.gif has 5 frames
ImportFrameAs<Bgra32>(source.Frames, dest.Frames, 0);
ImportFrameAs<Argb32>(source.Frames, dest.Frames, 1);

2
tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs

@ -70,7 +70,7 @@ public partial class ImageTests
{
using Image<Rgba32> image = new(5, 5);
string ext = Path.GetExtension(filename);
image.GetConfiguration().ImageFormatsManager.TryFindFormatByFileExtension(ext, out IImageFormat format);
image.Configuration.ImageFormatsManager.TryFindFormatByFileExtension(ext, out IImageFormat format);
Assert.Equal(mimeType, format!.DefaultMimeType);
using MemoryStream stream = new();

6
tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs

@ -136,7 +136,7 @@ public partial class ImageTests
ref Rgba32 pixel0 = ref imageMem.Span[0];
Assert.True(Unsafe.AreSame(ref array[0], ref pixel0));
Assert.Equal(cfg, image.GetConfiguration());
Assert.Equal(cfg, image.Configuration);
Assert.Equal(metaData, image.Metadata);
}
}
@ -239,7 +239,7 @@ public partial class ImageTests
ref Rgba32 pixel0 = ref imageMem.Span[0];
Assert.True(Unsafe.AreSame(ref Unsafe.As<byte, Rgba32>(ref array[0]), ref pixel0));
Assert.Equal(cfg, image.GetConfiguration());
Assert.Equal(cfg, image.Configuration);
Assert.Equal(metaData, image.Metadata);
}
}
@ -336,7 +336,7 @@ public partial class ImageTests
ref Rgba32 pixel_1 = ref imageSpan[imageSpan.Length - 1];
Assert.True(Unsafe.AreSame(ref array[array.Length - 1], ref pixel_1));
Assert.Equal(cfg, image.GetConfiguration());
Assert.Equal(cfg, image.Configuration);
Assert.Equal(metaData, image.Metadata);
}
}

13
tests/ImageSharp.Tests/Image/ImageTests.cs

@ -6,6 +6,7 @@ using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.Memory;
@ -31,10 +32,14 @@ public partial class ImageTests
Assert.Equal(11 * 23, imageMem.Length);
image.ComparePixelBufferTo(default(Rgba32));
Assert.Equal(Configuration.Default, image.GetConfiguration());
Assert.Equal(Configuration.Default, image.Configuration);
}
}
[Fact]
public void Width_Height_SizeNotRepresentable_ThrowsInvalidImageOperationException()
=> Assert.Throws<InvalidMemoryOperationException>(() => new Image<Rgba32>(int.MaxValue, int.MaxValue));
[Fact]
public void Configuration_Width_Height()
{
@ -48,7 +53,7 @@ public partial class ImageTests
Assert.Equal(11 * 23, imageMem.Length);
image.ComparePixelBufferTo(default(Rgba32));
Assert.Equal(configuration, image.GetConfiguration());
Assert.Equal(configuration, image.Configuration);
}
}
@ -66,7 +71,7 @@ public partial class ImageTests
Assert.Equal(11 * 23, imageMem.Length);
image.ComparePixelBufferTo(color);
Assert.Equal(configuration, image.GetConfiguration());
Assert.Equal(configuration, image.Configuration);
}
}
@ -83,7 +88,7 @@ public partial class ImageTests
{
Assert.Equal(21, image.Width);
Assert.Equal(22, image.Height);
Assert.Same(configuration, image.GetConfiguration());
Assert.Same(configuration, image.Configuration);
Assert.Same(metadata, image.Metadata);
Assert.Equal(dirtyValue, image[5, 5].PackedValue);

7
tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs

@ -107,6 +107,13 @@ public class UniformUnmanagedPoolMemoryAllocatorTests
}
}
[Fact]
public void AllocateGroup_SizeInBytesOverLongMaxValue_ThrowsInvalidMemoryOperationException()
{
var allocator = new UniformUnmanagedMemoryPoolMemoryAllocator(null);
Assert.Throws<InvalidMemoryOperationException>(() => allocator.AllocateGroup<S4>(int.MaxValue * (long)int.MaxValue, int.MaxValue));
}
[Fact]
public unsafe void Allocate_MemoryIsPinnableMultipleTimes()
{

24
tests/ImageSharp.Tests/Metadata/Profiles/Exif/Values/ExifValuesTests.cs

@ -70,8 +70,7 @@ public class ExifValuesTests
{ ExifTag.JPEGDCTables },
{ ExifTag.JPEGACTables },
{ ExifTag.StripRowCounts },
{ ExifTag.IntergraphRegisters },
{ ExifTag.TimeZoneOffset }
{ ExifTag.IntergraphRegisters }
};
public static TheoryData<ExifTag> NumberTags => new TheoryData<ExifTag>
@ -129,6 +128,7 @@ public class ExifValuesTests
{ ExifTag.GPSImgDirection },
{ ExifTag.GPSDestBearing },
{ ExifTag.GPSDestDistance },
{ ExifTag.GPSHPositioningError },
};
public static TheoryData<ExifTag> RationalArrayTags => new TheoryData<ExifTag>
@ -235,6 +235,11 @@ public class ExifValuesTests
{ ExifTag.Decode }
};
public static TheoryData<ExifTag> SignedShortArrayTags => new TheoryData<ExifTag>
{
{ ExifTag.TimeZoneOffset }
};
public static TheoryData<ExifTag> StringTags => new TheoryData<ExifTag>
{
{ ExifTag.ImageDescription },
@ -559,6 +564,21 @@ public class ExifValuesTests
Assert.Equal(expected, typed.Value);
}
[Theory]
[MemberData(nameof(SignedShortArrayTags))]
public void ExifSignedShortArrayTests(ExifTag tag)
{
short[] expected = new short[] { 21, 42 };
ExifValue value = ExifValues.Create(tag);
Assert.False(value.TrySetValue(expected.ToString()));
Assert.True(value.TrySetValue(expected));
var typed = (ExifSignedShortArray)value;
Assert.Equal(expected, typed.Value);
}
[Theory]
[MemberData(nameof(StringTags))]
public void ExifStringTests(ExifTag tag)

2
tests/ImageSharp.Tests/Processing/BaseImageOperationsExtensionTest.cs

@ -22,7 +22,7 @@ public abstract class BaseImageOperationsExtensionTest : IDisposable
this.options = new GraphicsOptions { Antialias = false };
this.source = new Image<Rgba32>(91 + 324, 123 + 56);
this.rect = new Rectangle(91, 123, 324, 56); // make this random?
this.internalOperations = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(this.source.GetConfiguration(), this.source, false);
this.internalOperations = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(this.source.Configuration, this.source, false);
this.internalOperations.SetGraphicsOptions(this.options);
this.operations = this.internalOperations;
}

2
tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs

@ -65,7 +65,7 @@ public class BokehBlurTest
// Make sure the kernel components are the same
using Image<Rgb24> image = new(1, 1);
Configuration configuration = image.GetConfiguration();
Configuration configuration = image.Configuration;
BokehBlurProcessor definition = new(10, BokehBlurProcessor.DefaultComponents, BokehBlurProcessor.DefaultGamma);
using BokehBlurProcessor<Rgb24> processor = (BokehBlurProcessor<Rgb24>)definition.CreatePixelSpecificProcessor(configuration, image, image.Bounds);

2
tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs

@ -28,7 +28,7 @@ public class ExactImageComparer : ImageComparer
var bBuffer = new Rgba64[width];
var differences = new List<PixelDifference>();
Configuration configuration = expected.GetConfiguration();
Configuration configuration = expected.Configuration;
Buffer2D<TPixelA> expectedBuffer = expected.PixelBuffer;
Buffer2D<TPixelB> actualBuffer = actual.PixelBuffer;

2
tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs

@ -72,7 +72,7 @@ public class TolerantImageComparer : ImageComparer
float totalDifference = 0F;
var differences = new List<PixelDifference>();
Configuration configuration = expected.GetConfiguration();
Configuration configuration = expected.Configuration;
Buffer2D<TPixelA> expectedBuffer = expected.PixelBuffer;
Buffer2D<TPixelB> actualBuffer = actual.PixelBuffer;

6
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/ImageSharpPngEncoderWithDefaultConfiguration.cs

@ -2,7 +2,6 @@
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
@ -15,10 +14,7 @@ public sealed class ImageSharpPngEncoderWithDefaultConfiguration : PngEncoder
/// <inheritdoc/>
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
Configuration configuration = Configuration.Default;
MemoryAllocator allocator = configuration.MemoryAllocator;
using PngEncoderCore encoder = new(allocator, configuration, this);
using PngEncoderCore encoder = new(Configuration.Default, this);
encoder.Encode(image, stream, cancellationToken);
}
}

8
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs

@ -45,7 +45,7 @@ public static class SystemDrawingBridge
long sourceRowByteCount = data.Stride;
long destRowByteCount = w * sizeof(Bgra32);
Configuration configuration = image.GetConfiguration();
Configuration configuration = image.Configuration;
image.ProcessPixelRows(accessor =>
{
using IMemoryOwner<Bgra32> workBuffer = Configuration.Default.MemoryAllocator.Allocate<Bgra32>(w);
@ -104,7 +104,7 @@ public static class SystemDrawingBridge
long sourceRowByteCount = data.Stride;
long destRowByteCount = w * sizeof(Bgr24);
Configuration configuration = image.GetConfiguration();
Configuration configuration = image.Configuration;
Buffer2D<TPixel> imageBuffer = image.Frames.RootFrame.PixelBuffer;
using (IMemoryOwner<Bgr24> workBuffer = Configuration.Default.MemoryAllocator.Allocate<Bgr24>(w))
@ -134,7 +134,7 @@ public static class SystemDrawingBridge
internal static unsafe Bitmap To32bppArgbSystemDrawingBitmap<TPixel>(Image<TPixel> image)
where TPixel : unmanaged, IPixel<TPixel>
{
Configuration configuration = image.GetConfiguration();
Configuration configuration = image.Configuration;
int w = image.Width;
int h = image.Height;
@ -148,7 +148,7 @@ public static class SystemDrawingBridge
long sourceRowByteCount = w * sizeof(Bgra32);
image.ProcessPixelRows(accessor =>
{
using IMemoryOwner<Bgra32> workBuffer = image.GetConfiguration().MemoryAllocator.Allocate<Bgra32>(w);
using IMemoryOwner<Bgra32> workBuffer = image.Configuration.MemoryAllocator.Allocate<Bgra32>(w);
fixed (Bgra32* sourcePtr = &workBuffer.GetReference())
{
for (int y = 0; y < h; y++)

4
tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs

@ -342,8 +342,8 @@ public class TestImageProviderTests
using Image<TPixel> image2 = provider.GetImage();
using Image<TPixel> image3 = provider.GetImage();
Assert.Same(customConfiguration, image2.GetConfiguration());
Assert.Same(customConfiguration, image3.GetConfiguration());
Assert.Same(customConfiguration, image2.Configuration);
Assert.Same(customConfiguration, image3.Configuration);
}
}

Loading…
Cancel
Save