diff --git a/shared-infrastructure b/shared-infrastructure index bf398a9b6b..9a82679e92 160000 --- a/shared-infrastructure +++ b/shared-infrastructure @@ -1 +1 @@ -Subproject commit bf398a9b6bb6d0acfe0525ee109276b4ef74646c +Subproject commit 9a82679e92df9476725fd2a2038604fd412af56c diff --git a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs index 10267c8ef7..4fa07931ed 100644 --- a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs +++ b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs @@ -27,8 +27,7 @@ public static class AdvancedImageExtensions Guard.NotNull(filePath, nameof(filePath)); string ext = Path.GetExtension(filePath); - IImageFormat format = source.GetConfiguration().ImageFormatsManager.FindFormatByFileExtension(ext); - if (format is null) + if (!source.GetConfiguration().ImageFormatsManager.TryFindFormatByFileExtension(ext, out IImageFormat? format)) { StringBuilder sb = new(); sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}'. Registered encoders include:"); @@ -40,7 +39,7 @@ public static class AdvancedImageExtensions throw new NotSupportedException(sb.ToString()); } - IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format); + IImageEncoder? encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format); if (encoder is null) { diff --git a/src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs b/src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs index 4957b7ba73..01dd3157ef 100644 --- a/src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs @@ -1,8 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Buffers.Binary; +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Formats.Bmp; @@ -15,9 +15,11 @@ public sealed class BmpImageFormatDetector : IImageFormatDetector public int HeaderSize => 2; /// - public IImageFormat DetectFormat(ReadOnlySpan header) + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) { - return this.IsSupportedFileFormat(header) ? BmpFormat.Instance : null; + format = this.IsSupportedFileFormat(header) ? BmpFormat.Instance : null; + + return format != null; } private bool IsSupportedFileFormat(ReadOnlySpan header) @@ -25,7 +27,8 @@ public sealed class BmpImageFormatDetector : IImageFormatDetector if (header.Length >= this.HeaderSize) { short fileTypeMarker = BinaryPrimitives.ReadInt16LittleEndian(header); - return fileTypeMarker == BmpConstants.TypeMarkers.Bitmap || fileTypeMarker == BmpConstants.TypeMarkers.BitmapArray; + return fileTypeMarker == BmpConstants.TypeMarkers.Bitmap || + fileTypeMarker == BmpConstants.TypeMarkers.BitmapArray; } return false; diff --git a/src/ImageSharp/Formats/Gif/GifImageFormatDetector.cs b/src/ImageSharp/Formats/Gif/GifImageFormatDetector.cs index c826765009..ffda8075af 100644 --- a/src/ImageSharp/Formats/Gif/GifImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Gif/GifImageFormatDetector.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable + +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Formats.Gif; @@ -13,9 +14,10 @@ public sealed class GifImageFormatDetector : IImageFormatDetector public int HeaderSize => 6; /// - public IImageFormat DetectFormat(ReadOnlySpan header) + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) { - return this.IsSupportedFileFormat(header) ? GifFormat.Instance : null; + format = this.IsSupportedFileFormat(header) ? GifFormat.Instance : null; + return format != null; } private bool IsSupportedFileFormat(ReadOnlySpan header) diff --git a/src/ImageSharp/Formats/IImageFormatDetector.cs b/src/ImageSharp/Formats/IImageFormatDetector.cs index 17f565d2b2..86750a7106 100644 --- a/src/ImageSharp/Formats/IImageFormatDetector.cs +++ b/src/ImageSharp/Formats/IImageFormatDetector.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Diagnostics.CodeAnalysis; + namespace SixLabors.ImageSharp.Formats; /// @@ -18,6 +20,7 @@ public interface IImageFormatDetector /// Detect mimetype /// /// The containing the file header. - /// returns the mime type of detected otherwise returns null - IImageFormat DetectFormat(ReadOnlySpan header); + /// The mime type of detected otherwise returns null + /// returns true when format was detected otherwise false. + bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format); } diff --git a/src/ImageSharp/Formats/ImageDecoderUtilities.cs b/src/ImageSharp/Formats/ImageDecoderUtilities.cs index 50635dbefb..2a5b91b094 100644 --- a/src/ImageSharp/Formats/ImageDecoderUtilities.cs +++ b/src/ImageSharp/Formats/ImageDecoderUtilities.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs index dc09bb6a13..d058e80c9b 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -1,8 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Formats; @@ -92,8 +92,9 @@ public class ImageFormatManager /// For the specified file extensions type find the e . /// /// The extension to discover - /// The if found otherwise null - public IImageFormat FindFormatByFileExtension(string extension) + /// The if found otherwise null + /// False if no format was found + public bool TryFindFormatByFileExtension(string extension, [NotNullWhen(true)] out IImageFormat? format) { Guard.NotNullOrWhiteSpace(extension, nameof(extension)); @@ -102,7 +103,10 @@ public class ImageFormatManager extension = extension[1..]; } - return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); + format = this.imageFormats.FirstOrDefault(x => + x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); + + return format != null; } /// @@ -110,7 +114,7 @@ public class ImageFormatManager /// /// The mime-type to discover /// The if found; otherwise null - public IImageFormat FindFormatByMimeType(string mimeType) + public IImageFormat? FindFormatByMimeType(string mimeType) => this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase)); /// @@ -160,11 +164,11 @@ public class ImageFormatManager /// /// The format to discover /// The if found otherwise null - public IImageDecoder FindDecoder(IImageFormat format) + public IImageDecoder? FindDecoder(IImageFormat format) { Guard.NotNull(format, nameof(format)); - return this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder decoder) + return this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder? decoder) ? decoder : null; } @@ -174,11 +178,11 @@ public class ImageFormatManager /// /// The format to discover /// The if found otherwise null - public IImageEncoder FindEncoder(IImageFormat format) + public IImageEncoder? FindEncoder(IImageFormat format) { Guard.NotNull(format, nameof(format)); - return this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder encoder) + return this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder? encoder) ? encoder : null; } diff --git a/src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs b/src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs index 54e1b28ee3..4daf9fd97b 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable + +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Formats.Jpeg; @@ -13,8 +14,11 @@ public sealed class JpegImageFormatDetector : IImageFormatDetector public int HeaderSize => 11; /// - public IImageFormat DetectFormat(ReadOnlySpan header) - => this.IsSupportedFileFormat(header) ? JpegFormat.Instance : null; + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) + { + format = this.IsSupportedFileFormat(header) ? JpegFormat.Instance : null; + return format != null; + } private bool IsSupportedFileFormat(ReadOnlySpan header) => header.Length >= this.HeaderSize diff --git a/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs b/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs index 01ad9c62be..a50a2ddb69 100644 --- a/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable + +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Formats.Pbm; @@ -17,7 +18,11 @@ public sealed class PbmImageFormatDetector : IImageFormatDetector public int HeaderSize => 2; /// - public IImageFormat DetectFormat(ReadOnlySpan header) => IsSupportedFileFormat(header) ? PbmFormat.Instance : null; + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) + { + format = IsSupportedFileFormat(header) ? PbmFormat.Instance : null; + return format != null; + } private static bool IsSupportedFileFormat(ReadOnlySpan header) { diff --git a/src/ImageSharp/Formats/Png/PngImageFormatDetector.cs b/src/ImageSharp/Formats/Png/PngImageFormatDetector.cs index a389428070..1b574d49bb 100644 --- a/src/ImageSharp/Formats/Png/PngImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Png/PngImageFormatDetector.cs @@ -1,8 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Buffers.Binary; +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Formats.Png; @@ -15,9 +15,10 @@ public sealed class PngImageFormatDetector : IImageFormatDetector public int HeaderSize => 8; /// - public IImageFormat DetectFormat(ReadOnlySpan header) + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) { - return this.IsSupportedFileFormat(header) ? PngFormat.Instance : null; + format = this.IsSupportedFileFormat(header) ? PngFormat.Instance : null; + return format != null; } private bool IsSupportedFileFormat(ReadOnlySpan header) diff --git a/src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs b/src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs index 82246f3474..ad76bc3fbd 100644 --- a/src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable + +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Formats.Tga; @@ -13,9 +14,10 @@ public sealed class TgaImageFormatDetector : IImageFormatDetector public int HeaderSize => 16; /// - public IImageFormat DetectFormat(ReadOnlySpan header) + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) { - return this.IsSupportedFileFormat(header) ? TgaFormat.Instance : null; + format = this.IsSupportedFileFormat(header) ? TgaFormat.Instance : null; + return format != null; } private bool IsSupportedFileFormat(ReadOnlySpan header) diff --git a/src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs b/src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs index c48014024f..6382037ed3 100644 --- a/src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable + +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Formats.Tiff; @@ -13,14 +14,10 @@ public sealed class TiffImageFormatDetector : IImageFormatDetector public int HeaderSize => 8; /// - public IImageFormat DetectFormat(ReadOnlySpan header) + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) { - if (this.IsSupportedFileFormat(header)) - { - return TiffFormat.Instance; - } - - return null; + format = this.IsSupportedFileFormat(header) ? TiffFormat.Instance : null; + return format != null; } private bool IsSupportedFileFormat(ReadOnlySpan header) diff --git a/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs b/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs index 9b52492aaa..2b91aa95fe 100644 --- a/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable + +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Formats.Webp; @@ -13,8 +14,11 @@ public sealed class WebpImageFormatDetector : IImageFormatDetector public int HeaderSize => 12; /// - public IImageFormat DetectFormat(ReadOnlySpan header) - => this.IsSupportedFileFormat(header) ? WebpFormat.Instance : null; + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) + { + format = this.IsSupportedFileFormat(header) ? WebpFormat.Instance : null; + return format != null; + } private bool IsSupportedFileFormat(ReadOnlySpan header) => header.Length >= this.HeaderSize && IsRiffContainer(header) && IsWebpFile(header); diff --git a/src/ImageSharp/Image.Decode.cs b/src/ImageSharp/Image.Decode.cs index 806a0f471b..a556cbceb3 100644 --- a/src/ImageSharp/Image.Decode.cs +++ b/src/ImageSharp/Image.Decode.cs @@ -82,8 +82,7 @@ public abstract partial class Image { if (formatDetector.HeaderSize <= headerSize) { - IImageFormat attemptFormat = formatDetector.DetectFormat(headersBuffer); - if (attemptFormat != null) + if (formatDetector.TryDetectFormat(headersBuffer, out IImageFormat attemptFormat)) { format = attemptFormat; } diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs index 2ea2b9d432..7a2e9d736e 100644 --- a/src/ImageSharp/Image.FromBytes.cs +++ b/src/ImageSharp/Image.FromBytes.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable +using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; @@ -16,18 +16,20 @@ public abstract partial class Image /// By reading the header on the provided byte span this calculates the images format. /// /// The byte span containing encoded image data to read the header from. - /// The format or null if none found. - public static IImageFormat DetectFormat(ReadOnlySpan data) - => DetectFormat(DecoderOptions.Default, data); + /// The format or null if none found. + /// returns true when format was detected otherwise false. + public static bool TryDetectFormat(ReadOnlySpan data, [NotNullWhen(true)] out IImageFormat? format) + => TryDetectFormat(DecoderOptions.Default, data, out format); /// /// By reading the header on the provided byte span this calculates the images format. /// /// The general decoder options. /// The byte span containing encoded image data to read the header from. + /// The mime type or null if none found. /// The options are null. - /// The mime type or null if none found. - public static IImageFormat DetectFormat(DecoderOptions options, ReadOnlySpan data) + /// returns true when format was detected otherwise false. + public static bool TryDetectFormat(DecoderOptions options, ReadOnlySpan data, [NotNullWhen(true)] out IImageFormat? format) { Guard.NotNull(options, nameof(options.Configuration)); @@ -35,20 +37,20 @@ public abstract partial class Image int maxHeaderSize = configuration.MaxHeaderSize; if (maxHeaderSize <= 0) { - return null; + format = null; + return false; } foreach (IImageFormatDetector detector in configuration.ImageFormatsManager.FormatDetectors) { - IImageFormat f = detector.DetectFormat(data); - - if (f != null) + if (detector.TryDetectFormat(data, out format)) { - return f; + return true; } } - return default; + format = default; + return false; } /// diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs index 199d450b89..cd27e2882d 100644 --- a/src/ImageSharp/Image.FromFile.cs +++ b/src/ImageSharp/Image.FromFile.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; @@ -15,23 +16,25 @@ public abstract partial class Image /// By reading the header on the provided file this calculates the images mime type. /// /// The image file to open and to read the header from. - /// The mime type or null if none found. - public static IImageFormat DetectFormat(string filePath) - => DetectFormat(DecoderOptions.Default, filePath); + /// The mime type or null if none found. + /// returns true when format was detected otherwise false. + public static bool TryDetectFormat(string filePath, [NotNullWhen(true)] out IImageFormat? format) + => TryDetectFormat(DecoderOptions.Default, filePath, out format); /// /// By reading the header on the provided file this calculates the images mime type. /// /// The general decoder options. /// The image file to open and to read the header from. + /// The mime type or null if none found. /// The configuration is null. - /// The mime type or null if none found. - public static IImageFormat DetectFormat(DecoderOptions options, string filePath) + /// returns true when format was detected otherwise false. + public static bool TryDetectFormat(DecoderOptions options, string filePath, [NotNullWhen(true)] out IImageFormat? format) { Guard.NotNull(options, nameof(options)); using Stream file = options.Configuration.FileSystem.OpenRead(filePath); - return DetectFormat(options, file); + return TryDetectFormat(options, file, out format); } /// diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs index 33653434d5..63b9b5c1b9 100644 --- a/src/ImageSharp/Image.FromStream.cs +++ b/src/ImageSharp/Image.FromStream.cs @@ -19,23 +19,28 @@ public abstract partial class Image /// By reading the header on the provided stream this calculates the images format type. /// /// The image stream to read the header from. + /// The format type or null if none found. /// The stream is null. /// The stream is not readable. - /// The format type or null if none found. - public static IImageFormat DetectFormat(Stream stream) - => DetectFormat(DecoderOptions.Default, stream); + /// returns true when format was detected otherwise false. + public static bool TryDetectFormat(Stream stream, [NotNullWhen(true)] out IImageFormat? format) + => TryDetectFormat(DecoderOptions.Default, stream, out format); /// /// By reading the header on the provided stream this calculates the images format type. /// /// The general decoder options. /// The image stream to read the header from. + /// The format type or null if none found. /// The options are null. /// The stream is null. /// The stream is not readable. - /// The format type or null if none found. - public static IImageFormat DetectFormat(DecoderOptions options, Stream stream) - => WithSeekableStream(options, stream, s => InternalDetectFormat(options.Configuration, s)); + /// returns true when format was detected otherwise false. + public static bool TryDetectFormat(DecoderOptions options, Stream stream, [NotNullWhen(true)] out IImageFormat? format) + { + format = WithSeekableStream(options, stream, s => InternalDetectFormat(options.Configuration, s)); + return format != null; + } /// /// By reading the header on the provided stream this calculates the images format type. diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index 01dd727fc0..31fd015096 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable -using System.Buffers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; @@ -420,7 +418,7 @@ public sealed class Image : Image { Guard.NotNull(frames, nameof(frames)); - ImageFrame rootFrame = frames.FirstOrDefault(); + ImageFrame? rootFrame = frames.FirstOrDefault(); if (rootFrame == null) { diff --git a/src/ImageSharp/Processing/Processors/CloningImageProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/CloningImageProcessor{TPixel}.cs index 1cf8f35795..aa000a10e7 100644 --- a/src/ImageSharp/Processing/Processors/CloningImageProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/CloningImageProcessor{TPixel}.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using SixLabors.ImageSharp.PixelFormats; @@ -73,7 +72,7 @@ public abstract class CloningImageProcessor : ICloningImageProcessor clone = default; + Image? clone = default; try { clone = ((ICloningImageProcessor)this).CloneAndExecute(); diff --git a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessorHelpers.cs b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessorHelpers.cs index df18baf839..4aefa0daef 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessorHelpers.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessorHelpers.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable + +using System.Diagnostics.CodeAnalysis; namespace SixLabors.ImageSharp.Processing.Processors.Convolution; @@ -99,7 +100,7 @@ internal static class ConvolutionProcessorHelpers /// The resulting 1D row vector, if possible. /// The resulting 1D column vector, if possible. /// Whether or not was linearly separable. - public static bool TryGetLinearlySeparableComponents(this DenseMatrix matrix, out float[] row, out float[] column) + public static bool TryGetLinearlySeparableComponents(this DenseMatrix matrix, [NotNullWhen(true)] out float[]? row, [NotNullWhen(true)] out float[]? column) { int height = matrix.Rows; int width = matrix.Columns; diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetector2DKernel.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetector2DKernel.cs index f03555bbaa..d900b2746a 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetector2DKernel.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetector2DKernel.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable namespace SixLabors.ImageSharp.Processing.Processors.Convolution; @@ -88,7 +87,7 @@ public readonly struct EdgeDetector2DKernel : IEquatable => !(left == right); /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj is EdgeDetector2DKernel kernel && this.Equals(kernel); /// diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorCompassKernel.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorCompassKernel.cs index d476ed9231..0c456eb88e 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorCompassKernel.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorCompassKernel.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable namespace SixLabors.ImageSharp.Processing.Processors.Convolution; @@ -135,7 +134,7 @@ public readonly struct EdgeDetectorCompassKernel : IEquatable !(left == right); /// - public override bool Equals(object obj) => obj is EdgeDetectorCompassKernel kernel && this.Equals(kernel); + public override bool Equals(object? obj) => obj is EdgeDetectorCompassKernel kernel && this.Equals(kernel); /// public bool Equals(EdgeDetectorCompassKernel other) => this.North.Equals(other.North) && this.NorthWest.Equals(other.NorthWest) && this.West.Equals(other.West) && this.SouthWest.Equals(other.SouthWest) && this.South.Equals(other.South) && this.SouthEast.Equals(other.SouthEast) && this.East.Equals(other.East) && this.NorthEast.Equals(other.NorthEast); diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorKernel.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorKernel.cs index 9022dd044a..42a0c1cfe8 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorKernel.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorKernel.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable namespace SixLabors.ImageSharp.Processing.Processors.Convolution; @@ -64,7 +63,7 @@ public readonly struct EdgeDetectorKernel : IEquatable => !(left == right); /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj is EdgeDetectorKernel kernel && this.Equals(kernel); /// diff --git a/src/ImageSharp/Processing/Processors/Convolution/Parameters/BokehBlurParameters.cs b/src/ImageSharp/Processing/Processors/Convolution/Parameters/BokehBlurParameters.cs index 15ff8560e1..cb92dce4a7 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Parameters/BokehBlurParameters.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Parameters/BokehBlurParameters.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable namespace SixLabors.ImageSharp.Processing.Processors.Convolution.Parameters; @@ -37,7 +36,7 @@ internal readonly struct BokehBlurParameters : IEquatable } /// - public override bool Equals(object obj) => obj is BokehBlurParameters other && this.Equals(other); + public override bool Equals(object? obj) => obj is BokehBlurParameters other && this.Equals(other); /// public override int GetHashCode() diff --git a/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs b/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs index 5706f2d992..3a869a0a28 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Numerics; using System.Runtime.CompilerServices; @@ -212,7 +211,7 @@ public readonly partial struct ErrorDither : IDither, IEquatable, I } /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj is ErrorDither dither && this.Equals(dither); /// @@ -220,8 +219,8 @@ public readonly partial struct ErrorDither : IDither, IEquatable, I => this.offset == other.offset && this.matrix.Equals(other.matrix); /// - public bool Equals(IDither other) - => this.Equals((object)other); + public bool Equals(IDither? other) + => this.Equals((object?)other); /// public override int GetHashCode() diff --git a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs index b96427934d..1a02e7a221 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Memory; @@ -200,7 +199,7 @@ public readonly partial struct OrderedDither : IDither, IEquatable - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj is OrderedDither dither && this.Equals(dither); /// @@ -209,8 +208,8 @@ public readonly partial struct OrderedDither : IDither, IEquatable this.thresholdMatrix.Equals(other.thresholdMatrix) && this.modulusX == other.modulusX && this.modulusY == other.modulusY; /// - public bool Equals(IDither other) - => this.Equals((object)other); + public bool Equals(IDither? other) + => this.Equals((object?)other); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs index b95bbe3793..abf283e6c1 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Buffers; using System.Diagnostics.CodeAnalysis; @@ -19,7 +18,7 @@ internal sealed class PaletteDitherProcessor : ImageProcessor { private readonly DitherProcessor ditherProcessor; private readonly IDither dither; - private IMemoryOwner paletteOwner; + private IMemoryOwner? paletteOwner; private bool isDisposed; /// @@ -62,7 +61,7 @@ internal sealed class PaletteDitherProcessor : ImageProcessor this.isDisposed = true; if (disposing) { - this.paletteOwner.Dispose(); + this.paletteOwner?.Dispose(); this.ditherProcessor.Dispose(); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs index 6e7384cbdd..d03a694ba5 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable +using System.Diagnostics.CodeAnalysis; using System.Numerics; namespace SixLabors.ImageSharp.Processing.Processors.Transforms; @@ -422,6 +422,7 @@ internal static class ResizeHelper return (new Size(Sanitize(width), Sanitize(height)), new Rectangle(targetX, targetY, Sanitize(targetWidth), Sanitize(targetHeight))); } + [DoesNotReturn] private static void ThrowInvalid(string message) => throw new InvalidOperationException(message); private static int Sanitize(int input) => Math.Max(1, input); diff --git a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs index d276f7eb6d..bfaa2166a3 100644 --- a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs +++ b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs @@ -122,7 +122,13 @@ public class ImageFormatManagerTests byte[] invalidImage = { 1, 2, 3 }; - Assert.Equal(Image.DetectFormat(jpegImage), JpegFormat.Instance); - Assert.True(Image.DetectFormat(invalidImage) is null); + bool resultValidImage = Image.TryDetectFormat(jpegImage, out IImageFormat format); + + bool resultInvalidImage = Image.TryDetectFormat(invalidImage, out IImageFormat formatInvalid); + + Assert.True(resultValidImage); + Assert.Equal(format, JpegFormat.Instance); + Assert.False(resultInvalidImage); + Assert.True(formatInvalid is null); } } diff --git a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs index 5e435ee9bb..fba19065b0 100644 --- a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs +++ b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs @@ -38,7 +38,7 @@ public abstract partial class ImageFrameCollectionTests using ImageFrame addedFrame = this.Collection.AddFrame((ImageFrame)null); }); - Assert.StartsWith("Parameter \"frame\" must be not null.", ex.Message); + Assert.StartsWith("Value cannot be null. (Parameter 'frame')", ex.Message); } [Fact] @@ -52,7 +52,7 @@ public abstract partial class ImageFrameCollectionTests using ImageFrame addedFrame = this.Collection.AddFrame(data); }); - Assert.StartsWith("Parameter \"source\" must be not null.", ex.Message); + Assert.StartsWith("Value cannot be null. (Parameter 'source')", ex.Message); } [Fact] @@ -89,7 +89,7 @@ public abstract partial class ImageFrameCollectionTests using ImageFrame insertedFrame = this.Collection.InsertFrame(1, null); }); - Assert.StartsWith("Parameter \"frame\" must be not null.", ex.Message); + Assert.StartsWith("Value cannot be null. (Parameter 'frame')", ex.Message); } [Fact] diff --git a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs index 60290a7eda..bc22806c3c 100644 --- a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs +++ b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs @@ -77,7 +77,7 @@ public abstract partial class ImageFrameCollectionTests ArgumentNullException ex = Assert.Throws( () => this.Collection.AddFrame(null)); - Assert.StartsWith("Parameter \"source\" must be not null.", ex.Message); + Assert.StartsWith("Value cannot be null. (Parameter 'source')", ex.Message); } [Fact] @@ -95,7 +95,7 @@ public abstract partial class ImageFrameCollectionTests ArgumentNullException ex = Assert.Throws( () => this.Collection.InsertFrame(1, null)); - Assert.StartsWith("Parameter \"source\" must be not null.", ex.Message); + Assert.StartsWith("Value cannot be null. (Parameter 'source')", ex.Message); } [Fact] diff --git a/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs index 271a4a08e8..86ceed73bb 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs @@ -22,14 +22,21 @@ public partial class ImageTests private IImageFormat LocalImageFormat => this.localImageFormatMock.Object; - private static readonly IImageFormat ExpectedGlobalFormat = - Configuration.Default.ImageFormatsManager.FindFormatByFileExtension("bmp"); + private static IImageFormat ExpectedGlobalFormat + { + get + { + Configuration.Default.ImageFormatsManager.TryFindFormatByFileExtension("bmp", out IImageFormat format); + return format!; + } + } [Fact] public void FromBytes_GlobalConfiguration() { - IImageFormat type = Image.DetectFormat(this.ActualImageSpan); + bool result = Image.TryDetectFormat(this.ActualImageSpan, out IImageFormat type); + Assert.True(result); Assert.Equal(ExpectedGlobalFormat, type); } @@ -41,15 +48,18 @@ public partial class ImageTests Configuration = this.LocalConfiguration }; - IImageFormat type = Image.DetectFormat(options, this.ByteArray); + bool result = Image.TryDetectFormat(options, this.ByteArray, out IImageFormat type); + Assert.True(result); Assert.Equal(this.LocalImageFormat, type); } [Fact] public void FromFileSystemPath_GlobalConfiguration() { - IImageFormat type = Image.DetectFormat(ActualImagePath); + bool result = Image.TryDetectFormat(ActualImagePath, out IImageFormat type); + + Assert.True(result); Assert.Equal(ExpectedGlobalFormat, type); } @@ -61,7 +71,9 @@ public partial class ImageTests Configuration = this.LocalConfiguration }; - IImageFormat type = Image.DetectFormat(options, this.MockFilePath); + bool result = Image.TryDetectFormat(options, this.MockFilePath, out IImageFormat type); + + Assert.True(result); Assert.Equal(this.LocalImageFormat, type); } @@ -70,7 +82,9 @@ public partial class ImageTests { using (var stream = new MemoryStream(this.ActualImageBytes)) { - IImageFormat type = Image.DetectFormat(stream); + bool result = Image.TryDetectFormat(stream, out IImageFormat type); + + Assert.True(result); Assert.Equal(ExpectedGlobalFormat, type); } } @@ -83,7 +97,9 @@ public partial class ImageTests Configuration = this.LocalConfiguration }; - IImageFormat type = Image.DetectFormat(options, this.DataStream); + bool result = Image.TryDetectFormat(options, this.DataStream, out IImageFormat type); + + Assert.True(result); Assert.Equal(this.LocalImageFormat, type); } @@ -95,7 +111,9 @@ public partial class ImageTests Configuration = new() }; - IImageFormat type = Image.DetectFormat(options, this.DataStream); + bool result = Image.TryDetectFormat(options, this.DataStream, out IImageFormat type); + + Assert.False(result); Assert.Null(type); } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs index bec58f56bd..49c9562531 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs @@ -25,8 +25,15 @@ public partial class ImageTests private IImageFormat LocalImageFormat => this.localImageFormatMock.Object; - private static readonly IImageFormat ExpectedGlobalFormat = - Configuration.Default.ImageFormatsManager.FindFormatByFileExtension("bmp"); + private static IImageFormat ExpectedGlobalFormat + { + get + { + Configuration.Default.ImageFormatsManager.TryFindFormatByFileExtension("bmp", out var format); + return format!; + } + } + [Fact] public void FromBytes_GlobalConfiguration() @@ -40,10 +47,7 @@ public partial class ImageTests [Fact] public void FromBytes_CustomConfiguration() { - DecoderOptions options = new() - { - Configuration = this.LocalConfiguration - }; + DecoderOptions options = new() { Configuration = this.LocalConfiguration }; IImageInfo info = Image.Identify(options, this.ByteArray, out IImageFormat type); @@ -63,10 +67,7 @@ public partial class ImageTests [Fact] public void FromFileSystemPath_CustomConfiguration() { - DecoderOptions options = new() - { - Configuration = this.LocalConfiguration - }; + DecoderOptions options = new() { Configuration = this.LocalConfiguration }; IImageInfo info = Image.Identify(options, this.MockFilePath, out IImageFormat type); @@ -119,10 +120,7 @@ public partial class ImageTests [Fact] public void FromStream_CustomConfiguration() { - DecoderOptions options = new() - { - Configuration = this.LocalConfiguration - }; + DecoderOptions options = new() { Configuration = this.LocalConfiguration }; IImageInfo info = Image.Identify(options, this.DataStream, out IImageFormat type); @@ -133,10 +131,7 @@ public partial class ImageTests [Fact] public void FromStream_CustomConfiguration_NoFormat() { - DecoderOptions options = new() - { - Configuration = this.LocalConfiguration - }; + DecoderOptions options = new() { Configuration = this.LocalConfiguration }; IImageInfo info = Image.Identify(options, this.DataStream); @@ -146,10 +141,7 @@ public partial class ImageTests [Fact] public void WhenNoMatchingFormatFound_ReturnsNull() { - DecoderOptions options = new() - { - Configuration = new() - }; + DecoderOptions options = new() { Configuration = new() }; IImageInfo info = Image.Identify(options, this.DataStream, out IImageFormat type); @@ -164,18 +156,15 @@ public partial class ImageTests using var zipFile = new ZipArchive(new MemoryStream( new byte[] { - 0x50, 0x4B, 0x03, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xAF, - 0x94, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6D, 0x79, 0x73, 0x74, 0x65, 0x72, - 0x79, 0x50, 0x4B, 0x01, 0x02, 0x3F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x77, 0xAF, 0x94, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, - 0x79, 0x73, 0x74, 0x65, 0x72, 0x79, 0x0A, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x46, 0x82, 0xFF, 0x91, 0x27, 0xF6, - 0xD7, 0x01, 0x55, 0xA1, 0xF9, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x55, 0xA1, - 0xF9, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x50, 0x4B, 0x05, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x59, 0x00, 0x00, 0x00, 0x25, 0x00, + 0x50, 0x4B, 0x03, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xAF, 0x94, 0x53, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6D, 0x79, + 0x73, 0x74, 0x65, 0x72, 0x79, 0x50, 0x4B, 0x01, 0x02, 0x3F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x77, 0xAF, 0x94, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6D, 0x79, 0x73, 0x74, 0x65, 0x72, 0x79, 0x0A, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x46, 0x82, 0xFF, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x55, 0xA1, + 0xF9, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x55, 0xA1, 0xF9, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x50, 0x4B, + 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x59, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00 })); using Stream stream = zipFile.Entries[0].Open(); @@ -236,18 +225,15 @@ public partial class ImageTests using var zipFile = new ZipArchive(new MemoryStream( new byte[] { - 0x50, 0x4B, 0x03, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xAF, - 0x94, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6D, 0x79, 0x73, 0x74, 0x65, 0x72, - 0x79, 0x50, 0x4B, 0x01, 0x02, 0x3F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x77, 0xAF, 0x94, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, - 0x79, 0x73, 0x74, 0x65, 0x72, 0x79, 0x0A, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x46, 0x82, 0xFF, 0x91, 0x27, 0xF6, - 0xD7, 0x01, 0x55, 0xA1, 0xF9, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x55, 0xA1, - 0xF9, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x50, 0x4B, 0x05, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x59, 0x00, 0x00, 0x00, 0x25, 0x00, + 0x50, 0x4B, 0x03, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xAF, 0x94, 0x53, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6D, 0x79, + 0x73, 0x74, 0x65, 0x72, 0x79, 0x50, 0x4B, 0x01, 0x02, 0x3F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x77, 0xAF, 0x94, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6D, 0x79, 0x73, 0x74, 0x65, 0x72, 0x79, 0x0A, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x46, 0x82, 0xFF, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x55, 0xA1, + 0xF9, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x55, 0xA1, 0xF9, 0x91, 0x27, 0xF6, 0xD7, 0x01, 0x50, 0x4B, + 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x59, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00 })); using Stream stream = zipFile.Entries[0].Open(); @@ -258,10 +244,7 @@ public partial class ImageTests [Fact] public async Task FromPathAsync_CustomConfiguration() { - DecoderOptions options = new() - { - Configuration = this.LocalConfiguration - }; + DecoderOptions options = new() { Configuration = this.LocalConfiguration }; IImageInfo info = await Image.IdentifyAsync(options, this.MockFilePath); Assert.Equal(this.LocalImageInfo, info); @@ -270,12 +253,10 @@ public partial class ImageTests [Fact] public async Task IdentifyWithFormatAsync_FromPath_CustomConfiguration() { - DecoderOptions options = new() - { - Configuration = this.LocalConfiguration - }; + DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - (IImageInfo ImageInfo, IImageFormat Format) info = await Image.IdentifyWithFormatAsync(options, this.MockFilePath); + (IImageInfo ImageInfo, IImageFormat Format) info = + await Image.IdentifyWithFormatAsync(options, this.MockFilePath); Assert.NotNull(info.ImageInfo); Assert.Equal(this.LocalImageFormat, info.Format); } @@ -300,13 +281,11 @@ public partial class ImageTests [Fact] public async Task FromStreamAsync_CustomConfiguration() { - DecoderOptions options = new() - { - Configuration = this.LocalConfiguration - }; + DecoderOptions options = new() { Configuration = this.LocalConfiguration }; var asyncStream = new AsyncStreamWrapper(this.DataStream, () => false); - (IImageInfo ImageInfo, IImageFormat Format) info = await Image.IdentifyWithFormatAsync(options, asyncStream); + (IImageInfo ImageInfo, IImageFormat Format) + info = await Image.IdentifyWithFormatAsync(options, asyncStream); Assert.Equal(this.LocalImageInfo, info.ImageInfo); Assert.Equal(this.LocalImageFormat, info.Format); @@ -315,13 +294,11 @@ public partial class ImageTests [Fact] public async Task WhenNoMatchingFormatFoundAsync_ReturnsNull() { - DecoderOptions options = new() - { - Configuration = new() - }; + DecoderOptions options = new() { Configuration = new() }; var asyncStream = new AsyncStreamWrapper(this.DataStream, () => false); - (IImageInfo ImageInfo, IImageFormat Format) info = await Image.IdentifyWithFormatAsync(options, asyncStream); + (IImageInfo ImageInfo, IImageFormat Format) + info = await Image.IdentifyWithFormatAsync(options, asyncStream); Assert.Null(info.ImageInfo); } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs b/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs index 1ceadb964d..3627ba2a65 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs @@ -77,8 +77,8 @@ public partial class ImageTests using (var image = new Image(5, 5)) { string ext = Path.GetExtension(filename); - IImageFormat format = image.GetConfiguration().ImageFormatsManager.FindFormatByFileExtension(ext); - Assert.Equal(mimeType, format.DefaultMimeType); + image.GetConfiguration().ImageFormatsManager.TryFindFormatByFileExtension(ext, out IImageFormat format); + Assert.Equal(mimeType, format!.DefaultMimeType); using (var stream = new MemoryStream()) { diff --git a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs index b65719228c..7309185c79 100644 --- a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs +++ b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs @@ -55,8 +55,8 @@ public class LargeImageIntegrationTests Configuration configuration = Configuration.Default.Clone(); configuration.PreferContiguousImageBuffers = true; - IImageEncoder encoder = configuration.ImageFormatsManager.FindEncoder( - configuration.ImageFormatsManager.FindFormatByFileExtension(formatInner)); + configuration.ImageFormatsManager.TryFindFormatByFileExtension(formatInner, out IImageFormat format); + IImageEncoder encoder = configuration.ImageFormatsManager.FindEncoder(format!); string dir = TestEnvironment.CreateOutputDirectory(".Temp"); string path = Path.Combine(dir, $"{Guid.NewGuid()}.{formatInner}"); using (Image temp = new(2048, 2048)) diff --git a/tests/ImageSharp.Tests/Image/MockImageFormatDetector.cs b/tests/ImageSharp.Tests/Image/MockImageFormatDetector.cs index d0576c828b..8564eaa5bb 100644 --- a/tests/ImageSharp.Tests/Image/MockImageFormatDetector.cs +++ b/tests/ImageSharp.Tests/Image/MockImageFormatDetector.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Formats; namespace SixLabors.ImageSharp.Tests; @@ -19,8 +20,10 @@ public class MockImageFormatDetector : IImageFormatDetector public int HeaderSize => 1; - public IImageFormat DetectFormat(ReadOnlySpan header) + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) { - return this.localImageFormatMock; + format = this.localImageFormatMock; + + return true; } } diff --git a/tests/ImageSharp.Tests/TestFormat.cs b/tests/ImageSharp.Tests/TestFormat.cs index f3176f16c5..bfad231949 100644 --- a/tests/ImageSharp.Tests/TestFormat.cs +++ b/tests/ImageSharp.Tests/TestFormat.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Diagnostics.CodeAnalysis; using System.Numerics; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; @@ -174,14 +175,11 @@ public class TestFormat : IImageFormatConfigurationModule, IImageFormat public int HeaderSize => this.testFormat.HeaderSize; - public IImageFormat DetectFormat(ReadOnlySpan header) + public bool TryDetectFormat(ReadOnlySpan header, [NotNullWhen(true)] out IImageFormat? format) { - if (this.testFormat.IsSupportedFileFormat(header)) - { - return this.testFormat; - } + format = this.testFormat.IsSupportedFileFormat(header) ? this.testFormat : null; - return null; + return format != null; } public TestHeader(TestFormat testFormat) => this.testFormat = testFormat; diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs index 68c1664a8f..f44ae5b23f 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Bmp; using SixLabors.ImageSharp.Formats.Gif; @@ -36,7 +37,9 @@ public static partial class TestEnvironment { string extension = Path.GetExtension(filePath); - return Configuration.ImageFormatsManager.FindFormatByFileExtension(extension); + Configuration.ImageFormatsManager.TryFindFormatByFileExtension(extension, out IImageFormat format); + + return format; } private static void ConfigureCodecs(