From 89d6fc8d693f78c96c2d4dbcbfb702478e05cec7 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 12 Jan 2023 21:02:26 +1000 Subject: [PATCH 01/16] Expose ImageInfo and add IImageFormat to metadata --- src/ImageSharp/Formats/Bmp/BmpDecoder.cs | 2 +- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 2 +- src/ImageSharp/Formats/Gif/GifDecoder.cs | 2 +- src/ImageSharp/Formats/Gif/GifDecoderCore.cs | 2 +- src/ImageSharp/Formats/IImageDecoder.cs | 6 +- .../Formats/IImageDecoderInternals.cs | 4 +- src/ImageSharp/Formats/ImageDecoder.cs | 86 +++++++++++++------ .../Formats/ImageDecoderUtilities.cs | 2 +- src/ImageSharp/Formats/ImageFormatManager.cs | 3 + src/ImageSharp/Formats/Jpeg/JpegDecoder.cs | 2 +- .../Formats/Jpeg/JpegDecoderCore.cs | 2 +- src/ImageSharp/Formats/Pbm/PbmDecoder.cs | 2 +- src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs | 2 +- src/ImageSharp/Formats/PixelTypeInfo.cs | 15 ++-- src/ImageSharp/Formats/Png/PngDecoder.cs | 4 +- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 2 +- .../Formats/SpecializedImageDecoder{T}.cs | 36 ++++++-- src/ImageSharp/Formats/Tga/TgaDecoder.cs | 2 +- src/ImageSharp/Formats/Tga/TgaDecoderCore.cs | 2 +- src/ImageSharp/Formats/Tiff/TiffDecoder.cs | 2 +- .../Formats/Tiff/TiffDecoderCore.cs | 2 +- src/ImageSharp/Formats/Webp/WebpDecoder.cs | 2 +- .../Formats/Webp/WebpDecoderCore.cs | 2 +- src/ImageSharp/IImageInfo.cs | 2 +- src/ImageSharp/Image.Decode.cs | 12 +-- src/ImageSharp/Image.FromBytes.cs | 12 +-- src/ImageSharp/Image.FromFile.cs | 30 +++---- src/ImageSharp/Image.FromStream.cs | 32 +++---- src/ImageSharp/ImageInfo.cs | 4 +- src/ImageSharp/ImageInfoExtensions.cs | 6 +- src/ImageSharp/Metadata/ImageMetadata.cs | 20 +++-- .../Linear/RotateProcessor{TPixel}.cs | 2 +- .../Transforms/TransformProcessorHelpers.cs | 2 +- .../Codecs/Jpeg/IdentifyJpeg.cs | 2 +- .../Formats/Bmp/BmpDecoderTests.cs | 4 +- .../Formats/Bmp/BmpMetadataTests.cs | 2 +- .../Formats/GeneralFormatTests.cs | 4 +- .../Formats/Gif/GifMetadataTests.cs | 6 +- .../Formats/Jpg/JpegDecoderTests.Metadata.cs | 10 +-- .../Formats/Pbm/PbmMetadataTests.cs | 6 +- .../Formats/Png/PngDecoderTests.cs | 2 +- .../Formats/Png/PngMetadataTests.cs | 8 +- .../Formats/Tga/TgaFileHeaderTests.cs | 2 +- .../Formats/Tiff/BigTiffDecoderTests.cs | 4 +- .../Formats/Tiff/TiffDecoderTests.cs | 4 +- .../Formats/Tiff/TiffMetadataTests.cs | 4 +- .../Formats/WebP/WebpDecoderTests.cs | 2 +- .../Image/ImageTests.Identify.cs | 48 +++++------ .../Image/ImageTests.ImageLoadTestBase.cs | 4 +- tests/ImageSharp.Tests/TestFormat.cs | 10 ++- .../ReferenceCodecs/MagickReferenceDecoder.cs | 7 +- .../SystemDrawingReferenceDecoder.cs | 2 +- .../Tests/TestImageProviderTests.cs | 14 ++- 53 files changed, 266 insertions(+), 187 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs index 15c213f88..da6556b36 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs @@ -20,7 +20,7 @@ public sealed class BmpDecoder : SpecializedImageDecoder public static BmpDecoder Instance { get; } = new(); /// - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(options, nameof(options)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index 4bdb7257a..fd0497d9a 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -209,7 +209,7 @@ internal sealed class BmpDecoderCore : IImageDecoderInternals } /// - public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) + public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) { this.ReadImageHeaders(stream, out _, out _); return new ImageInfo(new PixelTypeInfo(this.infoHeader.BitsPerPixel), this.infoHeader.Width, this.infoHeader.Height, this.metadata); diff --git a/src/ImageSharp/Formats/Gif/GifDecoder.cs b/src/ImageSharp/Formats/Gif/GifDecoder.cs index e08fc6230..6dbb07a13 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoder.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoder.cs @@ -20,7 +20,7 @@ public sealed class GifDecoder : ImageDecoder public static GifDecoder Instance { get; } = new(); /// - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(options, nameof(options)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index d67372419..8c5915800 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -175,7 +175,7 @@ internal sealed class GifDecoderCore : IImageDecoderInternals } /// - public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) + public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) { try { diff --git a/src/ImageSharp/Formats/IImageDecoder.cs b/src/ImageSharp/Formats/IImageDecoder.cs index 3729c98d9..eca2939bc 100644 --- a/src/ImageSharp/Formats/IImageDecoder.cs +++ b/src/ImageSharp/Formats/IImageDecoder.cs @@ -15,9 +15,9 @@ public interface IImageDecoder /// /// The general decoder options. /// The containing image data. - /// The object. + /// The object. /// Thrown if the encoded image contains errors. - public IImageInfo Identify(DecoderOptions options, Stream stream); + public ImageInfo Identify(DecoderOptions options, Stream stream); /// /// Reads the raw image information from the specified stream. @@ -27,7 +27,7 @@ public interface IImageDecoder /// The token to monitor for cancellation requests. /// The object. /// Thrown if the encoded image contains errors. - public Task IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default); + public Task IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default); /// /// Decodes the image from the specified stream to an of a specific pixel type. diff --git a/src/ImageSharp/Formats/IImageDecoderInternals.cs b/src/ImageSharp/Formats/IImageDecoderInternals.cs index d8cb1c662..06fb59764 100644 --- a/src/ImageSharp/Formats/IImageDecoderInternals.cs +++ b/src/ImageSharp/Formats/IImageDecoderInternals.cs @@ -41,10 +41,10 @@ internal interface IImageDecoderInternals /// /// The containing image data. /// The token to monitor for cancellation requests. - /// The . + /// The . /// /// Cancellable synchronous method. In case of cancellation, /// an shall be thrown which will be handled on the call site. /// - IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken); + ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken); } diff --git a/src/ImageSharp/Formats/ImageDecoder.cs b/src/ImageSharp/Formats/ImageDecoder.cs index 591f85df2..bc2620c7f 100644 --- a/src/ImageSharp/Formats/ImageDecoder.cs +++ b/src/ImageSharp/Formats/ImageDecoder.cs @@ -17,44 +17,74 @@ public abstract class ImageDecoder : IImageDecoder /// public Image Decode(DecoderOptions options, Stream stream) where TPixel : unmanaged, IPixel - => WithSeekableStream( - options, - stream, - s => this.Decode(options, s, default)); + { + Image image = WithSeekableStream( + options, + stream, + s => this.Decode(options, s, default)); + + this.SetDecoderFormat(options.Configuration, image); + + return image; + } /// public Image Decode(DecoderOptions options, Stream stream) - => WithSeekableStream( - options, - stream, - s => this.Decode(options, s, default)); + { + Image image = WithSeekableStream( + options, + stream, + s => this.Decode(options, s, default)); + + this.SetDecoderFormat(options.Configuration, image); + + return image; + } /// - public Task> DecodeAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) + public async Task> DecodeAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) where TPixel : unmanaged, IPixel - => WithSeekableMemoryStreamAsync( - options, - stream, - (s, ct) => this.Decode(options, s, ct), - cancellationToken); + { + Image image = await WithSeekableMemoryStreamAsync( + options, + stream, + (s, ct) => this.Decode(options, s, ct), + cancellationToken).ConfigureAwait(false); + + this.SetDecoderFormat(options.Configuration, image); + + return image; + } /// - public Task DecodeAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) - => WithSeekableMemoryStreamAsync( + public async Task DecodeAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) + { + Image image = await WithSeekableMemoryStreamAsync( options, stream, (s, ct) => this.Decode(options, s, ct), - cancellationToken); + cancellationToken).ConfigureAwait(false); + + this.SetDecoderFormat(options.Configuration, image); + + return image; + } /// - public IImageInfo Identify(DecoderOptions options, Stream stream) - => WithSeekableStream( - options, - stream, - s => this.Identify(options, s, default)); + public ImageInfo Identify(DecoderOptions options, Stream stream) + { + ImageInfo info = WithSeekableStream( + options, + stream, + s => this.Identify(options, s, default)); + + this.SetDecoderFormat(options.Configuration, info); + + return info; + } /// - public Task IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) + public Task IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) => WithSeekableMemoryStreamAsync( options, stream, @@ -98,9 +128,9 @@ public abstract class ImageDecoder : IImageDecoder /// The general decoder options. /// The containing image data. /// The token to monitor for cancellation requests. - /// The object. + /// The object. /// Thrown if the encoded image contains errors. - protected abstract IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken); + protected abstract ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken); /// /// Performs a scaling operation against the decoded image. If the target size is not set, or the image size @@ -252,4 +282,10 @@ public abstract class ImageDecoder : IImageDecoder memoryStream.Position = 0; return await action(memoryStream, position, cancellationToken).ConfigureAwait(false); } + + internal void SetDecoderFormat(Configuration configuration, Image image) + => image.Metadata.DecodedImageFormat = configuration.ImageFormatsManager.FindFormatByDecoder(this); + + internal void SetDecoderFormat(Configuration configuration, ImageInfo info) + => info.Metadata.DecodedImageFormat = configuration.ImageFormatsManager.FindFormatByDecoder(this); } diff --git a/src/ImageSharp/Formats/ImageDecoderUtilities.cs b/src/ImageSharp/Formats/ImageDecoderUtilities.cs index 2a5b91b09..e2c61c8eb 100644 --- a/src/ImageSharp/Formats/ImageDecoderUtilities.cs +++ b/src/ImageSharp/Formats/ImageDecoderUtilities.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Formats; /// internal static class ImageDecoderUtilities { - internal static IImageInfo Identify( + internal static ImageInfo Identify( this IImageDecoderInternals decoder, Configuration configuration, Stream stream, diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs index d058e80c9..8da897a01 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -117,6 +117,9 @@ public class ImageFormatManager public IImageFormat? FindFormatByMimeType(string mimeType) => this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase)); + internal IImageFormat? FindFormatByDecoder(IImageDecoder decoder) + => this.mimeTypeDecoders.FirstOrDefault(x => x.Value == decoder).Key; + /// /// Sets a specific image encoder as the encoder for a specific image format. /// diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs index b8a142d28..026c542dd 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs @@ -20,7 +20,7 @@ public sealed class JpegDecoder : SpecializedImageDecoder public static JpegDecoder Instance { get; } = new(); /// - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(options, nameof(options)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index f21ccdb62..511ec1ba1 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -225,7 +225,7 @@ internal sealed class JpegDecoderCore : IRawJpegData, IImageDecoderInternals } /// - public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) + public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) { this.ParseStream(stream, spectralConverter: null, cancellationToken); this.InitExifProfile(); diff --git a/src/ImageSharp/Formats/Pbm/PbmDecoder.cs b/src/ImageSharp/Formats/Pbm/PbmDecoder.cs index f7b32b5fc..a7dd8a0eb 100644 --- a/src/ImageSharp/Formats/Pbm/PbmDecoder.cs +++ b/src/ImageSharp/Formats/Pbm/PbmDecoder.cs @@ -36,7 +36,7 @@ public sealed class PbmDecoder : ImageDecoder public static PbmDecoder Instance { get; } = new(); /// - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(options, nameof(options)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs b/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs index 139cb2fcc..c5e0b0071 100644 --- a/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs +++ b/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs @@ -83,7 +83,7 @@ internal sealed class PbmDecoderCore : IImageDecoderInternals } /// - public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) + public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) { this.ProcessHeader(stream); diff --git a/src/ImageSharp/Formats/PixelTypeInfo.cs b/src/ImageSharp/Formats/PixelTypeInfo.cs index 79ea884ce..1328c6528 100644 --- a/src/ImageSharp/Formats/PixelTypeInfo.cs +++ b/src/ImageSharp/Formats/PixelTypeInfo.cs @@ -4,6 +4,9 @@ using System.Runtime.CompilerServices; using SixLabors.ImageSharp.PixelFormats; +// TODO: Review this class as it's used to represent 2 different things. +// 1.The encoded image pixel format. +// 2. The pixel format of the decoded image. namespace SixLabors.ImageSharp.Formats; /// @@ -16,9 +19,7 @@ public class PixelTypeInfo /// /// Color depth, in number of bits per pixel. public PixelTypeInfo(int bitsPerPixel) - { - this.BitsPerPixel = bitsPerPixel; - } + => this.BitsPerPixel = bitsPerPixel; /// /// Initializes a new instance of the class. @@ -43,12 +44,10 @@ public class PixelTypeInfo public PixelAlphaRepresentation? AlphaRepresentation { get; } internal static PixelTypeInfo Create() - where TPixel : unmanaged, IPixel => - new PixelTypeInfo(Unsafe.SizeOf() * 8); + where TPixel : unmanaged, IPixel + => new(Unsafe.SizeOf() * 8); internal static PixelTypeInfo Create(PixelAlphaRepresentation alpha) where TPixel : unmanaged, IPixel - { - return new PixelTypeInfo(Unsafe.SizeOf() * 8, alpha); - } + => new(Unsafe.SizeOf() * 8, alpha); } diff --git a/src/ImageSharp/Formats/Png/PngDecoder.cs b/src/ImageSharp/Formats/Png/PngDecoder.cs index 56e76da10..f273ac2b9 100644 --- a/src/ImageSharp/Formats/Png/PngDecoder.cs +++ b/src/ImageSharp/Formats/Png/PngDecoder.cs @@ -20,7 +20,7 @@ public sealed class PngDecoder : ImageDecoder public static PngDecoder Instance { get; } = new(); /// - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(options, nameof(options)); Guard.NotNull(stream, nameof(stream)); @@ -49,7 +49,7 @@ public sealed class PngDecoder : ImageDecoder Guard.NotNull(stream, nameof(stream)); PngDecoderCore decoder = new(options, true); - IImageInfo info = decoder.Identify(options.Configuration, stream, cancellationToken); + ImageInfo info = decoder.Identify(options.Configuration, stream, cancellationToken); stream.Position = 0; PngMetadata meta = info.Metadata.GetPngMetadata(); diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 37cc8b2f6..3b2f100e0 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -247,7 +247,7 @@ internal sealed class PngDecoderCore : IImageDecoderInternals } /// - public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) + public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) { ImageMetadata metadata = new(); PngMetadata pngMetadata = metadata.GetPngMetadata(); diff --git a/src/ImageSharp/Formats/SpecializedImageDecoder{T}.cs b/src/ImageSharp/Formats/SpecializedImageDecoder{T}.cs index fa6461464..59fa59bb9 100644 --- a/src/ImageSharp/Formats/SpecializedImageDecoder{T}.cs +++ b/src/ImageSharp/Formats/SpecializedImageDecoder{T}.cs @@ -17,34 +17,54 @@ public abstract class SpecializedImageDecoder : ImageDecoder, ISpecializedIma /// public Image Decode(T options, Stream stream) where TPixel : unmanaged, IPixel - => WithSeekableStream( + { + Image image = WithSeekableStream( options.GeneralOptions, stream, s => this.Decode(options, s, default)); + this.SetDecoderFormat(options.GeneralOptions.Configuration, image); + return image; + } + /// public Image Decode(T options, Stream stream) - => WithSeekableStream( + { + Image image = WithSeekableStream( options.GeneralOptions, stream, s => this.Decode(options, s, default)); + this.SetDecoderFormat(options.GeneralOptions.Configuration, image); + return image; + } + /// - public Task> DecodeAsync(T options, Stream stream, CancellationToken cancellationToken = default) + public async Task> DecodeAsync(T options, Stream stream, CancellationToken cancellationToken = default) where TPixel : unmanaged, IPixel - => WithSeekableMemoryStreamAsync( + { + Image image = await WithSeekableMemoryStreamAsync( options.GeneralOptions, stream, (s, ct) => this.Decode(options, s, ct), - cancellationToken); + cancellationToken).ConfigureAwait(false); + + this.SetDecoderFormat(options.GeneralOptions.Configuration, image); + return image; + } /// - public Task DecodeAsync(T options, Stream stream, CancellationToken cancellationToken = default) - => WithSeekableMemoryStreamAsync( + public async Task DecodeAsync(T options, Stream stream, CancellationToken cancellationToken = default) + { + Image image = await WithSeekableMemoryStreamAsync( options.GeneralOptions, stream, (s, ct) => this.Decode(options, s, ct), - cancellationToken); + cancellationToken).ConfigureAwait(false); + + this.SetDecoderFormat(options.GeneralOptions.Configuration, image); + return image; + } /// /// Decodes the image from the specified stream to an of a specific pixel type. diff --git a/src/ImageSharp/Formats/Tga/TgaDecoder.cs b/src/ImageSharp/Formats/Tga/TgaDecoder.cs index f6f1e6762..e7ff894da 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoder.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoder.cs @@ -20,7 +20,7 @@ public sealed class TgaDecoder : ImageDecoder public static TgaDecoder Instance { get; } = new(); /// - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(options, nameof(options)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs index ebb47b775..9c32471fd 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs @@ -647,7 +647,7 @@ internal sealed class TgaDecoderCore : IImageDecoderInternals } /// - public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) + public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) { this.ReadFileHeader(stream); return new ImageInfo( diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs index 3ec9b3d68..e9dee4ee4 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs @@ -20,7 +20,7 @@ public class TiffDecoder : ImageDecoder public static TiffDecoder Instance { get; } = new(); /// - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(options, nameof(options)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index 887d4eda4..e74c53e22 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -213,7 +213,7 @@ internal class TiffDecoderCore : IImageDecoderInternals } /// - public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) + public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) { this.inputStream = stream; DirectoryReader reader = new(stream, this.configuration.MemoryAllocator); diff --git a/src/ImageSharp/Formats/Webp/WebpDecoder.cs b/src/ImageSharp/Formats/Webp/WebpDecoder.cs index 7a97b86a7..daa5eaf4f 100644 --- a/src/ImageSharp/Formats/Webp/WebpDecoder.cs +++ b/src/ImageSharp/Formats/Webp/WebpDecoder.cs @@ -20,7 +20,7 @@ public sealed class WebpDecoder : ImageDecoder public static WebpDecoder Instance { get; } = new(); /// - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(options, nameof(options)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs b/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs index d313ebf76..29be86e22 100644 --- a/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs +++ b/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs @@ -145,7 +145,7 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable } /// - public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) + public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) { this.currentStream = stream; diff --git a/src/ImageSharp/IImageInfo.cs b/src/ImageSharp/IImageInfo.cs index 32ca9a9a2..411b8f1b0 100644 --- a/src/ImageSharp/IImageInfo.cs +++ b/src/ImageSharp/IImageInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using SixLabors.ImageSharp.Formats; diff --git a/src/ImageSharp/Image.Decode.cs b/src/ImageSharp/Image.Decode.cs index a556cbceb..d549fabee 100644 --- a/src/ImageSharp/Image.Decode.cs +++ b/src/ImageSharp/Image.Decode.cs @@ -179,12 +179,12 @@ public abstract partial class Image /// The general decoder options. /// The stream. /// - /// The or null if a suitable info detector is not found. + /// The or null if a suitable info detector is not found. /// - private static (IImageInfo ImageInfo, IImageFormat Format) InternalIdentify(DecoderOptions options, Stream stream) + private static (ImageInfo ImageInfo, IImageFormat Format) InternalIdentify(DecoderOptions options, Stream stream) { IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format); - IImageInfo info = decoder?.Identify(options, stream); + ImageInfo info = decoder?.Identify(options, stream); return (info, format); } @@ -195,9 +195,9 @@ public abstract partial class Image /// The stream. /// The token to monitor for cancellation requests. /// - /// The or null if a suitable info detector is not found. + /// The or null if a suitable info detector is not found. /// - private static async Task<(IImageInfo ImageInfo, IImageFormat Format)> InternalIdentifyAsync( + private static async Task<(ImageInfo ImageInfo, IImageFormat Format)> InternalIdentifyAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken) @@ -209,7 +209,7 @@ public abstract partial class Image return (null, null); } - IImageInfo info = await decoder.IdentifyAsync(options, stream, cancellationToken).ConfigureAwait(false); + ImageInfo info = await decoder.IdentifyAsync(options, stream, cancellationToken).ConfigureAwait(false); return (info, format); } } diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs index 7a2e9d736..a6c73c61e 100644 --- a/src/ImageSharp/Image.FromBytes.cs +++ b/src/ImageSharp/Image.FromBytes.cs @@ -60,9 +60,9 @@ public abstract partial class Image /// The data is null. /// The data is not readable. /// - /// The or null if suitable info detector not found. + /// The or null if suitable info detector not found. /// - public static IImageInfo Identify(ReadOnlySpan data) => Identify(data, out IImageFormat _); + public static ImageInfo Identify(ReadOnlySpan data) => Identify(data, out IImageFormat _); /// /// Reads the raw image information from the specified stream without fully decoding it. @@ -72,9 +72,9 @@ public abstract partial class Image /// The data is null. /// The data is not readable. /// - /// The or null if suitable info detector not found. + /// The or null if suitable info detector not found. /// - public static IImageInfo Identify(ReadOnlySpan data, out IImageFormat format) + public static ImageInfo Identify(ReadOnlySpan data, out IImageFormat format) => Identify(DecoderOptions.Default, data, out format); /// @@ -87,9 +87,9 @@ public abstract partial class Image /// The data is null. /// The data is not readable. /// - /// The or null if suitable info detector is not found. + /// The or null if suitable info detector is not found. /// - public static unsafe IImageInfo Identify(DecoderOptions options, ReadOnlySpan data, out IImageFormat format) + public static unsafe ImageInfo Identify(DecoderOptions options, ReadOnlySpan data, out IImageFormat format) { fixed (byte* ptr = data) { diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs index cd27e2882..1f17b698d 100644 --- a/src/ImageSharp/Image.FromFile.cs +++ b/src/ImageSharp/Image.FromFile.cs @@ -42,9 +42,9 @@ public abstract partial class Image /// /// The image file to open and to read the header from. /// - /// The or null if suitable info detector not found. + /// The or null if suitable info detector not found. /// - public static IImageInfo Identify(string filePath) + public static ImageInfo Identify(string filePath) => Identify(filePath, out IImageFormat _); /// @@ -53,9 +53,9 @@ public abstract partial class Image /// The image file to open and to read the header from. /// The format type of the decoded image. /// - /// The or null if suitable info detector not found. + /// The or null if suitable info detector not found. /// - public static IImageInfo Identify(string filePath, out IImageFormat format) + public static ImageInfo Identify(string filePath, out IImageFormat format) => Identify(DecoderOptions.Default, filePath, out format); /// @@ -66,9 +66,9 @@ public abstract partial class Image /// The format type of the decoded image. /// The configuration is null. /// - /// The or null if suitable info detector is not found. + /// The or null if suitable info detector is not found. /// - public static IImageInfo Identify(DecoderOptions options, string filePath, out IImageFormat format) + public static ImageInfo Identify(DecoderOptions options, string filePath, out IImageFormat format) { Guard.NotNull(options, nameof(options)); using Stream file = options.Configuration.FileSystem.OpenRead(filePath); @@ -83,9 +83,9 @@ public abstract partial class Image /// The configuration is null. /// /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// property set to null if suitable info detector is not found. /// - public static Task IdentifyAsync(string filePath, CancellationToken cancellationToken = default) + public static Task IdentifyAsync(string filePath, CancellationToken cancellationToken = default) => IdentifyAsync(DecoderOptions.Default, filePath, cancellationToken); /// @@ -97,14 +97,14 @@ public abstract partial class Image /// The configuration is null. /// /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// property set to null if suitable info detector is not found. /// - public static async Task IdentifyAsync( + public static async Task IdentifyAsync( DecoderOptions options, string filePath, CancellationToken cancellationToken = default) { - (IImageInfo ImageInfo, IImageFormat Format) res = + (ImageInfo ImageInfo, IImageFormat Format) res = await IdentifyWithFormatAsync(options, filePath, cancellationToken).ConfigureAwait(false); return res.ImageInfo; } @@ -117,9 +117,9 @@ public abstract partial class Image /// The configuration is null. /// /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// property set to null if suitable info detector is not found. /// - public static Task<(IImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( + public static Task<(ImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( string filePath, CancellationToken cancellationToken = default) => IdentifyWithFormatAsync(DecoderOptions.Default, filePath, cancellationToken); @@ -133,9 +133,9 @@ public abstract partial class Image /// The configuration is null. /// /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// property set to null if suitable info detector is not found. /// - public static async Task<(IImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( + public static async Task<(ImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( DecoderOptions options, string filePath, CancellationToken cancellationToken = default) diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs index 63b9b5c1b..fc6e14b2e 100644 --- a/src/ImageSharp/Image.FromStream.cs +++ b/src/ImageSharp/Image.FromStream.cs @@ -78,9 +78,9 @@ public abstract partial class Image /// The stream is not readable. /// Image contains invalid content. /// - /// The or null if a suitable info detector is not found. + /// The or null if a suitable info detector is not found. /// - public static IImageInfo Identify(Stream stream) + public static ImageInfo Identify(Stream stream) => Identify(stream, out IImageFormat _); /// @@ -95,7 +95,7 @@ public abstract partial class Image /// A representing the asynchronous operation or null if /// a suitable detector is not found. /// - public static Task IdentifyAsync(Stream stream, CancellationToken cancellationToken = default) + public static Task IdentifyAsync(Stream stream, CancellationToken cancellationToken = default) => IdentifyAsync(DecoderOptions.Default, stream, cancellationToken); /// @@ -107,9 +107,9 @@ public abstract partial class Image /// The stream is not readable. /// Image contains invalid content. /// - /// The or null if a suitable info detector is not found. + /// The or null if a suitable info detector is not found. /// - public static IImageInfo Identify(Stream stream, out IImageFormat format) + public static ImageInfo Identify(Stream stream, out IImageFormat format) => Identify(DecoderOptions.Default, stream, out format); /// @@ -122,9 +122,9 @@ public abstract partial class Image /// The stream is not readable. /// Image contains invalid content. /// - /// The or null if a suitable info detector is not found. + /// The or null if a suitable info detector is not found. /// - public static IImageInfo Identify(DecoderOptions options, Stream stream) + public static ImageInfo Identify(DecoderOptions options, Stream stream) => Identify(options, stream, out _); /// @@ -141,12 +141,12 @@ public abstract partial class Image /// A representing the asynchronous operation or null if /// a suitable detector is not found. /// - public static async Task IdentifyAsync( + public static async Task IdentifyAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) { - (IImageInfo ImageInfo, IImageFormat Format) res = await IdentifyWithFormatAsync(options, stream, cancellationToken).ConfigureAwait(false); + (ImageInfo ImageInfo, IImageFormat Format) res = await IdentifyWithFormatAsync(options, stream, cancellationToken).ConfigureAwait(false); return res.ImageInfo; } @@ -161,11 +161,11 @@ public abstract partial class Image /// The stream is not readable. /// Image contains invalid content. /// - /// The or null if a suitable info detector is not found. + /// The or null if a suitable info detector is not found. /// - public static IImageInfo Identify(DecoderOptions options, Stream stream, out IImageFormat format) + public static ImageInfo Identify(DecoderOptions options, Stream stream, out IImageFormat format) { - (IImageInfo ImageInfo, IImageFormat Format) data = WithSeekableStream(options, stream, s => InternalIdentify(options, s)); + (ImageInfo ImageInfo, IImageFormat Format) data = WithSeekableStream(options, stream, s => InternalIdentify(options, s)); format = data.Format; return data.ImageInfo; @@ -182,9 +182,9 @@ public abstract partial class Image /// Image contains invalid content. /// /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// property set to null if suitable info detector is not found. /// - public static Task<(IImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( + public static Task<(ImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( Stream stream, CancellationToken cancellationToken = default) => IdentifyWithFormatAsync(DecoderOptions.Default, stream, cancellationToken); @@ -201,9 +201,9 @@ public abstract partial class Image /// Image contains invalid content. /// /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// property set to null if suitable info detector is not found. /// - public static Task<(IImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( + public static Task<(ImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) diff --git a/src/ImageSharp/ImageInfo.cs b/src/ImageSharp/ImageInfo.cs index 5142a91a6..5b10440be 100644 --- a/src/ImageSharp/ImageInfo.cs +++ b/src/ImageSharp/ImageInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using SixLabors.ImageSharp.Formats; @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp; /// /// Contains information about the image including dimensions, pixel type information and additional metadata /// -internal sealed class ImageInfo : IImageInfo +public sealed class ImageInfo : IImageInfo { /// /// Initializes a new instance of the class. diff --git a/src/ImageSharp/ImageInfoExtensions.cs b/src/ImageSharp/ImageInfoExtensions.cs index 9dfc89289..0f47c8896 100644 --- a/src/ImageSharp/ImageInfoExtensions.cs +++ b/src/ImageSharp/ImageInfoExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. namespace SixLabors.ImageSharp; @@ -13,12 +13,12 @@ public static class ImageInfoExtensions /// /// The image info /// The - public static Size Size(this IImageInfo info) => new Size(info.Width, info.Height); + public static Size Size(this IImageInfo info) => new(info.Width, info.Height); /// /// Gets the bounds of the image. /// /// The image info /// The - public static Rectangle Bounds(this IImageInfo info) => new Rectangle(0, 0, info.Width, info.Height); + public static Rectangle Bounds(this IImageInfo info) => new(0, 0, info.Width, info.Height); } diff --git a/src/ImageSharp/Metadata/ImageMetadata.cs b/src/ImageSharp/Metadata/ImageMetadata.cs index 785f38941..f54fc5c7a 100644 --- a/src/ImageSharp/Metadata/ImageMetadata.cs +++ b/src/ImageSharp/Metadata/ImageMetadata.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Metadata.Profiles.Exif; @@ -69,6 +68,10 @@ public sealed class ImageMetadata : IDeepCloneable this.IccProfile = other.IccProfile?.DeepClone(); this.IptcProfile = other.IptcProfile?.DeepClone(); this.XmpProfile = other.XmpProfile?.DeepClone(); + + // NOTE: This clone is actually shallow but we share the same format + // instances for all images in the configuration. + this.DecodedImageFormat = other.DecodedImageFormat; } /// @@ -137,22 +140,27 @@ public sealed class ImageMetadata : IDeepCloneable /// /// Gets or sets the Exif profile. /// - public ExifProfile ExifProfile { get; set; } + public ExifProfile? ExifProfile { get; set; } /// /// Gets or sets the XMP profile. /// - public XmpProfile XmpProfile { get; set; } + public XmpProfile? XmpProfile { get; set; } /// /// Gets or sets the ICC profile. /// - public IccProfile IccProfile { get; set; } + public IccProfile? IccProfile { get; set; } /// /// Gets or sets the IPTC profile. /// - public IptcProfile IptcProfile { get; set; } + public IptcProfile? IptcProfile { get; set; } + + /// + /// Gets the original format, if any, the image was decode from. + /// + public IImageFormat? DecodedImageFormat { get; internal set; } /// /// Gets the metadata value associated with the specified key. @@ -165,7 +173,7 @@ public sealed class ImageMetadata : IDeepCloneable public TFormatMetadata GetFormatMetadata(IImageFormat key) where TFormatMetadata : class, IDeepCloneable { - if (this.formatMetadata.TryGetValue(key, out IDeepCloneable meta)) + if (this.formatMetadata.TryGetValue(key, out IDeepCloneable? meta)) { return (TFormatMetadata)meta; } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs index ac50337f6..3ffb1ab51 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs @@ -43,7 +43,7 @@ internal class RotateProcessor : AffineTransformProcessor /// protected override void AfterImageApply(Image destination) { - ExifProfile profile = destination.Metadata.ExifProfile; + ExifProfile? profile = destination.Metadata.ExifProfile; if (profile is null) { return; diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorHelpers.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorHelpers.cs index 8e7452679..172d7d677 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorHelpers.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorHelpers.cs @@ -19,7 +19,7 @@ internal static class TransformProcessorHelpers public static void UpdateDimensionalMetadata(Image image) where TPixel : unmanaged, IPixel { - ExifProfile profile = image.Metadata.ExifProfile; + ExifProfile? profile = image.Metadata.ExifProfile; if (profile is null) { return; diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs index aed3e4c03..d5ad59b00 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs @@ -22,7 +22,7 @@ public class IdentifyJpeg public void ReadImages() => this.jpegBytes ??= File.ReadAllBytes(this.TestImageFullPath); [Benchmark] - public IImageInfo Identify() + public ImageInfo Identify() { using MemoryStream memoryStream = new(this.jpegBytes); return JpegDecoder.Instance.Identify(DecoderOptions.Default, memoryStream); diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index e6eb389be..bfe490efa 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -475,7 +475,7 @@ public class BmpDecoderTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.Equal(expectedPixelSize, imageInfo.PixelType?.BitsPerPixel); } @@ -493,7 +493,7 @@ public class BmpDecoderTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.Equal(expectedWidth, imageInfo.Width); Assert.Equal(expectedHeight, imageInfo.Height); diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs index f4ce54670..712c7d8bf 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs @@ -38,7 +38,7 @@ public class BmpMetadataTests var testFile = TestFile.Create(imagePath); using (var stream = new MemoryStream(testFile.Bytes, false)) { - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); BmpMetadata bitmapMetadata = imageInfo.Metadata.GetBmpMetadata(); Assert.NotNull(bitmapMetadata); diff --git a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs index c9e50337e..95040e5d6 100644 --- a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs +++ b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs @@ -257,7 +257,7 @@ public class GeneralFormatTests image.Save(memoryStream, format); memoryStream.Position = 0; - IImageInfo imageInfo = Image.Identify(memoryStream); + ImageInfo imageInfo = Image.Identify(memoryStream); Assert.Equal(imageInfo.Width, width); Assert.Equal(imageInfo.Height, height); @@ -274,7 +274,7 @@ public class GeneralFormatTests byte[] invalid = new byte[10]; using MemoryStream memoryStream = new(invalid); - IImageInfo imageInfo = Image.Identify(memoryStream, out IImageFormat format); + ImageInfo imageInfo = Image.Identify(memoryStream, out IImageFormat format); Assert.Null(imageInfo); Assert.Null(format); diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs index 24eaa9607..7def2003a 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs @@ -113,7 +113,7 @@ public class GifMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo image = GifDecoder.Instance.Identify(DecoderOptions.Default, stream); + ImageInfo image = GifDecoder.Instance.Identify(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); Assert.Equal(yResolution, meta.VerticalResolution); @@ -126,7 +126,7 @@ public class GifMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo image = await GifDecoder.Instance.IdentifyAsync(DecoderOptions.Default, stream); + ImageInfo image = await GifDecoder.Instance.IdentifyAsync(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); Assert.Equal(yResolution, meta.VerticalResolution); @@ -165,7 +165,7 @@ public class GifMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo image = GifDecoder.Instance.Identify(DecoderOptions.Default, stream); + ImageInfo image = GifDecoder.Instance.Identify(DecoderOptions.Default, stream); GifMetadata meta = image.Metadata.GetGifMetadata(); Assert.Equal(repeatCount, meta.RepeatCount); } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs index d972f539e..80417653d 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs @@ -90,7 +90,7 @@ public partial class JpegDecoderTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo image = JpegDecoder.Instance.Identify(DecoderOptions.Default, stream); + ImageInfo image = JpegDecoder.Instance.Identify(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); Assert.Equal(yResolution, meta.VerticalResolution); @@ -103,7 +103,7 @@ public partial class JpegDecoderTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo image = await JpegDecoder.Instance.IdentifyAsync(DecoderOptions.Default, stream); + ImageInfo image = await JpegDecoder.Instance.IdentifyAsync(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); Assert.Equal(yResolution, meta.VerticalResolution); @@ -116,7 +116,7 @@ public partial class JpegDecoderTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo image = JpegDecoder.Instance.Identify(DecoderOptions.Default, stream); + ImageInfo image = JpegDecoder.Instance.Identify(DecoderOptions.Default, stream); JpegMetadata meta = image.Metadata.GetJpegMetadata(); Assert.Equal(quality, meta.Quality); } @@ -155,7 +155,7 @@ public partial class JpegDecoderTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo image = JpegDecoder.Instance.Identify(DecoderOptions.Default, stream); + ImageInfo image = JpegDecoder.Instance.Identify(DecoderOptions.Default, stream); JpegMetadata meta = image.Metadata.GetJpegMetadata(); Assert.Equal(expectedColorType, meta.ColorType); } @@ -180,7 +180,7 @@ public partial class JpegDecoderTests using var stream = new MemoryStream(testFile.Bytes, false); if (useIdentify) { - IImageInfo imageInfo = decoder.Identify(DecoderOptions.Default, stream); + ImageInfo imageInfo = decoder.Identify(DecoderOptions.Default, stream); test(imageInfo); } else diff --git a/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs index 7c57ee2fb..826d16e74 100644 --- a/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs @@ -35,7 +35,7 @@ public class PbmMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); PbmMetadata bitmapMetadata = imageInfo.Metadata.GetPbmMetadata(); Assert.NotNull(bitmapMetadata); @@ -54,7 +54,7 @@ public class PbmMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); PbmMetadata bitmapMetadata = imageInfo.Metadata.GetPbmMetadata(); Assert.NotNull(bitmapMetadata); @@ -73,7 +73,7 @@ public class PbmMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); PbmMetadata bitmapMetadata = imageInfo.Metadata.GetPbmMetadata(); Assert.NotNull(bitmapMetadata); diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index 2e1785cbb..ea958df37 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -504,7 +504,7 @@ public partial class PngDecoderTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); PngMetadata metadata = imageInfo.Metadata.GetPngMetadata(); Assert.True(metadata.HasTransparency); } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs index d283efc00..03de88a24 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs @@ -219,7 +219,7 @@ public class PngMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo image = PngDecoder.Instance.Identify(DecoderOptions.Default, stream); + ImageInfo image = PngDecoder.Instance.Identify(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); Assert.Equal(yResolution, meta.VerticalResolution); @@ -232,7 +232,7 @@ public class PngMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); PngMetadata meta = imageInfo.Metadata.GetFormatMetadata(PngFormat.Instance); VerifyTextDataIsPresent(meta); @@ -244,7 +244,7 @@ public class PngMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.NotNull(imageInfo.Metadata.ExifProfile); ExifProfile exif = imageInfo.Metadata.ExifProfile; @@ -281,7 +281,7 @@ public class PngMetadataTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.NotNull(imageInfo.Metadata.ExifProfile); diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs index a5997cb01..d34c051f8 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs @@ -41,7 +41,7 @@ public class TgaFileHeaderTests { using var stream = new MemoryStream(data); - IImageInfo info = Image.Identify(stream); + ImageInfo info = Image.Identify(stream); TgaMetadata tgaData = info.Metadata.GetTgaMetadata(); Assert.Equal(bitsPerPixel, tgaData.BitsPerPixel); Assert.Equal(width, info.Width); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs index 29017a674..bc8fe35a4 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs @@ -63,7 +63,7 @@ public class BigTiffDecoderTests : TiffDecoderBaseTester var testFile = TestFile.Create(imagePath); using (var stream = new MemoryStream(testFile.Bytes, false)) { - IImageInfo info = Image.Identify(stream); + ImageInfo info = Image.Identify(stream); Assert.Equal(expectedPixelSize, info.PixelType?.BitsPerPixel); Assert.Equal(expectedWidth, info.Width); @@ -87,7 +87,7 @@ public class BigTiffDecoderTests : TiffDecoderBaseTester var testFile = TestFile.Create(imagePath); using (var stream = new MemoryStream(testFile.Bytes, false)) { - IImageInfo info = Image.Identify(stream); + ImageInfo info = Image.Identify(stream); Assert.NotNull(info.Metadata); Assert.Equal(expectedByteOrder, info.Metadata.GetTiffMetadata().ByteOrder); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs index ced8ed6dd..60bc44ded 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs @@ -33,7 +33,7 @@ public class TiffDecoderTests : TiffDecoderBaseTester var testFile = TestFile.Create(imagePath); using (var stream = new MemoryStream(testFile.Bytes, false)) { - IImageInfo info = Image.Identify(stream); + ImageInfo info = Image.Identify(stream); Assert.Equal(expectedPixelSize, info.PixelType?.BitsPerPixel); Assert.Equal(expectedWidth, info.Width); @@ -53,7 +53,7 @@ public class TiffDecoderTests : TiffDecoderBaseTester TestFile testFile = TestFile.Create(imagePath); using (var stream = new MemoryStream(testFile.Bytes, false)) { - IImageInfo info = Image.Identify(stream); + ImageInfo info = Image.Identify(stream); Assert.NotNull(info.Metadata); Assert.Equal(expectedByteOrder, info.Metadata.GetTiffMetadata().ByteOrder); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs index f882bf415..6cf1bbc36 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs @@ -80,7 +80,7 @@ public class TiffMetadataTests var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata(); @@ -96,7 +96,7 @@ public class TiffMetadataTests var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata(); diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs index 694b8c23e..150c67d4f 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs @@ -41,7 +41,7 @@ public class WebpDecoderTests { var testFile = TestFile.Create(imagePath); using var stream = new MemoryStream(testFile.Bytes, false); - IImageInfo imageInfo = Image.Identify(stream); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.Equal(expectedWidth, imageInfo.Width); Assert.Equal(expectedHeight, imageInfo.Height); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs index 49c956253..1ff4d796a 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs @@ -21,7 +21,7 @@ public partial class ImageTests private static byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes; - private IImageInfo LocalImageInfo => this.localImageInfoMock.Object; + private ImageInfo LocalImageInfo => this.localImageInfoMock.Object; private IImageFormat LocalImageFormat => this.localImageFormatMock.Object; @@ -38,7 +38,7 @@ public partial class ImageTests [Fact] public void FromBytes_GlobalConfiguration() { - IImageInfo info = Image.Identify(ActualImageBytes, out IImageFormat type); + ImageInfo info = Image.Identify(ActualImageBytes, out IImageFormat type); Assert.Equal(ExpectedImageSize, info.Size()); Assert.Equal(ExpectedGlobalFormat, type); @@ -49,7 +49,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - IImageInfo info = Image.Identify(options, this.ByteArray, out IImageFormat type); + ImageInfo info = Image.Identify(options, this.ByteArray, out IImageFormat type); Assert.Equal(this.LocalImageInfo, info); Assert.Equal(this.LocalImageFormat, type); @@ -58,7 +58,7 @@ public partial class ImageTests [Fact] public void FromFileSystemPath_GlobalConfiguration() { - IImageInfo info = Image.Identify(ActualImagePath, out IImageFormat type); + ImageInfo info = Image.Identify(ActualImagePath, out IImageFormat type); Assert.NotNull(info); Assert.Equal(ExpectedGlobalFormat, type); @@ -69,7 +69,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - IImageInfo info = Image.Identify(options, this.MockFilePath, out IImageFormat type); + ImageInfo info = Image.Identify(options, this.MockFilePath, out IImageFormat type); Assert.Equal(this.LocalImageInfo, info); Assert.Equal(this.LocalImageFormat, type); @@ -79,7 +79,7 @@ public partial class ImageTests public void FromStream_GlobalConfiguration() { using var stream = new MemoryStream(ActualImageBytes); - IImageInfo info = Image.Identify(stream, out IImageFormat type); + ImageInfo info = Image.Identify(stream, out IImageFormat type); Assert.NotNull(info); Assert.Equal(ExpectedGlobalFormat, type); @@ -89,7 +89,7 @@ public partial class ImageTests public void FromStream_GlobalConfiguration_NoFormat() { using var stream = new MemoryStream(ActualImageBytes); - IImageInfo info = Image.Identify(stream); + ImageInfo info = Image.Identify(stream); Assert.NotNull(info); } @@ -100,7 +100,7 @@ public partial class ImageTests using var stream = new MemoryStream(ActualImageBytes); using var nonSeekableStream = new NonSeekableStream(stream); - IImageInfo info = Image.Identify(nonSeekableStream, out IImageFormat type); + ImageInfo info = Image.Identify(nonSeekableStream, out IImageFormat type); Assert.NotNull(info); Assert.Equal(ExpectedGlobalFormat, type); @@ -112,7 +112,7 @@ public partial class ImageTests using var stream = new MemoryStream(ActualImageBytes); using var nonSeekableStream = new NonSeekableStream(stream); - IImageInfo info = Image.Identify(nonSeekableStream); + ImageInfo info = Image.Identify(nonSeekableStream); Assert.NotNull(info); } @@ -122,7 +122,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - IImageInfo info = Image.Identify(options, this.DataStream, out IImageFormat type); + ImageInfo info = Image.Identify(options, this.DataStream, out IImageFormat type); Assert.Equal(this.LocalImageInfo, info); Assert.Equal(this.LocalImageFormat, type); @@ -133,7 +133,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - IImageInfo info = Image.Identify(options, this.DataStream); + ImageInfo info = Image.Identify(options, this.DataStream); Assert.Equal(this.LocalImageInfo, info); } @@ -143,7 +143,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = new() }; - IImageInfo info = Image.Identify(options, this.DataStream, out IImageFormat type); + ImageInfo info = Image.Identify(options, this.DataStream, out IImageFormat type); Assert.Null(info); Assert.Null(type); @@ -168,7 +168,7 @@ public partial class ImageTests 0x00, 0x00, 0x00, 0x00 })); using Stream stream = zipFile.Entries[0].Open(); - IImageInfo info = Image.Identify(stream); + ImageInfo info = Image.Identify(stream); Assert.Null(info); } @@ -177,7 +177,7 @@ public partial class ImageTests { using var stream = new MemoryStream(ActualImageBytes); var asyncStream = new AsyncStreamWrapper(stream, () => false); - IImageInfo info = await Image.IdentifyAsync(asyncStream); + ImageInfo info = await Image.IdentifyAsync(asyncStream); Assert.NotNull(info); } @@ -187,7 +187,7 @@ public partial class ImageTests { using var stream = new MemoryStream(ActualImageBytes); var asyncStream = new AsyncStreamWrapper(stream, () => false); - (IImageInfo ImageInfo, IImageFormat Format) res = await Image.IdentifyWithFormatAsync(asyncStream); + (ImageInfo ImageInfo, IImageFormat Format) res = await Image.IdentifyWithFormatAsync(asyncStream); Assert.Equal(ExpectedImageSize, res.ImageInfo.Size()); Assert.Equal(ExpectedGlobalFormat, res.Format); @@ -200,7 +200,7 @@ public partial class ImageTests using var nonSeekableStream = new NonSeekableStream(stream); var asyncStream = new AsyncStreamWrapper(nonSeekableStream, () => false); - IImageInfo info = await Image.IdentifyAsync(asyncStream); + ImageInfo info = await Image.IdentifyAsync(asyncStream); Assert.NotNull(info); } @@ -212,7 +212,7 @@ public partial class ImageTests using var nonSeekableStream = new NonSeekableStream(stream); var asyncStream = new AsyncStreamWrapper(nonSeekableStream, () => false); - (IImageInfo ImageInfo, IImageFormat Format) res = await Image.IdentifyWithFormatAsync(asyncStream); + (ImageInfo ImageInfo, IImageFormat Format) res = await Image.IdentifyWithFormatAsync(asyncStream); Assert.Equal(ExpectedImageSize, res.ImageInfo.Size()); Assert.Equal(ExpectedGlobalFormat, res.Format); @@ -237,7 +237,7 @@ public partial class ImageTests 0x00, 0x00, 0x00, 0x00 })); using Stream stream = zipFile.Entries[0].Open(); - IImageInfo info = await Image.IdentifyAsync(stream); + ImageInfo info = await Image.IdentifyAsync(stream); Assert.Null(info); } @@ -246,7 +246,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - IImageInfo info = await Image.IdentifyAsync(options, this.MockFilePath); + ImageInfo info = await Image.IdentifyAsync(options, this.MockFilePath); Assert.Equal(this.LocalImageInfo, info); } @@ -255,7 +255,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - (IImageInfo ImageInfo, IImageFormat Format) info = + (ImageInfo ImageInfo, IImageFormat Format) info = await Image.IdentifyWithFormatAsync(options, this.MockFilePath); Assert.NotNull(info.ImageInfo); Assert.Equal(this.LocalImageFormat, info.Format); @@ -264,7 +264,7 @@ public partial class ImageTests [Fact] public async Task IdentifyWithFormatAsync_FromPath_GlobalConfiguration() { - (IImageInfo ImageInfo, IImageFormat Format) res = await Image.IdentifyWithFormatAsync(ActualImagePath); + (ImageInfo ImageInfo, IImageFormat Format) res = await Image.IdentifyWithFormatAsync(ActualImagePath); Assert.Equal(ExpectedImageSize, res.ImageInfo.Size()); Assert.Equal(ExpectedGlobalFormat, res.Format); @@ -273,7 +273,7 @@ public partial class ImageTests [Fact] public async Task FromPathAsync_GlobalConfiguration() { - IImageInfo info = await Image.IdentifyAsync(ActualImagePath); + ImageInfo info = await Image.IdentifyAsync(ActualImagePath); Assert.Equal(ExpectedImageSize, info.Size()); } @@ -284,7 +284,7 @@ public partial class ImageTests DecoderOptions options = new() { Configuration = this.LocalConfiguration }; var asyncStream = new AsyncStreamWrapper(this.DataStream, () => false); - (IImageInfo ImageInfo, IImageFormat Format) + (ImageInfo ImageInfo, IImageFormat Format) info = await Image.IdentifyWithFormatAsync(options, asyncStream); Assert.Equal(this.LocalImageInfo, info.ImageInfo); @@ -297,7 +297,7 @@ public partial class ImageTests DecoderOptions options = new() { Configuration = new() }; var asyncStream = new AsyncStreamWrapper(this.DataStream, () => false); - (IImageInfo ImageInfo, IImageFormat Format) + (ImageInfo ImageInfo, IImageFormat Format) info = await Image.IdentifyWithFormatAsync(options, asyncStream); Assert.Null(info.ImageInfo); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs index 15e57b48a..bbc57b1e3 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs @@ -25,7 +25,7 @@ public partial class ImageTests protected Mock localImageFormatMock; - protected Mock localImageInfoMock; + protected Mock localImageInfoMock; protected readonly string MockFilePath = Guid.NewGuid().ToString(); @@ -56,7 +56,7 @@ public partial class ImageTests this.localStreamReturnImageRgba32 = new Image(1, 1); this.localStreamReturnImageAgnostic = new Image(1, 1); - this.localImageInfoMock = new Mock(); + this.localImageInfoMock = new Mock(); this.localImageFormatMock = new Mock(); this.localDecoder = new Mock(); diff --git a/tests/ImageSharp.Tests/TestFormat.cs b/tests/ImageSharp.Tests/TestFormat.cs index bfad23194..92dd79132 100644 --- a/tests/ImageSharp.Tests/TestFormat.cs +++ b/tests/ImageSharp.Tests/TestFormat.cs @@ -199,8 +199,12 @@ public class TestFormat : IImageFormatConfigurationModule, IImageFormat public bool IsSupportedFileFormat(Span header) => this.testFormat.IsSupportedFileFormat(header); - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) - => this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + { + Image image = + this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); + return new(image.PixelType, image.Width, image.Height, image.Metadata); + } protected override TestDecoderOptions CreateDefaultSpecializedOptions(DecoderOptions options) => new() { GeneralOptions = options }; @@ -208,7 +212,7 @@ public class TestFormat : IImageFormatConfigurationModule, IImageFormat protected override Image Decode(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken) { Configuration configuration = options.GeneralOptions.Configuration; - var ms = new MemoryStream(); + using MemoryStream ms = new(); stream.CopyTo(ms, configuration.StreamProcessingBufferSize); byte[] marker = ms.ToArray().Skip(this.testFormat.header.Length).ToArray(); this.testFormat.DecodeCalls.Add(new DecodeOperation diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs index 7203116c9..4bedf2ed9 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs @@ -72,8 +72,11 @@ public class MagickReferenceDecoder : ImageDecoder protected override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken) => this.Decode(options, stream, cancellationToken); - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) - => this.Decode(options, stream, cancellationToken); + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + { + Image image = this.Decode(options, stream, cancellationToken); + return new(image.PixelType, image.Width, image.Height, image.Metadata); + } private static void FromRgba32Bytes(Configuration configuration, Span rgbaBytes, IMemoryGroup destinationGroup) where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs index 503fd53ce..2deed6d48 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs @@ -13,7 +13,7 @@ public class SystemDrawingReferenceDecoder : ImageDecoder { public static SystemDrawingReferenceDecoder Instance { get; } = new SystemDrawingReferenceDecoder(); - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { using SDBitmap sourceBitmap = new(stream); PixelTypeInfo pixelType = new(SDImage.GetPixelFormatSize(sourceBitmap.PixelFormat)); diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs index 13edd2a06..3214bebc8 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -363,8 +363,11 @@ public class TestImageProviderTests } } - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) - => this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + { + Image image = this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); + return new(image.PixelType, image.Width, image.Height, image.Metadata); + } protected override Image Decode(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken) { @@ -403,8 +406,11 @@ public class TestImageProviderTests } } - protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) - => this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + { + Image image = this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); + return new(image.PixelType, image.Width, image.Height, image.Metadata); + } protected override Image Decode(TestDecoderWithParametersOptions options, Stream stream, CancellationToken cancellationToken) { From 3ee22e83bad1859fe165c038614671928d6d0182 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 12 Jan 2023 21:26:41 +1000 Subject: [PATCH 02/16] Detect non configuration decoder instances --- src/ImageSharp/Formats/ImageFormatManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs index 8da897a01..eeb1ebf8d 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -118,7 +118,7 @@ public class ImageFormatManager => this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase)); internal IImageFormat? FindFormatByDecoder(IImageDecoder decoder) - => this.mimeTypeDecoders.FirstOrDefault(x => x.Value == decoder).Key; + => this.mimeTypeDecoders.FirstOrDefault(x => x.Value.GetType() == decoder.GetType()).Key; /// /// Sets a specific image encoder as the encoder for a specific image format. From 538e1d4a3493a7b3dc03de8d7fb193692d22c9c9 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 12 Jan 2023 21:54:29 +1000 Subject: [PATCH 03/16] Update ImageTests.ImageLoadTestBase.cs --- .../Image/ImageTests.ImageLoadTestBase.cs | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs index bbc57b1e3..203f13279 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs @@ -25,13 +25,13 @@ public partial class ImageTests protected Mock localImageFormatMock; - protected Mock localImageInfoMock; + protected Mock localImageInfoMock; protected readonly string MockFilePath = Guid.NewGuid().ToString(); - internal readonly Mock LocalFileSystemMock = new Mock(); + internal readonly Mock LocalFileSystemMock = new(); - protected readonly TestFileSystem topLevelFileSystem = new TestFileSystem(); + protected readonly TestFileSystem topLevelFileSystem = new(); public Configuration LocalConfiguration { get; } @@ -56,21 +56,29 @@ public partial class ImageTests this.localStreamReturnImageRgba32 = new Image(1, 1); this.localStreamReturnImageAgnostic = new Image(1, 1); - this.localImageInfoMock = new Mock(); + this.localImageInfoMock = new Mock(); this.localImageFormatMock = new Mock(); this.localDecoder = new Mock(); this.localDecoder.Setup(x => x.Identify(It.IsAny(), It.IsAny())) - .Returns(this.localImageInfoMock.Object); + .Returns(() => + { + IImageInfo info = this.localImageInfoMock.Object; + return new ImageInfo(info.PixelType, info.Width, info.Height, info.Metadata); + }); this.localDecoder.Setup(x => x.IdentifyAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(Task.FromResult(this.localImageInfoMock.Object)); + .Returns(() => + { + IImageInfo info = this.localImageInfoMock.Object; + return Task.FromResult(new ImageInfo(info.PixelType, info.Width, info.Height, info.Metadata)); + }); this.localDecoder .Setup(x => x.Decode(It.IsAny(), It.IsAny())) - .Callback((c, s) => + .Callback((_, s) => { - using var ms = new MemoryStream(); + using MemoryStream ms = new(); s.CopyTo(ms); this.DecodedData = ms.ToArray(); }) @@ -78,9 +86,9 @@ public partial class ImageTests this.localDecoder .Setup(x => x.Decode(It.IsAny(), It.IsAny())) - .Callback((c, s) => + .Callback((_, s) => { - using var ms = new MemoryStream(); + using MemoryStream ms = new(); s.CopyTo(ms); this.DecodedData = ms.ToArray(); }) @@ -90,7 +98,7 @@ public partial class ImageTests .Setup(x => x.DecodeAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Callback((_, s, _) => { - using var ms = new MemoryStream(); + using MemoryStream ms = new(); s.CopyTo(ms); this.DecodedData = ms.ToArray(); }) @@ -100,7 +108,7 @@ public partial class ImageTests .Setup(x => x.DecodeAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Callback((_, s, _) => { - using var ms = new MemoryStream(); + using MemoryStream ms = new(); s.CopyTo(ms); this.DecodedData = ms.ToArray(); }) From 4a06d152ea5db529a0a5aeb7083b28313322f95a Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 12 Jan 2023 21:54:42 +1000 Subject: [PATCH 04/16] Update ImageFormatManager.cs --- src/ImageSharp/Formats/ImageFormatManager.cs | 28 ++++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs index eeb1ebf8d..3969693d6 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -91,9 +91,13 @@ public class ImageFormatManager /// /// For the specified file extensions type find the e . /// - /// The extension to discover - /// The if found otherwise null - /// False if no format was found + /// The extension to return the format for. + /// + /// When this method returns, contains the format that matches the given extension; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// . + /// if a match is found; otherwise, public bool TryFindFormatByFileExtension(string extension, [NotNullWhen(true)] out IImageFormat? format) { Guard.NotNullOrWhiteSpace(extension, nameof(extension)); @@ -106,16 +110,24 @@ public class ImageFormatManager format = this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); - return format != null; + return format is not null; } /// /// For the specified mime type find the . /// - /// The mime-type to discover - /// The if found; otherwise null - public IImageFormat? FindFormatByMimeType(string mimeType) - => this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase)); + /// The mime-type to return the format for. + /// + /// When this method returns, contains the format that matches the given mime-type; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// . + /// if a match is found; otherwise, + public bool TryFindFormatByMimeType(string mimeType, [NotNullWhen(true)] out IImageFormat? format) + { + format = this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase)); + return format is not null; + } internal IImageFormat? FindFormatByDecoder(IImageDecoder decoder) => this.mimeTypeDecoders.FirstOrDefault(x => x.Value.GetType() == decoder.GetType()).Key; From 250d73a9f568c277db5adcd8676078f68009ee7b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 12 Jan 2023 22:02:01 +1000 Subject: [PATCH 05/16] Fix build --- tests/ImageSharp.Tests/Image/ImageTests.Identify.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs index 1ff4d796a..641b0c810 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs @@ -21,7 +21,11 @@ public partial class ImageTests private static byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes; - private ImageInfo LocalImageInfo => this.localImageInfoMock.Object; + private ImageInfo LocalImageInfo => new( + this.localImageInfoMock.Object.PixelType, + this.localImageInfoMock.Object.Width, + this.localImageInfoMock.Object.Height, + this.localImageInfoMock.Object.Metadata); private IImageFormat LocalImageFormat => this.localImageFormatMock.Object; @@ -34,7 +38,6 @@ public partial class ImageTests } } - [Fact] public void FromBytes_GlobalConfiguration() { From ff4731abea49e54d51c79a061ae1a2fd49a5e078 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 12 Jan 2023 23:40:44 +1000 Subject: [PATCH 06/16] Attempt to fix equality match in identify tests --- .../Image/ImageTests.Identify.cs | 22 +++++++------------ .../Image/ImageTests.ImageLoadTestBase.cs | 18 +++++++-------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs index 641b0c810..83aeed5bd 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs @@ -21,12 +21,6 @@ public partial class ImageTests private static byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes; - private ImageInfo LocalImageInfo => new( - this.localImageInfoMock.Object.PixelType, - this.localImageInfoMock.Object.Width, - this.localImageInfoMock.Object.Height, - this.localImageInfoMock.Object.Metadata); - private IImageFormat LocalImageFormat => this.localImageFormatMock.Object; private static IImageFormat ExpectedGlobalFormat @@ -61,7 +55,7 @@ public partial class ImageTests [Fact] public void FromFileSystemPath_GlobalConfiguration() { - ImageInfo info = Image.Identify(ActualImagePath, out IImageFormat type); + ImageInfo info = Image.TryIdentify(ActualImagePath, out IImageFormat type); Assert.NotNull(info); Assert.Equal(ExpectedGlobalFormat, type); @@ -136,7 +130,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - ImageInfo info = Image.Identify(options, this.DataStream); + ImageInfo info = Image.TryIdentify(options, this.DataStream); Assert.Equal(this.LocalImageInfo, info); } @@ -190,7 +184,7 @@ public partial class ImageTests { using var stream = new MemoryStream(ActualImageBytes); var asyncStream = new AsyncStreamWrapper(stream, () => false); - (ImageInfo ImageInfo, IImageFormat Format) res = await Image.IdentifyWithFormatAsync(asyncStream); + (ImageInfo ImageInfo, IImageFormat Format) res = await Image.TryIdentifyAsync(asyncStream); Assert.Equal(ExpectedImageSize, res.ImageInfo.Size()); Assert.Equal(ExpectedGlobalFormat, res.Format); @@ -215,7 +209,7 @@ public partial class ImageTests using var nonSeekableStream = new NonSeekableStream(stream); var asyncStream = new AsyncStreamWrapper(nonSeekableStream, () => false); - (ImageInfo ImageInfo, IImageFormat Format) res = await Image.IdentifyWithFormatAsync(asyncStream); + (ImageInfo ImageInfo, IImageFormat Format) res = await Image.TryIdentifyAsync(asyncStream); Assert.Equal(ExpectedImageSize, res.ImageInfo.Size()); Assert.Equal(ExpectedGlobalFormat, res.Format); @@ -259,7 +253,7 @@ public partial class ImageTests DecoderOptions options = new() { Configuration = this.LocalConfiguration }; (ImageInfo ImageInfo, IImageFormat Format) info = - await Image.IdentifyWithFormatAsync(options, this.MockFilePath); + await Image.TryIdentifyAsync(options, this.MockFilePath); Assert.NotNull(info.ImageInfo); Assert.Equal(this.LocalImageFormat, info.Format); } @@ -267,7 +261,7 @@ public partial class ImageTests [Fact] public async Task IdentifyWithFormatAsync_FromPath_GlobalConfiguration() { - (ImageInfo ImageInfo, IImageFormat Format) res = await Image.IdentifyWithFormatAsync(ActualImagePath); + (ImageInfo ImageInfo, IImageFormat Format) res = await Image.TryIdentifyAsync(ActualImagePath); Assert.Equal(ExpectedImageSize, res.ImageInfo.Size()); Assert.Equal(ExpectedGlobalFormat, res.Format); @@ -288,7 +282,7 @@ public partial class ImageTests var asyncStream = new AsyncStreamWrapper(this.DataStream, () => false); (ImageInfo ImageInfo, IImageFormat Format) - info = await Image.IdentifyWithFormatAsync(options, asyncStream); + info = await Image.TryIdentifyAsync(options, asyncStream); Assert.Equal(this.LocalImageInfo, info.ImageInfo); Assert.Equal(this.LocalImageFormat, info.Format); @@ -301,7 +295,7 @@ public partial class ImageTests var asyncStream = new AsyncStreamWrapper(this.DataStream, () => false); (ImageInfo ImageInfo, IImageFormat Format) - info = await Image.IdentifyWithFormatAsync(options, asyncStream); + info = await Image.TryIdentifyAsync(options, asyncStream); Assert.Null(info.ImageInfo); } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs index 203f13279..235ea2d92 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs @@ -51,6 +51,12 @@ public partial class ImageTests protected byte[] ByteArray => ((MemoryStream)this.DataStream).ToArray(); + protected ImageInfo LocalImageInfo => new( + this.localImageInfoMock.Object.PixelType, + this.localImageInfoMock.Object.Width, + this.localImageInfoMock.Object.Height, + this.localImageInfoMock.Object.Metadata); + protected ImageLoadTestBase() { this.localStreamReturnImageRgba32 = new Image(1, 1); @@ -61,18 +67,10 @@ public partial class ImageTests this.localDecoder = new Mock(); this.localDecoder.Setup(x => x.Identify(It.IsAny(), It.IsAny())) - .Returns(() => - { - IImageInfo info = this.localImageInfoMock.Object; - return new ImageInfo(info.PixelType, info.Width, info.Height, info.Metadata); - }); + .Returns(this.LocalImageInfo); this.localDecoder.Setup(x => x.IdentifyAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(() => - { - IImageInfo info = this.localImageInfoMock.Object; - return Task.FromResult(new ImageInfo(info.PixelType, info.Width, info.Height, info.Metadata)); - }); + .Returns(Task.FromResult(this.LocalImageInfo)); this.localDecoder .Setup(x => x.Decode(It.IsAny(), It.IsAny())) From e35d1e7db5ceebe87d0a40b71e96f00a00ce0caf Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 12 Jan 2023 23:42:16 +1000 Subject: [PATCH 07/16] Fix ImageFormatManager docs --- src/ImageSharp/Formats/ImageFormatManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs index 3969693d6..5eeb1b812 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -96,7 +96,7 @@ public class ImageFormatManager /// When this method returns, contains the format that matches the given extension; /// otherwise, the default value for the type of the parameter. /// This parameter is passed uninitialized. - /// . + /// /// if a match is found; otherwise, public bool TryFindFormatByFileExtension(string extension, [NotNullWhen(true)] out IImageFormat? format) { @@ -121,7 +121,7 @@ public class ImageFormatManager /// When this method returns, contains the format that matches the given mime-type; /// otherwise, the default value for the type of the parameter. /// This parameter is passed uninitialized. - /// . + /// /// if a match is found; otherwise, public bool TryFindFormatByMimeType(string mimeType, [NotNullWhen(true)] out IImageFormat? format) { From 0aa12a4602a6f2fc1c1d3a063d1b8a15806086a8 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 14 Jan 2023 09:33:18 +1000 Subject: [PATCH 08/16] Refactor Identify and DetectFormat and fix tests --- src/ImageSharp/Common/Attempt{T}.cs | 24 ++ src/ImageSharp/Formats/ImageDecoder.cs | 18 +- src/ImageSharp/Image.Decode.cs | 79 +++---- src/ImageSharp/Image.FromBytes.cs | 49 ++-- src/ImageSharp/Image.FromFile.cs | 134 +++++------ src/ImageSharp/Image.FromStream.cs | 210 +++++++----------- .../Formats/Bmp/BmpDecoderTests.cs | 16 +- .../Formats/Bmp/BmpMetadataTests.cs | 33 ++- .../Formats/GeneralFormatTests.cs | 12 +- .../Formats/Gif/GifDecoderTests.cs | 18 +- .../Formats/Pbm/PbmMetadataTests.cs | 23 +- .../Formats/Png/PngDecoderTests.cs | 18 +- .../Formats/Png/PngMetadataTests.cs | 46 ++-- .../Formats/Tga/TgaFileHeaderTests.cs | 6 +- .../Formats/Tiff/BigTiffDecoderTests.cs | 50 ++--- .../Formats/Tiff/TiffDecoderTests.cs | 40 ++-- .../Formats/Tiff/TiffMetadataTests.cs | 28 +-- .../Formats/WebP/WebpDecoderTests.cs | 14 +- .../Image/ImageTests.Decode_Cancellation.cs | 2 +- .../Image/ImageTests.DetectFormat.cs | 55 +++-- .../Image/ImageTests.Identify.cs | 152 +++++++------ .../Image/ImageTests.ImageLoadTestBase.cs | 14 +- .../Image/ImageTests.WrapMemory.cs | 3 +- .../Image/MockImageFormatDetector.cs | 8 +- 24 files changed, 524 insertions(+), 528 deletions(-) create mode 100644 src/ImageSharp/Common/Attempt{T}.cs diff --git a/src/ImageSharp/Common/Attempt{T}.cs b/src/ImageSharp/Common/Attempt{T}.cs new file mode 100644 index 000000000..a243dffd1 --- /dev/null +++ b/src/ImageSharp/Common/Attempt{T}.cs @@ -0,0 +1,24 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Diagnostics.CodeAnalysis; + +namespace SixLabors.ImageSharp; + +/// +/// A wrapper for nullable values that correctly handles the return type based on the result. +/// +/// The type of nullable value. +public readonly struct Attempt +{ + /// + /// Gets a value indicating whether the attempted return was successful. + /// + [MemberNotNullWhen(returnValue: true, member: nameof(Value))] + public bool Success => this.Value is not null; + + /// + /// Gets the value when the attempted return is successful; otherwise, the default value for the type. + /// + public T? Value { get; init; } +} diff --git a/src/ImageSharp/Formats/ImageDecoder.cs b/src/ImageSharp/Formats/ImageDecoder.cs index bc2620c7f..dfb376197 100644 --- a/src/ImageSharp/Formats/ImageDecoder.cs +++ b/src/ImageSharp/Formats/ImageDecoder.cs @@ -84,12 +84,18 @@ public abstract class ImageDecoder : IImageDecoder } /// - public Task IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) - => WithSeekableMemoryStreamAsync( - options, - stream, - (s, ct) => this.Identify(options, s, ct), - cancellationToken); + public async Task IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) + { + ImageInfo info = await WithSeekableMemoryStreamAsync( + options, + stream, + (s, ct) => this.Identify(options, s, ct), + cancellationToken).ConfigureAwait(false); + + this.SetDecoderFormat(options.Configuration, info); + + return info; + } /// /// Decodes the image from the specified stream to an of a specific pixel type. diff --git a/src/ImageSharp/Image.Decode.cs b/src/ImageSharp/Image.Decode.cs index d549fabee..9a2844060 100644 --- a/src/ImageSharp/Image.Decode.cs +++ b/src/ImageSharp/Image.Decode.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Memory; @@ -45,7 +44,7 @@ public abstract partial class Image /// The general configuration. /// The image stream to read the header from. /// The mime type or null if none found. - private static IImageFormat InternalDetectFormat(Configuration configuration, Stream stream) + private static IImageFormat? InternalDetectFormat(Configuration configuration, Stream stream) { // We take a minimum of the stream length vs the max header size and always check below // to ensure that only formats that headers fit within the given buffer length are tested. @@ -77,15 +76,12 @@ public abstract partial class Image // Does the given stream contain enough data to fit in the header for the format // and does that data match the format specification? // Individual formats should still check since they are public. - IImageFormat format = null; + IImageFormat? format = null; foreach (IImageFormatDetector formatDetector in configuration.ImageFormatsManager.FormatDetectors) { - if (formatDetector.HeaderSize <= headerSize) + if (formatDetector.HeaderSize <= headerSize && formatDetector.TryDetectFormat(headersBuffer, out IImageFormat? attemptFormat)) { - if (formatDetector.TryDetectFormat(headersBuffer, out IImageFormat attemptFormat)) - { - format = attemptFormat; - } + format = attemptFormat; } } @@ -97,13 +93,11 @@ public abstract partial class Image /// /// The general decoder options. /// The image stream to read the header from. - /// The IImageFormat. - /// The image format or null if none found. - private static IImageDecoder DiscoverDecoder(DecoderOptions options, Stream stream, out IImageFormat format) + /// The or . + private static IImageDecoder? DiscoverDecoder(DecoderOptions options, Stream stream) { - format = InternalDetectFormat(options.Configuration, stream); - - return format != null + IImageFormat? format = InternalDetectFormat(options.Configuration, stream); + return format is not null ? options.Configuration.ImageFormatsManager.FindDecoder(format) : null; } @@ -117,60 +111,56 @@ public abstract partial class Image /// /// A new . /// - private static (Image Image, IImageFormat Format) Decode(DecoderOptions options, Stream stream) + private static Image? Decode(DecoderOptions options, Stream stream) where TPixel : unmanaged, IPixel { - IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format); + IImageDecoder? decoder = DiscoverDecoder(options, stream); if (decoder is null) { - return (null, null); + return null; } - Image img = decoder.Decode(options, stream); - return (img, format); + return decoder.Decode(options, stream); } - private static async Task<(Image Image, IImageFormat Format)> DecodeAsync( + private static async Task?> DecodeAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format); + IImageDecoder? decoder = DiscoverDecoder(options, stream); if (decoder is null) { - return (null, null); + return null; } - Image img = await decoder.DecodeAsync(options, stream, cancellationToken).ConfigureAwait(false); - return (img, format); + return await decoder.DecodeAsync(options, stream, cancellationToken).ConfigureAwait(false); } - private static (Image Image, IImageFormat Format) Decode(DecoderOptions options, Stream stream) + private static Image? Decode(DecoderOptions options, Stream stream) { - IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format); + IImageDecoder? decoder = DiscoverDecoder(options, stream); if (decoder is null) { - return (null, null); + return null; } - Image img = decoder.Decode(options, stream); - return (img, format); + return decoder.Decode(options, stream); } - private static async Task<(Image Image, IImageFormat Format)> DecodeAsync( + private static async Task DecodeAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken) { - IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format); + IImageDecoder? decoder = DiscoverDecoder(options, stream); if (decoder is null) { - return (null, null); + return null; } - Image img = await decoder.DecodeAsync(options, stream, cancellationToken).ConfigureAwait(false); - return (img, format); + return await decoder.DecodeAsync(options, stream, cancellationToken).ConfigureAwait(false); } /// @@ -181,11 +171,15 @@ public abstract partial class Image /// /// The or null if a suitable info detector is not found. /// - private static (ImageInfo ImageInfo, IImageFormat Format) InternalIdentify(DecoderOptions options, Stream stream) + private static ImageInfo? InternalIdentify(DecoderOptions options, Stream stream) { - IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format); - ImageInfo info = decoder?.Identify(options, stream); - return (info, format); + IImageDecoder? decoder = DiscoverDecoder(options, stream); + if (decoder is null) + { + return null; + } + + return decoder.Identify(options, stream); } /// @@ -197,19 +191,18 @@ public abstract partial class Image /// /// The or null if a suitable info detector is not found. /// - private static async Task<(ImageInfo ImageInfo, IImageFormat Format)> InternalIdentifyAsync( + private static async Task InternalIdentifyAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken) { - IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format); + IImageDecoder? decoder = DiscoverDecoder(options, stream); if (decoder is null) { - return (null, null); + return null; } - ImageInfo info = await decoder.IdentifyAsync(options, stream, cancellationToken).ConfigureAwait(false); - return (info, format); + return await decoder.IdentifyAsync(options, stream, cancellationToken).ConfigureAwait(false); } } diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs index a6c73c61e..921812834 100644 --- a/src/ImageSharp/Image.FromBytes.cs +++ b/src/ImageSharp/Image.FromBytes.cs @@ -55,46 +55,41 @@ public abstract partial class Image /// /// Reads the raw image information from the specified stream without fully decoding it. - /// - /// The byte span containing encoded image data to read the header from. - /// The data is null. - /// The data is not readable. - /// - /// The or null if suitable info detector not found. - /// - public static ImageInfo Identify(ReadOnlySpan data) => Identify(data, out IImageFormat _); - - /// - /// Reads the raw image information from the specified stream without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The byte array containing encoded image data to read the header from. - /// The format type of the decoded image. + /// + /// When this method returns, contains the raw image information; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if the information can be read; otherwise, /// The data is null. /// The data is not readable. - /// - /// The or null if suitable info detector not found. - /// - public static ImageInfo Identify(ReadOnlySpan data, out IImageFormat format) - => Identify(DecoderOptions.Default, data, out format); + public static bool TryIdentify(ReadOnlySpan data, [NotNullWhen(true)] out ImageInfo? info) + => TryIdentify(DecoderOptions.Default, data, out info); /// /// Reads the raw image information from the specified span of bytes without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The byte span containing encoded image data to read the header from. - /// The format type of the decoded image. + /// + /// When this method returns, contains the raw image information; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if the information can be read; otherwise, /// The configuration is null. /// The data is null. /// The data is not readable. - /// - /// The or null if suitable info detector is not found. - /// - public static unsafe ImageInfo Identify(DecoderOptions options, ReadOnlySpan data, out IImageFormat format) + public static unsafe bool TryIdentify(DecoderOptions options, ReadOnlySpan data, [NotNullWhen(true)] out ImageInfo? info) { fixed (byte* ptr = data) { - using var stream = new UnmanagedMemoryStream(ptr, data.Length); - return Identify(options, stream, out format); + using UnmanagedMemoryStream stream = new(ptr, data.Length); + return TryIdentify(options, stream, out info); } } @@ -141,7 +136,7 @@ public abstract partial class Image { fixed (byte* ptr = data) { - using var stream = new UnmanagedMemoryStream(ptr, data.Length); + using UnmanagedMemoryStream stream = new(ptr, data.Length); return Load(options, stream); } } @@ -166,7 +161,7 @@ public abstract partial class Image { fixed (byte* ptr = data) { - using var stream = new UnmanagedMemoryStream(ptr, data.Length); + using UnmanagedMemoryStream stream = new(ptr, data.Length); return Load(options, stream, out format); } } @@ -222,7 +217,7 @@ public abstract partial class Image { fixed (byte* ptr = data) { - using var stream = new UnmanagedMemoryStream(ptr, data.Length); + using UnmanagedMemoryStream stream = new(ptr, data.Length); return Load(options, stream, out format); } } diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs index 1f17b698d..515d8408c 100644 --- a/src/ImageSharp/Image.FromFile.cs +++ b/src/ImageSharp/Image.FromFile.cs @@ -13,22 +13,32 @@ namespace SixLabors.ImageSharp; public abstract partial class Image { /// - /// By reading the header on the provided file this calculates the images mime type. + /// Detects the encoded image format type from the specified file. + /// A return value indicates whether the operation succeeded. /// /// The image file to open and to read the header from. - /// The mime type or null if none found. - /// returns true when format was detected otherwise false. + /// + /// When this method returns, contains the format that matches the given file; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if a match is found; otherwise, 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. + /// Detects the encoded image format type from the specified file. + /// A return value indicates whether the operation succeeded. /// /// 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. - /// returns true when format was detected otherwise false. + /// + /// When this method returns, contains the format that matches the given file; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if a match is found; otherwise, + /// The options are null. public static bool TryDetectFormat(DecoderOptions options, string filePath, [NotNullWhen(true)] out IImageFormat? format) { Guard.NotNull(options, nameof(options)); @@ -38,112 +48,106 @@ public abstract partial class Image } /// - /// Reads the raw image information from the specified stream without fully decoding it. + /// Detects the encoded image format type from the specified file. + /// A return value indicates whether the operation succeeded. /// /// The image file to open and to read the header from. - /// - /// The or null if suitable info detector not found. - /// - public static ImageInfo Identify(string filePath) - => Identify(filePath, out IImageFormat _); - - /// - /// Reads the raw image information from the specified stream without fully decoding it. - /// - /// The image file to open and to read the header from. - /// The format type of the decoded image. - /// - /// The or null if suitable info detector not found. - /// - public static ImageInfo Identify(string filePath, out IImageFormat format) - => Identify(DecoderOptions.Default, filePath, out format); + /// The token to monitor for cancellation requests. + /// A representing the asynchronous operation. + public static Task> TryDetectFormatAsync( + string filePath, + CancellationToken cancellationToken = default) + => TryDetectFormatAsync(DecoderOptions.Default, filePath, cancellationToken); /// - /// Reads the raw image information from the specified stream without fully decoding it. + /// Detects the encoded image format type from the specified file. + /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image file to open and to read the header from. - /// The format type of the decoded image. - /// The configuration is null. - /// - /// The or null if suitable info detector is not found. - /// - public static ImageInfo Identify(DecoderOptions options, string filePath, out IImageFormat format) + /// The token to monitor for cancellation requests. + /// The options are null. + /// A representing the asynchronous operation. + public static async Task> TryDetectFormatAsync( + DecoderOptions options, + string filePath, + CancellationToken cancellationToken = default) { Guard.NotNull(options, nameof(options)); - using Stream file = options.Configuration.FileSystem.OpenRead(filePath); - return Identify(options, file, out format); + + using Stream stream = options.Configuration.FileSystem.OpenRead(filePath); + return await TryDetectFormatAsync(options, stream, cancellationToken).ConfigureAwait(false); } /// - /// Reads the raw image information from the specified stream without fully decoding it. + /// Reads the raw image information from the specified file path without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The image file to open and to read the header from. - /// The token to monitor for cancellation requests. - /// The configuration is null. - /// - /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. - /// - public static Task IdentifyAsync(string filePath, CancellationToken cancellationToken = default) - => IdentifyAsync(DecoderOptions.Default, filePath, cancellationToken); + /// + /// When this method returns, contains the raw image information; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if the information can be read; otherwise, + public static bool TryIdentify(string filePath, [NotNullWhen(true)] out ImageInfo? info) + => TryIdentify(DecoderOptions.Default, filePath, out info); /// - /// Reads the raw image information from the specified stream without fully decoding it. + /// Reads the raw image information from the specified file path without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image file to open and to read the header from. - /// The token to monitor for cancellation requests. - /// The configuration is null. - /// - /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. - /// - public static async Task IdentifyAsync( - DecoderOptions options, - string filePath, - CancellationToken cancellationToken = default) + /// + /// When this method returns, contains the raw image information; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if the information can be read; otherwise, + /// The options are null. + public static bool TryIdentify(DecoderOptions options, string filePath, [NotNullWhen(true)] out ImageInfo? info) { - (ImageInfo ImageInfo, IImageFormat Format) res = - await IdentifyWithFormatAsync(options, filePath, cancellationToken).ConfigureAwait(false); - return res.ImageInfo; + Guard.NotNull(options, nameof(options)); + + using Stream stream = options.Configuration.FileSystem.OpenRead(filePath); + return TryIdentify(options, stream, out info); } /// /// Reads the raw image information from the specified stream without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. /// The configuration is null. /// - /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// The representing the asynchronous operation. /// - public static Task<(ImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( + public static Task> TryIdentifyAsync( string filePath, CancellationToken cancellationToken = default) - => IdentifyWithFormatAsync(DecoderOptions.Default, filePath, cancellationToken); + => TryIdentifyAsync(DecoderOptions.Default, filePath, cancellationToken); /// /// Reads the raw image information from the specified stream without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. /// The configuration is null. /// - /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// The representing the asynchronous operation. /// - public static async Task<(ImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( + public static async Task> TryIdentifyAsync( DecoderOptions options, string filePath, CancellationToken cancellationToken = default) { Guard.NotNull(options, nameof(options)); using Stream stream = options.Configuration.FileSystem.OpenRead(filePath); - return await IdentifyWithFormatAsync(options, stream, cancellationToken) - .ConfigureAwait(false); + return await TryIdentifyAsync(options, stream, cancellationToken).ConfigureAwait(false); } /// diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs index fc6e14b2e..fa9285ef3 100644 --- a/src/ImageSharp/Image.FromStream.cs +++ b/src/ImageSharp/Image.FromStream.cs @@ -16,45 +16,59 @@ namespace SixLabors.ImageSharp; public abstract partial class Image { /// - /// By reading the header on the provided stream this calculates the images format type. + /// Detects the encoded image format type from the specified stream. + /// A return value indicates whether the operation succeeded. /// /// The image stream to read the header from. - /// The format type or null if none found. + /// + /// When this method returns, contains the format that matches the given stream; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if a match is found; otherwise, /// The stream is null. /// The stream is not readable. - /// 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. + /// Detects the encoded image format type from the specified stream. + /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image stream to read the header from. - /// The format type or null if none found. + /// + /// When this method returns, contains the format that matches the given stream; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if a match is found; otherwise, /// The options are null. /// The stream is null. /// The stream is not readable. - /// 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; + return format is not null; } /// - /// By reading the header on the provided stream this calculates the images format type. + /// Detects the encoded image format type from the specified stream. + /// A return value indicates whether the operation succeeded. /// /// The image stream to read the header from. /// The token to monitor for cancellation requests. /// The stream is null. /// The stream is not readable. - /// A representing the asynchronous operation or null if none is found. - public static Task DetectFormatAsync(Stream stream, CancellationToken cancellationToken = default) - => DetectFormatAsync(DecoderOptions.Default, stream, cancellationToken); + /// A representing the asynchronous operation. + public static Task> TryDetectFormatAsync( + Stream stream, + CancellationToken cancellationToken = default) + => TryDetectFormatAsync(DecoderOptions.Default, stream, cancellationToken); /// - /// By reading the header on the provided stream this calculates the images format type. + /// Detects the encoded image format type from the specified stream. + /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image stream to read the header from. @@ -62,117 +76,63 @@ public abstract partial class Image /// The options are null. /// The stream is null. /// The stream is not readable. - /// A representing the asynchronous operation. - public static Task DetectFormatAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) - => WithSeekableStreamAsync( + /// A representing the asynchronous operation. + public static async Task> TryDetectFormatAsync( + DecoderOptions options, + Stream stream, + CancellationToken cancellationToken = default) + { + IImageFormat? format = await WithSeekableStreamAsync( options, stream, (s, _) => Task.FromResult(InternalDetectFormat(options.Configuration, s)), - cancellationToken); - - /// - /// Reads the raw image information from the specified stream without fully decoding it. - /// - /// The image stream to read the header from. - /// The stream is null. - /// The stream is not readable. - /// Image contains invalid content. - /// - /// The or null if a suitable info detector is not found. - /// - public static ImageInfo Identify(Stream stream) - => Identify(stream, out IImageFormat _); + cancellationToken).ConfigureAwait(false); - /// - /// Reads the raw image information from the specified stream without fully decoding it. - /// - /// The image stream to read the header from. - /// The token to monitor for cancellation requests. - /// The stream is null. - /// The stream is not readable. - /// Image contains invalid content. - /// - /// A representing the asynchronous operation or null if - /// a suitable detector is not found. - /// - public static Task IdentifyAsync(Stream stream, CancellationToken cancellationToken = default) - => IdentifyAsync(DecoderOptions.Default, stream, cancellationToken); + return new() { Value = format }; + } /// /// Reads the raw image information from the specified stream without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The image stream to read the header from. - /// The format type of the decoded image. + /// + /// When this method returns, contains the raw image information; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if the information can be read; otherwise, /// The stream is null. /// The stream is not readable. /// Image contains invalid content. - /// - /// The or null if a suitable info detector is not found. - /// - public static ImageInfo Identify(Stream stream, out IImageFormat format) - => Identify(DecoderOptions.Default, stream, out format); + public static bool TryIdentify(Stream stream, [NotNullWhen(true)] out ImageInfo? info) + => TryIdentify(DecoderOptions.Default, stream, out info); /// /// Reads the raw image information from the specified stream without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image stream to read the information from. + /// + /// When this method returns, contains the raw image information; + /// otherwise, the default value for the type of the parameter. + /// This parameter is passed uninitialized. + /// + /// if the information can be read; otherwise, /// The options are null. /// The stream is null. /// The stream is not readable. /// Image contains invalid content. - /// - /// The or null if a suitable info detector is not found. - /// - public static ImageInfo Identify(DecoderOptions options, Stream stream) - => Identify(options, stream, out _); - - /// - /// Reads the raw image information from the specified stream without fully decoding it. - /// - /// The general decoder options. - /// The image stream to read the information from. - /// The token to monitor for cancellation requests. - /// The options are null. - /// The stream is null. - /// The stream is not readable. - /// Image contains invalid content. - /// - /// A representing the asynchronous operation or null if - /// a suitable detector is not found. - /// - public static async Task IdentifyAsync( - DecoderOptions options, - Stream stream, - CancellationToken cancellationToken = default) + public static bool TryIdentify(DecoderOptions options, Stream stream, [NotNullWhen(true)] out ImageInfo? info) { - (ImageInfo ImageInfo, IImageFormat Format) res = await IdentifyWithFormatAsync(options, stream, cancellationToken).ConfigureAwait(false); - return res.ImageInfo; - } - - /// - /// Reads the raw image information from the specified stream without fully decoding it. - /// - /// The general decoder options. - /// The image stream to read the information from. - /// The format type of the decoded image. - /// The options are null. - /// The stream is null. - /// The stream is not readable. - /// Image contains invalid content. - /// - /// The or null if a suitable info detector is not found. - /// - public static ImageInfo Identify(DecoderOptions options, Stream stream, out IImageFormat format) - { - (ImageInfo ImageInfo, IImageFormat Format) data = WithSeekableStream(options, stream, s => InternalIdentify(options, s)); - - format = data.Format; - return data.ImageInfo; + info = WithSeekableStream(options, stream, s => InternalIdentify(options, s)); + return info is not null; } /// /// Reads the raw image information from the specified stream without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The image stream to read the information from. /// The token to monitor for cancellation requests. @@ -181,16 +141,16 @@ public abstract partial class Image /// The stream is not readable. /// Image contains invalid content. /// - /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// The representing the asynchronous operation. /// - public static Task<(ImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( + public static Task> TryIdentifyAsync( Stream stream, CancellationToken cancellationToken = default) - => IdentifyWithFormatAsync(DecoderOptions.Default, stream, cancellationToken); + => TryIdentifyAsync(DecoderOptions.Default, stream, cancellationToken); /// /// Reads the raw image information from the specified stream without fully decoding it. + /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image stream to read the information from. @@ -200,18 +160,21 @@ public abstract partial class Image /// The stream is not readable. /// Image contains invalid content. /// - /// The representing the asynchronous operation with the parameter type - /// property set to null if suitable info detector is not found. + /// The representing the asynchronous operation. /// - public static Task<(ImageInfo ImageInfo, IImageFormat Format)> IdentifyWithFormatAsync( + public static async Task> TryIdentifyAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) - => WithSeekableStreamAsync( + { + ImageInfo? info = await WithSeekableStreamAsync( options, stream, (s, ct) => InternalIdentifyAsync(options, s, ct), - cancellationToken); + cancellationToken).ConfigureAwait(false); + + return new() { Value = info }; + } /// /// Decode a new instance of the class from the given stream. @@ -387,16 +350,15 @@ public abstract partial class Image public static Image Load(DecoderOptions options, Stream stream, out IImageFormat format) where TPixel : unmanaged, IPixel { - (Image Image, IImageFormat Format) data = WithSeekableStream(options, stream, s => Decode(options, s)); + Image? image = WithSeekableStream(options, stream, s => Decode(options, s)); - format = data.Format; - - if (data.Image is null) + if (image is null) { ThrowNotLoaded(options); } - return data.Image; + format = image.Metadata.DecodedImageFormat!; + return image; } /// @@ -416,16 +378,15 @@ public abstract partial class Image Stream stream, CancellationToken cancellationToken = default) { - (Image Image, IImageFormat Format) data = - await WithSeekableStreamAsync(options, stream, (s, ct) => DecodeAsync(options, s, ct), cancellationToken) - .ConfigureAwait(false); + Image? image = await WithSeekableStreamAsync(options, stream, (s, ct) => DecodeAsync(options, s, ct), cancellationToken) + .ConfigureAwait(false); - if (data.Image is null) + if (image is null) { ThrowNotLoaded(options); } - return data; + return new(image, image.Metadata.DecodedImageFormat!); } /// @@ -447,16 +408,15 @@ public abstract partial class Image CancellationToken cancellationToken = default) where TPixel : unmanaged, IPixel { - (Image Image, IImageFormat Format) data = - await WithSeekableStreamAsync(options, stream, (s, ct) => DecodeAsync(options, s, ct), cancellationToken) - .ConfigureAwait(false); + Image? image = await WithSeekableStreamAsync(options, stream, (s, ct) => DecodeAsync(options, s, ct), cancellationToken) + .ConfigureAwait(false); - if (data.Image is null) + if (image is null) { ThrowNotLoaded(options); } - return data; + return new(image, image.Metadata.DecodedImageFormat!); } /// @@ -498,16 +458,14 @@ public abstract partial class Image /// A new . public static Image Load(DecoderOptions options, Stream stream, out IImageFormat format) { - (Image img, IImageFormat fmt) = WithSeekableStream(options, stream, s => Decode(options, s)); - - format = fmt; - - if (img is null) + Image? image = WithSeekableStream(options, stream, s => Decode(options, s)); + if (image is null) { ThrowNotLoaded(options); } - return img; + format = image.Metadata.DecodedImageFormat!; + return image; } /// diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index bfe490efa..035481e01 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -473,9 +473,9 @@ public class BmpDecoderTests [InlineData(Bit1Pal1, 1)] public void Identify_DetectsCorrectPixelType(string imagePath, int expectedPixelSize) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); Assert.Equal(expectedPixelSize, imageInfo.PixelType?.BitsPerPixel); } @@ -491,9 +491,9 @@ public class BmpDecoderTests [InlineData(RLE8Inverted, 491, 272)] public void Identify_DetectsCorrectWidthAndHeight(string imagePath, int expectedWidth, int expectedHeight) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); Assert.Equal(expectedWidth, imageInfo.Width); Assert.Equal(expectedHeight, imageInfo.Height); @@ -503,8 +503,8 @@ public class BmpDecoderTests [MemberData(nameof(RatioFiles))] public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); using Image image = BmpDecoder.Instance.Decode(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs index 712c7d8bf..1aef3e748 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs @@ -14,8 +14,9 @@ public class BmpMetadataTests [Fact] public void CloneIsDeep() { - var meta = new BmpMetadata { BitsPerPixel = BmpBitsPerPixel.Pixel24, InfoHeaderType = BmpInfoHeaderType.Os2Version2 }; - var clone = (BmpMetadata)meta.DeepClone(); + BmpMetadata meta = new() + { BitsPerPixel = BmpBitsPerPixel.Pixel24, InfoHeaderType = BmpInfoHeaderType.Os2Version2 }; + BmpMetadata clone = (BmpMetadata)meta.DeepClone(); clone.BitsPerPixel = BmpBitsPerPixel.Pixel32; clone.InfoHeaderType = BmpInfoHeaderType.WinVersion2; @@ -35,15 +36,13 @@ public class BmpMetadataTests [InlineData(Os2v2, BmpInfoHeaderType.Os2Version2)] public void Identify_DetectsCorrectBitmapInfoHeaderType(string imagePath, BmpInfoHeaderType expectedInfoHeaderType) { - var testFile = TestFile.Create(imagePath); - using (var stream = new MemoryStream(testFile.Bytes, false)) - { - ImageInfo imageInfo = Image.Identify(stream); - Assert.NotNull(imageInfo); - BmpMetadata bitmapMetadata = imageInfo.Metadata.GetBmpMetadata(); - Assert.NotNull(bitmapMetadata); - Assert.Equal(expectedInfoHeaderType, bitmapMetadata.InfoHeaderType); - } + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); + Assert.NotNull(imageInfo); + BmpMetadata bitmapMetadata = imageInfo.Metadata.GetBmpMetadata(); + Assert.NotNull(bitmapMetadata); + Assert.Equal(expectedInfoHeaderType, bitmapMetadata.InfoHeaderType); } [Theory] @@ -51,12 +50,10 @@ public class BmpMetadataTests public void Decoder_CanReadColorProfile(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage(BmpDecoder.Instance)) - { - ImageSharp.Metadata.ImageMetadata metaData = image.Metadata; - Assert.NotNull(metaData); - Assert.NotNull(metaData.IccProfile); - Assert.Equal(16, metaData.IccProfile.Entries.Length); - } + using Image image = provider.GetImage(BmpDecoder.Instance); + ImageSharp.Metadata.ImageMetadata metaData = image.Metadata; + Assert.NotNull(metaData); + Assert.NotNull(metaData.IccProfile); + Assert.Equal(16, metaData.IccProfile.Entries.Length); } } diff --git a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs index 95040e5d6..400af5e45 100644 --- a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs +++ b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs @@ -7,7 +7,6 @@ using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Quantization; -using SixLabors.ImageSharp.Tests.TestUtilities; namespace SixLabors.ImageSharp.Tests.Formats; @@ -257,15 +256,11 @@ public class GeneralFormatTests image.Save(memoryStream, format); memoryStream.Position = 0; - ImageInfo imageInfo = Image.Identify(memoryStream); + Image.TryIdentify(memoryStream, out ImageInfo imageInfo); Assert.Equal(imageInfo.Width, width); Assert.Equal(imageInfo.Height, height); - memoryStream.Position = 0; - - imageInfo = Image.Identify(memoryStream, out IImageFormat detectedFormat); - - Assert.Equal(format, detectedFormat); + Assert.Equal(format, imageInfo.Metadata.DecodedImageFormat); } [Fact] @@ -274,10 +269,9 @@ public class GeneralFormatTests byte[] invalid = new byte[10]; using MemoryStream memoryStream = new(invalid); - ImageInfo imageInfo = Image.Identify(memoryStream, out IImageFormat format); + Image.TryIdentify(memoryStream, out ImageInfo imageInfo); Assert.Null(imageInfo); - Assert.Null(format); } private static IImageFormat GetFormat(string format) diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs index 9ddae6645..589baa613 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs @@ -59,13 +59,13 @@ public class GifDecoderTests [Fact] public unsafe void Decode_NonTerminatedFinalFrame() { - var testFile = TestFile.Create(TestImages.Gif.Rings); + TestFile testFile = TestFile.Create(TestImages.Gif.Rings); int length = testFile.Bytes.Length - 2; fixed (byte* data = testFile.Bytes.AsSpan(0, length)) { - using var stream = new UnmanagedMemoryStream(data, length); + using UnmanagedMemoryStream stream = new(data, length); using Image image = GifDecoder.Instance.Decode(DecoderOptions.Default, stream); Assert.Equal((200, 200), (image.Width, image.Height)); } @@ -120,9 +120,13 @@ public class GifDecoderTests [InlineData(TestImages.Gif.Trans, 8)] public void DetectPixelSize(string imagePath, int expectedPixelSize) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + + Image.TryIdentify(stream, out ImageInfo imageInfo); + + Assert.NotNull(imageInfo); + Assert.Equal(expectedPixelSize, imageInfo.PixelType.BitsPerPixel); } [Theory] @@ -155,9 +159,9 @@ public class GifDecoderTests [Fact] public void CanDecodeIntermingledImages() { - using (var kumin1 = Image.Load(TestFile.Create(TestImages.Gif.Kumin).Bytes)) + using (Image kumin1 = Image.Load(TestFile.Create(TestImages.Gif.Kumin).Bytes)) using (Image.Load(TestFile.Create(TestImages.Png.Icon).Bytes)) - using (var kumin2 = Image.Load(TestFile.Create(TestImages.Gif.Kumin).Bytes)) + using (Image kumin2 = Image.Load(TestFile.Create(TestImages.Gif.Kumin).Bytes)) { for (int i = 0; i < kumin1.Frames.Count; i++) { diff --git a/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs index 826d16e74..b4c39293d 100644 --- a/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs @@ -13,8 +13,9 @@ public class PbmMetadataTests [Fact] public void CloneIsDeep() { - var meta = new PbmMetadata { ColorType = PbmColorType.Grayscale }; - var clone = (PbmMetadata)meta.DeepClone(); + PbmMetadata meta = new() + { ColorType = PbmColorType.Grayscale }; + PbmMetadata clone = (PbmMetadata)meta.DeepClone(); clone.ColorType = PbmColorType.Rgb; clone.ComponentType = PbmComponentType.Short; @@ -33,9 +34,9 @@ public class PbmMetadataTests [InlineData(RgbPlain, PbmEncoding.Plain)] public void Identify_DetectsCorrectEncoding(string imagePath, PbmEncoding expectedEncoding) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); PbmMetadata bitmapMetadata = imageInfo.Metadata.GetPbmMetadata(); Assert.NotNull(bitmapMetadata); @@ -52,9 +53,9 @@ public class PbmMetadataTests [InlineData(RgbPlain, PbmColorType.Rgb)] public void Identify_DetectsCorrectColorType(string imagePath, PbmColorType expectedColorType) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); PbmMetadata bitmapMetadata = imageInfo.Metadata.GetPbmMetadata(); Assert.NotNull(bitmapMetadata); @@ -71,9 +72,9 @@ public class PbmMetadataTests [InlineData(RgbPlain, PbmComponentType.Byte)] public void Identify_DetectsCorrectComponentType(string imagePath, PbmComponentType expectedComponentType) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); PbmMetadata bitmapMetadata = imageInfo.Metadata.GetPbmMetadata(); Assert.NotNull(bitmapMetadata); diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index ea958df37..85849cdff 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -82,7 +82,7 @@ public partial class PngDecoderTests public void Decode_NonGeneric_CreatesCorrectImageType(string path, Type type) { string file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, path); - using var image = Image.Load(file); + using Image image = Image.Load(file); Assert.IsType(type, image); } @@ -304,9 +304,13 @@ public partial class PngDecoderTests [InlineData(TestImages.Png.Rgb48BppInterlaced, 48)] public void Identify(string imagePath, int expectedPixelSize) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + + Image.TryIdentify(stream, out ImageInfo imageInfo); + + Assert.NotNull(imageInfo); + Assert.Equal(expectedPixelSize, imageInfo.PixelType.BitsPerPixel); } [Theory] @@ -502,9 +506,9 @@ public partial class PngDecoderTests [InlineData(TestImages.Png.Issue2209IndexedWithTransparency)] public void Issue2209_Identify_HasTransparencyIsTrue(string imagePath) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); PngMetadata metadata = imageInfo.Metadata.GetPngMetadata(); Assert.True(metadata.HasTransparency); } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs index 03de88a24..351b44ee0 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs @@ -23,7 +23,7 @@ public class PngMetadataTests [Fact] public void CloneIsDeep() { - var meta = new PngMetadata + PngMetadata meta = new() { BitDepth = PngBitDepth.Bit16, ColorType = PngColorType.GrayscaleWithAlpha, @@ -32,7 +32,7 @@ public class PngMetadataTests TextData = new List { new PngTextData("name", "value", "foo", "bar") } }; - var clone = (PngMetadata)meta.DeepClone(); + PngMetadata clone = (PngMetadata)meta.DeepClone(); clone.BitDepth = PngBitDepth.Bit2; clone.ColorType = PngColorType.Palette; @@ -63,7 +63,7 @@ public class PngMetadataTests where TPixel : unmanaged, IPixel { using Image input = provider.GetImage(PngDecoder.Instance); - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); input.Save(memoryStream, new PngEncoder()); memoryStream.Position = 0; @@ -93,13 +93,13 @@ public class PngMetadataTests where TPixel : unmanaged, IPixel { using Image input = provider.GetImage(PngDecoder.Instance); - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); // This will be a zTXt chunk. - var expectedText = new PngTextData("large-text", new string('c', 100), string.Empty, string.Empty); + PngTextData expectedText = new("large-text", new string('c', 100), string.Empty, string.Empty); // This will be a iTXt chunk. - var expectedTextNoneLatin = new PngTextData("large-text-non-latin", new string('Ф', 100), "language-tag", "translated-keyword"); + PngTextData expectedTextNoneLatin = new("large-text-non-latin", new string('Ф', 100), "language-tag", "translated-keyword"); PngMetadata inputMetadata = input.Metadata.GetFormatMetadata(PngFormat.Instance); inputMetadata.TextData.Add(expectedText); inputMetadata.TextData.Add(expectedTextNoneLatin); @@ -153,7 +153,7 @@ public class PngMetadataTests SkipMetadata = false }; - var testFile = TestFile.Create(TestImages.Png.Blur); + TestFile testFile = TestFile.Create(TestImages.Png.Blur); using Image image = testFile.CreateRgba32Image(PngDecoder.Instance, options); PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance); @@ -172,7 +172,7 @@ public class PngMetadataTests SkipMetadata = true }; - var testFile = TestFile.Create(TestImages.Png.PngWithMetadata); + TestFile testFile = TestFile.Create(TestImages.Png.PngWithMetadata); using Image image = testFile.CreateRgba32Image(PngDecoder.Instance, options); PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance); @@ -183,8 +183,8 @@ public class PngMetadataTests [MemberData(nameof(RatioFiles))] public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); using Image image = PngDecoder.Instance.Decode(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); @@ -201,11 +201,11 @@ public class PngMetadataTests ImageSharp.Metadata.Profiles.Icc.IccProfile expectedProfile = input.Metadata.IccProfile; byte[] expectedProfileBytes = expectedProfile.ToByteArray(); - using var memStream = new MemoryStream(); + using MemoryStream memStream = new(); input.Save(memStream, new PngEncoder()); memStream.Position = 0; - using var output = Image.Load(memStream); + using Image output = Image.Load(memStream); ImageSharp.Metadata.Profiles.Icc.IccProfile actualProfile = output.Metadata.IccProfile; byte[] actualProfileBytes = actualProfile.ToByteArray(); @@ -217,8 +217,8 @@ public class PngMetadataTests [MemberData(nameof(RatioFiles))] public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); ImageInfo image = PngDecoder.Instance.Identify(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); @@ -230,9 +230,9 @@ public class PngMetadataTests [InlineData(TestImages.Png.PngWithMetadata)] public void Identify_ReadsTextData(string imagePath) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); PngMetadata meta = imageInfo.Metadata.GetFormatMetadata(PngFormat.Instance); VerifyTextDataIsPresent(meta); @@ -242,9 +242,9 @@ public class PngMetadataTests [InlineData(TestImages.Png.PngWithMetadata)] public void Identify_ReadsExifData(string imagePath) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); Assert.NotNull(imageInfo.Metadata.ExifProfile); ExifProfile exif = imageInfo.Metadata.ExifProfile; @@ -279,9 +279,9 @@ public class PngMetadataTests [InlineData(TestImages.Png.Issue1875)] public void Identify_ReadsLegacyExifData(string imagePath) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); Assert.NotNull(imageInfo.Metadata.ExifProfile); diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs index d34c051f8..5910a86ac 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs @@ -22,7 +22,7 @@ public class TgaFileHeaderTests [InlineData(new byte[] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 32, 8 })] // invalid height public void ImageLoad_WithNoValidTgaHeaderBytes_Throws_UnknownImageFormatException(byte[] data) { - using var stream = new MemoryStream(data); + using MemoryStream stream = new(data); Assert.Throws(() => { @@ -39,9 +39,9 @@ public class TgaFileHeaderTests [InlineData(new byte[] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 124, 0, 24, 32 }, 124, 124, TgaBitsPerPixel.Pixel24)] public void Identify_WithValidData_Works(byte[] data, int width, int height, TgaBitsPerPixel bitsPerPixel) { - using var stream = new MemoryStream(data); + using MemoryStream stream = new(data); - ImageInfo info = Image.Identify(stream); + Image.TryIdentify(stream, out ImageInfo info); TgaMetadata tgaData = info.Metadata.GetTgaMetadata(); Assert.Equal(bitsPerPixel, tgaData.BitsPerPixel); Assert.Equal(width, info.Width); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs index bc8fe35a4..de7e74720 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs @@ -60,23 +60,21 @@ public class BigTiffDecoderTests : TiffDecoderBaseTester [InlineData(MinIsBlack, 1, 32, 32, 96, 96, PixelResolutionUnit.PixelsPerInch)] public void Identify(string imagePath, int expectedPixelSize, int expectedWidth, int expectedHeight, double expectedHResolution, double expectedVResolution, PixelResolutionUnit expectedResolutionUnit) { - var testFile = TestFile.Create(imagePath); - using (var stream = new MemoryStream(testFile.Bytes, false)) - { - ImageInfo info = Image.Identify(stream); - - Assert.Equal(expectedPixelSize, info.PixelType?.BitsPerPixel); - Assert.Equal(expectedWidth, info.Width); - Assert.Equal(expectedHeight, info.Height); - Assert.NotNull(info.Metadata); - Assert.Equal(expectedHResolution, info.Metadata.HorizontalResolution); - Assert.Equal(expectedVResolution, info.Metadata.VerticalResolution); - Assert.Equal(expectedResolutionUnit, info.Metadata.ResolutionUnits); - - TiffMetadata tiffmeta = info.Metadata.GetTiffMetadata(); - Assert.NotNull(tiffmeta); - Assert.Equal(TiffFormatType.BigTIFF, tiffmeta.FormatType); - } + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo info); + + Assert.Equal(expectedPixelSize, info.PixelType?.BitsPerPixel); + Assert.Equal(expectedWidth, info.Width); + Assert.Equal(expectedHeight, info.Height); + Assert.NotNull(info.Metadata); + Assert.Equal(expectedHResolution, info.Metadata.HorizontalResolution); + Assert.Equal(expectedVResolution, info.Metadata.VerticalResolution); + Assert.Equal(expectedResolutionUnit, info.Metadata.ResolutionUnits); + + TiffMetadata tiffmeta = info.Metadata.GetTiffMetadata(); + Assert.NotNull(tiffmeta); + Assert.Equal(TiffFormatType.BigTIFF, tiffmeta.FormatType); } [Theory] @@ -84,19 +82,17 @@ public class BigTiffDecoderTests : TiffDecoderBaseTester [InlineData(BigTIFFMotorola, ImageSharp.ByteOrder.BigEndian)] public void ByteOrder(string imagePath, ByteOrder expectedByteOrder) { - var testFile = TestFile.Create(imagePath); - using (var stream = new MemoryStream(testFile.Bytes, false)) - { - ImageInfo info = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo info); - Assert.NotNull(info.Metadata); - Assert.Equal(expectedByteOrder, info.Metadata.GetTiffMetadata().ByteOrder); + Assert.NotNull(info.Metadata); + Assert.Equal(expectedByteOrder, info.Metadata.GetTiffMetadata().ByteOrder); - stream.Seek(0, SeekOrigin.Begin); + stream.Seek(0, SeekOrigin.Begin); - using var img = Image.Load(stream); - Assert.Equal(expectedByteOrder, img.Metadata.GetTiffMetadata().ByteOrder); - } + using Image img = Image.Load(stream); + Assert.Equal(expectedByteOrder, img.Metadata.GetTiffMetadata().ByteOrder); } [Theory] diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs index 60bc44ded..26f006b34 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs @@ -30,19 +30,17 @@ public class TiffDecoderTests : TiffDecoderBaseTester [InlineData(Flower4BitPalette, 4, 73, 43, 72, 72, PixelResolutionUnit.PixelsPerInch)] public void Identify(string imagePath, int expectedPixelSize, int expectedWidth, int expectedHeight, double expectedHResolution, double expectedVResolution, PixelResolutionUnit expectedResolutionUnit) { - var testFile = TestFile.Create(imagePath); - using (var stream = new MemoryStream(testFile.Bytes, false)) - { - ImageInfo info = Image.Identify(stream); - - Assert.Equal(expectedPixelSize, info.PixelType?.BitsPerPixel); - Assert.Equal(expectedWidth, info.Width); - Assert.Equal(expectedHeight, info.Height); - Assert.NotNull(info.Metadata); - Assert.Equal(expectedHResolution, info.Metadata.HorizontalResolution); - Assert.Equal(expectedVResolution, info.Metadata.VerticalResolution); - Assert.Equal(expectedResolutionUnit, info.Metadata.ResolutionUnits); - } + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo info); + + Assert.Equal(expectedPixelSize, info.PixelType?.BitsPerPixel); + Assert.Equal(expectedWidth, info.Width); + Assert.Equal(expectedHeight, info.Height); + Assert.NotNull(info.Metadata); + Assert.Equal(expectedHResolution, info.Metadata.HorizontalResolution); + Assert.Equal(expectedVResolution, info.Metadata.VerticalResolution); + Assert.Equal(expectedResolutionUnit, info.Metadata.ResolutionUnits); } [Theory] @@ -51,18 +49,16 @@ public class TiffDecoderTests : TiffDecoderBaseTester public void ByteOrder(string imagePath, ByteOrder expectedByteOrder) { TestFile testFile = TestFile.Create(imagePath); - using (var stream = new MemoryStream(testFile.Bytes, false)) - { - ImageInfo info = Image.Identify(stream); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo info); - Assert.NotNull(info.Metadata); - Assert.Equal(expectedByteOrder, info.Metadata.GetTiffMetadata().ByteOrder); + Assert.NotNull(info.Metadata); + Assert.Equal(expectedByteOrder, info.Metadata.GetTiffMetadata().ByteOrder); - stream.Seek(0, SeekOrigin.Begin); + stream.Seek(0, SeekOrigin.Begin); - using Image img = Image.Load(stream); - Assert.Equal(expectedByteOrder, img.Metadata.GetTiffMetadata().ByteOrder); - } + using Image img = Image.Load(stream); + Assert.Equal(expectedByteOrder, img.Metadata.GetTiffMetadata().ByteOrder); } [Theory] diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs index 6cf1bbc36..4d5f66503 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs @@ -27,12 +27,12 @@ public class TiffMetadataTests [Fact] public void TiffMetadata_CloneIsDeep() { - var meta = new TiffMetadata + TiffMetadata meta = new() { ByteOrder = ByteOrder.BigEndian, }; - var clone = (TiffMetadata)meta.DeepClone(); + TiffMetadata clone = (TiffMetadata)meta.DeepClone(); clone.ByteOrder = ByteOrder.LittleEndian; @@ -46,10 +46,10 @@ public class TiffMetadataTests { using Image image = provider.GetImage(TiffDecoder.Instance); TiffFrameMetadata meta = image.Frames.RootFrame.Metadata.GetTiffMetadata(); - var cloneSameAsSampleMetaData = (TiffFrameMetadata)meta.DeepClone(); + TiffFrameMetadata cloneSameAsSampleMetaData = (TiffFrameMetadata)meta.DeepClone(); VerifyExpectedTiffFrameMetaDataIsPresent(cloneSameAsSampleMetaData); - var clone = (TiffFrameMetadata)meta.DeepClone(); + TiffFrameMetadata clone = (TiffFrameMetadata)meta.DeepClone(); clone.BitsPerPixel = TiffBitsPerPixel.Bit8; clone.Compression = TiffCompression.None; @@ -77,10 +77,10 @@ public class TiffMetadataTests [InlineData(RgbUncompressed, 24)] public void Identify_DetectsCorrectBitPerPixel(string imagePath, int expectedBitsPerPixel) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata(); @@ -93,10 +93,10 @@ public class TiffMetadataTests [InlineData(LittleEndianByteOrder, ByteOrder.LittleEndian)] public void Identify_DetectsCorrectByteOrder(string imagePath, ByteOrder expectedByteOrder) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata(); @@ -173,7 +173,7 @@ public class TiffMetadataTests Assert.Equal("Copyright", exifProfile.GetValue(ExifTag.Copyright).Value); Assert.Equal(4, exifProfile.GetValue(ExifTag.Rating).Value); Assert.Equal(75, exifProfile.GetValue(ExifTag.RatingPercent).Value); - var expectedResolution = new Rational(10, 1, simplify: false); + Rational expectedResolution = new(10, 1, simplify: false); Assert.Equal(expectedResolution, exifProfile.GetValue(ExifTag.XResolution).Value); Assert.Equal(expectedResolution, exifProfile.GetValue(ExifTag.YResolution).Value); Assert.Equal(new Number[] { 8u }, exifProfile.GetValue(ExifTag.StripOffsets)?.Value, new NumberComparer()); @@ -242,13 +242,13 @@ public class TiffMetadataTests Assert.Equal(TiffBitsPerPixel.Bit4, frameMetaInput.BitsPerPixel); // Save to Tiff - var tiffEncoder = new TiffEncoder() { PhotometricInterpretation = TiffPhotometricInterpretation.Rgb }; - using var ms = new MemoryStream(); + TiffEncoder tiffEncoder = new() { PhotometricInterpretation = TiffPhotometricInterpretation.Rgb }; + using MemoryStream ms = new(); image.Save(ms, tiffEncoder); // Assert ms.Position = 0; - using var encodedImage = Image.Load(ms); + using Image encodedImage = Image.Load(ms); ImageMetadata encodedImageMetaData = encodedImage.Metadata; ImageFrame rootFrameEncodedImage = encodedImage.Frames.RootFrame; diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs index 150c67d4f..4d5d2aefd 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs @@ -39,9 +39,9 @@ public class WebpDecoderTests int expectedHeight, int expectedBitsPerPixel) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); - ImageInfo imageInfo = Image.Identify(stream); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); + Image.TryIdentify(stream, out ImageInfo imageInfo); Assert.NotNull(imageInfo); Assert.Equal(expectedWidth, imageInfo.Width); Assert.Equal(expectedHeight, imageInfo.Height); @@ -419,7 +419,7 @@ public class WebpDecoderTests private static void RunDecodeLossyWithHorizontalFilter() { - var provider = TestImageProvider.File(TestImageLossyHorizontalFilterPath); + TestImageProvider provider = TestImageProvider.File(TestImageLossyHorizontalFilterPath); using Image image = provider.GetImage(WebpDecoder.Instance); image.DebugSave(provider); image.CompareToOriginal(provider, ReferenceDecoder); @@ -427,7 +427,7 @@ public class WebpDecoderTests private static void RunDecodeLossyWithVerticalFilter() { - var provider = TestImageProvider.File(TestImageLossyVerticalFilterPath); + TestImageProvider provider = TestImageProvider.File(TestImageLossyVerticalFilterPath); using Image image = provider.GetImage(WebpDecoder.Instance); image.DebugSave(provider); image.CompareToOriginal(provider, ReferenceDecoder); @@ -435,7 +435,7 @@ public class WebpDecoderTests private static void RunDecodeLossyWithSimpleFilterTest() { - var provider = TestImageProvider.File(TestImageLossySimpleFilterPath); + TestImageProvider provider = TestImageProvider.File(TestImageLossySimpleFilterPath); using Image image = provider.GetImage(WebpDecoder.Instance); image.DebugSave(provider); image.CompareToOriginal(provider, ReferenceDecoder); @@ -443,7 +443,7 @@ public class WebpDecoderTests private static void RunDecodeLossyWithComplexFilterTest() { - var provider = TestImageProvider.File(TestImageLossyComplexFilterPath); + TestImageProvider provider = TestImageProvider.File(TestImageLossyComplexFilterPath); using Image image = provider.GetImage(WebpDecoder.Instance); image.DebugSave(provider); image.CompareToOriginal(provider, ReferenceDecoder); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs index d8d9f4fe2..d4a77d2c1 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs @@ -34,7 +34,7 @@ public partial class ImageTests { using FileStream fs = File.OpenRead(TestFile.GetInputFileFullPath(file)); CancellationToken preCancelled = new(canceled: true); - await Assert.ThrowsAnyAsync(async () => await Image.IdentifyAsync(fs, preCancelled)); + await Assert.ThrowsAnyAsync(async () => await Image.TryIdentifyAsync(fs, preCancelled)); } private static TheoryData CreateLoadData() diff --git a/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs index 86ceed73b..5a5f595ac 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs @@ -16,9 +16,9 @@ public partial class ImageTests { private static readonly string ActualImagePath = TestFile.GetInputFileFullPath(TestImages.Bmp.F); - private byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes; + private static byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes; - private ReadOnlySpan ActualImageSpan => this.ActualImageBytes.AsSpan(); + private static ReadOnlySpan ActualImageSpan => ActualImageBytes.AsSpan(); private IImageFormat LocalImageFormat => this.localImageFormatMock.Object; @@ -34,7 +34,7 @@ public partial class ImageTests [Fact] public void FromBytes_GlobalConfiguration() { - bool result = Image.TryDetectFormat(this.ActualImageSpan, out IImageFormat type); + bool result = Image.TryDetectFormat(ActualImageSpan, out IImageFormat type); Assert.True(result); Assert.Equal(ExpectedGlobalFormat, type); @@ -63,6 +63,15 @@ public partial class ImageTests Assert.Equal(ExpectedGlobalFormat, type); } + [Fact] + public async Task FromFileSystemPathAsync_GlobalConfiguration() + { + Attempt attempt = await Image.TryDetectFormatAsync(ActualImagePath); + + Assert.True(attempt.Success); + Assert.Equal(ExpectedGlobalFormat, attempt.Value); + } + [Fact] public void FromFileSystemPath_CustomConfiguration() { @@ -78,15 +87,27 @@ public partial class ImageTests } [Fact] - public void FromStream_GlobalConfiguration() + public async Task FromFileSystemPathAsync_CustomConfiguration() { - using (var stream = new MemoryStream(this.ActualImageBytes)) + DecoderOptions options = new() { - bool result = Image.TryDetectFormat(stream, out IImageFormat type); + Configuration = this.LocalConfiguration + }; - Assert.True(result); - Assert.Equal(ExpectedGlobalFormat, type); - } + Attempt attempt = await Image.TryDetectFormatAsync(options, this.MockFilePath); + + Assert.True(attempt.Success); + Assert.Equal(this.LocalImageFormat, attempt.Value); + } + + [Fact] + public void FromStream_GlobalConfiguration() + { + using MemoryStream stream = new(ActualImageBytes); + bool result = Image.TryDetectFormat(stream, out IImageFormat type); + + Assert.True(result); + Assert.Equal(ExpectedGlobalFormat, type); } [Fact] @@ -120,11 +141,9 @@ public partial class ImageTests [Fact] public async Task FromStreamAsync_GlobalConfiguration() { - using (var stream = new MemoryStream(this.ActualImageBytes)) - { - IImageFormat type = await Image.DetectFormatAsync(new AsyncStreamWrapper(stream, () => false)); - Assert.Equal(ExpectedGlobalFormat, type); - } + using MemoryStream stream = new(ActualImageBytes); + Attempt attempt = await Image.TryDetectFormatAsync(new AsyncStreamWrapper(stream, () => false)); + Assert.Equal(ExpectedGlobalFormat, attempt.Value); } [Fact] @@ -135,8 +154,8 @@ public partial class ImageTests Configuration = this.LocalConfiguration }; - IImageFormat type = await Image.DetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false)); - Assert.Equal(this.LocalImageFormat, type); + Attempt attempt = await Image.TryDetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false)); + Assert.Equal(this.LocalImageFormat, attempt.Value); } [Fact] @@ -147,8 +166,8 @@ public partial class ImageTests Configuration = new() }; - IImageFormat type = await Image.DetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false)); - Assert.Null(type); + Attempt attempt = await Image.TryDetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false)); + Assert.Null(attempt.Value); } } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs index 83aeed5bd..e9b61232a 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs @@ -27,7 +27,7 @@ public partial class ImageTests { get { - Configuration.Default.ImageFormatsManager.TryFindFormatByFileExtension("bmp", out var format); + Configuration.Default.ImageFormatsManager.TryFindFormatByFileExtension("bmp", out IImageFormat format); return format!; } } @@ -35,30 +35,27 @@ public partial class ImageTests [Fact] public void FromBytes_GlobalConfiguration() { - ImageInfo info = Image.Identify(ActualImageBytes, out IImageFormat type); - + Image.TryIdentify(ActualImageBytes, out ImageInfo info); Assert.Equal(ExpectedImageSize, info.Size()); - Assert.Equal(ExpectedGlobalFormat, type); + Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } [Fact] public void FromBytes_CustomConfiguration() { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - - ImageInfo info = Image.Identify(options, this.ByteArray, out IImageFormat type); + Image.TryIdentify(options, this.ByteArray, out ImageInfo info); Assert.Equal(this.LocalImageInfo, info); - Assert.Equal(this.LocalImageFormat, type); } [Fact] public void FromFileSystemPath_GlobalConfiguration() { - ImageInfo info = Image.TryIdentify(ActualImagePath, out IImageFormat type); + Image.TryIdentify(ActualImagePath, out ImageInfo info); Assert.NotNull(info); - Assert.Equal(ExpectedGlobalFormat, type); + Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } [Fact] @@ -66,27 +63,26 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - ImageInfo info = Image.Identify(options, this.MockFilePath, out IImageFormat type); + Image.TryIdentify(options, this.MockFilePath, out ImageInfo info); Assert.Equal(this.LocalImageInfo, info); - Assert.Equal(this.LocalImageFormat, type); } [Fact] public void FromStream_GlobalConfiguration() { - using var stream = new MemoryStream(ActualImageBytes); - ImageInfo info = Image.Identify(stream, out IImageFormat type); + using MemoryStream stream = new(ActualImageBytes); + Image.TryIdentify(stream, out ImageInfo info); Assert.NotNull(info); - Assert.Equal(ExpectedGlobalFormat, type); + Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } [Fact] public void FromStream_GlobalConfiguration_NoFormat() { - using var stream = new MemoryStream(ActualImageBytes); - ImageInfo info = Image.Identify(stream); + using MemoryStream stream = new(ActualImageBytes); + Image.TryIdentify(stream, out ImageInfo info); Assert.NotNull(info); } @@ -94,22 +90,22 @@ public partial class ImageTests [Fact] public void FromNonSeekableStream_GlobalConfiguration() { - using var stream = new MemoryStream(ActualImageBytes); - using var nonSeekableStream = new NonSeekableStream(stream); + using MemoryStream stream = new(ActualImageBytes); + using NonSeekableStream nonSeekableStream = new(stream); - ImageInfo info = Image.Identify(nonSeekableStream, out IImageFormat type); + Image.TryIdentify(nonSeekableStream, out ImageInfo info); Assert.NotNull(info); - Assert.Equal(ExpectedGlobalFormat, type); + Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } [Fact] public void FromNonSeekableStream_GlobalConfiguration_NoFormat() { - using var stream = new MemoryStream(ActualImageBytes); - using var nonSeekableStream = new NonSeekableStream(stream); + using MemoryStream stream = new(ActualImageBytes); + using NonSeekableStream nonSeekableStream = new(stream); - ImageInfo info = Image.Identify(nonSeekableStream); + Image.TryIdentify(nonSeekableStream, out ImageInfo info); Assert.NotNull(info); } @@ -119,10 +115,9 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - ImageInfo info = Image.Identify(options, this.DataStream, out IImageFormat type); + Image.TryIdentify(options, this.DataStream, out ImageInfo info); Assert.Equal(this.LocalImageInfo, info); - Assert.Equal(this.LocalImageFormat, type); } [Fact] @@ -130,7 +125,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - ImageInfo info = Image.TryIdentify(options, this.DataStream); + Image.TryIdentify(options, this.DataStream, out ImageInfo info); Assert.Equal(this.LocalImageInfo, info); } @@ -140,17 +135,15 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = new() }; - ImageInfo info = Image.Identify(options, this.DataStream, out IImageFormat type); - + Assert.False(Image.TryIdentify(options, this.DataStream, out ImageInfo info)); Assert.Null(info); - Assert.Null(type); } [Fact] public void FromStream_ZeroLength_ReturnsNull() { // https://github.com/SixLabors/ImageSharp/issues/1903 - using var zipFile = new ZipArchive(new MemoryStream( + using ZipArchive zipFile = new(new MemoryStream( new byte[] { 0x50, 0x4B, 0x03, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xAF, 0x94, 0x53, 0x00, 0x00, @@ -165,61 +158,67 @@ public partial class ImageTests 0x00, 0x00, 0x00, 0x00 })); using Stream stream = zipFile.Entries[0].Open(); - ImageInfo info = Image.Identify(stream); + + Assert.False(Image.TryIdentify(stream, out ImageInfo info)); Assert.Null(info); } [Fact] public async Task FromStreamAsync_GlobalConfiguration_NoFormat() { - using var stream = new MemoryStream(ActualImageBytes); - var asyncStream = new AsyncStreamWrapper(stream, () => false); - ImageInfo info = await Image.IdentifyAsync(asyncStream); + using MemoryStream stream = new(ActualImageBytes); + AsyncStreamWrapper asyncStream = new(stream, () => false); - Assert.NotNull(info); + Attempt attempt = await Image.TryIdentifyAsync(asyncStream); + + Assert.True(attempt.Success); + Assert.NotNull(attempt.Value); } [Fact] public async Task FromStreamAsync_GlobalConfiguration() { - using var stream = new MemoryStream(ActualImageBytes); - var asyncStream = new AsyncStreamWrapper(stream, () => false); - (ImageInfo ImageInfo, IImageFormat Format) res = await Image.TryIdentifyAsync(asyncStream); + using MemoryStream stream = new(ActualImageBytes); + AsyncStreamWrapper asyncStream = new(stream, () => false); + Attempt attempt = await Image.TryIdentifyAsync(asyncStream); - Assert.Equal(ExpectedImageSize, res.ImageInfo.Size()); - Assert.Equal(ExpectedGlobalFormat, res.Format); + Assert.True(attempt.Success); + Assert.Equal(ExpectedImageSize, attempt.Value.Size()); + Assert.Equal(ExpectedGlobalFormat, attempt.Value.Metadata.DecodedImageFormat); } [Fact] public async Task FromNonSeekableStreamAsync_GlobalConfiguration_NoFormat() { - using var stream = new MemoryStream(ActualImageBytes); - using var nonSeekableStream = new NonSeekableStream(stream); + using MemoryStream stream = new(ActualImageBytes); + using NonSeekableStream nonSeekableStream = new(stream); - var asyncStream = new AsyncStreamWrapper(nonSeekableStream, () => false); - ImageInfo info = await Image.IdentifyAsync(asyncStream); + AsyncStreamWrapper asyncStream = new(nonSeekableStream, () => false); + Attempt attempt = await Image.TryIdentifyAsync(asyncStream); - Assert.NotNull(info); + Assert.True(attempt.Success); + Assert.NotNull(attempt.Value); } [Fact] public async Task FromNonSeekableStreamAsync_GlobalConfiguration() { - using var stream = new MemoryStream(ActualImageBytes); - using var nonSeekableStream = new NonSeekableStream(stream); + using MemoryStream stream = new(ActualImageBytes); + using NonSeekableStream nonSeekableStream = new(stream); - var asyncStream = new AsyncStreamWrapper(nonSeekableStream, () => false); - (ImageInfo ImageInfo, IImageFormat Format) res = await Image.TryIdentifyAsync(asyncStream); + AsyncStreamWrapper asyncStream = new(nonSeekableStream, () => false); + Attempt attempt = await Image.TryIdentifyAsync(asyncStream); - Assert.Equal(ExpectedImageSize, res.ImageInfo.Size()); - Assert.Equal(ExpectedGlobalFormat, res.Format); + Assert.True(attempt.Success); + Assert.Equal(ExpectedImageSize, attempt.Value.Size()); + Assert.Equal(ExpectedGlobalFormat, attempt.Value.Metadata.DecodedImageFormat); } [Fact] public async Task FromStreamAsync_ZeroLength_ReturnsNull() { // https://github.com/SixLabors/ImageSharp/issues/1903 - using var zipFile = new ZipArchive(new MemoryStream( + using ZipArchive zipFile = new(new MemoryStream( new byte[] { 0x50, 0x4B, 0x03, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xAF, 0x94, 0x53, 0x00, 0x00, @@ -234,8 +233,11 @@ public partial class ImageTests 0x00, 0x00, 0x00, 0x00 })); using Stream stream = zipFile.Entries[0].Open(); - ImageInfo info = await Image.IdentifyAsync(stream); - Assert.Null(info); + + Attempt attempt = await Image.TryIdentifyAsync(stream); + + Assert.False(attempt.Success); + Assert.Null(attempt.Value); } [Fact] @@ -243,8 +245,10 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - ImageInfo info = await Image.IdentifyAsync(options, this.MockFilePath); - Assert.Equal(this.LocalImageInfo, info); + Attempt attempt = await Image.TryIdentifyAsync(options, this.MockFilePath); + + Assert.True(attempt.Success); + Assert.Equal(this.LocalImageInfo, attempt.Value); } [Fact] @@ -252,27 +256,28 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - (ImageInfo ImageInfo, IImageFormat Format) info = - await Image.TryIdentifyAsync(options, this.MockFilePath); - Assert.NotNull(info.ImageInfo); - Assert.Equal(this.LocalImageFormat, info.Format); + Attempt attempt = await Image.TryIdentifyAsync(options, this.MockFilePath); + + Assert.True(attempt.Success); + Assert.NotNull(attempt.Value); } [Fact] public async Task IdentifyWithFormatAsync_FromPath_GlobalConfiguration() { - (ImageInfo ImageInfo, IImageFormat Format) res = await Image.TryIdentifyAsync(ActualImagePath); + Attempt attempt = await Image.TryIdentifyAsync(ActualImagePath); - Assert.Equal(ExpectedImageSize, res.ImageInfo.Size()); - Assert.Equal(ExpectedGlobalFormat, res.Format); + Assert.Equal(ExpectedImageSize, attempt.Value.Size()); + Assert.Equal(ExpectedGlobalFormat, attempt.Value.Metadata.DecodedImageFormat); } [Fact] public async Task FromPathAsync_GlobalConfiguration() { - ImageInfo info = await Image.IdentifyAsync(ActualImagePath); + Attempt attempt = await Image.TryIdentifyAsync(ActualImagePath); - Assert.Equal(ExpectedImageSize, info.Size()); + Assert.True(attempt.Success); + Assert.Equal(ExpectedImageSize, attempt.Value.Size()); } [Fact] @@ -280,12 +285,11 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - var asyncStream = new AsyncStreamWrapper(this.DataStream, () => false); - (ImageInfo ImageInfo, IImageFormat Format) - info = await Image.TryIdentifyAsync(options, asyncStream); + AsyncStreamWrapper asyncStream = new(this.DataStream, () => false); + Attempt attempt = await Image.TryIdentifyAsync(options, asyncStream); - Assert.Equal(this.LocalImageInfo, info.ImageInfo); - Assert.Equal(this.LocalImageFormat, info.Format); + Assert.True(attempt.Success); + Assert.Equal(this.LocalImageInfo, attempt.Value); } [Fact] @@ -293,11 +297,11 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = new() }; - var asyncStream = new AsyncStreamWrapper(this.DataStream, () => false); - (ImageInfo ImageInfo, IImageFormat Format) - info = await Image.TryIdentifyAsync(options, asyncStream); + AsyncStreamWrapper asyncStream = new(this.DataStream, () => false); + Attempt attempt = await Image.TryIdentifyAsync(options, asyncStream); - Assert.Null(info.ImageInfo); + Assert.False(attempt.Success); + Assert.Null(attempt.Value); } } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs index 235ea2d92..4d3e4128f 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs @@ -51,18 +51,22 @@ public partial class ImageTests protected byte[] ByteArray => ((MemoryStream)this.DataStream).ToArray(); - protected ImageInfo LocalImageInfo => new( - this.localImageInfoMock.Object.PixelType, - this.localImageInfoMock.Object.Width, - this.localImageInfoMock.Object.Height, - this.localImageInfoMock.Object.Metadata); + protected ImageInfo LocalImageInfo { get; } protected ImageLoadTestBase() { + // TODO: Remove all this mocking. It's too complicated and we can now use fakes. this.localStreamReturnImageRgba32 = new Image(1, 1); this.localStreamReturnImageAgnostic = new Image(1, 1); this.localImageInfoMock = new Mock(); + + this.LocalImageInfo = new( + this.localImageInfoMock.Object.PixelType, + this.localImageInfoMock.Object.Width, + this.localImageInfoMock.Object.Height, + this.localImageInfoMock.Object.Metadata); + this.localImageFormatMock = new Mock(); this.localDecoder = new Mock(); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs b/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs index b62f3ebd8..3239c57b1 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs @@ -294,7 +294,6 @@ public partial class ImageTests } } - [Fact] public unsafe void WrapMemory_Throws_OnTooLessWrongSize() { @@ -307,7 +306,7 @@ public partial class ImageTests { try { - using (var image = Image.WrapMemory(cfg, ptr, 24, 5, 5, metaData)); + using var image = Image.WrapMemory(cfg, ptr, 24, 5, 5, metaData); } catch (Exception e) { diff --git a/tests/ImageSharp.Tests/Image/MockImageFormatDetector.cs b/tests/ImageSharp.Tests/Image/MockImageFormatDetector.cs index 8564eaa5b..b372adaaf 100644 --- a/tests/ImageSharp.Tests/Image/MockImageFormatDetector.cs +++ b/tests/ImageSharp.Tests/Image/MockImageFormatDetector.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System.Diagnostics.CodeAnalysis; @@ -11,12 +11,10 @@ namespace SixLabors.ImageSharp.Tests; /// public class MockImageFormatDetector : IImageFormatDetector { - private IImageFormat localImageFormatMock; + private readonly IImageFormat localImageFormatMock; public MockImageFormatDetector(IImageFormat imageFormat) - { - this.localImageFormatMock = imageFormat; - } + => this.localImageFormatMock = imageFormat; public int HeaderSize => 1; From f4217013331df5a9fed27cd0a2f6dd7a81896e09 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 14 Jan 2023 17:16:28 +1000 Subject: [PATCH 09/16] Refactor Load APIs --- .../Advanced/AdvancedImageExtensions.cs | 18 +- src/ImageSharp/Formats/ImageDecoder.cs | 17 +- .../Formats/ImageExtensions.Save.cs | 64 +-- src/ImageSharp/Formats/ImageFormatManager.cs | 51 ++- src/ImageSharp/Image.Decode.cs | 91 ++-- src/ImageSharp/Image.FromBytes.cs | 166 +++---- src/ImageSharp/Image.FromFile.cs | 255 ++++------- src/ImageSharp/Image.FromStream.cs | 291 +++---------- src/ImageSharp/Image.LoadPixelData.cs | 2 +- src/ImageSharp/ImageExtensions.cs | 4 +- .../Formats/Bmp/ImageExtensionsTest.cs | 72 ++- .../Formats/GeneralFormatTests.cs | 9 +- .../Formats/Gif/ImageExtensionsTest.cs | 72 ++- .../Formats/ImageFormatManagerTests.cs | 8 +- .../Formats/Jpg/ImageExtensionsTest.cs | 72 ++- .../Formats/Jpg/JpegDecoderTests.Metadata.cs | 42 +- .../Formats/Jpg/JpegDecoderTests.cs | 10 +- .../Formats/Pbm/ImageExtensionsTest.cs | 72 ++- .../Formats/Png/ImageExtensionsTest.cs | 72 ++- .../Formats/Tga/ImageExtensionsTest.cs | 72 ++- .../Formats/Tga/TgaFileHeaderTests.cs | 2 +- .../Formats/Tiff/ImageExtensionsTest.cs | 72 ++- .../Formats/WebP/ImageExtensionsTests.cs | 72 ++- .../Image/ImageTests.DetectFormat.cs | 12 +- .../Image/ImageTests.Identify.cs | 26 +- ...d_FileSystemPath_PassLocalConfiguration.cs | 38 +- ..._FileSystemPath_UseDefaultConfiguration.cs | 13 +- ...s.Load_FromBytes_PassLocalConfiguration.cs | 36 +- ...s.Load_FromBytes_UseGlobalConfiguration.cs | 13 +- ....Load_FromStream_PassLocalConfiguration.cs | 54 ++- ...ts.Load_FromStream_ThrowsRightException.cs | 4 +- ...Load_FromStream_UseDefaultConfiguration.cs | 29 +- .../ImageSharp.Tests/Image/ImageTests.Save.cs | 34 +- .../Image/ImageTests.SaveAsync.cs | 88 ++-- tests/ImageSharp.Tests/Image/ImageTests.cs | 72 +-- .../Image/LargeImageIntegrationTests.cs | 2 +- .../Processors/Transforms/ResizeTests.cs | 412 ++++++++---------- .../TestUtilities/TestEnvironment.Formats.cs | 4 +- 38 files changed, 963 insertions(+), 1480 deletions(-) diff --git a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs index 4fa07931e..c3a9c212e 100644 --- a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs +++ b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs @@ -19,9 +19,9 @@ public static class AdvancedImageExtensions /// /// The source image. /// The target file path to save the image to. - /// The file path is null. - /// No encoder available for provided path. /// The matching . + /// The file path is null. + /// No encoder available for provided path. public static IImageEncoder DetectEncoder(this Image source, string filePath) { Guard.NotNull(filePath, nameof(filePath)); @@ -30,27 +30,27 @@ public static class AdvancedImageExtensions 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:"); + sb = sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}'. Registered encoders include:"); foreach (IImageFormat fmt in source.GetConfiguration().ImageFormats) { - sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", fmt.Name, string.Join(", ", fmt.FileExtensions), Environment.NewLine); + sb = sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", fmt.Name, string.Join(", ", fmt.FileExtensions), Environment.NewLine); } - throw new NotSupportedException(sb.ToString()); + throw new UnknownImageFormatException(sb.ToString()); } - IImageEncoder? encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format); + IImageEncoder? encoder = source.GetConfiguration().ImageFormatsManager.GetEncoder(format); if (encoder is null) { StringBuilder sb = new(); - sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}' using image format '{format.Name}'. Registered encoders include:"); + sb = sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}' using image format '{format.Name}'. Registered encoders include:"); foreach (KeyValuePair enc in source.GetConfiguration().ImageFormatsManager.ImageEncoders) { - sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", enc.Key, enc.Value.GetType().Name, Environment.NewLine); + sb = sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", enc.Key, enc.Value.GetType().Name, Environment.NewLine); } - throw new NotSupportedException(sb.ToString()); + throw new UnknownImageFormatException(sb.ToString()); } return encoder; diff --git a/src/ImageSharp/Formats/ImageDecoder.cs b/src/ImageSharp/Formats/ImageDecoder.cs index dfb376197..715c2f541 100644 --- a/src/ImageSharp/Formats/ImageDecoder.cs +++ b/src/ImageSharp/Formats/ImageDecoder.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.PixelFormats; @@ -150,7 +149,7 @@ public abstract class ImageDecoder : IImageDecoder { ResizeOptions resizeOptions = new() { - Size = options.TargetSize.Value, + Size = options.TargetSize!.Value, Sampler = options.Sampler, Mode = ResizeMode.Max }; @@ -290,8 +289,18 @@ public abstract class ImageDecoder : IImageDecoder } internal void SetDecoderFormat(Configuration configuration, Image image) - => image.Metadata.DecodedImageFormat = configuration.ImageFormatsManager.FindFormatByDecoder(this); + { + if (configuration.ImageFormatsManager.TryFindFormatByDecoder(this, out IImageFormat? format)) + { + image.Metadata.DecodedImageFormat = format; + } + } internal void SetDecoderFormat(Configuration configuration, ImageInfo info) - => info.Metadata.DecodedImageFormat = configuration.ImageFormatsManager.FindFormatByDecoder(this); + { + if (configuration.ImageFormatsManager.TryFindFormatByDecoder(this, out IImageFormat? format)) + { + info.Metadata.DecodedImageFormat = format; + } + } } diff --git a/src/ImageSharp/Formats/ImageExtensions.Save.cs b/src/ImageSharp/Formats/ImageExtensions.Save.cs index 6249f8dc7..71458333f 100644 --- a/src/ImageSharp/Formats/ImageExtensions.Save.cs +++ b/src/ImageSharp/Formats/ImageExtensions.Save.cs @@ -58,7 +58,7 @@ public static partial class ImageExtensions public static void SaveAsBmp(this Image source, string path, BmpEncoder encoder) => source.Save( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(BmpFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(BmpFormat.Instance)); /// /// Saves the image to the given stream with the Bmp format. @@ -72,7 +72,7 @@ public static partial class ImageExtensions public static Task SaveAsBmpAsync(this Image source, string path, BmpEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(BmpFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(BmpFormat.Instance), cancellationToken); /// @@ -105,7 +105,7 @@ public static partial class ImageExtensions public static void SaveAsBmp(this Image source, Stream stream, BmpEncoder encoder) => source.Save( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(BmpFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(BmpFormat.Instance)); /// /// Saves the image to the given stream with the Bmp format. @@ -119,7 +119,7 @@ public static partial class ImageExtensions public static Task SaveAsBmpAsync(this Image source, Stream stream, BmpEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(BmpFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(BmpFormat.Instance), cancellationToken); /// @@ -160,7 +160,7 @@ public static partial class ImageExtensions public static void SaveAsGif(this Image source, string path, GifEncoder encoder) => source.Save( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(GifFormat.Instance)); /// /// Saves the image to the given stream with the Gif format. @@ -174,7 +174,7 @@ public static partial class ImageExtensions public static Task SaveAsGifAsync(this Image source, string path, GifEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(GifFormat.Instance), cancellationToken); /// @@ -207,7 +207,7 @@ public static partial class ImageExtensions public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder) => source.Save( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(GifFormat.Instance)); /// /// Saves the image to the given stream with the Gif format. @@ -221,7 +221,7 @@ public static partial class ImageExtensions public static Task SaveAsGifAsync(this Image source, Stream stream, GifEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(GifFormat.Instance), cancellationToken); /// @@ -262,7 +262,7 @@ public static partial class ImageExtensions public static void SaveAsJpeg(this Image source, string path, JpegEncoder encoder) => source.Save( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(JpegFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(JpegFormat.Instance)); /// /// Saves the image to the given stream with the Jpeg format. @@ -276,7 +276,7 @@ public static partial class ImageExtensions public static Task SaveAsJpegAsync(this Image source, string path, JpegEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(JpegFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(JpegFormat.Instance), cancellationToken); /// @@ -309,7 +309,7 @@ public static partial class ImageExtensions public static void SaveAsJpeg(this Image source, Stream stream, JpegEncoder encoder) => source.Save( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(JpegFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(JpegFormat.Instance)); /// /// Saves the image to the given stream with the Jpeg format. @@ -323,7 +323,7 @@ public static partial class ImageExtensions public static Task SaveAsJpegAsync(this Image source, Stream stream, JpegEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(JpegFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(JpegFormat.Instance), cancellationToken); /// @@ -364,7 +364,7 @@ public static partial class ImageExtensions public static void SaveAsPbm(this Image source, string path, PbmEncoder encoder) => source.Save( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PbmFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PbmFormat.Instance)); /// /// Saves the image to the given stream with the Pbm format. @@ -378,7 +378,7 @@ public static partial class ImageExtensions public static Task SaveAsPbmAsync(this Image source, string path, PbmEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PbmFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PbmFormat.Instance), cancellationToken); /// @@ -411,7 +411,7 @@ public static partial class ImageExtensions public static void SaveAsPbm(this Image source, Stream stream, PbmEncoder encoder) => source.Save( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PbmFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PbmFormat.Instance)); /// /// Saves the image to the given stream with the Pbm format. @@ -425,7 +425,7 @@ public static partial class ImageExtensions public static Task SaveAsPbmAsync(this Image source, Stream stream, PbmEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PbmFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PbmFormat.Instance), cancellationToken); /// @@ -466,7 +466,7 @@ public static partial class ImageExtensions public static void SaveAsPng(this Image source, string path, PngEncoder encoder) => source.Save( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PngFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PngFormat.Instance)); /// /// Saves the image to the given stream with the Png format. @@ -480,7 +480,7 @@ public static partial class ImageExtensions public static Task SaveAsPngAsync(this Image source, string path, PngEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PngFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PngFormat.Instance), cancellationToken); /// @@ -513,7 +513,7 @@ public static partial class ImageExtensions public static void SaveAsPng(this Image source, Stream stream, PngEncoder encoder) => source.Save( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PngFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PngFormat.Instance)); /// /// Saves the image to the given stream with the Png format. @@ -527,7 +527,7 @@ public static partial class ImageExtensions public static Task SaveAsPngAsync(this Image source, Stream stream, PngEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PngFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(PngFormat.Instance), cancellationToken); /// @@ -568,7 +568,7 @@ public static partial class ImageExtensions public static void SaveAsTga(this Image source, string path, TgaEncoder encoder) => source.Save( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TgaFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TgaFormat.Instance)); /// /// Saves the image to the given stream with the Tga format. @@ -582,7 +582,7 @@ public static partial class ImageExtensions public static Task SaveAsTgaAsync(this Image source, string path, TgaEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TgaFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TgaFormat.Instance), cancellationToken); /// @@ -615,7 +615,7 @@ public static partial class ImageExtensions public static void SaveAsTga(this Image source, Stream stream, TgaEncoder encoder) => source.Save( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TgaFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TgaFormat.Instance)); /// /// Saves the image to the given stream with the Tga format. @@ -629,7 +629,7 @@ public static partial class ImageExtensions public static Task SaveAsTgaAsync(this Image source, Stream stream, TgaEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TgaFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TgaFormat.Instance), cancellationToken); /// @@ -670,7 +670,7 @@ public static partial class ImageExtensions public static void SaveAsWebp(this Image source, string path, WebpEncoder encoder) => source.Save( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(WebpFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(WebpFormat.Instance)); /// /// Saves the image to the given stream with the Webp format. @@ -684,7 +684,7 @@ public static partial class ImageExtensions public static Task SaveAsWebpAsync(this Image source, string path, WebpEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(WebpFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(WebpFormat.Instance), cancellationToken); /// @@ -717,7 +717,7 @@ public static partial class ImageExtensions public static void SaveAsWebp(this Image source, Stream stream, WebpEncoder encoder) => source.Save( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(WebpFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(WebpFormat.Instance)); /// /// Saves the image to the given stream with the Webp format. @@ -731,7 +731,7 @@ public static partial class ImageExtensions public static Task SaveAsWebpAsync(this Image source, Stream stream, WebpEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(WebpFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(WebpFormat.Instance), cancellationToken); /// @@ -772,7 +772,7 @@ public static partial class ImageExtensions public static void SaveAsTiff(this Image source, string path, TiffEncoder encoder) => source.Save( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TiffFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TiffFormat.Instance)); /// /// Saves the image to the given stream with the Tiff format. @@ -786,7 +786,7 @@ public static partial class ImageExtensions public static Task SaveAsTiffAsync(this Image source, string path, TiffEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( path, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TiffFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TiffFormat.Instance), cancellationToken); /// @@ -819,7 +819,7 @@ public static partial class ImageExtensions public static void SaveAsTiff(this Image source, Stream stream, TiffEncoder encoder) => source.Save( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TiffFormat.Instance)); + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TiffFormat.Instance)); /// /// Saves the image to the given stream with the Tiff format. @@ -833,7 +833,7 @@ public static partial class ImageExtensions public static Task SaveAsTiffAsync(this Image source, Stream stream, TiffEncoder encoder, CancellationToken cancellationToken = default) => source.SaveAsync( stream, - encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TiffFormat.Instance), + encoder ?? source.GetConfiguration().ImageFormatsManager.GetEncoder(TiffFormat.Instance), cancellationToken); } diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs index 5eeb1b812..8b4e320c5 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -3,6 +3,8 @@ using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Text; namespace SixLabors.ImageSharp.Formats; @@ -129,8 +131,11 @@ public class ImageFormatManager return format is not null; } - internal IImageFormat? FindFormatByDecoder(IImageDecoder decoder) - => this.mimeTypeDecoders.FirstOrDefault(x => x.Value.GetType() == decoder.GetType()).Key; + internal bool TryFindFormatByDecoder(IImageDecoder decoder, [NotNullWhen(true)] out IImageFormat? format) + { + format = this.mimeTypeDecoders.FirstOrDefault(x => x.Value.GetType() == decoder.GetType()).Key; + return format is not null; + } /// /// Sets a specific image encoder as the encoder for a specific image format. @@ -178,32 +183,54 @@ public class ImageFormatManager /// For the specified mime type find the decoder. /// /// The format to discover - /// The if found otherwise null - public IImageDecoder? FindDecoder(IImageFormat format) + /// The . + /// The format is not registered. + public IImageDecoder GetDecoder(IImageFormat format) { Guard.NotNull(format, nameof(format)); - return this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder? decoder) - ? decoder - : null; + if (!this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder? decoder)) + { + ThrowInvalidDecoder(this); + } + + return decoder; } /// /// For the specified mime type find the encoder. /// /// The format to discover - /// The if found otherwise null - public IImageEncoder? FindEncoder(IImageFormat format) + /// The . + /// The format is not registered. + public IImageEncoder GetEncoder(IImageFormat format) { Guard.NotNull(format, nameof(format)); - return this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder? encoder) - ? encoder - : null; + if (!this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder? encoder)) + { + ThrowInvalidDecoder(this); + } + + return encoder; } /// /// Sets the max header size. /// private void SetMaxHeaderSize() => this.MaxHeaderSize = this.imageFormatDetectors.Max(x => x.HeaderSize); + + [DoesNotReturn] + internal static void ThrowInvalidDecoder(ImageFormatManager manager) + { + StringBuilder sb = new(); + sb = sb.AppendLine("Image cannot be loaded. Available decoders:"); + + foreach (KeyValuePair val in manager.ImageDecoders) + { + sb = sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine); + } + + throw new UnknownImageFormatException(sb.ToString()); + } } diff --git a/src/ImageSharp/Image.Decode.cs b/src/ImageSharp/Image.Decode.cs index 9a2844060..ae38144c0 100644 --- a/src/ImageSharp/Image.Decode.cs +++ b/src/ImageSharp/Image.Decode.cs @@ -44,14 +44,15 @@ public abstract partial class Image /// The general configuration. /// The image stream to read the header from. /// The mime type or null if none found. - private static IImageFormat? InternalDetectFormat(Configuration configuration, Stream stream) + /// The input format is not recognized. + private static IImageFormat InternalDetectFormat(Configuration configuration, Stream stream) { // We take a minimum of the stream length vs the max header size and always check below // to ensure that only formats that headers fit within the given buffer length are tested. int headerSize = (int)Math.Min(configuration.MaxHeaderSize, stream.Length); if (headerSize <= 0) { - return null; + ImageFormatManager.ThrowInvalidDecoder(configuration.ImageFormatsManager); } // Header sizes are so small, that headersBuffer will be always stackalloc-ed in practice, @@ -85,7 +86,12 @@ public abstract partial class Image } } - return format; + if (format is null) + { + ImageFormatManager.ThrowInvalidDecoder(configuration.ImageFormatsManager); + } + + return format!; } /// @@ -93,13 +99,11 @@ public abstract partial class Image /// /// The general decoder options. /// The image stream to read the header from. - /// The or . - private static IImageDecoder? DiscoverDecoder(DecoderOptions options, Stream stream) + /// The . + private static IImageDecoder DiscoverDecoder(DecoderOptions options, Stream stream) { - IImageFormat? format = InternalDetectFormat(options.Configuration, stream); - return format is not null - ? options.Configuration.ImageFormatsManager.FindDecoder(format) - : null; + IImageFormat format = InternalDetectFormat(options.Configuration, stream); + return options.Configuration.ImageFormatsManager.GetDecoder(format); } /// @@ -111,56 +115,36 @@ public abstract partial class Image /// /// A new . /// - private static Image? Decode(DecoderOptions options, Stream stream) + private static Image Decode(DecoderOptions options, Stream stream) where TPixel : unmanaged, IPixel { - IImageDecoder? decoder = DiscoverDecoder(options, stream); - if (decoder is null) - { - return null; - } - + IImageDecoder decoder = DiscoverDecoder(options, stream); return decoder.Decode(options, stream); } - private static async Task?> DecodeAsync( + private static Task> DecodeAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - IImageDecoder? decoder = DiscoverDecoder(options, stream); - if (decoder is null) - { - return null; - } - - return await decoder.DecodeAsync(options, stream, cancellationToken).ConfigureAwait(false); + IImageDecoder decoder = DiscoverDecoder(options, stream); + return decoder.DecodeAsync(options, stream, cancellationToken); } - private static Image? Decode(DecoderOptions options, Stream stream) + private static Image Decode(DecoderOptions options, Stream stream) { - IImageDecoder? decoder = DiscoverDecoder(options, stream); - if (decoder is null) - { - return null; - } - + IImageDecoder decoder = DiscoverDecoder(options, stream); return decoder.Decode(options, stream); } - private static async Task DecodeAsync( + private static Task DecodeAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken) { - IImageDecoder? decoder = DiscoverDecoder(options, stream); - if (decoder is null) - { - return null; - } - - return await decoder.DecodeAsync(options, stream, cancellationToken).ConfigureAwait(false); + IImageDecoder decoder = DiscoverDecoder(options, stream); + return decoder.DecodeAsync(options, stream, cancellationToken); } /// @@ -168,17 +152,10 @@ public abstract partial class Image /// /// The general decoder options. /// The stream. - /// - /// The or null if a suitable info detector is not found. - /// - private static ImageInfo? InternalIdentify(DecoderOptions options, Stream stream) + /// The . + private static ImageInfo InternalIdentify(DecoderOptions options, Stream stream) { - IImageDecoder? decoder = DiscoverDecoder(options, stream); - if (decoder is null) - { - return null; - } - + IImageDecoder decoder = DiscoverDecoder(options, stream); return decoder.Identify(options, stream); } @@ -188,21 +165,13 @@ public abstract partial class Image /// The general decoder options. /// The stream. /// The token to monitor for cancellation requests. - /// - /// The or null if a suitable info detector is not found. - /// - private static async Task InternalIdentifyAsync( + /// The . + private static Task InternalIdentifyAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken) { - IImageDecoder? decoder = DiscoverDecoder(options, stream); - - if (decoder is null) - { - return null; - } - - return await decoder.IdentifyAsync(options, stream, cancellationToken).ConfigureAwait(false); + IImageDecoder decoder = DiscoverDecoder(options, stream); + return decoder.IdentifyAsync(options, stream, cancellationToken); } } diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs index 921812834..0c209214d 100644 --- a/src/ImageSharp/Image.FromBytes.cs +++ b/src/ImageSharp/Image.FromBytes.cs @@ -15,21 +15,21 @@ 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 byte span containing encoded image data to read the header from. /// 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); + public static bool TryDetectFormat(ReadOnlySpan buffer, [NotNullWhen(true)] out IImageFormat? format) + => TryDetectFormat(DecoderOptions.Default, buffer, 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 byte span containing encoded image data to read the header from. /// The mime type or null if none found. /// The options are null. /// returns true when format was detected otherwise false. - public static bool TryDetectFormat(DecoderOptions options, ReadOnlySpan data, [NotNullWhen(true)] out IImageFormat? format) + public static bool TryDetectFormat(DecoderOptions options, ReadOnlySpan buffer, [NotNullWhen(true)] out IImageFormat? format) { Guard.NotNull(options, nameof(options.Configuration)); @@ -43,7 +43,7 @@ public abstract partial class Image foreach (IImageFormatDetector detector in configuration.ImageFormatsManager.FormatDetectors) { - if (detector.TryDetectFormat(data, out format)) + if (detector.TryDetectFormat(buffer, out format)) { return true; } @@ -57,7 +57,7 @@ public abstract partial class Image /// Reads the raw image information from the specified stream without fully decoding it. /// A return value indicates whether the operation succeeded. /// - /// The byte array containing encoded image data to read the header from. + /// The byte array containing encoded image data to read the header from. /// /// When this method returns, contains the raw image information; /// otherwise, the default value for the type of the parameter. @@ -66,15 +66,15 @@ public abstract partial class Image /// if the information can be read; otherwise, /// The data is null. /// The data is not readable. - public static bool TryIdentify(ReadOnlySpan data, [NotNullWhen(true)] out ImageInfo? info) - => TryIdentify(DecoderOptions.Default, data, out info); + public static bool TryIdentify(ReadOnlySpan buffer, [NotNullWhen(true)] out ImageInfo? info) + => TryIdentify(DecoderOptions.Default, buffer, out info); /// /// Reads the raw image information from the specified span of bytes without fully decoding it. /// A return value indicates whether the operation succeeded. /// /// The general decoder options. - /// The byte span containing encoded image data to read the header from. + /// The byte span containing encoded image data to read the header from. /// /// When this method returns, contains the raw image information; /// otherwise, the default value for the type of the parameter. @@ -84,141 +84,79 @@ public abstract partial class Image /// The configuration is null. /// The data is null. /// The data is not readable. - public static unsafe bool TryIdentify(DecoderOptions options, ReadOnlySpan data, [NotNullWhen(true)] out ImageInfo? info) + public static unsafe bool TryIdentify(DecoderOptions options, ReadOnlySpan buffer, [NotNullWhen(true)] out ImageInfo? info) { - fixed (byte* ptr = data) + fixed (byte* ptr = buffer) { - using UnmanagedMemoryStream stream = new(ptr, data.Length); + using UnmanagedMemoryStream stream = new(ptr, buffer.Length); return TryIdentify(options, stream, out info); } } /// - /// Load a new instance of from the given encoded byte span. + /// Creates a new instance of the class from the given byte span. + /// The pixel format is automatically determined by the decoder. /// - /// The byte span containing encoded image data. - /// The pixel format. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. - /// A new . - public static Image Load(ReadOnlySpan data) - where TPixel : unmanaged, IPixel - => Load(DecoderOptions.Default, data); - - /// - /// Load a new instance of from the given encoded byte span. - /// - /// The byte span containing image data. - /// The mime type of the decoded image. - /// The pixel format. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. - /// A new . - public static Image Load(ReadOnlySpan data, out IImageFormat format) - where TPixel : unmanaged, IPixel - => Load(DecoderOptions.Default, data, out format); + /// The byte span containing encoded image data. + /// . + /// The image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + /// The . + public static Image Load(ReadOnlySpan buffer) + => Load(DecoderOptions.Default, buffer); /// - /// Load a new instance of from the given encoded byte span. + /// Creates a new instance of the class from the given byte span. + /// The pixel format is automatically determined by the decoder. /// /// The general decoder options. - /// The byte span containing encoded image data. - /// The pixel format. + /// The byte span containing encoded image data. + /// . /// The options are null. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. - /// A new . - public static unsafe Image Load(DecoderOptions options, ReadOnlySpan data) - where TPixel : unmanaged, IPixel + /// The image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static unsafe Image Load(DecoderOptions options, ReadOnlySpan buffer) { - fixed (byte* ptr = data) + fixed (byte* ptr = buffer) { - using UnmanagedMemoryStream stream = new(ptr, data.Length); - return Load(options, stream); + using UnmanagedMemoryStream stream = new(ptr, buffer.Length); + return Load(options, stream); } } /// - /// Load a new instance of from the given encoded byte span. + /// Creates a new instance of the class from the given byte span. /// - /// The general decoder options. - /// The byte span containing image data. - /// The of the decoded image. /// The pixel format. - /// The options are null. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. - /// A new . - public static unsafe Image Load( - DecoderOptions options, - ReadOnlySpan data, - out IImageFormat format) + /// The byte span containing encoded image data. + /// . + /// The image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Image Load(ReadOnlySpan data) where TPixel : unmanaged, IPixel - { - fixed (byte* ptr = data) - { - using UnmanagedMemoryStream stream = new(ptr, data.Length); - return Load(options, stream, out format); - } - } - - /// - /// Load a new instance of from the given encoded byte span. - /// - /// The byte span containing image data. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. - /// The . - public static Image Load(ReadOnlySpan data) - => Load(DecoderOptions.Default, data); - - /// - /// Load a new instance of from the given encoded byte array. - /// - /// The byte span containing image data. - /// The detected format. - /// The decoder is null. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. - /// The . - public static Image Load(ReadOnlySpan data, out IImageFormat format) - => Load(DecoderOptions.Default, data, out format); - - /// - /// Decodes a new instance of from the given encoded byte span. - /// - /// The general decoder options. - /// The byte span containing image data. - /// The . - public static Image Load(DecoderOptions options, ReadOnlySpan data) - => Load(options, data, out _); + => Load(DecoderOptions.Default, data); /// - /// Load a new instance of from the given encoded byte span. + /// Creates a new instance of the class from the given byte span. /// + /// The pixel format. /// The general decoder options. - /// The byte span containing image data. - /// The of the decoded image.> + /// The byte span containing encoded image data. + /// . /// The options are null. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. - /// The . - public static unsafe Image Load( - DecoderOptions options, - ReadOnlySpan data, - out IImageFormat format) + /// The image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static unsafe Image Load(DecoderOptions options, ReadOnlySpan data) + where TPixel : unmanaged, IPixel { fixed (byte* ptr = data) { using UnmanagedMemoryStream stream = new(ptr, data.Length); - return Load(options, stream, out format); + return Load(options, stream); } } } diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs index 515d8408c..a8ed73c82 100644 --- a/src/ImageSharp/Image.FromFile.cs +++ b/src/ImageSharp/Image.FromFile.cs @@ -16,22 +16,22 @@ public abstract partial class Image /// Detects the encoded image format type from the specified file. /// A return value indicates whether the operation succeeded. /// - /// The image file to open and to read the header from. + /// The image file to open and to read the header from. /// /// When this method returns, contains the format that matches the given file; /// otherwise, the default value for the type of the parameter. /// This parameter is passed uninitialized. /// /// if a match is found; otherwise, - public static bool TryDetectFormat(string filePath, [NotNullWhen(true)] out IImageFormat? format) - => TryDetectFormat(DecoderOptions.Default, filePath, out format); + public static bool TryDetectFormat(string path, [NotNullWhen(true)] out IImageFormat? format) + => TryDetectFormat(DecoderOptions.Default, path, out format); /// /// Detects the encoded image format type from the specified file. /// A return value indicates whether the operation succeeded. /// /// The general decoder options. - /// The image file to open and to read the header from. + /// The image file to open and to read the header from. /// /// When this method returns, contains the format that matches the given file; /// otherwise, the default value for the type of the parameter. @@ -39,11 +39,11 @@ public abstract partial class Image /// /// if a match is found; otherwise, /// The options are null. - public static bool TryDetectFormat(DecoderOptions options, string filePath, [NotNullWhen(true)] out IImageFormat? format) + public static bool TryDetectFormat(DecoderOptions options, string path, [NotNullWhen(true)] out IImageFormat? format) { Guard.NotNull(options, nameof(options)); - using Stream file = options.Configuration.FileSystem.OpenRead(filePath); + using Stream file = options.Configuration.FileSystem.OpenRead(path); return TryDetectFormat(options, file, out format); } @@ -51,31 +51,31 @@ public abstract partial class Image /// Detects the encoded image format type from the specified file. /// A return value indicates whether the operation succeeded. /// - /// The image file to open and to read the header from. + /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. /// A representing the asynchronous operation. public static Task> TryDetectFormatAsync( - string filePath, + string path, CancellationToken cancellationToken = default) - => TryDetectFormatAsync(DecoderOptions.Default, filePath, cancellationToken); + => TryDetectFormatAsync(DecoderOptions.Default, path, cancellationToken); /// /// Detects the encoded image format type from the specified file. /// A return value indicates whether the operation succeeded. /// /// The general decoder options. - /// The image file to open and to read the header from. + /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. /// The options are null. /// A representing the asynchronous operation. public static async Task> TryDetectFormatAsync( DecoderOptions options, - string filePath, + string path, CancellationToken cancellationToken = default) { Guard.NotNull(options, nameof(options)); - using Stream stream = options.Configuration.FileSystem.OpenRead(filePath); + using Stream stream = options.Configuration.FileSystem.OpenRead(path); return await TryDetectFormatAsync(options, stream, cancellationToken).ConfigureAwait(false); } @@ -83,22 +83,22 @@ public abstract partial class Image /// Reads the raw image information from the specified file path without fully decoding it. /// A return value indicates whether the operation succeeded. /// - /// The image file to open and to read the header from. + /// The image file to open and to read the header from. /// /// When this method returns, contains the raw image information; /// otherwise, the default value for the type of the parameter. /// This parameter is passed uninitialized. /// /// if the information can be read; otherwise, - public static bool TryIdentify(string filePath, [NotNullWhen(true)] out ImageInfo? info) - => TryIdentify(DecoderOptions.Default, filePath, out info); + public static bool TryIdentify(string path, [NotNullWhen(true)] out ImageInfo? info) + => TryIdentify(DecoderOptions.Default, path, out info); /// /// Reads the raw image information from the specified file path without fully decoding it. /// A return value indicates whether the operation succeeded. /// /// The general decoder options. - /// The image file to open and to read the header from. + /// The image file to open and to read the header from. /// /// When this method returns, contains the raw image information; /// otherwise, the default value for the type of the parameter. @@ -106,11 +106,11 @@ public abstract partial class Image /// /// if the information can be read; otherwise, /// The options are null. - public static bool TryIdentify(DecoderOptions options, string filePath, [NotNullWhen(true)] out ImageInfo? info) + public static bool TryIdentify(DecoderOptions options, string path, [NotNullWhen(true)] out ImageInfo? info) { Guard.NotNull(options, nameof(options)); - using Stream stream = options.Configuration.FileSystem.OpenRead(filePath); + using Stream stream = options.Configuration.FileSystem.OpenRead(path); return TryIdentify(options, stream, out info); } @@ -118,197 +118,134 @@ public abstract partial class Image /// Reads the raw image information from the specified stream without fully decoding it. /// A return value indicates whether the operation succeeded. /// - /// The image file to open and to read the header from. + /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. - /// The configuration is null. + /// The options are null. /// /// The representing the asynchronous operation. /// public static Task> TryIdentifyAsync( - string filePath, + string path, CancellationToken cancellationToken = default) - => TryIdentifyAsync(DecoderOptions.Default, filePath, cancellationToken); + => TryIdentifyAsync(DecoderOptions.Default, path, cancellationToken); /// /// Reads the raw image information from the specified stream without fully decoding it. /// A return value indicates whether the operation succeeded. /// /// The general decoder options. - /// The image file to open and to read the header from. + /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. - /// The configuration is null. + /// The options are null. /// /// The representing the asynchronous operation. /// public static async Task> TryIdentifyAsync( DecoderOptions options, - string filePath, + string path, CancellationToken cancellationToken = default) { Guard.NotNull(options, nameof(options)); - using Stream stream = options.Configuration.FileSystem.OpenRead(filePath); + using Stream stream = options.Configuration.FileSystem.OpenRead(path); return await TryIdentifyAsync(options, stream, cancellationToken).ConfigureAwait(false); } /// - /// Create a new instance of the class from the given file. + /// Creates a new instance of the class from the given file path. + /// The pixel format is automatically determined by the decoder. /// /// The file path to the image. - /// - /// Thrown if the stream is not readable nor seekable. - /// - /// The . + /// . + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. public static Image Load(string path) => Load(DecoderOptions.Default, path); /// - /// Create a new instance of the class from the given file. - /// - /// The file path to the image. - /// The mime type of the decoded image. - /// - /// Thrown if the stream is not readable nor seekable. - /// - /// A new . - public static Image Load(string path, out IImageFormat format) - => Load(DecoderOptions.Default, path, out format); - - /// - /// Create a new instance of the class from the given file. + /// Creates a new instance of the class from the given file path. + /// The pixel format is automatically determined by the decoder. /// /// The general decoder options. /// The file path to the image. - /// The configuration is null. + /// . + /// The options are null. /// The path is null. - /// Image format not recognised. - /// Image format is not supported. - /// Image contains invalid content. - /// The . + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. public static Image Load(DecoderOptions options, string path) - => Load(options, path, out _); - - /// - /// Create a new instance of the class from the given file. - /// - /// The general decoder options. - /// The file path to the image. - /// The token to monitor for cancellation requests. - /// The configuration is null. - /// The path is null. - /// Image format not recognised. - /// Image format is not supported. - /// Image contains invalid content. - /// A representing the asynchronous operation. - public static async Task LoadAsync( - DecoderOptions options, - string path, - CancellationToken cancellationToken = default) { + Guard.NotNull(options, nameof(options)); + Guard.NotNull(path, nameof(path)); + using Stream stream = options.Configuration.FileSystem.OpenRead(path); - (Image img, _) = await LoadWithFormatAsync(options, stream, cancellationToken) - .ConfigureAwait(false); - return img; + return Load(options, stream); } /// - /// Create a new instance of the class from the given file. + /// Creates a new instance of the class from the given file path. + /// The pixel format is automatically determined by the decoder. /// /// The file path to the image. /// The token to monitor for cancellation requests. - /// The configuration is null. - /// The path is null. - /// The decoder is null. - /// Image format not recognised. - /// Image format is not supported. - /// Image contains invalid content. /// A representing the asynchronous operation. + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. public static Task LoadAsync(string path, CancellationToken cancellationToken = default) => LoadAsync(DecoderOptions.Default, path, cancellationToken); /// - /// Create a new instance of the class from the given file. - /// - /// The file path to the image. - /// The token to monitor for cancellation requests. - /// The configuration is null. - /// The path is null. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. - /// The pixel format. - /// A representing the asynchronous operation. - public static Task> LoadAsync(string path, CancellationToken cancellationToken = default) - where TPixel : unmanaged, IPixel - => LoadAsync(DecoderOptions.Default, path, cancellationToken); - - /// - /// Create a new instance of the class from the given file. + /// Creates a new instance of the class from the given file path. + /// The pixel format is automatically determined by the decoder. /// /// The general decoder options. /// The file path to the image. /// The token to monitor for cancellation requests. - /// The configuration is null. - /// The path is null. - /// Image format not recognised. - /// Image format is not supported. - /// Image contains invalid content. - /// The pixel format. /// A representing the asynchronous operation. - public static async Task> LoadAsync( + /// The options are null. + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static async Task LoadAsync( DecoderOptions options, string path, CancellationToken cancellationToken = default) - where TPixel : unmanaged, IPixel { - Guard.NotNull(options, nameof(options)); - using Stream stream = options.Configuration.FileSystem.OpenRead(path); - (Image img, _) = - await LoadWithFormatAsync(options, stream, cancellationToken).ConfigureAwait(false); - return img; + return await LoadAsync(options, stream, cancellationToken).ConfigureAwait(false); } /// - /// Create a new instance of the class from the given file. + /// Creates a new instance of the class from the given file path. /// + /// The pixel format. /// The file path to the image. + /// . /// The path is null. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. - /// The pixel format. - /// A new . + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. public static Image Load(string path) where TPixel : unmanaged, IPixel => Load(DecoderOptions.Default, path); /// - /// Create a new instance of the class from the given file. + /// Creates a new instance of the class from the given file path. /// - /// The file path to the image. - /// The mime type of the decoded image. - /// The path is null. - /// Image format not recognised. - /// Image contains invalid content. - /// Image format is not supported. /// The pixel format. - /// A new . - public static Image Load(string path, out IImageFormat format) - where TPixel : unmanaged, IPixel - => Load(DecoderOptions.Default, path, out format); - - /// - /// Create a new instance of the class from the given file. - /// /// The general decoder options. /// The file path to the image. - /// The configuration is null. + /// . + /// The options are null. /// The path is null. - /// Image format not recognised. - /// Image format is not supported. - /// Image contains invalid content. - /// The pixel format. - /// A new . + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. public static Image Load(DecoderOptions options, string path) where TPixel : unmanaged, IPixel { @@ -320,47 +257,43 @@ public abstract partial class Image } /// - /// Create a new instance of the class from the given file. + /// Creates a new instance of the class from the given file path. /// - /// The general decoder options. + /// The pixel format. /// The file path to the image. - /// The mime type of the decoded image. - /// The configuration is null. + /// The token to monitor for cancellation requests. + /// A representing the asynchronous operation. /// The path is null. - /// Image format not recognised. - /// Image format is not supported. - /// Image contains invalid content. - /// The pixel format. - /// A new . - public static Image Load(DecoderOptions options, string path, out IImageFormat format) + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Task> LoadAsync(string path, CancellationToken cancellationToken = default) where TPixel : unmanaged, IPixel - { - Guard.NotNull(options, nameof(options)); - Guard.NotNull(path, nameof(path)); - - using Stream stream = options.Configuration.FileSystem.OpenRead(path); - return Load(options, stream, out format); - } + => LoadAsync(DecoderOptions.Default, path, cancellationToken); /// - /// Create a new instance of the class from the given file. - /// The pixel type is selected by the decoder. + /// Creates a new instance of the class from the given file path. /// + /// The pixel format. /// The general decoder options. /// The file path to the image. - /// The mime type of the decoded image. - /// The configuration is null. + /// The token to monitor for cancellation requests. + /// A representing the asynchronous operation. + /// The options are null. /// The path is null. - /// Image format not recognised. - /// Image format is not supported. - /// Image contains invalid content. - /// A new . - public static Image Load(DecoderOptions options, string path, out IImageFormat format) + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static async Task> LoadAsync( + DecoderOptions options, + string path, + CancellationToken cancellationToken = default) + where TPixel : unmanaged, IPixel { Guard.NotNull(options, nameof(options)); Guard.NotNull(path, nameof(path)); using Stream stream = options.Configuration.FileSystem.OpenRead(path); - return Load(options, stream, out format); + return await LoadAsync(options, stream, cancellationToken).ConfigureAwait(false); } } diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs index fa9285ef3..9da77d66e 100644 --- a/src/ImageSharp/Image.FromStream.cs +++ b/src/ImageSharp/Image.FromStream.cs @@ -2,8 +2,6 @@ // Licensed under the Six Labors Split License. using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.PixelFormats; @@ -136,7 +134,6 @@ public abstract partial class Image /// /// The image stream to read the information from. /// The token to monitor for cancellation requests. - /// The options are null. /// The stream is null. /// The stream is not readable. /// Image contains invalid content. @@ -177,296 +174,130 @@ public abstract partial class Image } /// - /// Decode a new instance of the class from the given stream. - /// The pixel format is selected by the decoder. - /// - /// The stream containing image information. - /// The format type of the decoded image. - /// The stream is null. - /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// The . - public static Image Load(Stream stream, out IImageFormat format) - => Load(DecoderOptions.Default, stream, out format); - - /// - /// Decode a new instance of the class from the given stream. - /// The pixel format is selected by the decoder. + /// Creates a new instance of the class from the given stream. + /// The pixel format is automatically determined by the decoder. /// /// The stream containing image information. - /// The token to monitor for cancellation requests. + /// . /// The stream is null. /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// A representing the asynchronous operation. - public static Task<(Image Image, IImageFormat Format)> LoadWithFormatAsync(Stream stream, CancellationToken cancellationToken = default) - => LoadWithFormatAsync(DecoderOptions.Default, stream, cancellationToken); + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Image Load(Stream stream) + => Load(DecoderOptions.Default, stream); /// - /// Decode a new instance of the class from the given stream. - /// The pixel format is selected by the decoder. + /// Creates a new instance of the class from the given stream. + /// The pixel format is automatically determined by the decoder. /// + /// The general decoder options. /// The stream containing image information. + /// . + /// The options are null. /// The stream is null. /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// The . - public static Image Load(Stream stream) => Load(DecoderOptions.Default, stream); + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Image Load(DecoderOptions options, Stream stream) + => WithSeekableStream(options, stream, s => Decode(options, s)); /// - /// Decode a new instance of the class from the given stream. - /// The pixel format is selected by the decoder. + /// Creates a new instance of the class from the given stream. + /// The pixel format is automatically determined by the decoder. /// /// The stream containing image information. /// The token to monitor for cancellation requests. + /// A representing the asynchronous operation. /// The stream is null. /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// A representing the asynchronous operation. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. public static Task LoadAsync(Stream stream, CancellationToken cancellationToken = default) => LoadAsync(DecoderOptions.Default, stream, cancellationToken); /// - /// Decode a new instance of the class from the given stream. - /// - /// The general decoder options. - /// The stream containing image information. - /// The options are null. - /// The stream is null. - /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// A new . - public static Image Load(DecoderOptions options, Stream stream) - => Load(options, stream, out _); - - /// - /// Decode a new instance of the class from the given stream. + /// Creates a new instance of the class from the given stream. + /// The pixel format is automatically determined by the decoder. /// /// The general decoder options. /// The stream containing image information. /// The token to monitor for cancellation requests. + /// A representing the asynchronous operation. /// The options are null. /// The stream is null. /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// A representing the asynchronous operation. - public static async Task LoadAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) - => (await LoadWithFormatAsync(options, stream, cancellationToken).ConfigureAwait(false)).Image; + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Task LoadAsync( + DecoderOptions options, + Stream stream, + CancellationToken cancellationToken = default) + => WithSeekableStreamAsync(options, stream, (s, ct) => DecodeAsync(options, s, ct), cancellationToken); /// - /// Create a new instance of the class from the given stream. + /// Creates a new instance of the class from the given stream. /// + /// The pixel format. /// The stream containing image information. + /// . /// The stream is null. /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// The pixel format. - /// A new . + /// The encoded image contains invalid content. + /// The encoded image format is unknown. public static Image Load(Stream stream) where TPixel : unmanaged, IPixel => Load(DecoderOptions.Default, stream); /// - /// Create a new instance of the class from the given stream. - /// - /// The stream containing image information. - /// The token to monitor for cancellation requests. - /// The stream is null. - /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// The pixel format. - /// A representing the asynchronous operation. - public static Task> LoadAsync(Stream stream, CancellationToken cancellationToken = default) - where TPixel : unmanaged, IPixel - => LoadAsync(DecoderOptions.Default, stream, cancellationToken); - - /// - /// Create a new instance of the class from the given stream. + /// Creates a new instance of the class from the given stream. /// - /// The stream containing image information. - /// The format type of the decoded image. - /// The stream is null. - /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. /// The pixel format. - /// A new . - public static Image Load(Stream stream, out IImageFormat format) - where TPixel : unmanaged, IPixel - => Load(DecoderOptions.Default, stream, out format); - - /// - /// Create a new instance of the class from the given stream. - /// - /// The stream containing image information. - /// The token to monitor for cancellation requests. - /// The stream is null. - /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// The pixel format. - /// A representing the asynchronous operation. - public static Task<(Image Image, IImageFormat Format)> LoadWithFormatAsync(Stream stream, CancellationToken cancellationToken = default) - where TPixel : unmanaged, IPixel - => LoadWithFormatAsync(DecoderOptions.Default, stream, cancellationToken); - - /// - /// Create a new instance of the class from the given stream. - /// /// The general decoder options. /// The stream containing image information. + /// . /// The options are null. /// The stream is null. /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// The pixel format. - /// A new . + /// The encoded image contains invalid content. + /// The encoded image format is unknown. public static Image Load(DecoderOptions options, Stream stream) where TPixel : unmanaged, IPixel - => Load(options, stream, out IImageFormat _); + => WithSeekableStream(options, stream, s => Decode(options, s)); /// - /// Create a new instance of the class from the given stream. + /// Creates a new instance of the class from the given stream. /// - /// The general decoder options. - /// The stream containing image information. - /// The format type of the decoded image. - /// The options are null. - /// The stream is null. - /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. /// The pixel format. - /// A representing the asynchronous operation. - public static Image Load(DecoderOptions options, Stream stream, out IImageFormat format) - where TPixel : unmanaged, IPixel - { - Image? image = WithSeekableStream(options, stream, s => Decode(options, s)); - - if (image is null) - { - ThrowNotLoaded(options); - } - - format = image.Metadata.DecodedImageFormat!; - return image; - } - - /// - /// Create a new instance of the class from the given stream. - /// - /// The general decoder options. /// The stream containing image information. /// The token to monitor for cancellation requests. - /// The options are null. - /// The stream is null. - /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// A representing the asynchronous operation. - public static async Task<(Image Image, IImageFormat Format)> LoadWithFormatAsync( - DecoderOptions options, - Stream stream, - CancellationToken cancellationToken = default) - { - Image? image = await WithSeekableStreamAsync(options, stream, (s, ct) => DecodeAsync(options, s, ct), cancellationToken) - .ConfigureAwait(false); - - if (image is null) - { - ThrowNotLoaded(options); - } - - return new(image, image.Metadata.DecodedImageFormat!); - } - - /// - /// Create a new instance of the class from the given stream. - /// - /// The general decoder options. - /// The stream containing image information. - /// The token to monitor for cancellation requests. - /// The options are null. + /// A representing the asynchronous operation. /// The stream is null. /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// The pixel format. - /// A representing the asynchronous operation. - public static async Task<(Image Image, IImageFormat Format)> LoadWithFormatAsync( - DecoderOptions options, - Stream stream, - CancellationToken cancellationToken = default) + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Task> LoadAsync(Stream stream, CancellationToken cancellationToken = default) where TPixel : unmanaged, IPixel - { - Image? image = await WithSeekableStreamAsync(options, stream, (s, ct) => DecodeAsync(options, s, ct), cancellationToken) - .ConfigureAwait(false); - - if (image is null) - { - ThrowNotLoaded(options); - } - - return new(image, image.Metadata.DecodedImageFormat!); - } + => LoadAsync(DecoderOptions.Default, stream, cancellationToken); /// - /// Create a new instance of the class from the given stream. + /// Creates a new instance of the class from the given stream. /// + /// The pixel format. /// The general decoder options. /// The stream containing image information. /// The token to monitor for cancellation requests. + /// A representing the asynchronous operation. /// The options are null. /// The stream is null. /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// The pixel format. - /// A representing the asynchronous operation. - public static async Task> LoadAsync( + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Task> LoadAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) where TPixel : unmanaged, IPixel - { - (Image img, _) = await LoadWithFormatAsync(options, stream, cancellationToken) - .ConfigureAwait(false); - return img; - } - - /// - /// Decode a new instance of the class from the given stream. - /// The pixel format is selected by the decoder. - /// - /// The general decoder options. - /// The stream containing image information. - /// The format type of the decoded image. - /// The options are null. - /// The stream is null. - /// The stream is not readable or the image format is not supported. - /// Image format not recognised. - /// Image contains invalid content. - /// A new . - public static Image Load(DecoderOptions options, Stream stream, out IImageFormat format) - { - Image? image = WithSeekableStream(options, stream, s => Decode(options, s)); - if (image is null) - { - ThrowNotLoaded(options); - } - - format = image.Metadata.DecodedImageFormat!; - return image; - } + => WithSeekableStreamAsync(options, stream, (s, ct) => DecodeAsync(options, s, ct), cancellationToken); /// /// Performs the given action against the stream ensuring that it is seekable. @@ -549,18 +380,4 @@ public abstract partial class Image return await action(memoryStream, cancellationToken).ConfigureAwait(false); } - - [DoesNotReturn] - private static void ThrowNotLoaded(DecoderOptions options) - { - StringBuilder sb = new(); - sb.AppendLine("Image cannot be loaded. Available decoders:"); - - foreach (KeyValuePair val in options.Configuration.ImageFormatsManager.ImageDecoders) - { - sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine); - } - - throw new UnknownImageFormatException(sb.ToString()); - } } diff --git a/src/ImageSharp/Image.LoadPixelData.cs b/src/ImageSharp/Image.LoadPixelData.cs index 9a37adb3c..53b672b7d 100644 --- a/src/ImageSharp/Image.LoadPixelData.cs +++ b/src/ImageSharp/Image.LoadPixelData.cs @@ -72,7 +72,7 @@ public abstract partial class Image int count = width * height; Guard.MustBeGreaterThanOrEqualTo(data.Length, count, nameof(data)); - var image = new Image(configuration, width, height); + Image image = new(configuration, width, height); data = data[..count]; data.CopyTo(image.Frames.RootFrame.PixelBuffer.FastMemoryGroup); diff --git a/src/ImageSharp/ImageExtensions.cs b/src/ImageSharp/ImageExtensions.cs index 7cd8a7b2f..04930a268 100644 --- a/src/ImageSharp/ImageExtensions.cs +++ b/src/ImageSharp/ImageExtensions.cs @@ -95,7 +95,7 @@ public static partial class ImageExtensions throw new NotSupportedException("Cannot write to the stream."); } - IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format); + IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.GetEncoder(format); if (encoder is null) { @@ -139,7 +139,7 @@ public static partial class ImageExtensions throw new NotSupportedException("Cannot write to the stream."); } - IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format); + IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.GetEncoder(format); if (encoder is null) { diff --git a/tests/ImageSharp.Tests/Formats/Bmp/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Bmp/ImageExtensionsTest.cs index fbf9b20a9..1f5686cd7 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/ImageExtensionsTest.cs @@ -15,15 +15,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsBmp_Path.bmp"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsBmp(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/bmp", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is BmpFormat); } [Fact] @@ -32,15 +30,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsBmpAsync_Path.bmp"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsBmpAsync(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/bmp", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is BmpFormat); } [Fact] @@ -49,15 +45,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsBmp_Path_Encoder.bmp"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsBmp(file, new BmpEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/bmp", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is BmpFormat); } [Fact] @@ -66,86 +60,76 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsBmpAsync_Path_Encoder.bmp"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsBmpAsync(file, new BmpEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/bmp", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is BmpFormat); } [Fact] public void SaveAsBmp_Stream() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsBmp(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/bmp", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is BmpFormat); } [Fact] public async Task SaveAsBmpAsync_StreamAsync() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsBmpAsync(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/bmp", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is BmpFormat); } [Fact] public void SaveAsBmp_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsBmp(memoryStream, new BmpEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/bmp", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is BmpFormat); } [Fact] public async Task SaveAsBmpAsync_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsBmpAsync(memoryStream, new BmpEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/bmp", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is BmpFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs index 400af5e45..303703f74 100644 --- a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs +++ b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs @@ -207,10 +207,10 @@ public class GeneralFormatTests foreach (TestFile file in Files) { byte[] serialized; - using (Image image = Image.Load(file.Bytes, out IImageFormat mimeType)) + using (Image image = Image.Load(file.Bytes)) using (MemoryStream memoryStream = new()) { - image.Save(memoryStream, mimeType); + image.Save(memoryStream, image.Metadata.DecodedImageFormat); memoryStream.Flush(); serialized = memoryStream.ToArray(); } @@ -264,14 +264,13 @@ public class GeneralFormatTests } [Fact] - public void IdentifyReturnsNullWithInvalidStream() + public void Identify_UnknownImageFormatException_WithInvalidStream() { byte[] invalid = new byte[10]; using MemoryStream memoryStream = new(invalid); - Image.TryIdentify(memoryStream, out ImageInfo imageInfo); - Assert.Null(imageInfo); + Assert.Throws(() => Image.TryIdentify(invalid, out ImageInfo imageInfo)); } private static IImageFormat GetFormat(string format) diff --git a/tests/ImageSharp.Tests/Formats/Gif/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Gif/ImageExtensionsTest.cs index 8aac817b1..3ea0c2240 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/ImageExtensionsTest.cs @@ -15,15 +15,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsGif_Path.gif"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsGif(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/gif", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is GifFormat); } [Fact] @@ -32,15 +30,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsGifAsync_Path.gif"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsGifAsync(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/gif", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is GifFormat); } [Fact] @@ -49,15 +45,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsGif_Path_Encoder.gif"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsGif(file, new GifEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/gif", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is GifFormat); } [Fact] @@ -66,86 +60,76 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsGifAsync_Path_Encoder.gif"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsGifAsync(file, new GifEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/gif", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is GifFormat); } [Fact] public void SaveAsGif_Stream() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsGif(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/gif", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is GifFormat); } [Fact] public async Task SaveAsGifAsync_StreamAsync() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsGifAsync(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/gif", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is GifFormat); } [Fact] public void SaveAsGif_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsGif(memoryStream, new GifEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/gif", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is GifFormat); } [Fact] public async Task SaveAsGifAsync_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsGifAsync(memoryStream, new GifEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/gif", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is GifFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs index bfaa2166a..8d65eecb9 100644 --- a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs +++ b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs @@ -74,12 +74,12 @@ public class ImageFormatManagerTests { IImageEncoder encoder1 = new Mock().Object; this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder1); - IImageEncoder found = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat); + IImageEncoder found = this.FormatsManagerEmpty.GetEncoder(TestFormat.GlobalTestFormat); Assert.Equal(encoder1, found); IImageEncoder encoder2 = new Mock().Object; this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder2); - IImageEncoder found2 = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat); + IImageEncoder found2 = this.FormatsManagerEmpty.GetEncoder(TestFormat.GlobalTestFormat); Assert.Equal(encoder2, found2); Assert.NotEqual(found, found2); } @@ -89,12 +89,12 @@ public class ImageFormatManagerTests { IImageDecoder decoder1 = new Mock().Object; this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder1); - IImageDecoder found = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat); + IImageDecoder found = this.FormatsManagerEmpty.GetDecoder(TestFormat.GlobalTestFormat); Assert.Equal(decoder1, found); IImageDecoder decoder2 = new Mock().Object; this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder2); - IImageDecoder found2 = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat); + IImageDecoder found2 = this.FormatsManagerEmpty.GetDecoder(TestFormat.GlobalTestFormat); Assert.Equal(decoder2, found2); Assert.NotEqual(found, found2); } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Jpg/ImageExtensionsTest.cs index 0e799612d..12392568f 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ImageExtensionsTest.cs @@ -16,15 +16,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsJpeg_Path.jpg"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsJpeg(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/jpeg", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is JpegFormat); } [Fact] @@ -33,15 +31,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsJpegAsync_Path.jpg"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsJpegAsync(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/jpeg", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is JpegFormat); } [Fact] @@ -50,15 +46,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsJpeg_Path_Encoder.jpg"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsJpeg(file, new JpegEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/jpeg", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is JpegFormat); } [Fact] @@ -67,86 +61,76 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsJpegAsync_Path_Encoder.jpg"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsJpegAsync(file, new JpegEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/jpeg", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is JpegFormat); } [Fact] public void SaveAsJpeg_Stream() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsJpeg(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/jpeg", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is JpegFormat); } [Fact] public async Task SaveAsJpegAsync_StreamAsync() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsJpegAsync(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/jpeg", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is JpegFormat); } [Fact] public void SaveAsJpeg_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsJpeg(memoryStream, new JpegEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/jpeg", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is JpegFormat); } [Fact] public async Task SaveAsJpegAsync_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsJpegAsync(memoryStream, new JpegEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/jpeg", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is JpegFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs index 80417653d..5fecb2f9f 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs @@ -75,8 +75,8 @@ public partial class JpegDecoderTests [MemberData(nameof(RatioFiles))] public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); using Image image = JpegDecoder.Instance.Decode(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); @@ -88,8 +88,8 @@ public partial class JpegDecoderTests [MemberData(nameof(RatioFiles))] public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); ImageInfo image = JpegDecoder.Instance.Identify(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); @@ -101,8 +101,8 @@ public partial class JpegDecoderTests [MemberData(nameof(RatioFiles))] public async Task Identify_VerifyRatioAsync(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); ImageInfo image = await JpegDecoder.Instance.IdentifyAsync(DecoderOptions.Default, stream); ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); @@ -114,8 +114,8 @@ public partial class JpegDecoderTests [MemberData(nameof(QualityFiles))] public void Identify_VerifyQuality(string imagePath, int quality) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); ImageInfo image = JpegDecoder.Instance.Identify(DecoderOptions.Default, stream); JpegMetadata meta = image.Metadata.GetJpegMetadata(); Assert.Equal(quality, meta.Quality); @@ -125,8 +125,8 @@ public partial class JpegDecoderTests [MemberData(nameof(QualityFiles))] public void Decode_VerifyQuality(string imagePath, int quality) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); using Image image = JpegDecoder.Instance.Decode(DecoderOptions.Default, stream); JpegMetadata meta = image.Metadata.GetJpegMetadata(); Assert.Equal(quality, meta.Quality); @@ -136,8 +136,8 @@ public partial class JpegDecoderTests [MemberData(nameof(QualityFiles))] public async Task Decode_VerifyQualityAsync(string imagePath, int quality) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); using Image image = await JpegDecoder.Instance.DecodeAsync(DecoderOptions.Default, stream); JpegMetadata meta = image.Metadata.GetJpegMetadata(); Assert.Equal(quality, meta.Quality); @@ -153,8 +153,8 @@ public partial class JpegDecoderTests [InlineData(TestImages.Jpeg.Baseline.Jpeg411, JpegEncodingColor.YCbCrRatio411)] public void Identify_DetectsCorrectColorType(string imagePath, JpegEncodingColor expectedColorType) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); ImageInfo image = JpegDecoder.Instance.Identify(DecoderOptions.Default, stream); JpegMetadata meta = image.Metadata.GetJpegMetadata(); Assert.Equal(expectedColorType, meta.ColorType); @@ -176,8 +176,8 @@ public partial class JpegDecoderTests private static void TestImageInfo(string imagePath, IImageDecoder decoder, bool useIdentify, Action test) { - var testFile = TestFile.Create(imagePath); - using var stream = new MemoryStream(testFile.Bytes, false); + TestFile testFile = TestFile.Create(imagePath); + using MemoryStream stream = new(testFile.Bytes, false); if (useIdentify) { ImageInfo imageInfo = decoder.Identify(DecoderOptions.Default, stream); @@ -318,10 +318,10 @@ public partial class JpegDecoderTests [Fact] public void EncodedStringTags_WriteAndRead() { - using var memoryStream = new MemoryStream(); - using (var image = Image.Load(TestFile.GetInputFileFullPath(TestImages.Jpeg.Baseline.Calliphora))) + using MemoryStream memoryStream = new(); + using (Image image = Image.Load(TestFile.GetInputFileFullPath(TestImages.Jpeg.Baseline.Calliphora))) { - var exif = new ExifProfile(); + ExifProfile exif = new(); exif.SetValue(ExifTag.GPSDateStamp, "2022-01-06"); @@ -343,7 +343,7 @@ public partial class JpegDecoderTests } memoryStream.Seek(0, SeekOrigin.Begin); - using (var image = Image.Load(memoryStream)) + using (Image image = Image.Load(memoryStream)) { ExifProfile exif = image.Metadata.ExifProfile; VerifyEncodedStrings(exif); @@ -353,7 +353,7 @@ public partial class JpegDecoderTests [Fact] public void EncodedStringTags_Read() { - using var image = Image.Load(TestFile.GetInputFileFullPath(TestImages.Jpeg.Baseline.Calliphora_EncodedStrings)); + using Image image = Image.Load(TestFile.GetInputFileFullPath(TestImages.Jpeg.Baseline.Calliphora_EncodedStrings)); ExifProfile exif = image.Metadata.ExifProfile; VerifyEncodedStrings(exif); } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 18b4e1fba..1d5a7e0ff 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -35,7 +35,7 @@ public partial class JpegDecoderTests if (!CustomToleranceValues.TryGetValue(file, out float tolerance)) { - bool baseline = file.IndexOf("baseline", StringComparison.OrdinalIgnoreCase) >= 0; + bool baseline = file.Contains("baseline", StringComparison.OrdinalIgnoreCase); tolerance = baseline ? BaselineTolerance : ProgressiveTolerance; } @@ -68,9 +68,9 @@ public partial class JpegDecoderTests { JpegDecoderOptions options = new(); byte[] bytes = TestFile.Create(TestImages.Jpeg.Progressive.Progress).Bytes; - using var ms = new MemoryStream(bytes); - using var bufferedStream = new BufferedReadStream(Configuration.Default, ms); - using var decoder = new JpegDecoderCore(options); + using MemoryStream ms = new(bytes); + using BufferedReadStream bufferedStream = new(Configuration.Default, ms); + using JpegDecoderCore decoder = new(options); using Image image = decoder.Decode(bufferedStream, cancellationToken: default); // I don't know why these numbers are different. All I know is that the decoder works @@ -85,7 +85,7 @@ public partial class JpegDecoderTests public void Decode_NonGeneric_CreatesRgb24Image() { string file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Jpeg420Small); - using var image = Image.Load(file); + using Image image = Image.Load(file); Assert.IsType>(image); } diff --git a/tests/ImageSharp.Tests/Formats/Pbm/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Pbm/ImageExtensionsTest.cs index fba734f0e..1643e3dda 100644 --- a/tests/ImageSharp.Tests/Formats/Pbm/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Pbm/ImageExtensionsTest.cs @@ -15,15 +15,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsPbm_Path.pbm"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsPbm(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/x-portable-pixmap", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PbmFormat); } [Fact] @@ -32,15 +30,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsPbmAsync_Path.pbm"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsPbmAsync(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/x-portable-pixmap", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PbmFormat); } [Fact] @@ -49,15 +45,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsPbm_Path_Encoder.pbm"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsPbm(file, new PbmEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/x-portable-pixmap", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PbmFormat); } [Fact] @@ -66,86 +60,76 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsPbmAsync_Path_Encoder.pbm"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsPbmAsync(file, new PbmEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/x-portable-pixmap", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PbmFormat); } [Fact] public void SaveAsPbm_Stream() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsPbm(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/x-portable-pixmap", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is PbmFormat); } [Fact] public async Task SaveAsPbmAsync_StreamAsync() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsPbmAsync(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/x-portable-pixmap", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is PbmFormat); } [Fact] public void SaveAsPbm_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsPbm(memoryStream, new PbmEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/x-portable-pixmap", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is PbmFormat); } [Fact] public async Task SaveAsPbmAsync_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsPbmAsync(memoryStream, new PbmEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/x-portable-pixmap", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is PbmFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/Png/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Png/ImageExtensionsTest.cs index 321250fee..313b779e0 100644 --- a/tests/ImageSharp.Tests/Formats/Png/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Png/ImageExtensionsTest.cs @@ -16,15 +16,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsPng_Path.png"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsPng(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] @@ -33,15 +31,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsPngAsync_Path.png"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsPngAsync(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] @@ -50,15 +46,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsPng_Path_Encoder.png"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsPng(file, new PngEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] @@ -67,86 +61,76 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsPngAsync_Path_Encoder.png"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsPngAsync(file, new PngEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] public void SaveAsPng_Stream() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsPng(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] public async Task SaveAsPngAsync_StreamAsync() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsPngAsync(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] public void SaveAsPng_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsPng(memoryStream, new PngEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] public async Task SaveAsPngAsync_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsPngAsync(memoryStream, new PngEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is PngFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/Tga/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Tga/ImageExtensionsTest.cs index 8c0cfd5d1..fe9612543 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/ImageExtensionsTest.cs @@ -15,15 +15,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsTga_Path.tga"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsTga(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/tga", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is TgaFormat); } [Fact] @@ -32,15 +30,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsTgaAsync_Path.tga"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsTgaAsync(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/tga", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is TgaFormat); } [Fact] @@ -49,15 +45,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsTga_Path_Encoder.tga"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsTga(file, new TgaEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/tga", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is TgaFormat); } [Fact] @@ -66,86 +60,76 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsTgaAsync_Path_Encoder.tga"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsTgaAsync(file, new TgaEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/tga", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is TgaFormat); } [Fact] public void SaveAsTga_Stream() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsTga(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/tga", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is TgaFormat); } [Fact] public async Task SaveAsTgaAsync_StreamAsync() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsTgaAsync(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/tga", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is TgaFormat); } [Fact] public void SaveAsTga_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsTga(memoryStream, new TgaEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/tga", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is TgaFormat); } [Fact] public async Task SaveAsTgaAsync_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsTgaAsync(memoryStream, new TgaEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/tga", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is TgaFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs index 5910a86ac..f1efe47f9 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs @@ -26,7 +26,7 @@ public class TgaFileHeaderTests Assert.Throws(() => { - using (Image.Load(DecoderOptions.Default, stream, out IImageFormat _)) + using (Image.Load(DecoderOptions.Default, stream)) { } }); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs index 23806a18d..4ea4b632e 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs @@ -16,15 +16,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsTiff_Path.tiff"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsTiff(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/tiff", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is TiffFormat); } [Fact] @@ -33,15 +31,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); string file = Path.Combine(dir, "SaveAsTiffAsync_Path.tiff"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsTiffAsync(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/tiff", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is TiffFormat); } [Fact] @@ -50,15 +46,13 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsTiff_Path_Encoder.tiff"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsTiff(file, new TiffEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/tiff", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is TiffFormat); } [Fact] @@ -67,86 +61,76 @@ public class ImageExtensionsTest string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsTiffAsync_Path_Encoder.tiff"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsTiffAsync(file, new TiffEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/tiff", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is TiffFormat); } [Fact] public void SaveAsTiff_Stream() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsTiff(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/tiff", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is TiffFormat); } [Fact] public async Task SaveAsTiffAsync_StreamAsync() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsTiffAsync(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/tiff", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is TiffFormat); } [Fact] public void SaveAsTiff_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsTiff(memoryStream, new TiffEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/tiff", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is TiffFormat); } [Fact] public async Task SaveAsTiffAsync_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsTiffAsync(memoryStream, new TiffEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/tiff", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is TiffFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs index 737b023f1..5ed6c8dc4 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs @@ -16,15 +16,13 @@ public class ImageExtensionsTests string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTests)); string file = Path.Combine(dir, "SaveAsWebp_Path.webp"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsWebp(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/webp", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is WebpFormat); } [Fact] @@ -33,15 +31,13 @@ public class ImageExtensionsTests string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTests)); string file = Path.Combine(dir, "SaveAsWebpAsync_Path.webp"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsWebpAsync(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/webp", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is WebpFormat); } [Fact] @@ -50,15 +46,13 @@ public class ImageExtensionsTests string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsWebp_Path_Encoder.webp"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsWebp(file, new WebpEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/webp", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is WebpFormat); } [Fact] @@ -67,86 +61,76 @@ public class ImageExtensionsTests string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); string file = Path.Combine(dir, "SaveAsWebpAsync_Path_Encoder.webp"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsWebpAsync(file, new WebpEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/webp", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is WebpFormat); } [Fact] public void SaveAsWebp_Stream() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsWebp(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/webp", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is WebpFormat); } [Fact] public async Task SaveAsWebpAsync_StreamAsync() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsWebpAsync(memoryStream); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/webp", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is WebpFormat); } [Fact] public void SaveAsWebp_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.SaveAsWebp(memoryStream, new WebpEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/webp", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is WebpFormat); } [Fact] public async Task SaveAsWebpAsync_Stream_Encoder() { - using var memoryStream = new MemoryStream(); + using MemoryStream memoryStream = new(); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsWebpAsync(memoryStream, new WebpEncoder()); } memoryStream.Position = 0; - using (Image.Load(memoryStream, out IImageFormat mime)) - { - Assert.Equal("image/webp", mime.DefaultMimeType); - } + Image.TryDetectFormat(memoryStream, out IImageFormat format); + Assert.True(format is WebpFormat); } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs index 5a5f595ac..846538e42 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs @@ -125,17 +125,14 @@ public partial class ImageTests } [Fact] - public void WhenNoMatchingFormatFound_ReturnsNull() + public void WhenNoMatchingFormatFound_Throws_UnknownImageFormatException() { DecoderOptions options = new() { Configuration = new() }; - bool result = Image.TryDetectFormat(options, this.DataStream, out IImageFormat type); - - Assert.False(result); - Assert.Null(type); + Assert.Throws(() => Image.TryDetectFormat(options, this.DataStream, out IImageFormat type)); } [Fact] @@ -159,15 +156,14 @@ public partial class ImageTests } [Fact] - public async Task WhenNoMatchingFormatFoundAsync_ReturnsNull() + public Task WhenNoMatchingFormatFoundAsync_Throws_UnknownImageFormatException() { DecoderOptions options = new() { Configuration = new() }; - Attempt attempt = await Image.TryDetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false)); - Assert.Null(attempt.Value); + return Assert.ThrowsAsync(async () => await Image.TryDetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false))); } } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs index e9b61232a..9d0aa7a75 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs @@ -21,8 +21,6 @@ public partial class ImageTests private static byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes; - private IImageFormat LocalImageFormat => this.localImageFormatMock.Object; - private static IImageFormat ExpectedGlobalFormat { get @@ -131,16 +129,15 @@ public partial class ImageTests } [Fact] - public void WhenNoMatchingFormatFound_ReturnsNull() + public void WhenNoMatchingFormatFound_Throws_UnknownImageFormatException() { DecoderOptions options = new() { Configuration = new() }; - Assert.False(Image.TryIdentify(options, this.DataStream, out ImageInfo info)); - Assert.Null(info); + Assert.Throws(() => Image.TryIdentify(options, this.DataStream, out ImageInfo info)); } [Fact] - public void FromStream_ZeroLength_ReturnsNull() + public void FromStream_ZeroLength_Throws_UnknownImageFormatException() { // https://github.com/SixLabors/ImageSharp/issues/1903 using ZipArchive zipFile = new(new MemoryStream( @@ -159,8 +156,7 @@ public partial class ImageTests })); using Stream stream = zipFile.Entries[0].Open(); - Assert.False(Image.TryIdentify(stream, out ImageInfo info)); - Assert.Null(info); + Assert.Throws(() => Image.TryIdentify(stream, out ImageInfo info)); } [Fact] @@ -215,7 +211,7 @@ public partial class ImageTests } [Fact] - public async Task FromStreamAsync_ZeroLength_ReturnsNull() + public async Task FromStreamAsync_ZeroLength_Throws_UnknownImageFormatException() { // https://github.com/SixLabors/ImageSharp/issues/1903 using ZipArchive zipFile = new(new MemoryStream( @@ -234,10 +230,7 @@ public partial class ImageTests })); using Stream stream = zipFile.Entries[0].Open(); - Attempt attempt = await Image.TryIdentifyAsync(stream); - - Assert.False(attempt.Success); - Assert.Null(attempt.Value); + await Assert.ThrowsAsync(async () => await Image.TryIdentifyAsync(stream)); } [Fact] @@ -293,15 +286,12 @@ public partial class ImageTests } [Fact] - public async Task WhenNoMatchingFormatFoundAsync_ReturnsNull() + public Task WhenNoMatchingFormatFoundAsync_Throws_UnknownImageFormatException() { DecoderOptions options = new() { Configuration = new() }; AsyncStreamWrapper asyncStream = new(this.DataStream, () => false); - Attempt attempt = await Image.TryIdentifyAsync(options, asyncStream); - - Assert.False(attempt.Success); - Assert.Null(attempt.Value); + return Assert.ThrowsAsync(async () => await Image.TryIdentifyAsync(options, asyncStream)); } } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs index c8723e1f1..955693ff1 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs @@ -18,10 +18,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.MockFilePath); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat.Sample(), img); + using (Image img = Image.Load(options, this.MockFilePath)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat.Sample(), img); + } this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -34,10 +35,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.MockFilePath); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat.SampleAgnostic(), img); + using (Image img = Image.Load(options, this.MockFilePath)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat.SampleAgnostic(), img); + } this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -50,10 +52,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.MockFilePath, out IImageFormat format); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat, format); + using (Image img = Image.Load(options, this.MockFilePath)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat, img.Metadata.DecodedImageFormat); + } this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -66,17 +69,18 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.MockFilePath, out IImageFormat format); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat, format); + using (Image img = Image.Load(options, this.MockFilePath)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat, img.Metadata.DecodedImageFormat); + } this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); } [Fact] public void WhenFileNotFound_Throws() - => Assert.Throws( + => Assert.Throws( () => { DecoderOptions options = new() diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs index 67fec5e49..b355c42a6 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Bmp; using SixLabors.ImageSharp.PixelFormats; @@ -18,14 +17,14 @@ public partial class ImageTests [Fact] public void Path_Specific() { - using var img = Image.Load(this.Path); + using Image img = Image.Load(this.Path); VerifyDecodedImage(img); } [Fact] public void Path_Agnostic() { - using var img = Image.Load(this.Path); + using Image img = Image.Load(this.Path); VerifyDecodedImage(img); } @@ -53,17 +52,17 @@ public partial class ImageTests [Fact] public void Path_OutFormat_Specific() { - using var img = Image.Load(this.Path, out IImageFormat format); + using Image img = Image.Load(this.Path); VerifyDecodedImage(img); - Assert.IsType(format); + Assert.IsType(img.Metadata.DecodedImageFormat); } [Fact] public void Path_OutFormat_Agnostic() { - using var img = Image.Load(this.Path, out IImageFormat format); + using Image img = Image.Load(this.Path); VerifyDecodedImage(img); - Assert.IsType(format); + Assert.IsType(img.Metadata.DecodedImageFormat); } [Fact] diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs index 7946bdbed..3a47a0ea7 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs @@ -20,10 +20,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.ByteSpan); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat.Sample(), img); + using (Image img = Image.Load(options, this.ByteSpan)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat.Sample(), img); + } this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -36,10 +37,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.ByteSpan); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat.SampleAgnostic(), img); + using (Image img = Image.Load(options, this.ByteSpan)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat.SampleAgnostic(), img); + } this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -52,10 +54,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.ByteSpan, out IImageFormat format); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat, format); + using (Image img = Image.Load(options, this.ByteSpan)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat, img.Metadata.DecodedImageFormat); + } this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -68,10 +71,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.ByteSpan, out IImageFormat format); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat, format); + using (Image img = Image.Load(options, this.ByteSpan)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat, img.Metadata.DecodedImageFormat); + } this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs index 6ea469e65..a3d860596 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Bmp; using SixLabors.ImageSharp.PixelFormats; @@ -20,31 +19,31 @@ public partial class ImageTests [Fact] public void Bytes_Specific() { - using var img = Image.Load(ByteSpan); + using Image img = Image.Load(ByteSpan); VerifyDecodedImage(img); } [Fact] public void Bytes_Agnostic() { - using var img = Image.Load(ByteSpan); + using Image img = Image.Load(ByteSpan); VerifyDecodedImage(img); } [Fact] public void Bytes_OutFormat_Specific() { - using var img = Image.Load(ByteSpan, out IImageFormat format); + using Image img = Image.Load(ByteSpan); VerifyDecodedImage(img); - Assert.IsType(format); + Assert.IsType(img.Metadata.DecodedImageFormat); } [Fact] public void Bytes_OutFormat_Agnostic() { - using var img = Image.Load(ByteSpan, out IImageFormat format); + using Image img = Image.Load(ByteSpan); VerifyDecodedImage(img); - Assert.IsType(format); + Assert.IsType(img.Metadata.DecodedImageFormat); } } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs index 46e6dfac5..9d11d777a 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs @@ -18,10 +18,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.DataStream); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat.Sample(), img); + using (Image img = Image.Load(options, this.DataStream)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat.Sample(), img); + } this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -34,10 +35,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.DataStream); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat.SampleAgnostic(), img); + using (Image img = Image.Load(options, this.DataStream)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat.SampleAgnostic(), img); + } this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -50,10 +52,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var stream = new NonSeekableStream(this.DataStream); - var img = Image.Load(options, stream); - - Assert.NotNull(img); + NonSeekableStream stream = new(this.DataStream); + using (Image img = Image.Load(options, stream)) + { + Assert.NotNull(img); + } this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -66,10 +69,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var stream = new NonSeekableStream(this.DataStream); - Image img = await Image.LoadAsync(options, stream); - - Assert.NotNull(img); + NonSeekableStream stream = new(this.DataStream); + using (Image img = await Image.LoadAsync(options, stream)) + { + Assert.NotNull(img); + } this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -82,10 +86,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.DataStream, out IImageFormat format); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat, format); + using (Image img = Image.Load(options, this.DataStream)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat, img.Metadata.DecodedImageFormat); + } this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } @@ -98,10 +103,11 @@ public partial class ImageTests Configuration = this.TopLevelConfiguration }; - var img = Image.Load(options, this.DataStream, out IImageFormat format); - - Assert.NotNull(img); - Assert.Equal(this.TestFormat, format); + using (Image img = Image.Load(options, this.DataStream)) + { + Assert.NotNull(img); + Assert.Equal(this.TestFormat, img.Metadata.DecodedImageFormat); + } this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_ThrowsRightException.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_ThrowsRightException.cs index a051176a7..9b9f968bb 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_ThrowsRightException.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_ThrowsRightException.cs @@ -18,7 +18,7 @@ public partial class ImageTests public void Image_Load_Throws_UnknownImageFormatException() => Assert.Throws(() => { - using (Image.Load(DecoderOptions.Default, this.Stream, out IImageFormat format)) + using (Image.Load(DecoderOptions.Default, this.Stream)) { } }); @@ -27,7 +27,7 @@ public partial class ImageTests public void Image_Load_T_Throws_UnknownImageFormatException() => Assert.Throws(() => { - using (Image.Load(DecoderOptions.Default, this.Stream, out IImageFormat format)) + using (Image.Load(DecoderOptions.Default, this.Stream)) { } }); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs index 839749c5d..682ec2a41 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Bmp; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities; @@ -32,42 +31,42 @@ public partial class ImageTests [Fact] public void Stream_Specific() { - using var img = Image.Load(this.Stream); + using Image img = Image.Load(this.Stream); VerifyDecodedImage(img); } [Fact] public void Stream_Agnostic() { - using var img = Image.Load(this.Stream); + using Image img = Image.Load(this.Stream); VerifyDecodedImage(img); } [Fact] public void Stream_OutFormat_Specific() { - using var img = Image.Load(this.Stream, out IImageFormat format); + using Image img = Image.Load(this.Stream); VerifyDecodedImage(img); - Assert.IsType(format); + Assert.IsType(img.Metadata.DecodedImageFormat); } [Fact] public void Stream_OutFormat_Agnostic() { - using var img = Image.Load(this.Stream, out IImageFormat format); + using Image img = Image.Load(this.Stream); VerifyDecodedImage(img); - Assert.IsType(format); + Assert.IsType(img.Metadata.DecodedImageFormat); } [Fact] public async Task Async_Stream_OutFormat_Agnostic() { this.AllowSynchronousIO = false; - (Image Image, IImageFormat Format) formattedImage = await Image.LoadWithFormatAsync(this.Stream); - using (formattedImage.Image) + Image image = await Image.LoadAsync(this.Stream); + using (image) { - VerifyDecodedImage(formattedImage.Image); - Assert.IsType(formattedImage.Format); + VerifyDecodedImage(image); + Assert.IsType(image.Metadata.DecodedImageFormat); } } @@ -91,11 +90,11 @@ public partial class ImageTests public async Task Async_Stream_OutFormat_Specific() { this.AllowSynchronousIO = false; - (Image Image, IImageFormat Format) formattedImage = await Image.LoadWithFormatAsync(this.Stream); - using (formattedImage.Image) + Image image = await Image.LoadAsync(this.Stream); + using (image) { - VerifyDecodedImage(formattedImage.Image); - Assert.IsType(formattedImage.Format); + VerifyDecodedImage(image); + Assert.IsType(image.Metadata.DecodedImageFormat); } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Save.cs b/tests/ImageSharp.Tests/Image/ImageTests.Save.cs index 88a6b5890..8bdbb705a 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Save.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Save.cs @@ -19,30 +19,26 @@ public partial class ImageTests string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageTests)); string file = Path.Combine(dir, "DetectedEncoding.png"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.Save(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] - public void WhenExtensionIsUnknown_Throws() + public void WhenExtensionIsUnknown_Throws_UnknownImageFormatException() { string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageTests)); string file = Path.Combine(dir, "UnknownExtensionsEncoding_Throws.tmp"); - Assert.Throws( + Assert.Throws( () => { - using (var image = new Image(10, 10)) - { - image.Save(file); - } + using Image image = new(10, 10); + image.Save(file); }); } @@ -52,27 +48,23 @@ public partial class ImageTests string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageTests)); string file = Path.Combine(dir, "SetEncoding.dat"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { image.Save(file, new PngEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] public void ThrowsWhenDisposed() { - using var image = new Image(5, 5); + using Image image = new(5, 5); image.Dispose(); IImageEncoder encoder = Mock.Of(); - using (var stream = new MemoryStream()) - { - Assert.Throws(() => image.Save(stream, encoder)); - } + using MemoryStream stream = new(); + Assert.Throws(() => image.Save(stream, encoder)); } } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs b/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs index 3627ba2a6..b58d0cff3 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs @@ -21,30 +21,26 @@ public partial class ImageTests string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageTests)); string file = Path.Combine(dir, "DetectedEncodingAsync.png"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsync(file); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PngFormat); } [Fact] - public async Task WhenExtensionIsUnknown_Throws() + public Task WhenExtensionIsUnknown_Throws_UnknownImageFormatException() { string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageTests)); string file = Path.Combine(dir, "UnknownExtensionsEncoding_Throws.tmp"); - await Assert.ThrowsAsync( + return Assert.ThrowsAsync( async () => { - using (var image = new Image(10, 10)) - { - await image.SaveAsync(file); - } + using Image image = new(10, 10); + await image.SaveAsync(file); }); } @@ -54,15 +50,13 @@ public partial class ImageTests string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageTests)); string file = Path.Combine(dir, "SetEncoding.dat"); - using (var image = new Image(10, 10)) + using (Image image = new(10, 10)) { await image.SaveAsync(file, new PngEncoder()); } - using (Image.Load(file, out IImageFormat mime)) - { - Assert.Equal("image/png", mime.DefaultMimeType); - } + Image.TryDetectFormat(file, out IImageFormat format); + Assert.True(format is PngFormat); } [Theory] @@ -74,39 +68,29 @@ public partial class ImageTests [InlineData("test.gif", "image/gif")] public async Task SaveStreamWithMime(string filename, string mimeType) { - using (var image = new Image(5, 5)) - { - string ext = Path.GetExtension(filename); - image.GetConfiguration().ImageFormatsManager.TryFindFormatByFileExtension(ext, out IImageFormat format); - Assert.Equal(mimeType, format!.DefaultMimeType); - - using (var stream = new MemoryStream()) - { - var asyncStream = new AsyncStreamWrapper(stream, () => false); - await image.SaveAsync(asyncStream, format); + using Image image = new(5, 5); + string ext = Path.GetExtension(filename); + image.GetConfiguration().ImageFormatsManager.TryFindFormatByFileExtension(ext, out IImageFormat format); + Assert.Equal(mimeType, format!.DefaultMimeType); - stream.Position = 0; + using MemoryStream stream = new(); + AsyncStreamWrapper asyncStream = new(stream, () => false); + await image.SaveAsync(asyncStream, format); - (Image Image, IImageFormat Format) imf = await Image.LoadWithFormatAsync(stream); + stream.Position = 0; - Assert.Equal(format, imf.Format); - Assert.Equal(mimeType, imf.Format.DefaultMimeType); - - imf.Image.Dispose(); - } - } + Image.TryDetectFormat(stream, out IImageFormat format2); + Assert.Equal(format, format2); } [Fact] public async Task ThrowsWhenDisposed() { - var image = new Image(5, 5); + Image image = new(5, 5); image.Dispose(); IImageEncoder encoder = Mock.Of(); - using (var stream = new MemoryStream()) - { - await Assert.ThrowsAsync(async () => await image.SaveAsync(stream, encoder)); - } + using MemoryStream stream = new(); + await Assert.ThrowsAsync(async () => await image.SaveAsync(stream, encoder)); } [Theory] @@ -118,27 +102,23 @@ public partial class ImageTests [InlineData("test.gif")] public async Task SaveAsync_NeverCallsSyncMethods(string filename) { - using (var image = new Image(5, 5)) - { - IImageEncoder encoder = image.DetectEncoder(filename); - using (var stream = new MemoryStream()) - { - var asyncStream = new AsyncStreamWrapper(stream, () => false); - await image.SaveAsync(asyncStream, encoder); - } - } + using Image image = new(5, 5); + IImageEncoder encoder = image.DetectEncoder(filename); + using MemoryStream stream = new(); + AsyncStreamWrapper asyncStream = new(stream, () => false); + await image.SaveAsync(asyncStream, encoder); } [Fact] public async Task SaveAsync_WithNonSeekableStream_IsCancellable() { - using var image = new Image(4000, 4000); - var encoder = new PngEncoder() { CompressionLevel = PngCompressionLevel.BestCompression }; - using var stream = new MemoryStream(); - var asyncStream = new AsyncStreamWrapper(stream, () => false); - var cts = new CancellationTokenSource(); + using Image image = new(4000, 4000); + PngEncoder encoder = new() { CompressionLevel = PngCompressionLevel.BestCompression }; + using MemoryStream stream = new(); + AsyncStreamWrapper asyncStream = new(stream, () => false); + CancellationTokenSource cts = new(); - var pausedStream = new PausedStream(asyncStream); + PausedStream pausedStream = new(asyncStream); pausedStream.OnWaiting(s => { cts.Cancel(); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.cs b/tests/ImageSharp.Tests/Image/ImageTests.cs index 02ccfb713..eefa81835 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.cs @@ -23,7 +23,7 @@ public partial class ImageTests [Fact] public void Width_Height() { - using (var image = new Image(11, 23)) + using (Image image = new(11, 23)) { Assert.Equal(11, image.Width); Assert.Equal(23, image.Height); @@ -40,7 +40,7 @@ public partial class ImageTests { Configuration configuration = Configuration.Default.Clone(); - using (var image = new Image(configuration, 11, 23)) + using (Image image = new(configuration, 11, 23)) { Assert.Equal(11, image.Width); Assert.Equal(23, image.Height); @@ -58,7 +58,7 @@ public partial class ImageTests Configuration configuration = Configuration.Default.Clone(); Rgba32 color = Color.Aquamarine; - using (var image = new Image(configuration, 11, 23, color)) + using (Image image = new(configuration, 11, 23, color)) { Assert.Equal(11, image.Width); Assert.Equal(23, image.Height); @@ -77,9 +77,9 @@ public partial class ImageTests byte dirtyValue = 123; configuration.MemoryAllocator = new TestMemoryAllocator(dirtyValue); - var metadata = new ImageMetadata(); + ImageMetadata metadata = new(); - using (var image = Image.CreateUninitialized(configuration, 21, 22, metadata)) + using (Image image = Image.CreateUninitialized(configuration, 21, 22, metadata)) { Assert.Equal(21, image.Width); Assert.Equal(22, image.Height); @@ -108,7 +108,7 @@ public partial class ImageTests this.LimitBufferCapacity(100); } - using var image = new Image(this.configuration, 10, 10); + using Image image = new(this.configuration, 10, 10); Rgba32 val = image[3, 4]; Assert.Equal(default(Rgba32), val); image[3, 4] = Color.Red; @@ -116,7 +116,7 @@ public partial class ImageTests Assert.Equal(Color.Red.ToRgba32(), val); } - public static TheoryData OutOfRangeData = new TheoryData() + public static TheoryData OutOfRangeData = new() { { false, -1 }, { false, 10 }, @@ -133,7 +133,7 @@ public partial class ImageTests this.LimitBufferCapacity(100); } - using var image = new Image(this.configuration, 10, 10); + using Image image = new(this.configuration, 10, 10); ArgumentOutOfRangeException ex = Assert.Throws(() => _ = image[x, 3]); Assert.Equal("x", ex.ParamName); } @@ -147,7 +147,7 @@ public partial class ImageTests this.LimitBufferCapacity(100); } - using var image = new Image(this.configuration, 10, 10); + using Image image = new(this.configuration, 10, 10); ArgumentOutOfRangeException ex = Assert.Throws(() => image[x, 3] = default); Assert.Equal("x", ex.ParamName); } @@ -161,7 +161,7 @@ public partial class ImageTests this.LimitBufferCapacity(100); } - using var image = new Image(this.configuration, 10, 10); + using Image image = new(this.configuration, 10, 10); ArgumentOutOfRangeException ex = Assert.Throws(() => image[3, y] = default); Assert.Equal("y", ex.ParamName); } @@ -178,7 +178,7 @@ public partial class ImageTests this.LimitBufferCapacity(20); } - using var image = new Image(this.configuration, 10, 10); + using Image image = new(this.configuration, 10, 10); if (disco) { Assert.True(image.GetPixelMemoryGroup().Count > 1); @@ -204,7 +204,7 @@ public partial class ImageTests [InlineData(true)] public void CopyPixelDataTo_DestinationTooShort_Throws(bool byteSpan) { - using var image = new Image(this.configuration, 10, 10); + using Image image = new(this.configuration, 10, 10); Assert.ThrowsAny(() => { @@ -243,7 +243,7 @@ public partial class ImageTests [Fact] public void NullReference_Throws() { - using var img = new Image(1, 1); + using Image img = new(1, 1); Assert.Throws(() => img.ProcessPixelRows(null)); @@ -262,7 +262,7 @@ public partial class ImageTests public void MultipleDisposeCalls() { - var image = new Image(this.configuration, 10, 10); + Image image = new(this.configuration, 10, 10); image.Dispose(); image.Dispose(); } @@ -270,24 +270,24 @@ public partial class ImageTests [Fact] public void NonPrivateProperties_ObjectDisposedException() { - var image = new Image(this.configuration, 10, 10); - var genericImage = (Image)image; + Image image = new(this.configuration, 10, 10); + Image genericImage = (Image)image; image.Dispose(); // Image - Assert.Throws(() => { var prop = image.Frames; }); + Assert.Throws(() => { ImageFrameCollection prop = image.Frames; }); // Image - Assert.Throws(() => { var prop = genericImage.Frames; }); + Assert.Throws(() => { ImageFrameCollection prop = genericImage.Frames; }); } [Fact] public void Save_ObjectDisposedException() { - using var stream = new MemoryStream(); - var image = new Image(this.configuration, 10, 10); - var encoder = new JpegEncoder(); + using MemoryStream stream = new(); + Image image = new(this.configuration, 10, 10); + JpegEncoder encoder = new(); image.Dispose(); @@ -307,18 +307,18 @@ public partial class ImageTests [Fact] public void NonPrivateMethods_ObjectDisposedException() { - var image = new Image(this.configuration, 10, 10); - var genericImage = (Image)image; + Image image = new(this.configuration, 10, 10); + Image genericImage = (Image)image; image.Dispose(); // Image - Assert.Throws(() => { var res = image.Clone(this.configuration); }); - Assert.Throws(() => { var res = image.CloneAs(this.configuration); }); - Assert.Throws(() => { var res = image.DangerousTryGetSinglePixelMemory(out Memory _); }); + Assert.Throws(() => { Image res = image.Clone(this.configuration); }); + Assert.Throws(() => { Image res = image.CloneAs(this.configuration); }); + Assert.Throws(() => { bool res = image.DangerousTryGetSinglePixelMemory(out Memory _); }); // Image - Assert.Throws(() => { var res = genericImage.CloneAs(this.configuration); }); + Assert.Throws(() => { Image res = genericImage.CloneAs(this.configuration); }); } } @@ -327,29 +327,29 @@ public partial class ImageTests [Fact] public void KnownExtension_ReturnsEncoder() { - using var image = new Image(1, 1); + using Image image = new(1, 1); IImageEncoder encoder = image.DetectEncoder("dummy.png"); Assert.NotNull(encoder); Assert.IsType(encoder); } [Fact] - public void UnknownExtension_ThrowsNotSupportedException() + public void UnknownExtension_ThrowsUnknownImageFormatException() { - using var image = new Image(1, 1); - Assert.Throws(() => image.DetectEncoder("dummy.yolo")); + using Image image = new(1, 1); + Assert.Throws(() => image.DetectEncoder("dummy.yolo")); } [Fact] - public void NoDetectorRegisteredForKnownExtension_ThrowsNotSupportedException() + public void NoDetectorRegisteredForKnownExtension_ThrowsUnknownImageFormatException() { - var configuration = new Configuration(); - var format = new TestFormat(); + Configuration configuration = new(); + TestFormat format = new(); configuration.ImageFormatsManager.AddImageFormat(format); configuration.ImageFormatsManager.AddImageFormatDetector(new MockImageFormatDetector(format)); - using var image = new Image(configuration, 1, 1); - Assert.Throws(() => image.DetectEncoder($"dummy.{format.Extension}")); + using Image image = new(configuration, 1, 1); + Assert.Throws(() => image.DetectEncoder($"dummy.{format.Extension}")); } } } diff --git a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs index 7309185c7..12caa6e7a 100644 --- a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs +++ b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs @@ -56,7 +56,7 @@ public class LargeImageIntegrationTests Configuration configuration = Configuration.Default.Clone(); configuration.PreferContiguousImageBuffers = true; configuration.ImageFormatsManager.TryFindFormatByFileExtension(formatInner, out IImageFormat format); - IImageEncoder encoder = configuration.ImageFormatsManager.FindEncoder(format!); + IImageEncoder encoder = configuration.ImageFormatsManager.GetEncoder(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/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index 38615f09e..86b9223c2 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -38,15 +38,13 @@ public class ResizeTests { string filePath = TestFile.GetInputFileFullPath(TestImages.Jpeg.Baseline.Calliphora); - using (var image = Image.Load(filePath)) - { - image.Mutate(x => x.Resize(image.Size() / 2)); - string path = System.IO.Path.Combine( - TestEnvironment.CreateOutputDirectory(nameof(ResizeTests)), - nameof(this.Resize_PixelAgnostic) + ".png"); + using Image image = Image.Load(filePath); + image.Mutate(x => x.Resize(image.Size() / 2)); + string path = Path.Combine( + TestEnvironment.CreateOutputDirectory(nameof(ResizeTests)), + nameof(this.Resize_PixelAgnostic) + ".png"); - image.Save(path); - } + image.Save(path); } [Theory(Skip = "Debug only, enable manually")] @@ -63,11 +61,9 @@ public class ResizeTests provider.Configuration.WorkingBufferSizeHintInBytes = workingBufferSizeHintInKilobytes * 1024; - using (Image image = provider.GetImage()) - { - image.Mutate(x => x.Resize(destSize, destSize)); - image.DebugSave(provider, appendPixelTypeToFileName: false); - } + using Image image = provider.GetImage(); + image.Mutate(x => x.Resize(destSize, destSize)); + image.DebugSave(provider, appendPixelTypeToFileName: false); } [Theory] @@ -81,14 +77,12 @@ public class ResizeTests // [WithBasicTestPatternImages(15, 12, PixelTypes.Rgba32, 2, 3, 1, 2)] means: // resizing: (15, 12) -> (10, 6) // kernel dimensions: (3, 4) - using (Image image = provider.GetImage()) - { - var destSize = new Size(image.Width * wN / wD, image.Height * hN / hD); - image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false)); - FormattableString outputInfo = $"({wN}÷{wD},{hN}÷{hD})"; - image.DebugSave(provider, outputInfo, appendPixelTypeToFileName: false); - image.CompareToReferenceOutput(provider, outputInfo, appendPixelTypeToFileName: false); - } + using Image image = provider.GetImage(); + Size destSize = new Size(image.Width * wN / wD, image.Height * hN / hD); + image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false)); + FormattableString outputInfo = $"({wN}÷{wD},{hN}÷{hD})"; + image.DebugSave(provider, outputInfo, appendPixelTypeToFileName: false); + image.CompareToReferenceOutput(provider, outputInfo, appendPixelTypeToFileName: false); } private static readonly int SizeOfVector4 = Unsafe.SizeOf(); @@ -106,48 +100,44 @@ public class ResizeTests int workingBufferLimitInRows) where TPixel : unmanaged, IPixel { - using (Image image0 = provider.GetImage()) - { - Size destSize = image0.Size() / 4; - - var configuration = Configuration.CreateDefaultInstance(); - - int workingBufferSizeHintInBytes = workingBufferLimitInRows * destSize.Width * SizeOfVector4; - var allocator = new TestMemoryAllocator(); - allocator.EnableNonThreadSafeLogging(); - configuration.MemoryAllocator = allocator; - configuration.WorkingBufferSizeHintInBytes = workingBufferSizeHintInBytes; - - var verticalKernelMap = ResizeKernelMap.Calculate( - default, - destSize.Height, - image0.Height, - Configuration.Default.MemoryAllocator); - int minimumWorkerAllocationInBytes = verticalKernelMap.MaxDiameter * 2 * destSize.Width * SizeOfVector4; - verticalKernelMap.Dispose(); - - using (Image image = image0.Clone(configuration)) - { - image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false)); - - image.DebugSave( - provider, - testOutputDetails: workingBufferLimitInRows, - appendPixelTypeToFileName: false); - image.CompareToReferenceOutput( - ImageComparer.TolerantPercentage(0.004f), - provider, - testOutputDetails: workingBufferLimitInRows, - appendPixelTypeToFileName: false); + using Image image0 = provider.GetImage(); + Size destSize = image0.Size() / 4; + + Configuration configuration = Configuration.CreateDefaultInstance(); + + int workingBufferSizeHintInBytes = workingBufferLimitInRows * destSize.Width * SizeOfVector4; + TestMemoryAllocator allocator = new TestMemoryAllocator(); + allocator.EnableNonThreadSafeLogging(); + configuration.MemoryAllocator = allocator; + configuration.WorkingBufferSizeHintInBytes = workingBufferSizeHintInBytes; + + ResizeKernelMap verticalKernelMap = ResizeKernelMap.Calculate( + default, + destSize.Height, + image0.Height, + Configuration.Default.MemoryAllocator); + int minimumWorkerAllocationInBytes = verticalKernelMap.MaxDiameter * 2 * destSize.Width * SizeOfVector4; + verticalKernelMap.Dispose(); + + using Image image = image0.Clone(configuration); + image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false)); + + image.DebugSave( + provider, + testOutputDetails: workingBufferLimitInRows, + appendPixelTypeToFileName: false); + image.CompareToReferenceOutput( + ImageComparer.TolerantPercentage(0.004f), + provider, + testOutputDetails: workingBufferLimitInRows, + appendPixelTypeToFileName: false); - Assert.NotEmpty(allocator.AllocationLog); + Assert.NotEmpty(allocator.AllocationLog); - int maxAllocationSize = allocator.AllocationLog.Where( - e => e.ElementType == typeof(Vector4)).Max(e => e.LengthInBytes); + int maxAllocationSize = allocator.AllocationLog.Where( + e => e.ElementType == typeof(Vector4)).Max(e => e.LengthInBytes); - Assert.True(maxAllocationSize <= Math.Max(workingBufferSizeHintInBytes, minimumWorkerAllocationInBytes)); - } - } + Assert.True(maxAllocationSize <= Math.Max(workingBufferSizeHintInBytes, minimumWorkerAllocationInBytes)); } [Theory] @@ -188,13 +178,11 @@ public class ResizeTests public void Resize_Compand(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - image.Mutate(x => x.Resize(image.Size() / 2, true)); + using Image image = provider.GetImage(); + image.Mutate(x => x.Resize(image.Size() / 2, true)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider); } [Theory] @@ -223,7 +211,7 @@ public class ResizeTests provider.RunValidatingProcessorTest( x => { - var resizeOptions = new ResizeOptions() + ResizeOptions resizeOptions = new ResizeOptions() { Size = x.GetCurrentSize() / 2, Mode = ResizeMode.Crop, @@ -243,13 +231,11 @@ public class ResizeTests public void Resize_IsAppliedToAllFrames(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2, KnownResamplers.Bicubic)); + using Image image = provider.GetImage(); + image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2, KnownResamplers.Bicubic)); - // Comparer fights decoder with gif-s. Could not use CompareToReferenceOutput here :( - image.DebugSave(provider, extension: "gif"); - } + // Comparer fights decoder with gif-s. Could not use CompareToReferenceOutput here :( + image.DebugSave(provider, extension: "gif"); } [Theory] @@ -265,17 +251,13 @@ public class ResizeTests public void Resize_ThrowsForWrappedMemoryImage(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image0 = provider.GetImage()) - { - Assert.True(image0.DangerousTryGetSinglePixelMemory(out Memory imageMem)); - var mmg = TestMemoryManager.CreateAsCopyOf(imageMem.Span); + using Image image0 = provider.GetImage(); + Assert.True(image0.DangerousTryGetSinglePixelMemory(out Memory imageMem)); + TestMemoryManager mmg = TestMemoryManager.CreateAsCopyOf(imageMem.Span); - using (var image1 = Image.WrapMemory(mmg.Memory, image0.Width, image0.Height)) - { - Assert.ThrowsAny( - () => { image1.Mutate(x => x.Resize(image0.Width / 2, image0.Height / 2, true)); }); - } - } + using Image image1 = Image.WrapMemory(mmg.Memory, image0.Width, image0.Height); + Assert.ThrowsAny( + () => { image1.Mutate(x => x.Resize(image0.Width / 2, image0.Height / 2, true)); }); } [Theory] @@ -341,7 +323,7 @@ public class ResizeTests && TestEnvironment.NetCoreVersion == null && sampler is NearestNeighborResampler; - var comparer = ImageComparer.TolerantPercentage(allowHigherInaccuracy ? 0.3f : 0.017f); + ImageComparer comparer = ImageComparer.TolerantPercentage(allowHigherInaccuracy ? 0.3f : 0.017f); // Let's make the working buffer size non-default: provider.Configuration.WorkingBufferSizeHintInBytes = 16 * 1024 * SizeOfVector4; @@ -382,27 +364,25 @@ public class ResizeTests public void ResizeFromSourceRectangle(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - var sourceRectangle = new Rectangle( - image.Width / 8, - image.Height / 8, - image.Width / 4, - image.Height / 4); - var destRectangle = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); - - image.Mutate( - x => x.Resize( - image.Width, - image.Height, - KnownResamplers.Bicubic, - sourceRectangle, - destRectangle, - false)); - - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + using Image image = provider.GetImage(); + Rectangle sourceRectangle = new Rectangle( + image.Width / 8, + image.Height / 8, + image.Width / 4, + image.Height / 4); + Rectangle destRectangle = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); + + image.Mutate( + x => x.Resize( + image.Width, + image.Height, + KnownResamplers.Bicubic, + sourceRectangle, + destRectangle, + false)); + + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -410,13 +390,11 @@ public class ResizeTests public void ResizeHeightAndKeepAspect(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - image.Mutate(x => x.Resize(0, image.Height / 3, false)); + using Image image = provider.GetImage(); + image.Mutate(x => x.Resize(0, image.Height / 3, false)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -424,12 +402,10 @@ public class ResizeTests public void ResizeHeightCannotKeepAspectKeepsOnePixel(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - image.Mutate(x => x.Resize(0, 5)); - Assert.Equal(1, image.Width); - Assert.Equal(5, image.Height); - } + using Image image = provider.GetImage(); + image.Mutate(x => x.Resize(0, 5)); + Assert.Equal(1, image.Width); + Assert.Equal(5, image.Height); } [Theory] @@ -437,13 +413,11 @@ public class ResizeTests public void ResizeWidthAndKeepAspect(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - image.Mutate(x => x.Resize(image.Width / 3, 0, false)); + using Image image = provider.GetImage(); + image.Mutate(x => x.Resize(image.Width / 3, 0, false)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -451,12 +425,10 @@ public class ResizeTests public void ResizeWidthCannotKeepAspectKeepsOnePixel(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - image.Mutate(x => x.Resize(5, 0)); - Assert.Equal(5, image.Width); - Assert.Equal(1, image.Height); - } + using Image image = provider.GetImage(); + image.Mutate(x => x.Resize(5, 0)); + Assert.Equal(5, image.Width); + Assert.Equal(1, image.Height); } [Theory] @@ -464,20 +436,18 @@ public class ResizeTests public void ResizeWithBoxPadMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) + using Image image = provider.GetImage(); + ResizeOptions options = new ResizeOptions { - var options = new ResizeOptions - { - Size = new Size(image.Width + 200, image.Height + 200), - Mode = ResizeMode.BoxPad, - PadColor = Color.HotPink - }; + Size = new Size(image.Width + 200, image.Height + 200), + Mode = ResizeMode.BoxPad, + PadColor = Color.HotPink + }; - image.Mutate(x => x.Resize(options)); + image.Mutate(x => x.Resize(options)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -485,15 +455,13 @@ public class ResizeTests public void ResizeWithCropHeightMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - var options = new ResizeOptions { Size = new Size(image.Width, image.Height / 2) }; + using Image image = provider.GetImage(); + ResizeOptions options = new ResizeOptions { Size = new Size(image.Width, image.Height / 2) }; - image.Mutate(x => x.Resize(options)); + image.Mutate(x => x.Resize(options)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -501,15 +469,13 @@ public class ResizeTests public void ResizeWithCropWidthMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - var options = new ResizeOptions { Size = new Size(image.Width / 2, image.Height) }; + using Image image = provider.GetImage(); + ResizeOptions options = new ResizeOptions { Size = new Size(image.Width / 2, image.Height) }; - image.Mutate(x => x.Resize(options)); + image.Mutate(x => x.Resize(options)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -517,19 +483,17 @@ public class ResizeTests public void CanResizeLargeImageWithCropMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) + using Image image = provider.GetImage(); + ResizeOptions options = new ResizeOptions { - var options = new ResizeOptions - { - Size = new Size(480, 600), - Mode = ResizeMode.Crop - }; + Size = new Size(480, 600), + Mode = ResizeMode.Crop + }; - image.Mutate(x => x.Resize(options)); + image.Mutate(x => x.Resize(options)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -537,15 +501,13 @@ public class ResizeTests public void ResizeWithMaxMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - var options = new ResizeOptions { Size = new Size(300, 300), Mode = ResizeMode.Max }; + using Image image = provider.GetImage(); + ResizeOptions options = new ResizeOptions { Size = new Size(300, 300), Mode = ResizeMode.Max }; - image.Mutate(x => x.Resize(options)); + image.Mutate(x => x.Resize(options)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -553,19 +515,17 @@ public class ResizeTests public void ResizeWithMinMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) + using Image image = provider.GetImage(); + ResizeOptions options = new ResizeOptions { - var options = new ResizeOptions - { - Size = new Size((int)Math.Round(image.Width * .75F), (int)Math.Round(image.Height * .95F)), - Mode = ResizeMode.Min - }; + Size = new Size((int)Math.Round(image.Width * .75F), (int)Math.Round(image.Height * .95F)), + Mode = ResizeMode.Min + }; - image.Mutate(x => x.Resize(options)); + image.Mutate(x => x.Resize(options)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -573,20 +533,18 @@ public class ResizeTests public void ResizeWithPadMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) + using Image image = provider.GetImage(); + ResizeOptions options = new ResizeOptions { - var options = new ResizeOptions - { - Size = new Size(image.Width + 200, image.Height), - Mode = ResizeMode.Pad, - PadColor = Color.Lavender - }; + Size = new Size(image.Width + 200, image.Height), + Mode = ResizeMode.Pad, + PadColor = Color.Lavender + }; - image.Mutate(x => x.Resize(options)); + image.Mutate(x => x.Resize(options)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -594,19 +552,17 @@ public class ResizeTests public void ResizeWithStretchMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) + using Image image = provider.GetImage(); + ResizeOptions options = new ResizeOptions { - var options = new ResizeOptions - { - Size = new Size(image.Width / 2, image.Height), - Mode = ResizeMode.Stretch - }; + Size = new Size(image.Width / 2, image.Height), + Mode = ResizeMode.Stretch + }; - image.Mutate(x => x.Resize(options)); + image.Mutate(x => x.Resize(options)); - image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); - } + image.DebugSave(provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } [Theory] @@ -622,27 +578,23 @@ public class ResizeTests return; } - using (Image image = provider.GetImage()) - { - // Don't bother saving, we're testing the EXIF metadata updates. - image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2)); - } + using Image image = provider.GetImage(); + // Don't bother saving, we're testing the EXIF metadata updates. + image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2)); } [Fact] public void Issue1195() { - using (var image = new Image(2, 300)) - { - var size = new Size(50, 50); - image.Mutate(x => x - .Resize( - new ResizeOptions - { - Size = size, - Mode = ResizeMode.Max - })); - } + using Image image = new Image(2, 300); + Size size = new Size(50, 50); + image.Mutate(x => x + .Resize( + new ResizeOptions + { + Size = size, + Mode = ResizeMode.Max + })); } [Theory] @@ -653,20 +605,18 @@ public class ResizeTests [InlineData(3, 7)] public void Issue1342(int width, int height) { - using (var image = new Image(1, 1)) - { - var size = new Size(width, height); - image.Mutate(x => x - .Resize( - new ResizeOptions - { - Size = size, - Sampler = KnownResamplers.NearestNeighbor - })); + using Image image = new Image(1, 1); + Size size = new Size(width, height); + image.Mutate(x => x + .Resize( + new ResizeOptions + { + Size = size, + Sampler = KnownResamplers.NearestNeighbor + })); - Assert.Equal(width, image.Width); - Assert.Equal(height, image.Height); - } + Assert.Equal(width, image.Width); + Assert.Equal(height, image.Height); } [Theory] diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs index f44ae5b23..b91b5631b 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs @@ -24,13 +24,13 @@ public static partial class TestEnvironment internal static IImageDecoder GetReferenceDecoder(string filePath) { IImageFormat format = GetImageFormat(filePath); - return Configuration.ImageFormatsManager.FindDecoder(format); + return Configuration.ImageFormatsManager.GetDecoder(format); } internal static IImageEncoder GetReferenceEncoder(string filePath) { IImageFormat format = GetImageFormat(filePath); - return Configuration.ImageFormatsManager.FindEncoder(format); + return Configuration.ImageFormatsManager.GetEncoder(format); } internal static IImageFormat GetImageFormat(string filePath) From 7139a5284824cf8e9cf129f454edfa89ee2f142f Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 14 Jan 2023 17:42:23 +1000 Subject: [PATCH 10/16] Refactor Identify tests --- src/ImageSharp/Image.FromBytes.cs | 36 +++------ src/ImageSharp/Image.FromFile.cs | 55 ++++++------- src/ImageSharp/Image.FromStream.cs | 71 +++++++---------- .../Formats/Bmp/BmpDecoderTests.cs | 4 +- .../Formats/Bmp/BmpMetadataTests.cs | 2 +- .../Formats/GeneralFormatTests.cs | 4 +- .../Formats/Gif/GifDecoderTests.cs | 2 +- .../Formats/Pbm/PbmMetadataTests.cs | 6 +- .../Formats/Png/PngDecoderTests.cs | 4 +- .../Formats/Png/PngMetadataTests.cs | 6 +- .../Formats/Tga/TgaFileHeaderTests.cs | 2 +- .../Formats/Tiff/BigTiffDecoderTests.cs | 4 +- .../Formats/Tiff/TiffDecoderTests.cs | 4 +- .../Formats/Tiff/TiffMetadataTests.cs | 4 +- .../Formats/WebP/WebpDecoderTests.cs | 2 +- .../Image/ImageTests.Decode_Cancellation.cs | 2 +- .../Image/ImageTests.Identify.cs | 79 ++++++++----------- 17 files changed, 126 insertions(+), 161 deletions(-) diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs index 0c209214d..414ed05c2 100644 --- a/src/ImageSharp/Image.FromBytes.cs +++ b/src/ImageSharp/Image.FromBytes.cs @@ -55,41 +55,31 @@ public abstract partial class Image /// /// Reads the raw image information from the specified stream without fully decoding it. - /// A return value indicates whether the operation succeeded. /// /// The byte array containing encoded image data to read the header from. - /// - /// When this method returns, contains the raw image information; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// - /// if the information can be read; otherwise, - /// The data is null. - /// The data is not readable. - public static bool TryIdentify(ReadOnlySpan buffer, [NotNullWhen(true)] out ImageInfo? info) - => TryIdentify(DecoderOptions.Default, buffer, out info); + /// The . + /// The image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static ImageInfo Identify(ReadOnlySpan buffer) + => Identify(DecoderOptions.Default, buffer); /// /// Reads the raw image information from the specified span of bytes without fully decoding it. - /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The byte span containing encoded image data to read the header from. - /// - /// When this method returns, contains the raw image information; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// - /// if the information can be read; otherwise, - /// The configuration is null. - /// The data is null. - /// The data is not readable. - public static unsafe bool TryIdentify(DecoderOptions options, ReadOnlySpan buffer, [NotNullWhen(true)] out ImageInfo? info) + /// The . + /// The options are null. + /// The image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static unsafe ImageInfo Identify(DecoderOptions options, ReadOnlySpan buffer) { fixed (byte* ptr = buffer) { using UnmanagedMemoryStream stream = new(ptr, buffer.Length); - return TryIdentify(options, stream, out info); + return Identify(options, stream); } } diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs index a8ed73c82..4bd36397f 100644 --- a/src/ImageSharp/Image.FromFile.cs +++ b/src/ImageSharp/Image.FromFile.cs @@ -84,70 +84,71 @@ public abstract partial class Image /// A return value indicates whether the operation succeeded. /// /// The image file to open and to read the header from. - /// - /// When this method returns, contains the raw image information; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// /// if the information can be read; otherwise, - public static bool TryIdentify(string path, [NotNullWhen(true)] out ImageInfo? info) - => TryIdentify(DecoderOptions.Default, path, out info); + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static ImageInfo Identify(string path) + => Identify(DecoderOptions.Default, path); /// /// Reads the raw image information from the specified file path without fully decoding it. - /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image file to open and to read the header from. - /// - /// When this method returns, contains the raw image information; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// - /// if the information can be read; otherwise, + /// The . /// The options are null. - public static bool TryIdentify(DecoderOptions options, string path, [NotNullWhen(true)] out ImageInfo? info) + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static ImageInfo Identify(DecoderOptions options, string path) { Guard.NotNull(options, nameof(options)); using Stream stream = options.Configuration.FileSystem.OpenRead(path); - return TryIdentify(options, stream, out info); + return Identify(options, stream); } /// /// Reads the raw image information from the specified stream without fully decoding it. - /// A return value indicates whether the operation succeeded. /// /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. /// The options are null. /// - /// The representing the asynchronous operation. + /// The representing the asynchronous operation. /// - public static Task> TryIdentifyAsync( - string path, - CancellationToken cancellationToken = default) - => TryIdentifyAsync(DecoderOptions.Default, path, cancellationToken); + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Task IdentifyAsync(string path, CancellationToken cancellationToken = default) + => IdentifyAsync(DecoderOptions.Default, path, cancellationToken); /// /// Reads the raw image information from the specified stream without fully decoding it. - /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. - /// The options are null. /// - /// The representing the asynchronous operation. + /// The representing the asynchronous operation. /// - public static async Task> TryIdentifyAsync( + /// The options are null. + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static async Task IdentifyAsync( DecoderOptions options, string path, CancellationToken cancellationToken = default) { Guard.NotNull(options, nameof(options)); using Stream stream = options.Configuration.FileSystem.OpenRead(path); - return await TryIdentifyAsync(options, stream, cancellationToken).ConfigureAwait(false); + return await IdentifyAsync(options, stream, cancellationToken).ConfigureAwait(false); } /// diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs index 9da77d66e..b48055ea7 100644 --- a/src/ImageSharp/Image.FromStream.cs +++ b/src/ImageSharp/Image.FromStream.cs @@ -91,87 +91,70 @@ public abstract partial class Image /// /// Reads the raw image information from the specified stream without fully decoding it. - /// A return value indicates whether the operation succeeded. /// /// The image stream to read the header from. - /// - /// When this method returns, contains the raw image information; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// /// if the information can be read; otherwise, /// The stream is null. - /// The stream is not readable. - /// Image contains invalid content. - public static bool TryIdentify(Stream stream, [NotNullWhen(true)] out ImageInfo? info) - => TryIdentify(DecoderOptions.Default, stream, out info); + /// The stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static ImageInfo Identify(Stream stream) + => Identify(DecoderOptions.Default, stream); /// /// Reads the raw image information from the specified stream without fully decoding it. - /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image stream to read the information from. - /// - /// When this method returns, contains the raw image information; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// - /// if the information can be read; otherwise, + /// The . /// The options are null. /// The stream is null. - /// The stream is not readable. - /// Image contains invalid content. - public static bool TryIdentify(DecoderOptions options, Stream stream, [NotNullWhen(true)] out ImageInfo? info) - { - info = WithSeekableStream(options, stream, s => InternalIdentify(options, s)); - return info is not null; - } + /// The stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static ImageInfo Identify(DecoderOptions options, Stream stream) + => WithSeekableStream(options, stream, s => InternalIdentify(options, s)); /// /// Reads the raw image information from the specified stream without fully decoding it. - /// A return value indicates whether the operation succeeded. /// /// The image stream to read the information from. /// The token to monitor for cancellation requests. - /// The stream is null. - /// The stream is not readable. - /// Image contains invalid content. /// - /// The representing the asynchronous operation. + /// The representing the asynchronous operation. /// - public static Task> TryIdentifyAsync( + /// The stream is null. + /// The stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Task IdentifyAsync( Stream stream, CancellationToken cancellationToken = default) - => TryIdentifyAsync(DecoderOptions.Default, stream, cancellationToken); + => IdentifyAsync(DecoderOptions.Default, stream, cancellationToken); /// /// Reads the raw image information from the specified stream without fully decoding it. - /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image stream to read the information from. /// The token to monitor for cancellation requests. - /// The options are null. - /// The stream is null. - /// The stream is not readable. - /// Image contains invalid content. /// - /// The representing the asynchronous operation. + /// The representing the asynchronous operation. /// - public static async Task> TryIdentifyAsync( + /// The options are null. + /// The stream is null. + /// The stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Task IdentifyAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) - { - ImageInfo? info = await WithSeekableStreamAsync( + => WithSeekableStreamAsync( options, stream, (s, ct) => InternalIdentifyAsync(options, s, ct), - cancellationToken).ConfigureAwait(false); - - return new() { Value = info }; - } + cancellationToken); /// /// Creates a new instance of the class from the given stream. diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index 035481e01..e76f21d0e 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -475,7 +475,7 @@ public class BmpDecoderTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.Equal(expectedPixelSize, imageInfo.PixelType?.BitsPerPixel); } @@ -493,7 +493,7 @@ public class BmpDecoderTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.Equal(expectedWidth, imageInfo.Width); Assert.Equal(expectedHeight, imageInfo.Height); diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs index 1aef3e748..1d8435671 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs @@ -38,7 +38,7 @@ public class BmpMetadataTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); BmpMetadata bitmapMetadata = imageInfo.Metadata.GetBmpMetadata(); Assert.NotNull(bitmapMetadata); diff --git a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs index 303703f74..1d84d6600 100644 --- a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs +++ b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs @@ -256,7 +256,7 @@ public class GeneralFormatTests image.Save(memoryStream, format); memoryStream.Position = 0; - Image.TryIdentify(memoryStream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(memoryStream); Assert.Equal(imageInfo.Width, width); Assert.Equal(imageInfo.Height, height); @@ -270,7 +270,7 @@ public class GeneralFormatTests using MemoryStream memoryStream = new(invalid); - Assert.Throws(() => Image.TryIdentify(invalid, out ImageInfo imageInfo)); + Assert.Throws(() => Image.Identify(invalid)); } private static IImageFormat GetFormat(string format) diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs index 589baa613..022451668 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs @@ -123,7 +123,7 @@ public class GifDecoderTests TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.Equal(expectedPixelSize, imageInfo.PixelType.BitsPerPixel); diff --git a/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs index b4c39293d..499607772 100644 --- a/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Pbm/PbmMetadataTests.cs @@ -36,7 +36,7 @@ public class PbmMetadataTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); PbmMetadata bitmapMetadata = imageInfo.Metadata.GetPbmMetadata(); Assert.NotNull(bitmapMetadata); @@ -55,7 +55,7 @@ public class PbmMetadataTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); PbmMetadata bitmapMetadata = imageInfo.Metadata.GetPbmMetadata(); Assert.NotNull(bitmapMetadata); @@ -74,7 +74,7 @@ public class PbmMetadataTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); PbmMetadata bitmapMetadata = imageInfo.Metadata.GetPbmMetadata(); Assert.NotNull(bitmapMetadata); diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index 85849cdff..7e6f5138a 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -307,7 +307,7 @@ public partial class PngDecoderTests TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.Equal(expectedPixelSize, imageInfo.PixelType.BitsPerPixel); @@ -508,7 +508,7 @@ public partial class PngDecoderTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); PngMetadata metadata = imageInfo.Metadata.GetPngMetadata(); Assert.True(metadata.HasTransparency); } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs index 351b44ee0..9653a0656 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs @@ -232,7 +232,7 @@ public class PngMetadataTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); PngMetadata meta = imageInfo.Metadata.GetFormatMetadata(PngFormat.Instance); VerifyTextDataIsPresent(meta); @@ -244,7 +244,7 @@ public class PngMetadataTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.NotNull(imageInfo.Metadata.ExifProfile); ExifProfile exif = imageInfo.Metadata.ExifProfile; @@ -281,7 +281,7 @@ public class PngMetadataTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.NotNull(imageInfo.Metadata.ExifProfile); diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs index f1efe47f9..bf24ba350 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs @@ -41,7 +41,7 @@ public class TgaFileHeaderTests { using MemoryStream stream = new(data); - Image.TryIdentify(stream, out ImageInfo info); + ImageInfo info = Image.Identify(stream); TgaMetadata tgaData = info.Metadata.GetTgaMetadata(); Assert.Equal(bitsPerPixel, tgaData.BitsPerPixel); Assert.Equal(width, info.Width); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs index de7e74720..5c110844c 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs @@ -62,7 +62,7 @@ public class BigTiffDecoderTests : TiffDecoderBaseTester { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo info); + ImageInfo info = Image.Identify(stream); Assert.Equal(expectedPixelSize, info.PixelType?.BitsPerPixel); Assert.Equal(expectedWidth, info.Width); @@ -84,7 +84,7 @@ public class BigTiffDecoderTests : TiffDecoderBaseTester { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo info); + ImageInfo info = Image.Identify(stream); Assert.NotNull(info.Metadata); Assert.Equal(expectedByteOrder, info.Metadata.GetTiffMetadata().ByteOrder); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs index 26f006b34..8c43fd81d 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs @@ -32,7 +32,7 @@ public class TiffDecoderTests : TiffDecoderBaseTester { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo info); + ImageInfo info = Image.Identify(stream); Assert.Equal(expectedPixelSize, info.PixelType?.BitsPerPixel); Assert.Equal(expectedWidth, info.Width); @@ -50,7 +50,7 @@ public class TiffDecoderTests : TiffDecoderBaseTester { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo info); + ImageInfo info = Image.Identify(stream); Assert.NotNull(info.Metadata); Assert.Equal(expectedByteOrder, info.Metadata.GetTiffMetadata().ByteOrder); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs index 4d5f66503..2a809e895 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs @@ -80,7 +80,7 @@ public class TiffMetadataTests TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata(); @@ -96,7 +96,7 @@ public class TiffMetadataTests TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata(); diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs index 4d5d2aefd..003e5ad4c 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs @@ -41,7 +41,7 @@ public class WebpDecoderTests { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); - Image.TryIdentify(stream, out ImageInfo imageInfo); + ImageInfo imageInfo = Image.Identify(stream); Assert.NotNull(imageInfo); Assert.Equal(expectedWidth, imageInfo.Width); Assert.Equal(expectedHeight, imageInfo.Height); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs index d4a77d2c1..d8d9f4fe2 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs @@ -34,7 +34,7 @@ public partial class ImageTests { using FileStream fs = File.OpenRead(TestFile.GetInputFileFullPath(file)); CancellationToken preCancelled = new(canceled: true); - await Assert.ThrowsAnyAsync(async () => await Image.TryIdentifyAsync(fs, preCancelled)); + await Assert.ThrowsAnyAsync(async () => await Image.IdentifyAsync(fs, preCancelled)); } private static TheoryData CreateLoadData() diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs index 9d0aa7a75..0cda1c1fb 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs @@ -33,7 +33,7 @@ public partial class ImageTests [Fact] public void FromBytes_GlobalConfiguration() { - Image.TryIdentify(ActualImageBytes, out ImageInfo info); + ImageInfo info = Image.Identify(ActualImageBytes); Assert.Equal(ExpectedImageSize, info.Size()); Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } @@ -42,7 +42,7 @@ public partial class ImageTests public void FromBytes_CustomConfiguration() { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - Image.TryIdentify(options, this.ByteArray, out ImageInfo info); + ImageInfo info = Image.Identify(options, this.ByteArray); Assert.Equal(this.LocalImageInfo, info); } @@ -50,7 +50,7 @@ public partial class ImageTests [Fact] public void FromFileSystemPath_GlobalConfiguration() { - Image.TryIdentify(ActualImagePath, out ImageInfo info); + ImageInfo info = Image.Identify(ActualImagePath); Assert.NotNull(info); Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); @@ -61,7 +61,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - Image.TryIdentify(options, this.MockFilePath, out ImageInfo info); + ImageInfo info = Image.Identify(options, this.MockFilePath); Assert.Equal(this.LocalImageInfo, info); } @@ -70,7 +70,7 @@ public partial class ImageTests public void FromStream_GlobalConfiguration() { using MemoryStream stream = new(ActualImageBytes); - Image.TryIdentify(stream, out ImageInfo info); + ImageInfo info = Image.Identify(stream); Assert.NotNull(info); Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); @@ -80,7 +80,7 @@ public partial class ImageTests public void FromStream_GlobalConfiguration_NoFormat() { using MemoryStream stream = new(ActualImageBytes); - Image.TryIdentify(stream, out ImageInfo info); + ImageInfo info = Image.Identify(stream); Assert.NotNull(info); } @@ -91,7 +91,7 @@ public partial class ImageTests using MemoryStream stream = new(ActualImageBytes); using NonSeekableStream nonSeekableStream = new(stream); - Image.TryIdentify(nonSeekableStream, out ImageInfo info); + ImageInfo info = Image.Identify(nonSeekableStream); Assert.NotNull(info); Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); @@ -103,7 +103,7 @@ public partial class ImageTests using MemoryStream stream = new(ActualImageBytes); using NonSeekableStream nonSeekableStream = new(stream); - Image.TryIdentify(nonSeekableStream, out ImageInfo info); + ImageInfo info = Image.Identify(nonSeekableStream); Assert.NotNull(info); } @@ -113,7 +113,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - Image.TryIdentify(options, this.DataStream, out ImageInfo info); + ImageInfo info = Image.Identify(options, this.DataStream); Assert.Equal(this.LocalImageInfo, info); } @@ -123,7 +123,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - Image.TryIdentify(options, this.DataStream, out ImageInfo info); + ImageInfo info = Image.Identify(options, this.DataStream); Assert.Equal(this.LocalImageInfo, info); } @@ -133,7 +133,7 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = new() }; - Assert.Throws(() => Image.TryIdentify(options, this.DataStream, out ImageInfo info)); + Assert.Throws(() => Image.Identify(options, this.DataStream)); } [Fact] @@ -156,7 +156,7 @@ public partial class ImageTests })); using Stream stream = zipFile.Entries[0].Open(); - Assert.Throws(() => Image.TryIdentify(stream, out ImageInfo info)); + Assert.Throws(() => Image.Identify(stream)); } [Fact] @@ -165,10 +165,8 @@ public partial class ImageTests using MemoryStream stream = new(ActualImageBytes); AsyncStreamWrapper asyncStream = new(stream, () => false); - Attempt attempt = await Image.TryIdentifyAsync(asyncStream); - - Assert.True(attempt.Success); - Assert.NotNull(attempt.Value); + ImageInfo info = await Image.IdentifyAsync(asyncStream); + Assert.NotNull(info); } [Fact] @@ -176,11 +174,10 @@ public partial class ImageTests { using MemoryStream stream = new(ActualImageBytes); AsyncStreamWrapper asyncStream = new(stream, () => false); - Attempt attempt = await Image.TryIdentifyAsync(asyncStream); + ImageInfo info = await Image.IdentifyAsync(asyncStream); - Assert.True(attempt.Success); - Assert.Equal(ExpectedImageSize, attempt.Value.Size()); - Assert.Equal(ExpectedGlobalFormat, attempt.Value.Metadata.DecodedImageFormat); + Assert.Equal(ExpectedImageSize, info.Size()); + Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } [Fact] @@ -190,10 +187,9 @@ public partial class ImageTests using NonSeekableStream nonSeekableStream = new(stream); AsyncStreamWrapper asyncStream = new(nonSeekableStream, () => false); - Attempt attempt = await Image.TryIdentifyAsync(asyncStream); + ImageInfo info = await Image.IdentifyAsync(asyncStream); - Assert.True(attempt.Success); - Assert.NotNull(attempt.Value); + Assert.NotNull(info); } [Fact] @@ -203,11 +199,10 @@ public partial class ImageTests using NonSeekableStream nonSeekableStream = new(stream); AsyncStreamWrapper asyncStream = new(nonSeekableStream, () => false); - Attempt attempt = await Image.TryIdentifyAsync(asyncStream); + ImageInfo info = await Image.IdentifyAsync(asyncStream); - Assert.True(attempt.Success); - Assert.Equal(ExpectedImageSize, attempt.Value.Size()); - Assert.Equal(ExpectedGlobalFormat, attempt.Value.Metadata.DecodedImageFormat); + Assert.Equal(ExpectedImageSize, info.Size()); + Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } [Fact] @@ -230,7 +225,7 @@ public partial class ImageTests })); using Stream stream = zipFile.Entries[0].Open(); - await Assert.ThrowsAsync(async () => await Image.TryIdentifyAsync(stream)); + await Assert.ThrowsAsync(async () => await Image.IdentifyAsync(stream)); } [Fact] @@ -238,10 +233,9 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - Attempt attempt = await Image.TryIdentifyAsync(options, this.MockFilePath); + ImageInfo info = await Image.IdentifyAsync(options, this.MockFilePath); - Assert.True(attempt.Success); - Assert.Equal(this.LocalImageInfo, attempt.Value); + Assert.Equal(this.LocalImageInfo, info); } [Fact] @@ -249,28 +243,26 @@ public partial class ImageTests { DecoderOptions options = new() { Configuration = this.LocalConfiguration }; - Attempt attempt = await Image.TryIdentifyAsync(options, this.MockFilePath); + ImageInfo info = await Image.IdentifyAsync(options, this.MockFilePath); - Assert.True(attempt.Success); - Assert.NotNull(attempt.Value); + Assert.NotNull(info); } [Fact] public async Task IdentifyWithFormatAsync_FromPath_GlobalConfiguration() { - Attempt attempt = await Image.TryIdentifyAsync(ActualImagePath); + ImageInfo info = await Image.IdentifyAsync(ActualImagePath); - Assert.Equal(ExpectedImageSize, attempt.Value.Size()); - Assert.Equal(ExpectedGlobalFormat, attempt.Value.Metadata.DecodedImageFormat); + Assert.Equal(ExpectedImageSize, info.Size()); + Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } [Fact] public async Task FromPathAsync_GlobalConfiguration() { - Attempt attempt = await Image.TryIdentifyAsync(ActualImagePath); + ImageInfo info = await Image.IdentifyAsync(ActualImagePath); - Assert.True(attempt.Success); - Assert.Equal(ExpectedImageSize, attempt.Value.Size()); + Assert.Equal(ExpectedImageSize, info.Size()); } [Fact] @@ -279,10 +271,9 @@ public partial class ImageTests DecoderOptions options = new() { Configuration = this.LocalConfiguration }; AsyncStreamWrapper asyncStream = new(this.DataStream, () => false); - Attempt attempt = await Image.TryIdentifyAsync(options, asyncStream); + ImageInfo info = await Image.IdentifyAsync(options, asyncStream); - Assert.True(attempt.Success); - Assert.Equal(this.LocalImageInfo, attempt.Value); + Assert.Equal(this.LocalImageInfo, info); } [Fact] @@ -291,7 +282,7 @@ public partial class ImageTests DecoderOptions options = new() { Configuration = new() }; AsyncStreamWrapper asyncStream = new(this.DataStream, () => false); - return Assert.ThrowsAsync(async () => await Image.TryIdentifyAsync(options, asyncStream)); + return Assert.ThrowsAsync(async () => await Image.IdentifyAsync(options, asyncStream)); } } } From eff9b0a6a53ae88648e9d5cf139b3dfc4897f089 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 14 Jan 2023 18:56:00 +1000 Subject: [PATCH 11/16] Revert recent Detect changes and normalize. --- src/ImageSharp/Image.FromBytes.cs | 38 +++++------- src/ImageSharp/Image.FromFile.cs | 51 +++++++-------- src/ImageSharp/Image.FromStream.cs | 62 +++++++------------ .../Formats/Bmp/ImageExtensionsTest.cs | 16 ++--- .../Formats/Gif/ImageExtensionsTest.cs | 16 ++--- .../Formats/ImageFormatManagerTests.cs | 13 ++-- .../Formats/Jpg/ImageExtensionsTest.cs | 16 ++--- .../Formats/Pbm/ImageExtensionsTest.cs | 16 ++--- .../Formats/Png/ImageExtensionsTest.cs | 16 ++--- .../Formats/Tga/ImageExtensionsTest.cs | 16 ++--- .../Formats/Tiff/ImageExtensionsTest.cs | 16 ++--- .../Formats/WebP/ImageExtensionsTests.cs | 16 ++--- .../Image/ImageTests.DetectFormat.cs | 59 +++++++----------- .../ImageSharp.Tests/Image/ImageTests.Save.cs | 4 +- .../Image/ImageTests.SaveAsync.cs | 6 +- tests/ImageSharp.Tests/TestImages.cs | 1 - 16 files changed, 157 insertions(+), 205 deletions(-) diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs index 414ed05c2..96ef84510 100644 --- a/src/ImageSharp/Image.FromBytes.cs +++ b/src/ImageSharp/Image.FromBytes.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; @@ -16,41 +15,32 @@ 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. - /// returns true when format was detected otherwise false. - public static bool TryDetectFormat(ReadOnlySpan buffer, [NotNullWhen(true)] out IImageFormat? format) - => TryDetectFormat(DecoderOptions.Default, buffer, out format); + /// The . + /// The image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static IImageFormat DetectFormat(ReadOnlySpan buffer) + => DetectFormat(DecoderOptions.Default, buffer); /// /// 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 . /// The options are null. - /// returns true when format was detected otherwise false. - public static bool TryDetectFormat(DecoderOptions options, ReadOnlySpan buffer, [NotNullWhen(true)] out IImageFormat? format) + /// The image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static unsafe IImageFormat DetectFormat(DecoderOptions options, ReadOnlySpan buffer) { Guard.NotNull(options, nameof(options.Configuration)); - Configuration configuration = options.Configuration; - int maxHeaderSize = configuration.MaxHeaderSize; - if (maxHeaderSize <= 0) - { - format = null; - return false; - } - - foreach (IImageFormatDetector detector in configuration.ImageFormatsManager.FormatDetectors) + fixed (byte* ptr = buffer) { - if (detector.TryDetectFormat(buffer, out format)) - { - return true; - } + using UnmanagedMemoryStream stream = new(ptr, buffer.Length); + return DetectFormat(options, stream); } - - format = default; - return false; } /// diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs index 4bd36397f..24a737493 100644 --- a/src/ImageSharp/Image.FromFile.cs +++ b/src/ImageSharp/Image.FromFile.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; @@ -14,61 +13,59 @@ public abstract partial class Image { /// /// Detects the encoded image format type from the specified file. - /// A return value indicates whether the operation succeeded. /// /// The image file to open and to read the header from. - /// - /// When this method returns, contains the format that matches the given file; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// - /// if a match is found; otherwise, - public static bool TryDetectFormat(string path, [NotNullWhen(true)] out IImageFormat? format) - => TryDetectFormat(DecoderOptions.Default, path, out format); + /// The . + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static IImageFormat DetectFormat(string path) + => DetectFormat(DecoderOptions.Default, path); /// /// Detects the encoded image format type from the specified file. - /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image file to open and to read the header from. - /// - /// When this method returns, contains the format that matches the given file; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// - /// if a match is found; otherwise, + /// The . /// The options are null. - public static bool TryDetectFormat(DecoderOptions options, string path, [NotNullWhen(true)] out IImageFormat? format) + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static IImageFormat DetectFormat(DecoderOptions options, string path) { Guard.NotNull(options, nameof(options)); using Stream file = options.Configuration.FileSystem.OpenRead(path); - return TryDetectFormat(options, file, out format); + return DetectFormat(options, file); } /// /// Detects the encoded image format type from the specified file. - /// A return value indicates whether the operation succeeded. /// /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. - /// A representing the asynchronous operation. - public static Task> TryDetectFormatAsync( + /// A representing the asynchronous operation. + public static Task DetectFormatAsync( string path, CancellationToken cancellationToken = default) - => TryDetectFormatAsync(DecoderOptions.Default, path, cancellationToken); + => DetectFormatAsync(DecoderOptions.Default, path, cancellationToken); /// /// Detects the encoded image format type from the specified file. - /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image file to open and to read the header from. /// The token to monitor for cancellation requests. + /// A representing the asynchronous operation. /// The options are null. - /// A representing the asynchronous operation. - public static async Task> TryDetectFormatAsync( + /// The path is null. + /// The file stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static async Task DetectFormatAsync( DecoderOptions options, string path, CancellationToken cancellationToken = default) @@ -76,7 +73,7 @@ public abstract partial class Image Guard.NotNull(options, nameof(options)); using Stream stream = options.Configuration.FileSystem.OpenRead(path); - return await TryDetectFormatAsync(options, stream, cancellationToken).ConfigureAwait(false); + return await DetectFormatAsync(options, stream, cancellationToken).ConfigureAwait(false); } /// diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs index b48055ea7..1748ca00e 100644 --- a/src/ImageSharp/Image.FromStream.cs +++ b/src/ImageSharp/Image.FromStream.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.PixelFormats; @@ -15,79 +14,66 @@ public abstract partial class Image { /// /// Detects the encoded image format type from the specified stream. - /// A return value indicates whether the operation succeeded. /// /// The image stream to read the header from. - /// - /// When this method returns, contains the format that matches the given stream; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// - /// if a match is found; otherwise, + /// The . /// The stream is null. - /// The stream is not readable. - public static bool TryDetectFormat(Stream stream, [NotNullWhen(true)] out IImageFormat? format) - => TryDetectFormat(DecoderOptions.Default, stream, out format); + /// The stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static IImageFormat DetectFormat(Stream stream) + => DetectFormat(DecoderOptions.Default, stream); /// /// Detects the encoded image format type from the specified stream. - /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image stream to read the header from. - /// - /// When this method returns, contains the format that matches the given stream; - /// otherwise, the default value for the type of the parameter. - /// This parameter is passed uninitialized. - /// /// if a match is found; otherwise, /// The options are null. /// The stream is null. - /// The stream is not readable. - public static bool TryDetectFormat(DecoderOptions options, Stream stream, [NotNullWhen(true)] out IImageFormat? format) - { - format = WithSeekableStream(options, stream, s => InternalDetectFormat(options.Configuration, s)); - return format is not null; - } + /// The stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static IImageFormat DetectFormat(DecoderOptions options, Stream stream) + => WithSeekableStream(options, stream, s => InternalDetectFormat(options.Configuration, s)); /// /// Detects the encoded image format type from the specified stream. - /// A return value indicates whether the operation succeeded. /// /// The image stream to read the header from. /// The token to monitor for cancellation requests. + /// A representing the asynchronous operation. /// The stream is null. - /// The stream is not readable. - /// A representing the asynchronous operation. - public static Task> TryDetectFormatAsync( + /// The stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Task DetectFormatAsync( Stream stream, CancellationToken cancellationToken = default) - => TryDetectFormatAsync(DecoderOptions.Default, stream, cancellationToken); + => DetectFormatAsync(DecoderOptions.Default, stream, cancellationToken); /// /// Detects the encoded image format type from the specified stream. - /// A return value indicates whether the operation succeeded. /// /// The general decoder options. /// The image stream to read the header from. /// The token to monitor for cancellation requests. + /// A representing the asynchronous operation. /// The options are null. /// The stream is null. - /// The stream is not readable. - /// A representing the asynchronous operation. - public static async Task> TryDetectFormatAsync( + /// The stream is not readable or the image format is not supported. + /// The encoded image contains invalid content. + /// The encoded image format is unknown. + public static Task DetectFormatAsync( DecoderOptions options, Stream stream, CancellationToken cancellationToken = default) - { - IImageFormat? format = await WithSeekableStreamAsync( + => WithSeekableStreamAsync( options, stream, (s, _) => Task.FromResult(InternalDetectFormat(options.Configuration, s)), - cancellationToken).ConfigureAwait(false); - - return new() { Value = format }; - } + cancellationToken); /// /// Reads the raw image information from the specified stream without fully decoding it. diff --git a/tests/ImageSharp.Tests/Formats/Bmp/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Bmp/ImageExtensionsTest.cs index 1f5686cd7..14b017bee 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/ImageExtensionsTest.cs @@ -20,7 +20,7 @@ public class ImageExtensionsTest image.SaveAsBmp(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is BmpFormat); } @@ -35,7 +35,7 @@ public class ImageExtensionsTest await image.SaveAsBmpAsync(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is BmpFormat); } @@ -50,7 +50,7 @@ public class ImageExtensionsTest image.SaveAsBmp(file, new BmpEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is BmpFormat); } @@ -65,7 +65,7 @@ public class ImageExtensionsTest await image.SaveAsBmpAsync(file, new BmpEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is BmpFormat); } @@ -81,7 +81,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is BmpFormat); } @@ -97,7 +97,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is BmpFormat); } @@ -113,7 +113,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is BmpFormat); } @@ -129,7 +129,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is BmpFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/Gif/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Gif/ImageExtensionsTest.cs index 3ea0c2240..97fdb38e7 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/ImageExtensionsTest.cs @@ -20,7 +20,7 @@ public class ImageExtensionsTest image.SaveAsGif(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is GifFormat); } @@ -35,7 +35,7 @@ public class ImageExtensionsTest await image.SaveAsGifAsync(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is GifFormat); } @@ -50,7 +50,7 @@ public class ImageExtensionsTest image.SaveAsGif(file, new GifEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is GifFormat); } @@ -65,7 +65,7 @@ public class ImageExtensionsTest await image.SaveAsGifAsync(file, new GifEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is GifFormat); } @@ -81,7 +81,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is GifFormat); } @@ -97,7 +97,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is GifFormat); } @@ -113,7 +113,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is GifFormat); } @@ -129,7 +129,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is GifFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs index 8d65eecb9..74c7fc1d0 100644 --- a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs +++ b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs @@ -120,15 +120,10 @@ public class ImageFormatManagerTests jpegImage = buffer.ToArray(); } - byte[] invalidImage = { 1, 2, 3 }; - - bool resultValidImage = Image.TryDetectFormat(jpegImage, out IImageFormat format); + IImageFormat format = Image.DetectFormat(jpegImage); + Assert.IsType(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); + byte[] invalidImage = { 1, 2, 3 }; + Assert.Throws(() => Image.DetectFormat(invalidImage)); } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Jpg/ImageExtensionsTest.cs index 12392568f..b1f799732 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ImageExtensionsTest.cs @@ -21,7 +21,7 @@ public class ImageExtensionsTest image.SaveAsJpeg(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is JpegFormat); } @@ -36,7 +36,7 @@ public class ImageExtensionsTest await image.SaveAsJpegAsync(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is JpegFormat); } @@ -51,7 +51,7 @@ public class ImageExtensionsTest image.SaveAsJpeg(file, new JpegEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is JpegFormat); } @@ -66,7 +66,7 @@ public class ImageExtensionsTest await image.SaveAsJpegAsync(file, new JpegEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is JpegFormat); } @@ -82,7 +82,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is JpegFormat); } @@ -98,7 +98,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is JpegFormat); } @@ -114,7 +114,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is JpegFormat); } @@ -130,7 +130,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is JpegFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/Pbm/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Pbm/ImageExtensionsTest.cs index 1643e3dda..5cbdd3dab 100644 --- a/tests/ImageSharp.Tests/Formats/Pbm/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Pbm/ImageExtensionsTest.cs @@ -20,7 +20,7 @@ public class ImageExtensionsTest image.SaveAsPbm(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PbmFormat); } @@ -35,7 +35,7 @@ public class ImageExtensionsTest await image.SaveAsPbmAsync(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PbmFormat); } @@ -50,7 +50,7 @@ public class ImageExtensionsTest image.SaveAsPbm(file, new PbmEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PbmFormat); } @@ -65,7 +65,7 @@ public class ImageExtensionsTest await image.SaveAsPbmAsync(file, new PbmEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PbmFormat); } @@ -81,7 +81,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is PbmFormat); } @@ -97,7 +97,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is PbmFormat); } @@ -113,7 +113,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is PbmFormat); } @@ -129,7 +129,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is PbmFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/Png/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Png/ImageExtensionsTest.cs index 313b779e0..a03e1a7aa 100644 --- a/tests/ImageSharp.Tests/Formats/Png/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Png/ImageExtensionsTest.cs @@ -21,7 +21,7 @@ public class ImageExtensionsTest image.SaveAsPng(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PngFormat); } @@ -36,7 +36,7 @@ public class ImageExtensionsTest await image.SaveAsPngAsync(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PngFormat); } @@ -51,7 +51,7 @@ public class ImageExtensionsTest image.SaveAsPng(file, new PngEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PngFormat); } @@ -66,7 +66,7 @@ public class ImageExtensionsTest await image.SaveAsPngAsync(file, new PngEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PngFormat); } @@ -82,7 +82,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is PngFormat); } @@ -98,7 +98,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is PngFormat); } @@ -114,7 +114,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is PngFormat); } @@ -130,7 +130,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is PngFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/Tga/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Tga/ImageExtensionsTest.cs index fe9612543..9b6daee4c 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/ImageExtensionsTest.cs @@ -20,7 +20,7 @@ public class ImageExtensionsTest image.SaveAsTga(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is TgaFormat); } @@ -35,7 +35,7 @@ public class ImageExtensionsTest await image.SaveAsTgaAsync(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is TgaFormat); } @@ -50,7 +50,7 @@ public class ImageExtensionsTest image.SaveAsTga(file, new TgaEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is TgaFormat); } @@ -65,7 +65,7 @@ public class ImageExtensionsTest await image.SaveAsTgaAsync(file, new TgaEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is TgaFormat); } @@ -81,7 +81,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is TgaFormat); } @@ -97,7 +97,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is TgaFormat); } @@ -113,7 +113,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is TgaFormat); } @@ -129,7 +129,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is TgaFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs index 4ea4b632e..bf9e73ea6 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs @@ -21,7 +21,7 @@ public class ImageExtensionsTest image.SaveAsTiff(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is TiffFormat); } @@ -36,7 +36,7 @@ public class ImageExtensionsTest await image.SaveAsTiffAsync(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is TiffFormat); } @@ -51,7 +51,7 @@ public class ImageExtensionsTest image.SaveAsTiff(file, new TiffEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is TiffFormat); } @@ -66,7 +66,7 @@ public class ImageExtensionsTest await image.SaveAsTiffAsync(file, new TiffEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is TiffFormat); } @@ -82,7 +82,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is TiffFormat); } @@ -98,7 +98,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is TiffFormat); } @@ -114,7 +114,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is TiffFormat); } @@ -130,7 +130,7 @@ public class ImageExtensionsTest memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is TiffFormat); } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs index 5ed6c8dc4..ea13fd712 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs @@ -21,7 +21,7 @@ public class ImageExtensionsTests image.SaveAsWebp(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is WebpFormat); } @@ -36,7 +36,7 @@ public class ImageExtensionsTests await image.SaveAsWebpAsync(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is WebpFormat); } @@ -51,7 +51,7 @@ public class ImageExtensionsTests image.SaveAsWebp(file, new WebpEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is WebpFormat); } @@ -66,7 +66,7 @@ public class ImageExtensionsTests await image.SaveAsWebpAsync(file, new WebpEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is WebpFormat); } @@ -82,7 +82,7 @@ public class ImageExtensionsTests memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is WebpFormat); } @@ -98,7 +98,7 @@ public class ImageExtensionsTests memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is WebpFormat); } @@ -114,7 +114,7 @@ public class ImageExtensionsTests memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is WebpFormat); } @@ -130,7 +130,7 @@ public class ImageExtensionsTests memoryStream.Position = 0; - Image.TryDetectFormat(memoryStream, out IImageFormat format); + IImageFormat format = Image.DetectFormat(memoryStream); Assert.True(format is WebpFormat); } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs index 846538e42..f9a68c8bf 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs @@ -34,10 +34,8 @@ public partial class ImageTests [Fact] public void FromBytes_GlobalConfiguration() { - bool result = Image.TryDetectFormat(ActualImageSpan, out IImageFormat type); - - Assert.True(result); - Assert.Equal(ExpectedGlobalFormat, type); + IImageFormat format = Image.DetectFormat(ActualImageSpan); + Assert.Equal(ExpectedGlobalFormat, format); } [Fact] @@ -48,28 +46,22 @@ public partial class ImageTests Configuration = this.LocalConfiguration }; - bool result = Image.TryDetectFormat(options, this.ByteArray, out IImageFormat type); - - Assert.True(result); - Assert.Equal(this.LocalImageFormat, type); + IImageFormat format = Image.DetectFormat(options, this.ByteArray); + Assert.Equal(this.LocalImageFormat, format); } [Fact] public void FromFileSystemPath_GlobalConfiguration() { - bool result = Image.TryDetectFormat(ActualImagePath, out IImageFormat type); - - Assert.True(result); - Assert.Equal(ExpectedGlobalFormat, type); + IImageFormat format = Image.DetectFormat(ActualImagePath); + Assert.Equal(ExpectedGlobalFormat, format); } [Fact] public async Task FromFileSystemPathAsync_GlobalConfiguration() { - Attempt attempt = await Image.TryDetectFormatAsync(ActualImagePath); - - Assert.True(attempt.Success); - Assert.Equal(ExpectedGlobalFormat, attempt.Value); + IImageFormat format = await Image.DetectFormatAsync(ActualImagePath); + Assert.Equal(ExpectedGlobalFormat, format); } [Fact] @@ -80,10 +72,8 @@ public partial class ImageTests Configuration = this.LocalConfiguration }; - bool result = Image.TryDetectFormat(options, this.MockFilePath, out IImageFormat type); - - Assert.True(result); - Assert.Equal(this.LocalImageFormat, type); + IImageFormat format = Image.DetectFormat(options, this.MockFilePath); + Assert.Equal(this.LocalImageFormat, format); } [Fact] @@ -94,20 +84,17 @@ public partial class ImageTests Configuration = this.LocalConfiguration }; - Attempt attempt = await Image.TryDetectFormatAsync(options, this.MockFilePath); - - Assert.True(attempt.Success); - Assert.Equal(this.LocalImageFormat, attempt.Value); + IImageFormat format = await Image.DetectFormatAsync(options, this.MockFilePath); + Assert.Equal(this.LocalImageFormat, format); } [Fact] public void FromStream_GlobalConfiguration() { using MemoryStream stream = new(ActualImageBytes); - bool result = Image.TryDetectFormat(stream, out IImageFormat type); + IImageFormat format = Image.DetectFormat(stream); - Assert.True(result); - Assert.Equal(ExpectedGlobalFormat, type); + Assert.Equal(ExpectedGlobalFormat, format); } [Fact] @@ -118,10 +105,8 @@ public partial class ImageTests Configuration = this.LocalConfiguration }; - bool result = Image.TryDetectFormat(options, this.DataStream, out IImageFormat type); - - Assert.True(result); - Assert.Equal(this.LocalImageFormat, type); + IImageFormat format = Image.DetectFormat(options, this.DataStream); + Assert.Equal(this.LocalImageFormat, format); } [Fact] @@ -132,15 +117,15 @@ public partial class ImageTests Configuration = new() }; - Assert.Throws(() => Image.TryDetectFormat(options, this.DataStream, out IImageFormat type)); + Assert.Throws(() => Image.DetectFormat(options, this.DataStream)); } [Fact] public async Task FromStreamAsync_GlobalConfiguration() { using MemoryStream stream = new(ActualImageBytes); - Attempt attempt = await Image.TryDetectFormatAsync(new AsyncStreamWrapper(stream, () => false)); - Assert.Equal(ExpectedGlobalFormat, attempt.Value); + IImageFormat format = await Image.DetectFormatAsync(new AsyncStreamWrapper(stream, () => false)); + Assert.Equal(ExpectedGlobalFormat, format); } [Fact] @@ -151,8 +136,8 @@ public partial class ImageTests Configuration = this.LocalConfiguration }; - Attempt attempt = await Image.TryDetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false)); - Assert.Equal(this.LocalImageFormat, attempt.Value); + IImageFormat format = await Image.DetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false)); + Assert.Equal(this.LocalImageFormat, format); } [Fact] @@ -163,7 +148,7 @@ public partial class ImageTests Configuration = new() }; - return Assert.ThrowsAsync(async () => await Image.TryDetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false))); + return Assert.ThrowsAsync(async () => await Image.DetectFormatAsync(options, new AsyncStreamWrapper(this.DataStream, () => false))); } } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Save.cs b/tests/ImageSharp.Tests/Image/ImageTests.Save.cs index 8bdbb705a..867930c4c 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Save.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Save.cs @@ -24,7 +24,7 @@ public partial class ImageTests image.Save(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PngFormat); } @@ -53,7 +53,7 @@ public partial class ImageTests image.Save(file, new PngEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PngFormat); } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs b/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs index b58d0cff3..87794f335 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs @@ -26,7 +26,7 @@ public partial class ImageTests await image.SaveAsync(file); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PngFormat); } @@ -55,7 +55,7 @@ public partial class ImageTests await image.SaveAsync(file, new PngEncoder()); } - Image.TryDetectFormat(file, out IImageFormat format); + IImageFormat format = Image.DetectFormat(file); Assert.True(format is PngFormat); } @@ -79,7 +79,7 @@ public partial class ImageTests stream.Position = 0; - Image.TryDetectFormat(stream, out IImageFormat format2); + IImageFormat format2 = Image.DetectFormat(stream); Assert.Equal(format, format2); } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 638f7dfb7..29223b1fe 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. - // ReSharper disable InconsistentNaming // ReSharper disable MemberHidesStaticFromOuterClass namespace SixLabors.ImageSharp.Tests; From 94850fcc53c43d9ee1602fe3a9fe814503024604 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 14 Jan 2023 21:17:56 +1000 Subject: [PATCH 12/16] Delete Attempt{T}.cs --- src/ImageSharp/Common/Attempt{T}.cs | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 src/ImageSharp/Common/Attempt{T}.cs diff --git a/src/ImageSharp/Common/Attempt{T}.cs b/src/ImageSharp/Common/Attempt{T}.cs deleted file mode 100644 index a243dffd1..000000000 --- a/src/ImageSharp/Common/Attempt{T}.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Diagnostics.CodeAnalysis; - -namespace SixLabors.ImageSharp; - -/// -/// A wrapper for nullable values that correctly handles the return type based on the result. -/// -/// The type of nullable value. -public readonly struct Attempt -{ - /// - /// Gets a value indicating whether the attempted return was successful. - /// - [MemberNotNullWhen(returnValue: true, member: nameof(Value))] - public bool Success => this.Value is not null; - - /// - /// Gets the value when the attempted return is successful; otherwise, the default value for the type. - /// - public T? Value { get; init; } -} From 7af3cf1fff28c02d4090111c5e7ad14259c3e9a5 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 15 Jan 2023 09:55:16 +1100 Subject: [PATCH 13/16] Update tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs Co-authored-by: Scott Williams --- .../TestUtilities/Tests/TestImageProviderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs index 3214bebc8..8addab3b1 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -365,7 +365,7 @@ public class TestImageProviderTests protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { - Image image = this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); + using Image image = this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); return new(image.PixelType, image.Width, image.Height, image.Metadata); } From 289d7eef309ed7b953a15d836a2b255f156d9a06 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 15 Jan 2023 09:55:26 +1100 Subject: [PATCH 14/16] Update tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs Co-authored-by: Scott Williams --- .../TestUtilities/Tests/TestImageProviderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs index 8addab3b1..0a3e45b3c 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -408,7 +408,7 @@ public class TestImageProviderTests protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { - Image image = this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); + using Image image = this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken); return new(image.PixelType, image.Width, image.Height, image.Metadata); } From 4967c71ad06184ff987980907f18c58be435214b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 15 Jan 2023 09:55:34 +1100 Subject: [PATCH 15/16] Update tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs Co-authored-by: Scott Williams --- .../TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs index 4bedf2ed9..a0fdb1331 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs @@ -74,7 +74,7 @@ public class MagickReferenceDecoder : ImageDecoder protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) { - Image image = this.Decode(options, stream, cancellationToken); + using Image image = this.Decode(options, stream, cancellationToken); return new(image.PixelType, image.Width, image.Height, image.Metadata); } From 96a22c40ad938783b8c41d054871c83955eeb6b5 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 15 Jan 2023 17:47:19 +1000 Subject: [PATCH 16/16] Remove IImageInfo, IImage and use inheritance. --- src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs | 18 +++--- src/ImageSharp/Formats/Gif/GifEncoderCore.cs | 4 +- src/ImageSharp/Formats/ImageDecoder.cs | 2 +- src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs | 2 +- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 2 +- src/ImageSharp/IImage.cs | 11 ---- src/ImageSharp/IImageInfo.cs | 34 ----------- src/ImageSharp/Image.cs | 32 +++-------- src/ImageSharp/ImageInfo.cs | 56 ++++++++++++++----- src/ImageSharp/ImageInfoExtensions.cs | 24 -------- src/ImageSharp/Image{TPixel}.cs | 2 +- .../DefaultImageProcessorContext{TPixel}.cs | 2 +- .../DrawImageProcessor{TPixelBg,TPixelFg}.cs | 2 +- .../EntropyCropProcessor{TPixel}.cs | 38 ++++--------- .../Resize/ResizeProcessor{TPixel}.cs | 2 +- .../Codecs/Png/DecodeFilteredPng.cs | 4 +- .../Codecs/Png/DecodePng.cs | 17 ++---- .../Codecs/Tiff/DecodeTiff.cs | 16 ++---- .../Processing/Diffuse.cs | 8 +-- .../Processing/Rotate.cs | 4 +- .../ImageSharp.Benchmarks/Processing/Skew.cs | 4 +- .../Advanced/AdvancedImageExtensionsTests.cs | 12 ++-- .../Formats/Jpg/JpegDecoderTests.Metadata.cs | 2 +- .../Image/ImageRotationTests.cs | 12 ++-- .../Image/ImageTests.Identify.cs | 10 ++-- .../Image/ImageTests.ImageLoadTestBase.cs | 12 +--- ..._FileSystemPath_UseDefaultConfiguration.cs | 2 +- ...s.Load_FromBytes_UseGlobalConfiguration.cs | 2 +- ...Load_FromStream_UseDefaultConfiguration.cs | 2 +- tests/ImageSharp.Tests/ImageInfoTests.cs | 24 ++++---- .../BaseImageOperationsExtensionTest.cs | 2 +- .../Processing/FakeImageOperationsProvider.cs | 2 +- .../Processors/Convolution/BokehBlurTest.cs | 33 +++++------ .../Transforms/AffineTransformTests.cs | 2 +- .../Processors/Transforms/ResizeTests.cs | 8 +-- .../LoadResizeSaveProfilingBenchmarks.cs | 2 +- .../ImageComparison/ImageComparer.cs | 8 +-- 37 files changed, 160 insertions(+), 259 deletions(-) delete mode 100644 src/ImageSharp/IImage.cs delete mode 100644 src/ImageSharp/IImageInfo.cs delete mode 100644 src/ImageSharp/ImageInfoExtensions.cs diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs index 53cb066f0..9f1e85639 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -215,15 +215,15 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals BmpInfoHeader infoHeader = new( headerSize: infoHeaderSize, - height: height, width: width, - bitsPerPixel: bpp, + height: height, planes: 1, + bitsPerPixel: bpp, imageSize: height * bytesPerLine, - clrUsed: 0, - clrImportant: 0, xPelsPerMeter: hResolution, - yPelsPerMeter: vResolution); + yPelsPerMeter: vResolution, + clrUsed: 0, + clrImportant: 0); if ((this.infoHeaderType is BmpInfoHeaderType.WinVersion4 or BmpInfoHeaderType.WinVersion5) && this.bitsPerPixel == BmpBitsPerPixel.Pixel32) { @@ -470,7 +470,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals using IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(this.configuration); frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image); - using IndexedImageFrame quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds()); + using IndexedImageFrame quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds); ReadOnlySpan quantizedColorPalette = quantized.Palette.Span; this.WriteColorPalette(stream, quantizedColorPalette, colorPalette); @@ -541,7 +541,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image); - using IndexedImageFrame quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds()); + using IndexedImageFrame quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds); using IMemoryOwner colorPaletteBuffer = this.memoryAllocator.Allocate(ColorPaletteSize4Bit, AllocationOptions.Clean); Span colorPalette = colorPaletteBuffer.GetSpan(); @@ -588,7 +588,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image); - using IndexedImageFrame quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds()); + using IndexedImageFrame quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds); using IMemoryOwner colorPaletteBuffer = this.memoryAllocator.Allocate(ColorPaletteSize2Bit, AllocationOptions.Clean); Span colorPalette = colorPaletteBuffer.GetSpan(); @@ -644,7 +644,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image); - using IndexedImageFrame quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds()); + using IndexedImageFrame quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds); using IMemoryOwner colorPaletteBuffer = this.memoryAllocator.Allocate(ColorPaletteSize1Bit, AllocationOptions.Clean); Span colorPalette = colorPaletteBuffer.GetSpan(); diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index c35ee9985..9cc045d45 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -99,12 +99,12 @@ internal sealed class GifEncoderCore : IImageEncoderInternals if (useGlobalTable) { frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image); - quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds()); + quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds); } else { frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image.Frames.RootFrame); - quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds()); + quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds); } } diff --git a/src/ImageSharp/Formats/ImageDecoder.cs b/src/ImageSharp/Formats/ImageDecoder.cs index 715c2f541..ebb45d701 100644 --- a/src/ImageSharp/Formats/ImageDecoder.cs +++ b/src/ImageSharp/Formats/ImageDecoder.cs @@ -172,7 +172,7 @@ public abstract class ImageDecoder : IImageDecoder } Size targetSize = options.TargetSize.Value; - Size currentSize = image.Size(); + Size currentSize = image.Size; return currentSize.Width != targetSize.Width && currentSize.Height != targetSize.Height; } diff --git a/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs b/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs index 7c7860c58..4a07173a1 100644 --- a/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs +++ b/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs @@ -68,7 +68,7 @@ internal sealed class PbmEncoderCore : IImageEncoderInternals this.SanitizeAndSetEncoderOptions(image); byte signature = this.DeduceSignature(); - this.WriteHeader(stream, signature, image.Size()); + this.WriteHeader(stream, signature, image.Size); this.WritePixels(stream, image.Frames.RootFrame); diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 8b3dcc159..5a66fc7d4 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -1300,7 +1300,7 @@ internal sealed class PngEncoderCore : IImageEncoderInternals, IDisposable using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(image.GetConfiguration()); frameQuantizer.BuildPalette(encoder.PixelSamplingStrategy, image); - return frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds()); + return frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds); } /// diff --git a/src/ImageSharp/IImage.cs b/src/ImageSharp/IImage.cs deleted file mode 100644 index 9940a7954..000000000 --- a/src/ImageSharp/IImage.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -namespace SixLabors.ImageSharp; - -/// -/// Encapsulates the properties and methods that describe an image. -/// -public interface IImage : IImageInfo, IDisposable -{ -} diff --git a/src/ImageSharp/IImageInfo.cs b/src/ImageSharp/IImageInfo.cs deleted file mode 100644 index 411b8f1b0..000000000 --- a/src/ImageSharp/IImageInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using SixLabors.ImageSharp.Formats; -using SixLabors.ImageSharp.Metadata; - -namespace SixLabors.ImageSharp; - -/// -/// Encapsulates properties that describe basic image information including dimensions, pixel type information -/// and additional metadata. -/// -public interface IImageInfo -{ - /// - /// Gets information about the image pixels. - /// - PixelTypeInfo PixelType { get; } - - /// - /// Gets the width. - /// - int Width { get; } - - /// - /// Gets the height. - /// - int Height { get; } - - /// - /// Gets the metadata of the image. - /// - ImageMetadata Metadata { get; } -} diff --git a/src/ImageSharp/Image.cs b/src/ImageSharp/Image.cs index 2df86b109..65b2d68b0 100644 --- a/src/ImageSharp/Image.cs +++ b/src/ImageSharp/Image.cs @@ -14,11 +14,9 @@ namespace SixLabors.ImageSharp; /// For the non-generic type, the pixel type is only known at runtime. /// is always implemented by a pixel-specific instance. /// -public abstract partial class Image : IImage, IConfigurationProvider +public abstract partial class Image : ImageInfo, IDisposable, IConfigurationProvider { private bool isDisposed; - - private Size size; private readonly Configuration configuration; /// @@ -27,16 +25,12 @@ public abstract partial class Image : IImage, IConfigurationProvider /// /// The configuration which allows altering default behaviour or extending the library. /// - /// The . - /// The . - /// The . + /// The pixel type information. + /// The image metadata. + /// The size in px units. protected Image(Configuration configuration, PixelTypeInfo pixelType, ImageMetadata metadata, Size size) - { - this.configuration = configuration ?? Configuration.Default; - this.PixelType = pixelType; - this.size = size; - this.Metadata = metadata ?? new ImageMetadata(); - } + : base(pixelType, size, metadata) + => this.configuration = configuration ?? Configuration.Default; /// /// Initializes a new instance of the class. @@ -61,18 +55,6 @@ public abstract partial class Image : IImage, IConfigurationProvider /// protected abstract ImageFrameCollection NonGenericFrameCollection { get; } - /// - public PixelTypeInfo PixelType { get; } - - /// - public int Width => this.size.Width; - - /// - public int Height => this.size.Height; - - /// - public ImageMetadata Metadata { get; } - /// /// Gets the frames of the image as (non-generic) . /// @@ -148,7 +130,7 @@ public abstract partial class Image : IImage, IConfigurationProvider /// Update the size of the image after mutation. /// /// The . - protected void UpdateSize(Size size) => this.size = size; + protected void UpdateSize(Size size) => this.Size = size; /// /// Disposes the object and frees resources for the Garbage Collector. diff --git a/src/ImageSharp/ImageInfo.cs b/src/ImageSharp/ImageInfo.cs index 5b10440be..9a6452ab8 100644 --- a/src/ImageSharp/ImageInfo.cs +++ b/src/ImageSharp/ImageInfo.cs @@ -9,32 +9,60 @@ namespace SixLabors.ImageSharp; /// /// Contains information about the image including dimensions, pixel type information and additional metadata /// -public sealed class ImageInfo : IImageInfo +public class ImageInfo { /// /// Initializes a new instance of the class. /// - /// The image pixel type information. - /// The width of the image in pixels. - /// The height of the image in pixels. - /// The images metadata. + /// The pixel type information. + /// The width of the image in px units. + /// The height of the image in px units. + /// The image metadata. public ImageInfo(PixelTypeInfo pixelType, int width, int height, ImageMetadata metadata) + : this(pixelType, new(width, height), metadata) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The pixel type information. + /// The size of the image in px units. + /// The image metadata. + public ImageInfo(PixelTypeInfo pixelType, Size size, ImageMetadata metadata) { this.PixelType = pixelType; - this.Width = width; - this.Height = height; - this.Metadata = metadata; + this.Metadata = metadata ?? new ImageMetadata(); + this.Size = size; } - /// + /// + /// Gets information about the image pixels. + /// public PixelTypeInfo PixelType { get; } - /// - public int Width { get; } + /// + /// Gets the image width in px units. + /// + public int Width => this.Size.Width; - /// - public int Height { get; } + /// + /// Gets the image height in px units. + /// + public int Height => this.Size.Height; - /// + /// + /// Gets any metadata associated wit The image. + /// public ImageMetadata Metadata { get; } + + /// + /// Gets the size of the image in px units. + /// + public Size Size { get; internal set; } + + /// + /// Gets the bounds of the image. + /// + public Rectangle Bounds => new(0, 0, this.Width, this.Height); } diff --git a/src/ImageSharp/ImageInfoExtensions.cs b/src/ImageSharp/ImageInfoExtensions.cs deleted file mode 100644 index 0f47c8896..000000000 --- a/src/ImageSharp/ImageInfoExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -namespace SixLabors.ImageSharp; - -/// -/// Extension methods that allow the addition of geometry calculating methods to the type -/// -public static class ImageInfoExtensions -{ - /// - /// Gets the bounds of the image. - /// - /// The image info - /// The - public static Size Size(this IImageInfo info) => new(info.Width, info.Height); - - /// - /// Gets the bounds of the image. - /// - /// The image info - /// The - public static Rectangle Bounds(this IImageInfo info) => new(0, 0, info.Width, info.Height); -} diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index 31fd01509..9e3cc065c 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -411,7 +411,7 @@ public sealed class Image : Image this.frames[i].SwapOrCopyPixelsBufferFrom(sourceFrames[i]); } - this.UpdateSize(pixelSource.Size()); + this.UpdateSize(pixelSource.Size); } private static Size ValidateFramesAndGetSize(IEnumerable> frames) diff --git a/src/ImageSharp/Processing/DefaultImageProcessorContext{TPixel}.cs b/src/ImageSharp/Processing/DefaultImageProcessorContext{TPixel}.cs index 9893bceab..208455b90 100644 --- a/src/ImageSharp/Processing/DefaultImageProcessorContext{TPixel}.cs +++ b/src/ImageSharp/Processing/DefaultImageProcessorContext{TPixel}.cs @@ -95,5 +95,5 @@ internal class DefaultImageProcessorContext : IInternalImageProcessingCo return this; } - private Rectangle GetCurrentBounds() => this.destination?.Bounds() ?? this.source.Bounds(); + private Rectangle GetCurrentBounds() => this.destination?.Bounds ?? this.source.Bounds; } diff --git a/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs b/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs index ac0d36751..82e639f1b 100644 --- a/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs +++ b/src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs @@ -78,7 +78,7 @@ internal class DrawImageProcessor : ImageProcessor int locationY = this.Location.Y; // Align start/end positions. - Rectangle bounds = targetImage.Bounds(); + Rectangle bounds = targetImage.Bounds; int minX = Math.Max(this.Location.X, sourceRectangle.X); int maxX = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Right); diff --git a/src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs index 1ba62aa9e..9afc852b5 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs @@ -27,9 +27,7 @@ internal class EntropyCropProcessor : ImageProcessor /// The source area to process for the current processor instance. public EntropyCropProcessor(Configuration configuration, EntropyCropProcessor definition, Image source, Rectangle sourceRectangle) : base(configuration, source, sourceRectangle) - { - this.definition = definition; - } + => this.definition = definition; /// protected override void BeforeImageApply() @@ -38,7 +36,7 @@ internal class EntropyCropProcessor : ImageProcessor // TODO: This is clunky. We should add behavior enum to ExtractFrame. // All frames have be the same size so we only need to calculate the correct dimensions for the first frame - using (var temp = new Image(this.Configuration, this.Source.Metadata.DeepClone(), new[] { this.Source.Frames.RootFrame.Clone() })) + using (Image temp = new(this.Configuration, this.Source.Metadata.DeepClone(), new[] { this.Source.Frames.RootFrame.Clone() })) { Configuration configuration = this.Source.GetConfiguration(); @@ -52,7 +50,7 @@ internal class EntropyCropProcessor : ImageProcessor rectangle = GetFilteredBoundingRectangle(temp.Frames.RootFrame, 0); } - new CropProcessor(rectangle, this.Source.Size()).Execute(this.Configuration, this.Source, this.SourceRectangle); + new CropProcessor(rectangle, this.Source.Size).Execute(this.Configuration, this.Source, this.SourceRectangle); base.BeforeImageApply(); } @@ -77,7 +75,7 @@ internal class EntropyCropProcessor : ImageProcessor /// [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Rectangle GetBoundingRectangle(Point topLeft, Point bottomRight) - => new Rectangle( + => new( topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, @@ -99,29 +97,13 @@ internal class EntropyCropProcessor : ImageProcessor int height = bitmap.Height; Point topLeft = default; Point bottomRight = default; - - Func, int, int, float, bool> delegateFunc; - - // Determine which channel to check against - switch (channel) + Func, int, int, float, bool> delegateFunc = channel switch { - case RgbaComponent.R: - delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().X - b) > Constants.Epsilon; - break; - - case RgbaComponent.G: - delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Y - b) > Constants.Epsilon; - break; - - case RgbaComponent.B: - delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Z - b) > Constants.Epsilon; - break; - - default: - delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().W - b) > Constants.Epsilon; - break; - } - + RgbaComponent.R => (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().X - b) > Constants.Epsilon, + RgbaComponent.G => (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Y - b) > Constants.Epsilon, + RgbaComponent.B => (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Z - b) > Constants.Epsilon, + _ => (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().W - b) > Constants.Epsilon, + }; int GetMinY(ImageFrame pixels) { for (int y = 0; y < height; y++) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs index 4fbd7cfd2..ba96e76ae 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs @@ -82,7 +82,7 @@ internal class ResizeProcessor : TransformProcessor, IResampling return; } - var interest = Rectangle.Intersect(destinationRectangle, destination.Bounds()); + var interest = Rectangle.Intersect(destinationRectangle, destination.Bounds); if (sampler is NearestNeighborResampler) { diff --git a/tests/ImageSharp.Benchmarks/Codecs/Png/DecodeFilteredPng.cs b/tests/ImageSharp.Benchmarks/Codecs/Png/DecodeFilteredPng.cs index 74f500666..986c1431c 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Png/DecodeFilteredPng.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Png/DecodeFilteredPng.cs @@ -56,8 +56,8 @@ public class DecodeFilteredPng [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Size LoadPng(byte[] bytes) { - using var image = Image.Load(bytes); - return image.Size(); + using Image image = Image.Load(bytes); + return image.Size; } private static string TestImageFullPath(string path) diff --git a/tests/ImageSharp.Benchmarks/Codecs/Png/DecodePng.cs b/tests/ImageSharp.Benchmarks/Codecs/Png/DecodePng.cs index a73d62859..c23fa25cc 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Png/DecodePng.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Png/DecodePng.cs @@ -22,26 +22,21 @@ public class DecodePng [GlobalSetup] public void ReadImages() - { - if (this.pngBytes == null) - { - this.pngBytes = File.ReadAllBytes(this.TestImageFullPath); - } - } + => this.pngBytes ??= File.ReadAllBytes(this.TestImageFullPath); [Benchmark(Baseline = true, Description = "System.Drawing Png")] public SDSize PngSystemDrawing() { - using var memoryStream = new MemoryStream(this.pngBytes); - using var image = SDImage.FromStream(memoryStream); + using MemoryStream memoryStream = new(this.pngBytes); + using SDImage image = SDImage.FromStream(memoryStream); return image.Size; } [Benchmark(Description = "ImageSharp Png")] public Size PngImageSharp() { - using var memoryStream = new MemoryStream(this.pngBytes); - using var image = Image.Load(memoryStream); - return image.Size(); + using MemoryStream memoryStream = new(this.pngBytes); + using Image image = Image.Load(memoryStream); + return image.Size; } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Tiff/DecodeTiff.cs b/tests/ImageSharp.Benchmarks/Codecs/Tiff/DecodeTiff.cs index 4edb251fa..83f5fdd21 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Tiff/DecodeTiff.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Tiff/DecodeTiff.cs @@ -69,20 +69,16 @@ public class DecodeTiff [Benchmark(Baseline = true, Description = "System.Drawing Tiff")] public SDSize TiffSystemDrawing() { - using (var memoryStream = new MemoryStream(this.data)) - using (var image = SDImage.FromStream(memoryStream)) - { - return image.Size; - } + using MemoryStream memoryStream = new(this.data); + using SDImage image = SDImage.FromStream(memoryStream); + return image.Size; } [Benchmark(Description = "ImageSharp Tiff")] public Size TiffCore() { - using (var ms = new MemoryStream(this.data)) - using (var image = Image.Load(ms)) - { - return image.Size(); - } + using MemoryStream ms = new(this.data); + using Image image = Image.Load(ms); + return image.Size; } } diff --git a/tests/ImageSharp.Benchmarks/Processing/Diffuse.cs b/tests/ImageSharp.Benchmarks/Processing/Diffuse.cs index 7d6a52af2..c74c4a858 100644 --- a/tests/ImageSharp.Benchmarks/Processing/Diffuse.cs +++ b/tests/ImageSharp.Benchmarks/Processing/Diffuse.cs @@ -13,19 +13,19 @@ public class Diffuse [Benchmark] public Size DoDiffuse() { - using var image = new Image(Configuration.Default, 800, 800, Color.BlanchedAlmond); + using Image image = new(Configuration.Default, 800, 800, Color.BlanchedAlmond); image.Mutate(x => x.Dither(KnownDitherings.FloydSteinberg)); - return image.Size(); + return image.Size; } [Benchmark] public Size DoDither() { - using var image = new Image(Configuration.Default, 800, 800, Color.BlanchedAlmond); + using Image image = new(Configuration.Default, 800, 800, Color.BlanchedAlmond); image.Mutate(x => x.Dither()); - return image.Size(); + return image.Size; } } diff --git a/tests/ImageSharp.Benchmarks/Processing/Rotate.cs b/tests/ImageSharp.Benchmarks/Processing/Rotate.cs index c392d9964..b9b0f6b3d 100644 --- a/tests/ImageSharp.Benchmarks/Processing/Rotate.cs +++ b/tests/ImageSharp.Benchmarks/Processing/Rotate.cs @@ -13,10 +13,10 @@ public class Rotate [Benchmark] public Size DoRotate() { - using var image = new Image(Configuration.Default, 400, 400, Color.BlanchedAlmond); + using Image image = new(Configuration.Default, 400, 400, Color.BlanchedAlmond); image.Mutate(x => x.Rotate(37.5F)); - return image.Size(); + return image.Size; } } diff --git a/tests/ImageSharp.Benchmarks/Processing/Skew.cs b/tests/ImageSharp.Benchmarks/Processing/Skew.cs index bc64382c1..26f2e7d2d 100644 --- a/tests/ImageSharp.Benchmarks/Processing/Skew.cs +++ b/tests/ImageSharp.Benchmarks/Processing/Skew.cs @@ -13,10 +13,10 @@ public class Skew [Benchmark] public Size DoSkew() { - using var image = new Image(Configuration.Default, 400, 400, Color.BlanchedAlmond); + using Image image = new(Configuration.Default, 400, 400, Color.BlanchedAlmond); image.Mutate(x => x.Skew(20, 10)); - return image.Size(); + return image.Size; } } diff --git a/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs b/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs index 03e062cc0..57a90c77b 100644 --- a/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs +++ b/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs @@ -30,7 +30,7 @@ public class AdvancedImageExtensionsTests IMemoryGroup memoryGroup = image.GetPixelMemoryGroup(); // Assert: - VerifyMemoryGroupDataMatchesTestPattern(provider, memoryGroup, image.Size()); + VerifyMemoryGroupDataMatchesTestPattern(provider, memoryGroup, image.Size); } [Theory] @@ -57,23 +57,23 @@ public class AdvancedImageExtensionsTests where TPixel : unmanaged, IPixel { using Image image0 = provider.GetImage(); - var targetBuffer = new TPixel[image0.Width * image0.Height]; + TPixel[] targetBuffer = new TPixel[image0.Width * image0.Height]; Assert.True(image0.DangerousTryGetSinglePixelMemory(out Memory sourceBuffer)); sourceBuffer.CopyTo(targetBuffer); - var managerOfExternalMemory = new TestMemoryManager(targetBuffer); + TestMemoryManager managerOfExternalMemory = new(targetBuffer); Memory externalMemory = managerOfExternalMemory.Memory; - using (var image1 = Image.WrapMemory(externalMemory, image0.Width, image0.Height)) + using (Image image1 = Image.WrapMemory(externalMemory, image0.Width, image0.Height)) { - VerifyMemoryGroupDataMatchesTestPattern(provider, image1.GetPixelMemoryGroup(), image1.Size()); + VerifyMemoryGroupDataMatchesTestPattern(provider, image1.GetPixelMemoryGroup(), image1.Size); } // Make sure externalMemory works after destruction: - VerifyMemoryGroupDataMatchesTestPattern(provider, image0.GetPixelMemoryGroup(), image0.Size()); + VerifyMemoryGroupDataMatchesTestPattern(provider, image0.GetPixelMemoryGroup(), image0.Size); } private static void VerifyMemoryGroupDataMatchesTestPattern( diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs index 5fecb2f9f..7e0b1de82 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs @@ -174,7 +174,7 @@ public partial class JpegDecoderTests Assert.Equal(expectedColorType, meta.ColorType); } - private static void TestImageInfo(string imagePath, IImageDecoder decoder, bool useIdentify, Action test) + private static void TestImageInfo(string imagePath, IImageDecoder decoder, bool useIdentify, Action test) { TestFile testFile = TestFile.Create(imagePath); using MemoryStream stream = new(testFile.Bytes, false); diff --git a/tests/ImageSharp.Tests/Image/ImageRotationTests.cs b/tests/ImageSharp.Tests/Image/ImageRotationTests.cs index 978e0921c..e7d3b548b 100644 --- a/tests/ImageSharp.Tests/Image/ImageRotationTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageRotationTests.cs @@ -45,12 +45,10 @@ public class ImageRotationTests private static (Size Original, Size Rotated) Rotate(int angle) { - var file = TestFile.Create(TestImages.Bmp.Car); - using (var image = Image.Load(file.FullPath)) - { - Size original = image.Size(); - image.Mutate(x => x.Rotate(angle)); - return (original, image.Size()); - } + TestFile file = TestFile.Create(TestImages.Bmp.Car); + using Image image = Image.Load(file.FullPath); + Size original = image.Size; + image.Mutate(x => x.Rotate(angle)); + return (original, image.Size); } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs index 0cda1c1fb..7f6651d90 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs @@ -34,7 +34,7 @@ public partial class ImageTests public void FromBytes_GlobalConfiguration() { ImageInfo info = Image.Identify(ActualImageBytes); - Assert.Equal(ExpectedImageSize, info.Size()); + Assert.Equal(ExpectedImageSize, info.Size); Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } @@ -176,7 +176,7 @@ public partial class ImageTests AsyncStreamWrapper asyncStream = new(stream, () => false); ImageInfo info = await Image.IdentifyAsync(asyncStream); - Assert.Equal(ExpectedImageSize, info.Size()); + Assert.Equal(ExpectedImageSize, info.Size); Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } @@ -201,7 +201,7 @@ public partial class ImageTests AsyncStreamWrapper asyncStream = new(nonSeekableStream, () => false); ImageInfo info = await Image.IdentifyAsync(asyncStream); - Assert.Equal(ExpectedImageSize, info.Size()); + Assert.Equal(ExpectedImageSize, info.Size); Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } @@ -253,7 +253,7 @@ public partial class ImageTests { ImageInfo info = await Image.IdentifyAsync(ActualImagePath); - Assert.Equal(ExpectedImageSize, info.Size()); + Assert.Equal(ExpectedImageSize, info.Size); Assert.Equal(ExpectedGlobalFormat, info.Metadata.DecodedImageFormat); } @@ -262,7 +262,7 @@ public partial class ImageTests { ImageInfo info = await Image.IdentifyAsync(ActualImagePath); - Assert.Equal(ExpectedImageSize, info.Size()); + Assert.Equal(ExpectedImageSize, info.Size); } [Fact] diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs index 4d3e4128f..a8f9981b4 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs @@ -5,6 +5,7 @@ using Moq; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Tests; @@ -25,8 +26,6 @@ public partial class ImageTests protected Mock localImageFormatMock; - protected Mock localImageInfoMock; - protected readonly string MockFilePath = Guid.NewGuid().ToString(); internal readonly Mock LocalFileSystemMock = new(); @@ -58,14 +57,7 @@ public partial class ImageTests // TODO: Remove all this mocking. It's too complicated and we can now use fakes. this.localStreamReturnImageRgba32 = new Image(1, 1); this.localStreamReturnImageAgnostic = new Image(1, 1); - - this.localImageInfoMock = new Mock(); - - this.LocalImageInfo = new( - this.localImageInfoMock.Object.PixelType, - this.localImageInfoMock.Object.Width, - this.localImageInfoMock.Object.Height, - this.localImageInfoMock.Object.Metadata); + this.LocalImageInfo = new(new PixelTypeInfo(8), new(1, 1), new ImageMetadata()); this.localImageFormatMock = new Mock(); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs index b355c42a6..3e488be9a 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs @@ -12,7 +12,7 @@ public partial class ImageTests { private string Path { get; } = TestFile.GetInputFileFullPath(TestImages.Bmp.Bit8); - private static void VerifyDecodedImage(Image img) => Assert.Equal(new Size(127, 64), img.Size()); + private static void VerifyDecodedImage(Image img) => Assert.Equal(new Size(127, 64), img.Size); [Fact] public void Path_Specific() diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs index a3d860596..00ec985ac 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs @@ -14,7 +14,7 @@ public partial class ImageTests private static Span ByteSpan => new(ByteArray); - private static void VerifyDecodedImage(Image img) => Assert.Equal(new Size(127, 64), img.Size()); + private static void VerifyDecodedImage(Image img) => Assert.Equal(new Size(127, 64), img.Size); [Fact] public void Bytes_Specific() diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs index 682ec2a41..7a5bd186b 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs @@ -26,7 +26,7 @@ public partial class ImageTests } private static void VerifyDecodedImage(Image img) - => Assert.Equal(new Size(127, 64), img.Size()); + => Assert.Equal(new Size(127, 64), img.Size); [Fact] public void Stream_Specific() diff --git a/tests/ImageSharp.Tests/ImageInfoTests.cs b/tests/ImageSharp.Tests/ImageInfoTests.cs index 48b982e1a..39091281d 100644 --- a/tests/ImageSharp.Tests/ImageInfoTests.cs +++ b/tests/ImageSharp.Tests/ImageInfoTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using SixLabors.ImageSharp.Formats; @@ -11,20 +11,20 @@ public class ImageInfoTests [Fact] public void ImageInfoInitializesCorrectly() { - const int Width = 50; - const int Height = 60; - var size = new Size(Width, Height); - var rectangle = new Rectangle(0, 0, Width, Height); - var pixelType = new PixelTypeInfo(8); - var meta = new ImageMetadata(); + const int width = 50; + const int height = 60; + Size size = new(width, height); + Rectangle rectangle = new(0, 0, width, height); + PixelTypeInfo pixelType = new(8); + ImageMetadata meta = new(); - var info = new ImageInfo(pixelType, Width, Height, meta); + ImageInfo info = new(pixelType, width, height, meta); Assert.Equal(pixelType, info.PixelType); - Assert.Equal(Width, info.Width); - Assert.Equal(Height, info.Height); - Assert.Equal(size, info.Size()); - Assert.Equal(rectangle, info.Bounds()); + Assert.Equal(width, info.Width); + Assert.Equal(height, info.Height); + Assert.Equal(size, info.Size); + Assert.Equal(rectangle, info.Bounds); Assert.Equal(meta, info.Metadata); } } diff --git a/tests/ImageSharp.Tests/Processing/BaseImageOperationsExtensionTest.cs b/tests/ImageSharp.Tests/Processing/BaseImageOperationsExtensionTest.cs index 9070b8158..98b5c8e98 100644 --- a/tests/ImageSharp.Tests/Processing/BaseImageOperationsExtensionTest.cs +++ b/tests/ImageSharp.Tests/Processing/BaseImageOperationsExtensionTest.cs @@ -15,7 +15,7 @@ public abstract class BaseImageOperationsExtensionTest : IDisposable protected readonly GraphicsOptions options; private readonly Image source; - public Rectangle SourceBounds() => this.source.Bounds(); + public Rectangle SourceBounds() => this.source.Bounds; public BaseImageOperationsExtensionTest() { diff --git a/tests/ImageSharp.Tests/Processing/FakeImageOperationsProvider.cs b/tests/ImageSharp.Tests/Processing/FakeImageOperationsProvider.cs index 071c2fa68..17f63384e 100644 --- a/tests/ImageSharp.Tests/Processing/FakeImageOperationsProvider.cs +++ b/tests/ImageSharp.Tests/Processing/FakeImageOperationsProvider.cs @@ -64,7 +64,7 @@ internal class FakeImageOperationsProvider : IImageProcessingContextFactory public Size GetCurrentSize() { - return this.Source.Size(); + return this.Source.Size; } public IImageProcessingContext ApplyProcessor(IImageProcessor processor, Rectangle rectangle) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs index 175e31633..0e53856da 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs @@ -48,7 +48,7 @@ public class BokehBlurTest public void VerifyComplexComponents() { // Get the saved components - var components = new List(); + List components = new(); foreach (Match match in Regex.Matches(Components10x2, @"\[\[(.*?)\]\]", RegexOptions.Singleline)) { string[] values = match.Groups[1].Value.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); @@ -64,23 +64,20 @@ public class BokehBlurTest } // Make sure the kernel components are the same - using (var image = new Image(1, 1)) + using Image image = new(1, 1); + Configuration configuration = image.GetConfiguration(); + BokehBlurProcessor definition = new(10, BokehBlurProcessor.DefaultComponents, BokehBlurProcessor.DefaultGamma); + + using BokehBlurProcessor processor = (BokehBlurProcessor)definition.CreatePixelSpecificProcessor(configuration, image, image.Bounds); + Assert.Equal(components.Count, processor.Kernels.Count); + foreach ((Complex64[] a, Complex64[] b) in components.Zip(processor.Kernels, (a, b) => (a, b))) { - Configuration configuration = image.GetConfiguration(); - var definition = new BokehBlurProcessor(10, BokehBlurProcessor.DefaultComponents, BokehBlurProcessor.DefaultGamma); - using (var processor = (BokehBlurProcessor)definition.CreatePixelSpecificProcessor(configuration, image, image.Bounds())) + Span spanA = a.AsSpan(), spanB = b.AsSpan(); + Assert.Equal(spanA.Length, spanB.Length); + for (int i = 0; i < spanA.Length; i++) { - Assert.Equal(components.Count, processor.Kernels.Count); - foreach ((Complex64[] a, Complex64[] b) in components.Zip(processor.Kernels, (a, b) => (a, b))) - { - Span spanA = a.AsSpan(), spanB = b.AsSpan(); - Assert.Equal(spanA.Length, spanB.Length); - for (int i = 0; i < spanA.Length; i++) - { - Assert.True(Math.Abs(Math.Abs(spanA[i].Real) - Math.Abs(spanB[i].Real)) < 0.0001f); - Assert.True(Math.Abs(Math.Abs(spanA[i].Imaginary) - Math.Abs(spanB[i].Imaginary)) < 0.0001f); - } - } + Assert.True(Math.Abs(Math.Abs(spanA[i].Real) - Math.Abs(spanB[i].Real)) < 0.0001f); + Assert.True(Math.Abs(Math.Abs(spanA[i].Imaginary) - Math.Abs(spanB[i].Imaginary)) < 0.0001f); } } } @@ -110,7 +107,7 @@ public class BokehBlurTest public override string ToString() => $"R{this.Radius}_C{this.Components}_G{this.Gamma}"; } - public static readonly TheoryData BokehBlurValues = new TheoryData + public static readonly TheoryData BokehBlurValues = new() { new BokehBlurInfo { Radius = 8, Components = 1, Gamma = 1 }, new BokehBlurInfo { Radius = 16, Components = 1, Gamma = 3 }, @@ -167,7 +164,7 @@ public class BokehBlurTest x => { Size size = x.GetCurrentSize(); - var bounds = new Rectangle(10, 10, size.Width / 2, size.Height / 2); + Rectangle bounds = new(10, 10, size.Width / 2, size.Height / 2); x.BokehBlur(value.Radius, value.Components, value.Gamma, bounds); }, testOutputDetails: value.ToString(), diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs index a8182bd07..0fc5e286d 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs @@ -106,7 +106,7 @@ public class AffineTransformTests .AppendScale(new SizeF(sx, sy)) .AppendTranslation(new PointF(tx, ty)); - this.PrintMatrix(builder.BuildMatrix(image.Size())); + this.PrintMatrix(builder.BuildMatrix(image.Size)); image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic)); diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index 86b9223c2..d8ce88dc3 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -39,7 +39,7 @@ public class ResizeTests string filePath = TestFile.GetInputFileFullPath(TestImages.Jpeg.Baseline.Calliphora); using Image image = Image.Load(filePath); - image.Mutate(x => x.Resize(image.Size() / 2)); + image.Mutate(x => x.Resize(image.Size / 2)); string path = Path.Combine( TestEnvironment.CreateOutputDirectory(nameof(ResizeTests)), nameof(this.Resize_PixelAgnostic) + ".png"); @@ -101,7 +101,7 @@ public class ResizeTests where TPixel : unmanaged, IPixel { using Image image0 = provider.GetImage(); - Size destSize = image0.Size() / 4; + Size destSize = image0.Size / 4; Configuration configuration = Configuration.CreateDefaultInstance(); @@ -155,7 +155,7 @@ public class ResizeTests { using Image expected = provider.GetImage(); int width = expected.Width; - Size destSize = expected.Size() / 4; + Size destSize = expected.Size / 4; expected.Mutate(c => c.Resize(destSize, KnownResamplers.Bicubic, false)); // Replace configuration: @@ -179,7 +179,7 @@ public class ResizeTests where TPixel : unmanaged, IPixel { using Image image = provider.GetImage(); - image.Mutate(x => x.Resize(image.Size() / 2, true)); + image.Mutate(x => x.Resize(image.Size / 2, true)); image.DebugSave(provider); image.CompareToReferenceOutput(ValidatorComparer, provider); diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs index 3aa879cf4..a1d7e358b 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs @@ -35,7 +35,7 @@ public class LoadResizeSaveProfilingBenchmarks : MeasureFixture { using (var image = Image.Load(options, imageBytes)) { - image.Mutate(x => x.Resize(image.Size() / 4)); + image.Mutate(x => x.Resize(image.Size / 4)); image.SaveAsJpeg(ms); } diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs index 3de525964..29f9d1626 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs @@ -76,9 +76,9 @@ public static class ImageComparerExtensions where TPixelA : unmanaged, IPixel where TPixelB : unmanaged, IPixel { - if (expected.Size() != actual.Size()) + if (expected.Size != actual.Size) { - throw new ImageDimensionsMismatchException(expected.Size(), actual.Size()); + throw new ImageDimensionsMismatchException(expected.Size, actual.Size); } if (expected.Frames.Count != actual.Frames.Count) @@ -101,9 +101,9 @@ public static class ImageComparerExtensions where TPixelA : unmanaged, IPixel where TPixelB : unmanaged, IPixel { - if (expected.Size() != actual.Size()) + if (expected.Size != actual.Size) { - throw new ImageDimensionsMismatchException(expected.Size(), actual.Size()); + throw new ImageDimensionsMismatchException(expected.Size, actual.Size); } if (expected.Frames.Count != actual.Frames.Count)