diff --git a/src/ImageSharp/Advanced/AotCompilerTools.cs b/src/ImageSharp/Advanced/AotCompilerTools.cs
index 0cf28c6bb..4ac95be9a 100644
--- a/src/ImageSharp/Advanced/AotCompilerTools.cs
+++ b/src/ImageSharp/Advanced/AotCompilerTools.cs
@@ -248,7 +248,7 @@ internal static class AotCompilerTools
}
///
- /// This method pre-seeds the all in the AoT compiler.
+ /// This method pre-seeds the all in the AoT compiler.
///
/// The pixel format.
[Preserve]
@@ -280,14 +280,14 @@ internal static class AotCompilerTools
}
///
- /// This method pre-seeds the in the AoT compiler.
+ /// This method pre-seeds the in the AoT compiler.
///
/// The pixel format.
/// The decoder.
[Preserve]
private static void AotCompileImageDecoder()
where TPixel : unmanaged, IPixel
- where TDecoder : class, IImageDecoder
+ where TDecoder : ImageDecoder
=> default(TDecoder).Decode(default, default, default);
///
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
index 35d5690c7..d56aaa1ac 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
@@ -8,10 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Bmp;
///
/// Image decoder for generating an image out of a Windows bitmap stream.
///
-public class BmpDecoder : IImageDecoderSpecialized
+public sealed class BmpDecoder : SpecializedImageDecoder
{
///
- IImageInfo IImageInfoDetector.Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -20,27 +20,23 @@ public class BmpDecoder : IImageDecoderSpecialized
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoderSpecialized)this).Decode(new() { GeneralOptions = options }, stream, cancellationToken);
-
- ///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoderSpecialized)this).Decode(new() { GeneralOptions = options }, stream, cancellationToken);
-
- ///
- Image IImageDecoderSpecialized.Decode(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
Image image = new BmpDecoderCore(options).Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
- ImageDecoderUtilities.Resize(options.GeneralOptions, image);
+ Resize(options.GeneralOptions, image);
return image;
}
///
- Image IImageDecoderSpecialized.Decode(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoderSpecialized)this).Decode(options, stream, cancellationToken);
+ protected internal override Image Decode(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
+
+ ///
+ protected internal override BmpDecoderOptions CreateDefaultSpecializedOptions(DecoderOptions options)
+ => new() { GeneralOptions = options };
}
diff --git a/src/ImageSharp/Formats/Gif/GifDecoder.cs b/src/ImageSharp/Formats/Gif/GifDecoder.cs
index cf8f4637e..6ae877516 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoder.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoder.cs
@@ -8,10 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Gif;
///
/// Decoder for generating an image out of a gif encoded stream.
///
-public sealed class GifDecoder : IImageDecoder
+public sealed class GifDecoder : ImageDecoder
{
///
- IImageInfo IImageInfoDetector.Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -20,7 +20,7 @@ public sealed class GifDecoder : IImageDecoder
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -28,12 +28,12 @@ public sealed class GifDecoder : IImageDecoder
GifDecoderCore decoder = new(options);
Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
- ImageDecoderUtilities.Resize(options, image);
+ Resize(options, image);
return image;
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoder)this).Decode(options, stream, cancellationToken);
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
diff --git a/src/ImageSharp/Formats/IImageDecoder.cs b/src/ImageSharp/Formats/IImageDecoder.cs
deleted file mode 100644
index 7052bc49f..000000000
--- a/src/ImageSharp/Formats/IImageDecoder.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp.Formats;
-
-///
-/// Encapsulates properties and methods required for decoding an image from a stream.
-///
-public interface IImageDecoder : IImageInfoDetector
-{
- ///
- /// Decodes the image from the specified stream to an of a specific pixel type.
- ///
- ///
- /// This method is designed to support the ImageSharp internal infrastructure and is not recommended for direct use.
- ///
- /// The pixel format.
- /// The general decoder options.
- /// The containing image data.
- /// The token to monitor for cancellation requests.
- /// The .
- /// Thrown if the encoded image contains errors.
- Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- where TPixel : unmanaged, IPixel;
-
- ///
- /// Decodes the image from the specified stream to an .
- ///
- ///
- /// This method is designed to support the ImageSharp internal infrastructure and is not recommended for direct use.
- ///
- /// The general decoder options.
- /// The containing image data.
- /// The token to monitor for cancellation requests.
- /// The .
- /// Thrown if the encoded image contains errors.
- Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken);
-}
diff --git a/src/ImageSharp/Formats/IImageDecoderSpecialized{T}.cs b/src/ImageSharp/Formats/IImageDecoderSpecialized{T}.cs
deleted file mode 100644
index 77cffe34c..000000000
--- a/src/ImageSharp/Formats/IImageDecoderSpecialized{T}.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp.Formats;
-
-///
-/// The base class for all specialized image decoders.
-///
-/// The type of specialized options.
-public interface IImageDecoderSpecialized : IImageDecoder
- where T : ISpecializedDecoderOptions
-{
- ///
- /// Decodes the image from the specified stream to an of a specific pixel type.
- ///
- ///
- /// This method is designed to support the ImageSharp internal infrastructure and is not recommended for direct use.
- ///
- /// The pixel format.
- /// The specialized decoder options.
- /// The containing image data.
- /// The token to monitor for cancellation requests.
- /// The .
- /// Thrown if the encoded image contains errors.
- public Image Decode(T options, Stream stream, CancellationToken cancellationToken)
- where TPixel : unmanaged, IPixel;
-
- ///
- /// Decodes the image from the specified stream to an of a specific pixel type.
- ///
- ///
- /// This method is designed to support the ImageSharp internal infrastructure and is not recommended for direct use.
- ///
- /// The specialized decoder options.
- /// The containing image data.
- /// The token to monitor for cancellation requests.
- /// The .
- /// Thrown if the encoded image contains errors.
- public Image Decode(T options, Stream stream, CancellationToken cancellationToken);
-}
diff --git a/src/ImageSharp/Formats/ImageDecoder.cs b/src/ImageSharp/Formats/ImageDecoder.cs
new file mode 100644
index 000000000..000cb9923
--- /dev/null
+++ b/src/ImageSharp/Formats/ImageDecoder.cs
@@ -0,0 +1,145 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
+
+namespace SixLabors.ImageSharp.Formats;
+
+///
+/// The base class for all image decoders.
+///
+public abstract class ImageDecoder
+{
+ ///
+ /// Decodes the image from the specified stream to an of a specific pixel type.
+ ///
+ ///
+ /// This method is designed to support the ImageSharp internal infrastructure and is not recommended for direct use.
+ ///
+ /// The pixel format.
+ /// The general decoder options.
+ /// The containing image data.
+ /// The token to monitor for cancellation requests.
+ /// The .
+ /// Thrown if the encoded image contains errors.
+ protected internal abstract Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ where TPixel : unmanaged, IPixel;
+
+ ///
+ /// Decodes the image from the specified stream to an .
+ ///
+ ///
+ /// This method is designed to support the ImageSharp internal infrastructure and is not recommended for direct use.
+ ///
+ /// The general decoder options.
+ /// The containing image data.
+ /// The token to monitor for cancellation requests.
+ /// The .
+ /// Thrown if the encoded image contains errors.
+ protected internal abstract Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken);
+
+ ///
+ /// Reads the raw image information from the specified stream.
+ ///
+ ///
+ /// This method is designed to support the ImageSharp internal infrastructure and is not recommended for direct use.
+ ///
+ /// The general decoder options.
+ /// The containing image data.
+ /// The token to monitor for cancellation requests.
+ /// The object.
+ /// Thrown if the encoded image contains errors.
+ protected internal abstract IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken);
+
+ ///
+ /// Performs a resize operation against the decoded image. If the target size is not set, or the image size
+ /// already matches the target size, the image is untouched.
+ ///
+ /// The decoder options.
+ /// The decoded image.
+ protected static void Resize(DecoderOptions options, Image image)
+ {
+ if (ShouldResize(options, image))
+ {
+ ResizeOptions resizeOptions = new()
+ {
+ Size = options.TargetSize.Value,
+ Sampler = options.Sampler,
+ Mode = ResizeMode.Max
+ };
+
+ image.Mutate(x => x.Resize(resizeOptions));
+ }
+ }
+
+ ///
+ /// Determines whether the decoded image should be resized.
+ ///
+ /// The decoder options.
+ /// The decoded image.
+ /// if the image should be resized, otherwise; .
+ private static bool ShouldResize(DecoderOptions options, Image image)
+ {
+ if (options.TargetSize is null)
+ {
+ return false;
+ }
+
+ Size targetSize = options.TargetSize.Value;
+ Size currentSize = image.Size();
+ return currentSize.Width != targetSize.Width && currentSize.Height != targetSize.Height;
+ }
+}
+
+///
+/// The base class for all specialized image decoders.
+/// Specialized decoders allow for additional options to be passed to the decoder.
+///
+/// The type of specialized options.
+public abstract class SpecializedImageDecoder : ImageDecoder
+ where T : ISpecializedDecoderOptions
+{
+ ///
+ /// Decodes the image from the specified stream to an of a specific pixel type.
+ ///
+ ///
+ /// This method is designed to support the ImageSharp internal infrastructure and is not recommended for direct use.
+ ///
+ /// The pixel format.
+ /// The specialized decoder options.
+ /// The containing image data.
+ /// The token to monitor for cancellation requests.
+ /// The .
+ /// Thrown if the encoded image contains errors.
+ protected internal abstract Image Decode(T options, Stream stream, CancellationToken cancellationToken)
+ where TPixel : unmanaged, IPixel;
+
+ ///
+ /// Decodes the image from the specified stream to an of a specific pixel type.
+ ///
+ ///
+ /// This method is designed to support the ImageSharp internal infrastructure and is not recommended for direct use.
+ ///
+ /// The specialized decoder options.
+ /// The containing image data.
+ /// The token to monitor for cancellation requests.
+ /// The .
+ /// Thrown if the encoded image contains errors.
+ protected internal abstract Image Decode(T options, Stream stream, CancellationToken cancellationToken);
+
+ ///
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken);
+
+ ///
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken);
+
+ ///
+ /// A factory method for creating the default specialized options.
+ ///
+ /// The general decoder options.
+ /// The new .
+ protected internal abstract T CreateDefaultSpecializedOptions(DecoderOptions options);
+}
diff --git a/src/ImageSharp/Formats/ImageDecoderExtensions.cs b/src/ImageSharp/Formats/ImageDecoderExtensions.cs
index a18974bbd..26ceec3f6 100644
--- a/src/ImageSharp/Formats/ImageDecoderExtensions.cs
+++ b/src/ImageSharp/Formats/ImageDecoderExtensions.cs
@@ -6,7 +6,7 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats;
///
-/// Extensions methods for and .
+/// Extensions methods for and .
///
public static class ImageDecoderExtensions
{
@@ -18,7 +18,7 @@ public static class ImageDecoderExtensions
/// The containing image data.
/// The object.
/// Thrown if the encoded image contains errors.
- public static IImageInfo Identify(this IImageDecoder decoder, DecoderOptions options, Stream stream)
+ public static IImageInfo Identify(this ImageDecoder decoder, DecoderOptions options, Stream stream)
=> Image.WithSeekableStream(
options,
stream,
@@ -33,7 +33,7 @@ public static class ImageDecoderExtensions
/// The token to monitor for cancellation requests.
/// The object.
/// Thrown if the encoded image contains errors.
- public static Task IdentifyAsync(this IImageDecoder decoder, DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
+ public static Task IdentifyAsync(this ImageDecoder decoder, DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
=> Image.WithSeekableStreamAsync(
options,
stream,
@@ -49,7 +49,7 @@ public static class ImageDecoderExtensions
/// The containing image data.
/// The .
/// Thrown if the encoded image contains errors.
- public static Image Decode(this IImageDecoder decoder, DecoderOptions options, Stream stream)
+ public static Image Decode(this ImageDecoder decoder, DecoderOptions options, Stream stream)
where TPixel : unmanaged, IPixel
=> Image.WithSeekableStream(
options,
@@ -64,7 +64,7 @@ public static class ImageDecoderExtensions
/// The containing image data.
/// The .
/// Thrown if the encoded image contains errors.
- public static Image Decode(this IImageDecoder decoder, DecoderOptions options, Stream stream)
+ public static Image Decode(this ImageDecoder decoder, DecoderOptions options, Stream stream)
=> Image.WithSeekableStream(
options,
stream,
@@ -80,7 +80,7 @@ public static class ImageDecoderExtensions
/// The token to monitor for cancellation requests.
/// A representing the asynchronous operation.
/// Thrown if the encoded image contains errors.
- public static Task> DecodeAsync(this IImageDecoder decoder, DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
+ public static Task> DecodeAsync(this ImageDecoder decoder, DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
where TPixel : unmanaged, IPixel
=> Image.WithSeekableStreamAsync(
options,
@@ -97,7 +97,7 @@ public static class ImageDecoderExtensions
/// The token to monitor for cancellation requests.
/// A representing the asynchronous operation.
/// Thrown if the encoded image contains errors.
- public static Task DecodeAsync(this IImageDecoder decoder, DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
+ public static Task DecodeAsync(this ImageDecoder decoder, DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
=> Image.WithSeekableStreamAsync(
options,
stream,
@@ -114,7 +114,7 @@ public static class ImageDecoderExtensions
/// The containing image data.
/// The .
/// Thrown if the encoded image contains errors.
- public static Image Decode(this IImageDecoderSpecialized decoder, T options, Stream stream)
+ public static Image Decode(this SpecializedImageDecoder decoder, T options, Stream stream)
where T : ISpecializedDecoderOptions
where TPixel : unmanaged, IPixel
=> Image.WithSeekableStream(
@@ -131,7 +131,7 @@ public static class ImageDecoderExtensions
/// The containing image data.
/// The .
/// Thrown if the encoded image contains errors.
- public static Image Decode(this IImageDecoderSpecialized decoder, T options, Stream stream)
+ public static Image Decode(this SpecializedImageDecoder decoder, T options, Stream stream)
where T : ISpecializedDecoderOptions
=> Image.WithSeekableStream(
options.GeneralOptions,
@@ -149,7 +149,7 @@ public static class ImageDecoderExtensions
/// The token to monitor for cancellation requests.
/// A representing the asynchronous operation.
/// Thrown if the encoded image contains errors.
- public static Task> DecodeAsync(this IImageDecoderSpecialized decoder, T options, Stream stream, CancellationToken cancellationToken = default)
+ public static Task> DecodeAsync(this SpecializedImageDecoder decoder, T options, Stream stream, CancellationToken cancellationToken = default)
where T : ISpecializedDecoderOptions
where TPixel : unmanaged, IPixel
=> Image.WithSeekableStreamAsync(
@@ -168,7 +168,7 @@ public static class ImageDecoderExtensions
/// The token to monitor for cancellation requests.
/// A representing the asynchronous operation.
/// Thrown if the encoded image contains errors.
- public static Task DecodeAsync(this IImageDecoderSpecialized decoder, T options, Stream stream, CancellationToken cancellationToken = default)
+ public static Task DecodeAsync(this SpecializedImageDecoder decoder, T options, Stream stream, CancellationToken cancellationToken = default)
where T : ISpecializedDecoderOptions
=> Image.WithSeekableStreamAsync(
options.GeneralOptions,
diff --git a/src/ImageSharp/Formats/ImageDecoderUtilities.cs b/src/ImageSharp/Formats/ImageDecoderUtilities.cs
index c05e0d83c..288f72eac 100644
--- a/src/ImageSharp/Formats/ImageDecoderUtilities.cs
+++ b/src/ImageSharp/Formats/ImageDecoderUtilities.cs
@@ -4,54 +4,14 @@
using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing;
namespace SixLabors.ImageSharp.Formats;
///
-/// Utility methods for .
+/// Utility methods for .
///
internal static class ImageDecoderUtilities
{
- ///
- /// Performs a resize operation against the decoded image. If the target size is not set, or the image size
- /// already matches the target size, the image is untouched.
- ///
- /// The decoder options.
- /// The decoded image.
- public static void Resize(DecoderOptions options, Image image)
- {
- if (ShouldResize(options, image))
- {
- ResizeOptions resizeOptions = new()
- {
- Size = options.TargetSize.Value,
- Sampler = options.Sampler,
- Mode = ResizeMode.Max
- };
-
- image.Mutate(x => x.Resize(resizeOptions));
- }
- }
-
- ///
- /// Determines whether the decoded image should be resized.
- ///
- /// The decoder options.
- /// The decoded image.
- /// if the image should be resized, otherwise; .
- private static bool ShouldResize(DecoderOptions options, Image image)
- {
- if (options.TargetSize is null)
- {
- return false;
- }
-
- Size targetSize = options.TargetSize.Value;
- Size currentSize = image.Size();
- return currentSize.Width != targetSize.Width && currentSize.Height != targetSize.Height;
- }
-
internal static IImageInfo Identify(
this IImageDecoderInternals decoder,
Configuration configuration,
diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs
index 9f22c6229..922018456 100644
--- a/src/ImageSharp/Formats/ImageFormatManager.cs
+++ b/src/ImageSharp/Formats/ImageFormatManager.cs
@@ -22,9 +22,9 @@ public class ImageFormatManager
private readonly ConcurrentDictionary mimeTypeEncoders = new();
///
- /// The list of supported keyed to mime types.
+ /// The list of supported keyed to mime types.
///
- private readonly ConcurrentDictionary mimeTypeDecoders = new();
+ private readonly ConcurrentDictionary mimeTypeDecoders = new();
///
/// The list of supported s.
@@ -59,9 +59,9 @@ public class ImageFormatManager
internal IEnumerable FormatDetectors => this.imageFormatDetectors;
///
- /// Gets the currently registered s.
+ /// Gets the currently registered s.
///
- internal IEnumerable> ImageDecoders => this.mimeTypeDecoders;
+ internal IEnumerable> ImageDecoders => this.mimeTypeDecoders;
///
/// Gets the currently registered s.
@@ -122,7 +122,7 @@ public class ImageFormatManager
Guard.NotNull(imageFormat, nameof(imageFormat));
Guard.NotNull(encoder, nameof(encoder));
this.AddImageFormat(imageFormat);
- this.mimeTypeEncoders.AddOrUpdate(imageFormat, encoder, (s, e) => encoder);
+ this.mimeTypeEncoders.AddOrUpdate(imageFormat, encoder, (_, _) => encoder);
}
///
@@ -130,12 +130,12 @@ public class ImageFormatManager
///
/// The image format to register the encoder for.
/// The decoder to use,
- public void SetDecoder(IImageFormat imageFormat, IImageDecoder decoder)
+ public void SetDecoder(IImageFormat imageFormat, ImageDecoder decoder)
{
Guard.NotNull(imageFormat, nameof(imageFormat));
Guard.NotNull(decoder, nameof(decoder));
this.AddImageFormat(imageFormat);
- this.mimeTypeDecoders.AddOrUpdate(imageFormat, decoder, (s, e) => decoder);
+ this.mimeTypeDecoders.AddOrUpdate(imageFormat, decoder, (_, _) => decoder);
}
///
@@ -158,12 +158,12 @@ 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 if found otherwise null
+ public ImageDecoder FindDecoder(IImageFormat format)
{
Guard.NotNull(format, nameof(format));
- return this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder decoder)
+ return this.mimeTypeDecoders.TryGetValue(format, out ImageDecoder decoder)
? decoder
: null;
}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
index 7e85ddad5..25ace3b8e 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
@@ -8,10 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg;
///
/// Decoder for generating an image out of a jpeg encoded stream.
///
-public sealed class JpegDecoder : IImageDecoderSpecialized
+public sealed class JpegDecoder : SpecializedImageDecoder
{
///
- IImageInfo IImageInfoDetector.Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -21,15 +21,7 @@ public sealed class JpegDecoder : IImageDecoderSpecialized
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoderSpecialized)this).Decode(new() { GeneralOptions = options }, stream, cancellationToken);
-
- ///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoderSpecialized)this).Decode(new() { GeneralOptions = options }, stream, cancellationToken);
-
- ///
- Image IImageDecoderSpecialized.Decode(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -39,13 +31,17 @@ public sealed class JpegDecoder : IImageDecoderSpecialized
if (options.ResizeMode != JpegDecoderResizeMode.IdctOnly)
{
- ImageDecoderUtilities.Resize(options.GeneralOptions, image);
+ Resize(options.GeneralOptions, image);
}
return image;
}
///
- Image IImageDecoderSpecialized.Decode(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoderSpecialized)this).Decode(options, stream, cancellationToken);
+ protected internal override Image Decode(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
+
+ ///
+ protected internal override JpegDecoderOptions CreateDefaultSpecializedOptions(DecoderOptions options)
+ => new() { GeneralOptions = options };
}
diff --git a/src/ImageSharp/Formats/Pbm/PbmDecoder.cs b/src/ImageSharp/Formats/Pbm/PbmDecoder.cs
index 2caf8ecc1..acfebdc84 100644
--- a/src/ImageSharp/Formats/Pbm/PbmDecoder.cs
+++ b/src/ImageSharp/Formats/Pbm/PbmDecoder.cs
@@ -24,10 +24,10 @@ namespace SixLabors.ImageSharp.Formats.Pbm;
///
/// The specification of these images is found at .
///
-public sealed class PbmDecoder : IImageDecoder
+public sealed class PbmDecoder : ImageDecoder
{
///
- IImageInfo IImageInfoDetector.Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -36,7 +36,7 @@ public sealed class PbmDecoder : IImageDecoder
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -44,12 +44,12 @@ public sealed class PbmDecoder : IImageDecoder
PbmDecoderCore decoder = new(options);
Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
- ImageDecoderUtilities.Resize(options, image);
+ Resize(options, image);
return image;
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoder)this).Decode(options, stream, cancellationToken);
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
diff --git a/src/ImageSharp/Formats/Png/PngDecoder.cs b/src/ImageSharp/Formats/Png/PngDecoder.cs
index bcc193f0b..617ca1c17 100644
--- a/src/ImageSharp/Formats/Png/PngDecoder.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoder.cs
@@ -8,10 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Png;
///
/// Decoder for generating an image out of a png encoded stream.
///
-public sealed class PngDecoder : IImageDecoder
+public sealed class PngDecoder : ImageDecoder
{
///
- IImageInfo IImageInfoDetector.Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -20,7 +20,7 @@ public sealed class PngDecoder : IImageDecoder
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -28,13 +28,13 @@ public sealed class PngDecoder : IImageDecoder
PngDecoderCore decoder = new(options);
Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
- ImageDecoderUtilities.Resize(options, image);
+ Resize(options, image);
return image;
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -47,48 +47,47 @@ public sealed class PngDecoder : IImageDecoder
PngColorType color = meta.ColorType.GetValueOrDefault();
PngBitDepth bits = meta.BitDepth.GetValueOrDefault();
- var imageDecoder = (IImageDecoder)this;
switch (color)
{
case PngColorType.Grayscale:
if (bits == PngBitDepth.Bit16)
{
return !meta.HasTransparency
- ? imageDecoder.Decode(options, stream, cancellationToken)
- : imageDecoder.Decode(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
}
return !meta.HasTransparency
- ? imageDecoder.Decode(options, stream, cancellationToken)
- : imageDecoder.Decode(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
case PngColorType.Rgb:
if (bits == PngBitDepth.Bit16)
{
return !meta.HasTransparency
- ? imageDecoder.Decode(options, stream, cancellationToken)
- : imageDecoder.Decode(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
}
return !meta.HasTransparency
- ? imageDecoder.Decode(options, stream, cancellationToken)
- : imageDecoder.Decode(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
case PngColorType.Palette:
- return imageDecoder.Decode(options, stream, cancellationToken);
+ return this.Decode(options, stream, cancellationToken);
case PngColorType.GrayscaleWithAlpha:
return (bits == PngBitDepth.Bit16)
- ? imageDecoder.Decode(options, stream, cancellationToken)
- : imageDecoder.Decode(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
case PngColorType.RgbWithAlpha:
return (bits == PngBitDepth.Bit16)
- ? imageDecoder.Decode(options, stream, cancellationToken)
- : imageDecoder.Decode(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
default:
- return imageDecoder.Decode(options, stream, cancellationToken);
+ return this.Decode(options, stream, cancellationToken);
}
}
}
diff --git a/src/ImageSharp/Formats/Tga/TgaDecoder.cs b/src/ImageSharp/Formats/Tga/TgaDecoder.cs
index 362daa77d..b6ae9bd57 100644
--- a/src/ImageSharp/Formats/Tga/TgaDecoder.cs
+++ b/src/ImageSharp/Formats/Tga/TgaDecoder.cs
@@ -8,10 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Tga;
///
/// Image decoder for Truevision TGA images.
///
-public sealed class TgaDecoder : IImageDecoder
+public sealed class TgaDecoder : ImageDecoder
{
///
- IImageInfo IImageInfoDetector.Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -20,7 +20,7 @@ public sealed class TgaDecoder : IImageDecoder
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -28,12 +28,12 @@ public sealed class TgaDecoder : IImageDecoder
TgaDecoderCore decoder = new(options);
Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
- ImageDecoderUtilities.Resize(options, image);
+ Resize(options, image);
return image;
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoder)this).Decode(options, stream, cancellationToken);
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs
index 4e1c9c2f8..04b57e297 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs
@@ -32,7 +32,7 @@ internal class WebpTiffCompression : TiffBaseDecompressor
///
protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken)
{
- using Image image = ((IImageDecoder)new WebpDecoder()).Decode(this.options, stream, cancellationToken);
+ using Image image = new WebpDecoder().Decode(this.options, stream, cancellationToken);
CopyImageBytesToBuffer(buffer, image.Frames.RootFrame.PixelBuffer);
}
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs
index b433222a0..a2d585a4c 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs
@@ -8,10 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff;
///
/// Image decoder for generating an image out of a TIFF stream.
///
-public class TiffDecoder : IImageDecoder
+public class TiffDecoder : ImageDecoder
{
///
- IImageInfo IImageInfoDetector.Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -20,7 +20,7 @@ public class TiffDecoder : IImageDecoder
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -28,12 +28,12 @@ public class TiffDecoder : IImageDecoder
TiffDecoderCore decoder = new(options);
Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
- ImageDecoderUtilities.Resize(options, image);
+ Resize(options, image);
return image;
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoder)this).Decode(options, stream, cancellationToken);
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
diff --git a/src/ImageSharp/Formats/Webp/WebpDecoder.cs b/src/ImageSharp/Formats/Webp/WebpDecoder.cs
index 86c868d7e..aa62ee709 100644
--- a/src/ImageSharp/Formats/Webp/WebpDecoder.cs
+++ b/src/ImageSharp/Formats/Webp/WebpDecoder.cs
@@ -8,10 +8,10 @@ namespace SixLabors.ImageSharp.Formats.Webp;
///
/// Image decoder for generating an image out of a webp stream.
///
-public sealed class WebpDecoder : IImageDecoder
+public sealed class WebpDecoder : ImageDecoder
{
///
- IImageInfo IImageInfoDetector.Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -21,7 +21,7 @@ public sealed class WebpDecoder : IImageDecoder
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
@@ -29,12 +29,12 @@ public sealed class WebpDecoder : IImageDecoder
using WebpDecoderCore decoder = new(options);
Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
- ImageDecoderUtilities.Resize(options, image);
+ Resize(options, image);
return image;
}
///
- Image IImageDecoder.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoder)this).Decode(options, stream, cancellationToken);
+ protected internal override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
diff --git a/src/ImageSharp/Image.Decode.cs b/src/ImageSharp/Image.Decode.cs
index 6953da1ce..9e902c7bb 100644
--- a/src/ImageSharp/Image.Decode.cs
+++ b/src/ImageSharp/Image.Decode.cs
@@ -99,7 +99,7 @@ public abstract partial class Image
/// 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)
+ private static ImageDecoder DiscoverDecoder(DecoderOptions options, Stream stream, out IImageFormat format)
{
format = InternalDetectFormat(options.Configuration, stream);
@@ -121,7 +121,7 @@ public abstract partial class Image
private static (Image Image, IImageFormat Format) Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
where TPixel : unmanaged, IPixel
{
- IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format);
+ ImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format);
if (decoder is null)
{
return (null, null);
@@ -133,7 +133,7 @@ public abstract partial class Image
private static (Image Image, IImageFormat Format) Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
{
- IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format);
+ ImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format);
if (decoder is null)
{
return (null, null);
@@ -154,14 +154,8 @@ public abstract partial class Image
///
private static (IImageInfo ImageInfo, IImageFormat Format) InternalIdentity(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
{
- IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format);
-
- if (decoder is not IImageInfoDetector detector)
- {
- return (null, null);
- }
-
- IImageInfo info = detector?.Identify(options, stream, cancellationToken);
+ ImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format);
+ IImageInfo info = decoder?.Identify(options, stream, cancellationToken);
return (info, format);
}
}
diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs
index eefb08776..8cf7e0fe2 100644
--- a/src/ImageSharp/Image.FromStream.cs
+++ b/src/ImageSharp/Image.FromStream.cs
@@ -610,7 +610,7 @@ public abstract partial class Image
StringBuilder sb = new();
sb.AppendLine("Image cannot be loaded. Available decoders:");
- foreach (KeyValuePair val in options.Configuration.ImageFormatsManager.ImageDecoders)
+ foreach (KeyValuePair val in options.Configuration.ImageFormatsManager.ImageDecoders)
{
sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine);
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs
index 0b977bfbc..fc8beb687 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs
@@ -19,19 +19,13 @@ public class IdentifyJpeg
public string TestImage { get; set; }
[GlobalSetup]
- public void ReadImages()
- {
- if (this.jpegBytes == null)
- {
- this.jpegBytes = File.ReadAllBytes(this.TestImageFullPath);
- }
- }
+ public void ReadImages() => this.jpegBytes ??= File.ReadAllBytes(this.TestImageFullPath);
[Benchmark]
public IImageInfo Identify()
{
- using var memoryStream = new MemoryStream(this.jpegBytes);
- IImageDecoder decoder = new JpegDecoder();
+ using MemoryStream memoryStream = new(this.jpegBytes);
+ JpegDecoder decoder = new();
return decoder.Identify(DecoderOptions.Default, memoryStream, default);
}
}
diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
index 8743e77bd..14eff7ba9 100644
--- a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
@@ -278,7 +278,7 @@ public class BmpEncoderTests
// Use the default decoder to test our encoded image. This verifies the content.
// We do not verify the reference image though as some are invalid.
- IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
+ ImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
using FileStream stream = File.OpenRead(actualOutputFile);
using Image referenceImage = referenceDecoder.Decode(DecoderOptions.Default, stream, default);
referenceImage.CompareToReferenceOutput(
@@ -309,7 +309,7 @@ public class BmpEncoderTests
// Use the default decoder to test our encoded image. This verifies the content.
// We do not verify the reference image though as some are invalid.
- IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
+ ImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
using FileStream stream = File.OpenRead(actualOutputFile);
using Image referenceImage = referenceDecoder.Decode(DecoderOptions.Default, stream, default);
referenceImage.CompareToReferenceOutput(
@@ -378,7 +378,7 @@ public class BmpEncoderTests
bool supportTransparency = true, // if set to true, will write a V4 header, otherwise a V3 header.
IQuantizer quantizer = null,
ImageComparer customComparer = null,
- IImageDecoder referenceDecoder = null)
+ ImageDecoder referenceDecoder = null)
where TPixel : unmanaged, IPixel
{
using Image image = provider.GetImage();
diff --git a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
index 06fe2601c..c982979ff 100644
--- a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
+++ b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
@@ -64,7 +64,7 @@ public class ImageFormatManagerTests
[Fact]
public void RegisterNullSetDecoder()
{
- Assert.Throws(() => this.DefaultFormatsManager.SetDecoder(null, new Mock().Object));
+ Assert.Throws(() => this.DefaultFormatsManager.SetDecoder(null, new Mock().Object));
Assert.Throws(() => this.DefaultFormatsManager.SetDecoder(BmpFormat.Instance, null));
Assert.Throws(() => this.DefaultFormatsManager.SetDecoder(null, null));
}
@@ -87,14 +87,14 @@ public class ImageFormatManagerTests
[Fact]
public void RegisterMimeTypeDecoderReplacesLast()
{
- IImageDecoder decoder1 = new Mock().Object;
+ ImageDecoder decoder1 = new Mock().Object;
this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder1);
- IImageDecoder found = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat);
+ ImageDecoder found = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat);
Assert.Equal(decoder1, found);
- IImageDecoder decoder2 = new Mock().Object;
+ ImageDecoder decoder2 = new Mock().Object;
this.FormatsManagerEmpty.SetDecoder(TestFormat.GlobalTestFormat, decoder2);
- IImageDecoder found2 = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat);
+ ImageDecoder found2 = this.FormatsManagerEmpty.FindDecoder(TestFormat.GlobalTestFormat);
Assert.Equal(decoder2, found2);
Assert.NotEqual(found, found2);
}
@@ -102,8 +102,8 @@ public class ImageFormatManagerTests
[Fact]
public void AddFormatCallsConfig()
{
- var provider = new Mock();
- var config = new Configuration();
+ Mock provider = new();
+ Configuration config = new();
config.Configure(provider.Object);
provider.Verify(x => x.Configure(config));
@@ -113,9 +113,9 @@ public class ImageFormatManagerTests
public void DetectFormatAllocatesCleanBuffer()
{
byte[] jpegImage;
- using (var buffer = new MemoryStream())
+ using (MemoryStream buffer = new())
{
- using var image = new Image(100, 100);
+ using Image image = new(100, 100);
image.SaveAsJpeg(buffer);
jpegImage = buffer.ToArray();
}
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs
index 3603000f6..f88431be7 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs
@@ -178,7 +178,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, ImageDecoder decoder, bool useIdentify, Action test)
{
var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false);
@@ -196,7 +196,7 @@ public partial class JpegDecoderTests
private static void TestMetadataImpl(
bool useIdentify,
- IImageDecoder decoder,
+ ImageDecoder decoder,
string imagePath,
int expectedPixelSize,
bool exifProfilePresent,
diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
index 2656144d3..0f33f2231 100644
--- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
@@ -588,7 +588,7 @@ public partial class PngEncoderTests
string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType);
// Compare to the Magick reference decoder.
- IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
+ ImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
// We compare using both our decoder and the reference decoder as pixel transformation
// occurs within the encoder itself leaving the input image unaffected.
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderBaseTester.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderBaseTester.cs
index 95f37ba40..456604d8b 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderBaseTester.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderBaseTester.cs
@@ -16,7 +16,7 @@ public abstract class TiffDecoderBaseTester
protected static MagickReferenceDecoder ReferenceDecoder => new();
- protected static void TestTiffDecoder(TestImageProvider provider, IImageDecoder referenceDecoder = null, bool useExactComparer = true, float compareTolerance = 0.001f)
+ protected static void TestTiffDecoder(TestImageProvider provider, ImageDecoder referenceDecoder = null, bool useExactComparer = true, float compareTolerance = 0.001f)
where TPixel : unmanaged, IPixel
{
using Image image = provider.GetImage(TiffDecoder);
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs
index 6da0d4fd8..0b4016dd5 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff;
[Trait("Format", "Tiff")]
public abstract class TiffEncoderBaseTester
{
- protected static readonly IImageDecoder ReferenceDecoder = new MagickReferenceDecoder();
+ protected static readonly ImageDecoder ReferenceDecoder = new MagickReferenceDecoder();
protected static void TestStripLength(
TestImageProvider provider,
@@ -85,7 +85,7 @@ public abstract class TiffEncoderBaseTester
TiffPredictor predictor = TiffPredictor.None,
bool useExactComparer = true,
float compareTolerance = 0.001f,
- IImageDecoder imageDecoder = null)
+ ImageDecoder imageDecoder = null)
where TPixel : unmanaged, IPixel
{
using Image image = provider.GetImage();
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.Fakes.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.Fakes.cs
new file mode 100644
index 000000000..10d834235
--- /dev/null
+++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.Fakes.cs
@@ -0,0 +1,14 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SixLabors.ImageSharp.Tests;
+
+public partial class ImageTests
+{
+}
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs
index cace719bd..3f51f1967 100644
--- a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs
+++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs
@@ -19,7 +19,7 @@ public partial class ImageTests
protected Image localStreamReturnImageAgnostic;
- protected Mock localDecoder;
+ protected Mock localDecoder;
protected IImageFormatDetector localMimeTypeDetector;
@@ -59,11 +59,10 @@ public partial class ImageTests
this.localImageInfoMock = new Mock();
this.localImageFormatMock = new Mock();
- var detector = new Mock();
- detector.Setup(x => x.Identify(It.IsAny(), It.IsAny(), It.IsAny()))
+ this.localDecoder = new Mock();
+ this.localDecoder.Setup(x => x.Identify(It.IsAny(), It.IsAny(), It.IsAny()))
.Returns(this.localImageInfoMock.Object);
- this.localDecoder = detector.As();
this.localDecoder
.Setup(x => x.Decode(It.IsAny(), It.IsAny(), It.IsAny()))
.Callback((c, s, ct) =>
diff --git a/tests/ImageSharp.Tests/TestFile.cs b/tests/ImageSharp.Tests/TestFile.cs
index 9d920d718..fc95d5fa8 100644
--- a/tests/ImageSharp.Tests/TestFile.cs
+++ b/tests/ImageSharp.Tests/TestFile.cs
@@ -143,19 +143,22 @@ public sealed class TestFile
///
/// Creates a new image.
///
+ /// The image decoder.
///
/// The .
///
- public Image CreateRgba32Image(IImageDecoder decoder)
+ public Image CreateRgba32Image(ImageDecoder decoder)
=> this.CreateRgba32Image(decoder, new());
///
/// Creates a new image.
///
+ /// The image decoder.
+ /// The general decoder options.
///
/// The .
///
- public Image CreateRgba32Image(IImageDecoder decoder, DecoderOptions options)
+ public Image CreateRgba32Image(ImageDecoder decoder, DecoderOptions options)
{
options.Configuration = this.Image.GetConfiguration();
using MemoryStream stream = new(this.Bytes);
diff --git a/tests/ImageSharp.Tests/TestFormat.cs b/tests/ImageSharp.Tests/TestFormat.cs
index 127ccd32d..cecde5ddb 100644
--- a/tests/ImageSharp.Tests/TestFormat.cs
+++ b/tests/ImageSharp.Tests/TestFormat.cs
@@ -187,7 +187,7 @@ public class TestFormat : IConfigurationModule, IImageFormat
public TestHeader(TestFormat testFormat) => this.testFormat = testFormat;
}
- public class TestDecoder : IImageDecoderSpecialized
+ public class TestDecoder : SpecializedImageDecoder
{
private readonly TestFormat testFormat;
@@ -201,18 +201,13 @@ public class TestFormat : IConfigurationModule, IImageFormat
public bool IsSupportedFileFormat(Span header) => this.testFormat.IsSupportedFileFormat(header);
- public IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoderSpecialized)this).Decode(new() { GeneralOptions = options }, stream, cancellationToken);
+ protected internal override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(this.CreateDefaultSpecializedOptions(options), stream, cancellationToken);
- public Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- where TPixel : unmanaged, IPixel
- => ((IImageDecoderSpecialized)this).Decode(new() { GeneralOptions = options }, stream, cancellationToken);
-
- public Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => ((IImageDecoderSpecialized)this).Decode(new() { GeneralOptions = options }, stream, cancellationToken);
+ protected internal override TestDecoderOptions CreateDefaultSpecializedOptions(DecoderOptions options)
+ => new() { GeneralOptions = options };
- public Image Decode(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- where TPixel : unmanaged, IPixel
+ protected internal override Image Decode(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Configuration configuration = options.GeneralOptions.Configuration;
var ms = new MemoryStream();
@@ -229,7 +224,7 @@ public class TestFormat : IConfigurationModule, IImageFormat
return this.testFormat.Sample();
}
- public Image Decode(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ protected internal override Image Decode(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
=> this.Decode(options, stream, cancellationToken);
}
diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs
index a0f544b2f..e9b7b8407 100644
--- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs
@@ -27,7 +27,7 @@ public abstract partial class TestImageProvider : IXunitSerializable
public Key(
PixelTypes pixelType,
string filePath,
- IImageDecoder customDecoder,
+ ImageDecoder customDecoder,
DecoderOptions options,
ISpecializedDecoderOptions specialized)
{
@@ -175,11 +175,11 @@ public abstract partial class TestImageProvider : IXunitSerializable
public override Image GetImage()
{
- IImageDecoder decoder = TestEnvironment.GetReferenceDecoder(this.FilePath);
+ ImageDecoder decoder = TestEnvironment.GetReferenceDecoder(this.FilePath);
return this.GetImage(decoder);
}
- public override Image GetImage(IImageDecoder decoder, DecoderOptions options)
+ public override Image GetImage(ImageDecoder decoder, DecoderOptions options)
{
Guard.NotNull(decoder, nameof(decoder));
Guard.NotNull(options, nameof(options));
@@ -202,7 +202,7 @@ public abstract partial class TestImageProvider : IXunitSerializable
return cachedImage.Clone(this.Configuration);
}
- public override Task> GetImageAsync(IImageDecoder decoder, DecoderOptions options)
+ public override Task> GetImageAsync(ImageDecoder decoder, DecoderOptions options)
{
Guard.NotNull(decoder, nameof(decoder));
Guard.NotNull(options, nameof(options));
@@ -216,7 +216,7 @@ public abstract partial class TestImageProvider : IXunitSerializable
return Task.FromResult(decoder.Decode(options, stream, default));
}
- public override Image