Browse Source

Merge pull request #2312 from stefannikolei/stefannikolei/nullable

Remove some nullable disable comments
pull/2316/head
James Jackson-South 4 years ago
committed by GitHub
parent
commit
f1968ba5e8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      shared-infrastructure
  2. 5
      src/ImageSharp/Advanced/AdvancedImageExtensions.cs
  3. 11
      src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs
  4. 8
      src/ImageSharp/Formats/Gif/GifImageFormatDetector.cs
  5. 7
      src/ImageSharp/Formats/IImageFormatDetector.cs
  6. 1
      src/ImageSharp/Formats/ImageDecoderUtilities.cs
  7. 22
      src/ImageSharp/Formats/ImageFormatManager.cs
  8. 10
      src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs
  9. 9
      src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs
  10. 7
      src/ImageSharp/Formats/Png/PngImageFormatDetector.cs
  11. 8
      src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs
  12. 13
      src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs
  13. 10
      src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs
  14. 3
      src/ImageSharp/Image.Decode.cs
  15. 26
      src/ImageSharp/Image.FromBytes.cs
  16. 15
      src/ImageSharp/Image.FromFile.cs
  17. 17
      src/ImageSharp/Image.FromStream.cs
  18. 4
      src/ImageSharp/Image{TPixel}.cs
  19. 3
      src/ImageSharp/Processing/Processors/CloningImageProcessor{TPixel}.cs
  20. 5
      src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessorHelpers.cs
  21. 3
      src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetector2DKernel.cs
  22. 3
      src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorCompassKernel.cs
  23. 3
      src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorKernel.cs
  24. 3
      src/ImageSharp/Processing/Processors/Convolution/Parameters/BokehBlurParameters.cs
  25. 7
      src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs
  26. 7
      src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs
  27. 5
      src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs
  28. 3
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs
  29. 10
      tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
  30. 6
      tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs
  31. 4
      tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs
  32. 36
      tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs
  33. 107
      tests/ImageSharp.Tests/Image/ImageTests.Identify.cs
  34. 4
      tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs
  35. 4
      tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs
  36. 7
      tests/ImageSharp.Tests/Image/MockImageFormatDetector.cs
  37. 10
      tests/ImageSharp.Tests/TestFormat.cs
  38. 5
      tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs

2
shared-infrastructure

@ -1 +1 @@
Subproject commit bf398a9b6bb6d0acfe0525ee109276b4ef74646c
Subproject commit 9a82679e92df9476725fd2a2038604fd412af56c

5
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)
{

11
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;
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public bool TryDetectFormat(ReadOnlySpan<byte> 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<byte> 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;

8
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;
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public bool TryDetectFormat(ReadOnlySpan<byte> 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<byte> header)

7
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;
/// <summary>
@ -18,6 +20,7 @@ public interface IImageFormatDetector
/// Detect mimetype
/// </summary>
/// <param name="header">The <see cref="T:byte[]"/> containing the file header.</param>
/// <returns>returns the mime type of detected otherwise returns null</returns>
IImageFormat DetectFormat(ReadOnlySpan<byte> header);
/// <param name="format">The mime type of detected otherwise returns null</param>
/// <returns>returns true when format was detected otherwise false.</returns>
bool TryDetectFormat(ReadOnlySpan<byte> header, [NotNullWhen(true)] out IImageFormat? format);
}

1
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;

22
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 <see cref="IImageFormat"/>.
/// </summary>
/// <param name="extension">The extension to discover</param>
/// <returns>The <see cref="IImageFormat"/> if found otherwise null</returns>
public IImageFormat FindFormatByFileExtension(string extension)
/// <param name="format">The <see cref="IImageFormat"/> if found otherwise null</param>
/// <returns>False if no format was found</returns>
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;
}
/// <summary>
@ -110,7 +114,7 @@ public class ImageFormatManager
/// </summary>
/// <param name="mimeType">The mime-type to discover</param>
/// <returns>The <see cref="IImageFormat"/> if found; otherwise null</returns>
public IImageFormat FindFormatByMimeType(string mimeType)
public IImageFormat? FindFormatByMimeType(string mimeType)
=> this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase));
/// <summary>
@ -160,11 +164,11 @@ public class ImageFormatManager
/// </summary>
/// <param name="format">The format to discover</param>
/// <returns>The <see cref="IImageDecoder"/> if found otherwise null</returns>
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
/// </summary>
/// <param name="format">The format to discover</param>
/// <returns>The <see cref="IImageEncoder"/> if found otherwise null</returns>
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;
}

10
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;
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
=> this.IsSupportedFileFormat(header) ? JpegFormat.Instance : null;
public bool TryDetectFormat(ReadOnlySpan<byte> header, [NotNullWhen(true)] out IImageFormat? format)
{
format = this.IsSupportedFileFormat(header) ? JpegFormat.Instance : null;
return format != null;
}
private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
=> header.Length >= this.HeaderSize

9
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;
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header) => IsSupportedFileFormat(header) ? PbmFormat.Instance : null;
public bool TryDetectFormat(ReadOnlySpan<byte> header, [NotNullWhen(true)] out IImageFormat? format)
{
format = IsSupportedFileFormat(header) ? PbmFormat.Instance : null;
return format != null;
}
private static bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
{

7
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;
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public bool TryDetectFormat(ReadOnlySpan<byte> 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<byte> header)

8
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;
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public bool TryDetectFormat(ReadOnlySpan<byte> 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<byte> header)

13
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;
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public bool TryDetectFormat(ReadOnlySpan<byte> 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<byte> header)

10
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;
/// <inheritdoc />
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
=> this.IsSupportedFileFormat(header) ? WebpFormat.Instance : null;
public bool TryDetectFormat(ReadOnlySpan<byte> header, [NotNullWhen(true)] out IImageFormat? format)
{
format = this.IsSupportedFileFormat(header) ? WebpFormat.Instance : null;
return format != null;
}
private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
=> header.Length >= this.HeaderSize && IsRiffContainer(header) && IsWebpFile(header);

3
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;
}

26
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.
/// </summary>
/// <param name="data">The byte span containing encoded image data to read the header from.</param>
/// <returns>The format or null if none found.</returns>
public static IImageFormat DetectFormat(ReadOnlySpan<byte> data)
=> DetectFormat(DecoderOptions.Default, data);
/// <param name="format">The format or null if none found.</param>
/// <returns>returns true when format was detected otherwise false.</returns>
public static bool TryDetectFormat(ReadOnlySpan<byte> data, [NotNullWhen(true)] out IImageFormat? format)
=> TryDetectFormat(DecoderOptions.Default, data, out format);
/// <summary>
/// By reading the header on the provided byte span this calculates the images format.
/// </summary>
/// <param name="options">The general decoder options.</param>
/// <param name="data">The byte span containing encoded image data to read the header from.</param>
/// <param name="format">The mime type or null if none found.</param>
/// <exception cref="ArgumentNullException">The options are null.</exception>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(DecoderOptions options, ReadOnlySpan<byte> data)
/// <returns>returns true when format was detected otherwise false.</returns>
public static bool TryDetectFormat(DecoderOptions options, ReadOnlySpan<byte> 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;
}
/// <summary>

15
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.
/// </summary>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(string filePath)
=> DetectFormat(DecoderOptions.Default, filePath);
/// <param name="format">The mime type or null if none found.</param>
/// <returns>returns true when format was detected otherwise false.</returns>
public static bool TryDetectFormat(string filePath, [NotNullWhen(true)] out IImageFormat? format)
=> TryDetectFormat(DecoderOptions.Default, filePath, out format);
/// <summary>
/// By reading the header on the provided file this calculates the images mime type.
/// </summary>
/// <param name="options">The general decoder options.</param>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <param name="format">The mime type or null if none found.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(DecoderOptions options, string filePath)
/// <returns>returns true when format was detected otherwise false.</returns>
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);
}
/// <summary>

17
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.
/// </summary>
/// <param name="stream">The image stream to read the header from.</param>
/// <param name="format">The format type or null if none found.</param>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <returns>The format type or null if none found.</returns>
public static IImageFormat DetectFormat(Stream stream)
=> DetectFormat(DecoderOptions.Default, stream);
/// <returns>returns true when format was detected otherwise false.</returns>
public static bool TryDetectFormat(Stream stream, [NotNullWhen(true)] out IImageFormat? format)
=> TryDetectFormat(DecoderOptions.Default, stream, out format);
/// <summary>
/// By reading the header on the provided stream this calculates the images format type.
/// </summary>
/// <param name="options">The general decoder options.</param>
/// <param name="stream">The image stream to read the header from.</param>
/// <param name="format">The format type or null if none found.</param>
/// <exception cref="ArgumentNullException">The options are null.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <returns>The format type or null if none found.</returns>
public static IImageFormat DetectFormat(DecoderOptions options, Stream stream)
=> WithSeekableStream(options, stream, s => InternalDetectFormat(options.Configuration, s));
/// <returns>returns true when format was detected otherwise false.</returns>
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;
}
/// <summary>
/// By reading the header on the provided stream this calculates the images format type.

4
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<TPixel> : Image
{
Guard.NotNull(frames, nameof(frames));
ImageFrame<TPixel> rootFrame = frames.FirstOrDefault();
ImageFrame<TPixel>? rootFrame = frames.FirstOrDefault();
if (rootFrame == null)
{

3
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<TPixel> : ICloningImageProcessor<TPi
// Create an interim clone of the source image to operate on.
// Doing this allows for the application of transforms that will alter
// the dimensions of the image.
Image<TPixel> clone = default;
Image<TPixel>? clone = default;
try
{
clone = ((ICloningImageProcessor<TPixel>)this).CloneAndExecute();

5
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
/// <param name="row">The resulting 1D row vector, if possible.</param>
/// <param name="column">The resulting 1D column vector, if possible.</param>
/// <returns>Whether or not <paramref name="matrix"/> was linearly separable.</returns>
public static bool TryGetLinearlySeparableComponents(this DenseMatrix<float> matrix, out float[] row, out float[] column)
public static bool TryGetLinearlySeparableComponents(this DenseMatrix<float> matrix, [NotNullWhen(true)] out float[]? row, [NotNullWhen(true)] out float[]? column)
{
int height = matrix.Rows;
int width = matrix.Columns;

3
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<EdgeDetector2DKernel>
=> !(left == right);
/// <inheritdoc/>
public override bool Equals(object obj)
public override bool Equals(object? obj)
=> obj is EdgeDetector2DKernel kernel && this.Equals(kernel);
/// <inheritdoc/>

3
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<EdgeDetectorCompas
=> !(left == right);
/// <inheritdoc/>
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);
/// <inheritdoc/>
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);

3
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<EdgeDetectorKernel>
=> !(left == right);
/// <inheritdoc/>
public override bool Equals(object obj)
public override bool Equals(object? obj)
=> obj is EdgeDetectorKernel kernel && this.Equals(kernel);
/// <inheritdoc/>

3
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<BokehBlurParameters>
}
/// <inheritdoc/>
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);
/// <inheritdoc/>
public override int GetHashCode()

7
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<ErrorDither>, I
}
/// <inheritdoc/>
public override bool Equals(object obj)
public override bool Equals(object? obj)
=> obj is ErrorDither dither && this.Equals(dither);
/// <inheritdoc/>
@ -220,8 +219,8 @@ public readonly partial struct ErrorDither : IDither, IEquatable<ErrorDither>, I
=> this.offset == other.offset && this.matrix.Equals(other.matrix);
/// <inheritdoc/>
public bool Equals(IDither other)
=> this.Equals((object)other);
public bool Equals(IDither? other)
=> this.Equals((object?)other);
/// <inheritdoc/>
public override int GetHashCode()

7
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<OrderedDither
}
/// <inheritdoc/>
public override bool Equals(object obj)
public override bool Equals(object? obj)
=> obj is OrderedDither dither && this.Equals(dither);
/// <inheritdoc/>
@ -209,8 +208,8 @@ public readonly partial struct OrderedDither : IDither, IEquatable<OrderedDither
=> this.thresholdMatrix.Equals(other.thresholdMatrix) && this.modulusX == other.modulusX && this.modulusY == other.modulusY;
/// <inheritdoc/>
public bool Equals(IDither other)
=> this.Equals((object)other);
public bool Equals(IDither? other)
=> this.Equals((object?)other);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]

5
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<TPixel> : ImageProcessor<TPixel>
{
private readonly DitherProcessor ditherProcessor;
private readonly IDither dither;
private IMemoryOwner<TPixel> paletteOwner;
private IMemoryOwner<TPixel>? paletteOwner;
private bool isDisposed;
/// <summary>
@ -62,7 +61,7 @@ internal sealed class PaletteDitherProcessor<TPixel> : ImageProcessor<TPixel>
this.isDisposed = true;
if (disposing)
{
this.paletteOwner.Dispose();
this.paletteOwner?.Dispose();
this.ditherProcessor.Dispose();
}

3
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);

10
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);
}
}

6
tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs

@ -38,7 +38,7 @@ public abstract partial class ImageFrameCollectionTests
using ImageFrame<Rgba32> addedFrame = this.Collection.AddFrame((ImageFrame<Rgba32>)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<Rgba32> 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<Rgba32> 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]

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

@ -77,7 +77,7 @@ public abstract partial class ImageFrameCollectionTests
ArgumentNullException ex = Assert.Throws<ArgumentNullException>(
() => 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<ArgumentNullException>(
() => 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]

36
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);
}

107
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);
}

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

@ -77,8 +77,8 @@ public partial class ImageTests
using (var image = new Image<Rgba32>(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())
{

4
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<Rgba32> temp = new(2048, 2048))

7
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<byte> header)
public bool TryDetectFormat(ReadOnlySpan<byte> header, [NotNullWhen(true)] out IImageFormat? format)
{
return this.localImageFormatMock;
format = this.localImageFormatMock;
return true;
}
}

10
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<byte> header)
public bool TryDetectFormat(ReadOnlySpan<byte> 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;

5
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(

Loading…
Cancel
Save