diff --git a/src/ImageSharp/Advanced/AotCompilerTools.cs b/src/ImageSharp/Advanced/AotCompilerTools.cs
index 5e8b899a4d..1732a6bdbf 100644
--- a/src/ImageSharp/Advanced/AotCompilerTools.cs
+++ b/src/ImageSharp/Advanced/AotCompilerTools.cs
@@ -210,7 +210,7 @@ namespace SixLabors.ImageSharp.Advanced
}
///
- /// This method pre-seeds the all in the AoT compiler.
+ /// This method pre-seeds the all in the AoT compiler.
///
/// The pixel format.
[Preserve]
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
index 3474606828..5b0e803f39 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
@@ -10,31 +10,41 @@ namespace SixLabors.ImageSharp.Formats.Bmp
///
/// Image decoder for generating an image out of a Windows bitmap stream.
///
- public class BmpDecoder : ImageDecoder
+ public class BmpDecoder : ImageDecoder, IImageDecoderSpecialized
{
///
- public override Image DecodeSpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
+ Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
- BmpDecoderCore decoder = new(options);
- Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
-
- Resize(options.GeneralOptions, image);
-
- return image;
+ return new BmpDecoderCore(new() { GeneralOptions = options }).Identify(options.Configuration, stream, cancellationToken);
}
///
- public override Image DecodeSpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
+
+ ///
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
///
- public override IImageInfo IdentifySpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public Image DecodeSpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ where TPixel : unmanaged, IPixel
{
+ Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
- return new BmpDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
+ Image image = new BmpDecoderCore(options).Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
+
+ Resize(options.GeneralOptions, image);
+
+ return image;
}
+
+ ///
+ public Image DecodeSpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(options, stream, cancellationToken);
}
}
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
index d9e2c17b8e..1adc34849e 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
@@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
///
/// A useful decoding source example can be found at
///
- internal sealed class BmpDecoderCore : IImageDecoderInternals
+ internal sealed class BmpDecoderCore : IImageDecoderInternals
{
///
/// The default mask for the red part of the color for 16 bit rgb bitmaps.
@@ -99,19 +99,26 @@ namespace SixLabors.ImageSharp.Formats.Bmp
///
private readonly MemoryAllocator memoryAllocator;
+ ///
+ /// How to deal with skipped pixels,
+ /// which can occur during decoding run length encoded bitmaps.
+ ///
+ private readonly RleSkippedPixelHandling rleSkippedPixelHandling;
+
///
/// Initializes a new instance of the class.
///
/// The options.
public BmpDecoderCore(BmpDecoderOptions options)
{
- this.Options = options;
+ this.Options = options.GeneralOptions;
+ this.rleSkippedPixelHandling = options.RleSkippedPixelHandling;
this.configuration = options.GeneralOptions.Configuration;
this.memoryAllocator = this.configuration.MemoryAllocator;
}
///
- public BmpDecoderOptions Options { get; }
+ public DecoderOptions Options { get; }
///
public Size Dimensions => new(this.infoHeader.Width, this.infoHeader.Height);
@@ -322,7 +329,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
byte colorIdx = bufferRow[x];
if (undefinedPixelsSpan[rowStartIdx + x])
{
- switch (this.Options.RleSkippedPixelHandling)
+ switch (this.rleSkippedPixelHandling)
{
case RleSkippedPixelHandling.FirstColorOfPalette:
color.FromBgr24(Unsafe.As(ref colors[colorIdx * 4]));
@@ -394,7 +401,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
int idx = rowStartIdx + (x * 3);
if (undefinedPixelsSpan[yMulWidth + x])
{
- switch (this.Options.RleSkippedPixelHandling)
+ switch (this.rleSkippedPixelHandling)
{
case RleSkippedPixelHandling.FirstColorOfPalette:
color.FromBgr24(Unsafe.As(ref bufferSpan[idx]));
diff --git a/src/ImageSharp/Formats/Gif/GifDecoder.cs b/src/ImageSharp/Formats/Gif/GifDecoder.cs
index 5115486a45..3729e42084 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoder.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoder.cs
@@ -10,29 +10,33 @@ namespace SixLabors.ImageSharp.Formats.Gif
///
/// Decoder for generating an image out of a gif encoded stream.
///
- public sealed class GifDecoder : ImageDecoder
+ public sealed class GifDecoder : ImageDecoder
{
///
- public override Image DecodeSpecialized(GifDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
- GifDecoderCore decoder = new(options);
- Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
-
- Resize(options.GeneralOptions, image);
+ Guard.NotNull(options, nameof(options));
+ Guard.NotNull(stream, nameof(stream));
- return image;
+ return new GifDecoderCore(options).Identify(options.Configuration, stream, cancellationToken);
}
///
- public override Image DecodeSpecialized(GifDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
-
- ///
- public override IImageInfo IdentifySpecialized(GifDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
+ Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
- return new GifDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
+ GifDecoderCore decoder = new(options);
+ Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
+
+ Resize(options, image);
+
+ return image;
}
+
+ ///
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
}
diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
index ff4b97b3c8..b307ffd60f 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
@@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
///
/// Performs the gif decoding operation.
///
- internal sealed class GifDecoderCore : IImageDecoderInternals
+ internal sealed class GifDecoderCore : IImageDecoderInternals
{
///
/// The temp buffer used to reduce allocations.
@@ -90,17 +90,17 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// Initializes a new instance of the class.
///
/// The decoder options.
- public GifDecoderCore(GifDecoderOptions options)
+ public GifDecoderCore(DecoderOptions options)
{
this.Options = options;
- this.configuration = options.GeneralOptions.Configuration;
- this.skipMetadata = options.GeneralOptions.SkipMetadata;
- this.maxFrames = options.GeneralOptions.MaxFrames;
+ this.configuration = options.Configuration;
+ this.skipMetadata = options.SkipMetadata;
+ this.maxFrames = options.MaxFrames;
this.memoryAllocator = this.configuration.MemoryAllocator;
}
///
- public GifDecoderOptions Options { get; }
+ public DecoderOptions Options { get; }
///
public Size Dimensions => new(this.imageDescriptor.Width, this.imageDescriptor.Height);
diff --git a/src/ImageSharp/Formats/Gif/GifDecoderOptions.cs b/src/ImageSharp/Formats/Gif/GifDecoderOptions.cs
deleted file mode 100644
index 3c5f7bddc1..0000000000
--- a/src/ImageSharp/Formats/Gif/GifDecoderOptions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-namespace SixLabors.ImageSharp.Formats.Gif
-{
- ///
- /// Configuration options for decoding Gif images.
- ///
- public sealed class GifDecoderOptions : ISpecializedDecoderOptions
- {
- ///
- public DecoderOptions GeneralOptions { get; set; } = new();
- }
-}
diff --git a/src/ImageSharp/Formats/IImageDecoder.cs b/src/ImageSharp/Formats/IImageDecoder.cs
index cdec1e9289..b0363ccf9f 100644
--- a/src/ImageSharp/Formats/IImageDecoder.cs
+++ b/src/ImageSharp/Formats/IImageDecoder.cs
@@ -15,6 +15,9 @@ namespace SixLabors.ImageSharp.Formats
///
/// 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.
@@ -27,6 +30,9 @@ namespace SixLabors.ImageSharp.Formats
///
/// 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.
diff --git a/src/ImageSharp/Formats/IImageDecoderInternals{T}.cs b/src/ImageSharp/Formats/IImageDecoderInternals.cs
similarity index 88%
rename from src/ImageSharp/Formats/IImageDecoderInternals{T}.cs
rename to src/ImageSharp/Formats/IImageDecoderInternals.cs
index 27b8a434b4..63596266fb 100644
--- a/src/ImageSharp/Formats/IImageDecoderInternals{T}.cs
+++ b/src/ImageSharp/Formats/IImageDecoderInternals.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors.
+// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
@@ -11,14 +11,12 @@ namespace SixLabors.ImageSharp.Formats
///
/// Abstraction for shared internals for XXXDecoderCore implementations to be used with .
///
- /// The type of specialized decoder options.
- internal interface IImageDecoderInternals
- where T : ISpecializedDecoderOptions
+ internal interface IImageDecoderInternals
{
///
- /// Gets the specialized decoder options.
+ /// Gets the general decoder options.
///
- T Options { get; }
+ DecoderOptions Options { get; }
///
/// Gets the dimensions of the image being decoded.
diff --git a/src/ImageSharp/Formats/IImageDecoderSpecialized{T}.cs b/src/ImageSharp/Formats/IImageDecoderSpecialized{T}.cs
new file mode 100644
index 0000000000..46ad284da3
--- /dev/null
+++ b/src/ImageSharp/Formats/IImageDecoderSpecialized{T}.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.IO;
+using System.Threading;
+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.
+ ///
+ /// 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 DecodeSpecialized(T options, Stream stream, CancellationToken cancellationToken)
+ where TPixel : unmanaged, IPixel;
+
+ ///
+ /// Decodes the image from the specified stream to an of a specific pixel type.
+ ///
+ /// 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 DecodeSpecialized(T options, Stream stream, CancellationToken cancellationToken);
+ }
+}
diff --git a/src/ImageSharp/Formats/IImageInfoDetector.cs b/src/ImageSharp/Formats/IImageInfoDetector.cs
index 443e8b9809..1bc8a44092 100644
--- a/src/ImageSharp/Formats/IImageInfoDetector.cs
+++ b/src/ImageSharp/Formats/IImageInfoDetector.cs
@@ -14,6 +14,9 @@ namespace SixLabors.ImageSharp.Formats
///
/// 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.
diff --git a/src/ImageSharp/Formats/ImageDecoder.cs b/src/ImageSharp/Formats/ImageDecoder.cs
new file mode 100644
index 0000000000..4863f5b67d
--- /dev/null
+++ b/src/ImageSharp/Formats/ImageDecoder.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.IO;
+using System.Threading;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
+
+namespace SixLabors.ImageSharp.Formats
+{
+ ///
+ /// The base class for all image decoders.
+ ///
+ public abstract class ImageDecoder : IImageInfoDetector, IImageDecoder
+ {
+ ///
+ public abstract IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken);
+
+ ///
+ public abstract Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ where TPixel : unmanaged, IPixel;
+
+ ///
+ public abstract Image Decode(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 = KnownResamplers.Box,
+ 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;
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/ImageDecoderSpecializedExtensions.cs b/src/ImageSharp/Formats/ImageDecoderSpecializedExtensions.cs
new file mode 100644
index 0000000000..d23f088aaa
--- /dev/null
+++ b/src/ImageSharp/Formats/ImageDecoderSpecializedExtensions.cs
@@ -0,0 +1,82 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Formats
+{
+ ///
+ /// Extensions methods for .
+ ///
+ public static class ImageDecoderSpecializedExtensions
+ {
+ ///
+ /// Decodes the image from the specified stream to an of a specific pixel type.
+ ///
+ /// The type of specialized options.
+ /// The pixel format.
+ /// The decoder.
+ /// The specialized decoder options.
+ /// The containing image data.
+ /// The .
+ /// Thrown if the encoded image contains errors.
+ public static Image DecodeSpecialized(this IImageDecoderSpecialized decoder, T options, Stream stream)
+ where T : ISpecializedDecoderOptions
+ where TPixel : unmanaged, IPixel
+ => decoder.DecodeSpecialized(options, stream, default);
+
+ ///
+ /// Decodes the image from the specified stream to an of a specific pixel type.
+ ///
+ /// The type of specialized options.
+ /// The decoder.
+ /// The specialized decoder options.
+ /// The containing image data.
+ /// The .
+ /// Thrown if the encoded image contains errors.
+ public static Image DecodeSpecialized(this IImageDecoderSpecialized decoder, T options, Stream stream)
+ where T : ISpecializedDecoderOptions
+ => decoder.DecodeSpecialized(options, stream, default);
+
+ ///
+ /// Decodes the image from the specified stream to an of a specific pixel type.
+ ///
+ /// The type of specialized options.
+ /// The pixel format.
+ /// The decoder.
+ /// The specialized decoder options.
+ /// The containing image data.
+ /// The token to monitor for cancellation requests.
+ /// A representing the asynchronous operation.
+ /// Thrown if the encoded image contains errors.
+ public static Task> DecodeSpecializedAsync(this IImageDecoderSpecialized decoder, T options, Stream stream, CancellationToken cancellationToken = default)
+ where T : ISpecializedDecoderOptions
+ where TPixel : unmanaged, IPixel
+ => Image.WithSeekableStreamAsync(
+ options.GeneralOptions,
+ stream,
+ (s, ct) => decoder.DecodeSpecialized(options, s, ct),
+ cancellationToken);
+
+ ///
+ /// Decodes the image from the specified stream to an of a specific pixel type.
+ ///
+ /// The type of specialized options.
+ /// The decoder.
+ /// The specialized decoder options.
+ /// The containing image data.
+ /// The token to monitor for cancellation requests.
+ /// A representing the asynchronous operation.
+ /// Thrown if the encoded image contains errors.
+ public static Task DecodeSpecializedAsync(this IImageDecoderSpecialized decoder, T options, Stream stream, CancellationToken cancellationToken = default)
+ where T : ISpecializedDecoderOptions
+ => Image.WithSeekableStreamAsync(
+ options.GeneralOptions,
+ stream,
+ (s, ct) => decoder.DecodeSpecialized(options, s, ct),
+ cancellationToken);
+ }
+}
diff --git a/src/ImageSharp/Formats/ImageDecoderUtilities.cs b/src/ImageSharp/Formats/ImageDecoderUtilities.cs
index 1dc0841f28..b6cefd2c89 100644
--- a/src/ImageSharp/Formats/ImageDecoderUtilities.cs
+++ b/src/ImageSharp/Formats/ImageDecoderUtilities.cs
@@ -12,12 +12,11 @@ namespace SixLabors.ImageSharp.Formats
{
internal static class ImageDecoderUtilities
{
- public static IImageInfo Identify(
- this IImageDecoderInternals decoder,
+ public static IImageInfo Identify(
+ this IImageDecoderInternals decoder,
Configuration configuration,
Stream stream,
CancellationToken cancellationToken)
- where T : ISpecializedDecoderOptions
{
using var bufferedReadStream = new BufferedReadStream(configuration, stream);
@@ -31,22 +30,20 @@ namespace SixLabors.ImageSharp.Formats
}
}
- public static Image Decode(
- this IImageDecoderInternals decoder,
+ public static Image Decode(
+ this IImageDecoderInternals decoder,
Configuration configuration,
Stream stream,
CancellationToken cancellationToken)
- where T : ISpecializedDecoderOptions
where TPixel : unmanaged, IPixel
- => decoder.Decode(configuration, stream, DefaultLargeImageExceptionFactory, cancellationToken);
+ => decoder.Decode(configuration, stream, DefaultLargeImageExceptionFactory, cancellationToken);
- public static Image Decode(
- this IImageDecoderInternals decoder,
+ public static Image Decode(
+ this IImageDecoderInternals decoder,
Configuration configuration,
Stream stream,
Func largeImageExceptionFactory,
CancellationToken cancellationToken)
- where T : ISpecializedDecoderOptions
where TPixel : unmanaged, IPixel
{
using var bufferedReadStream = new BufferedReadStream(configuration, stream);
diff --git a/src/ImageSharp/Formats/ImageDecoder{T}.cs b/src/ImageSharp/Formats/ImageDecoder{T}.cs
deleted file mode 100644
index 6f43b053f9..0000000000
--- a/src/ImageSharp/Formats/ImageDecoder{T}.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-using System.IO;
-using System.Threading;
-using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing;
-
-namespace SixLabors.ImageSharp.Formats
-{
- ///
- /// The base class for all image decoders.
- ///
- /// The type of specialized decoder options.
- public abstract class ImageDecoder : IImageInfoDetector, IImageDecoder
- where T : class, ISpecializedDecoderOptions, new()
- {
- ///
- public IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- {
- T specializedOptions = new() { GeneralOptions = options };
- return this.IdentifySpecialized(specializedOptions, stream, cancellationToken);
- }
-
- ///
- public Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- where TPixel : unmanaged, IPixel
- {
- T specializedOptions = new() { GeneralOptions = options };
- Image image = this.DecodeSpecialized(specializedOptions, stream, cancellationToken);
-
- Resize(options, image);
-
- return image;
- }
-
- ///
- public Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
- {
- T specializedOptions = new() { GeneralOptions = options };
- Image image = this.DecodeSpecialized(specializedOptions, stream, cancellationToken);
-
- Resize(options, image);
-
- return image;
- }
-
- ///
- /// Reads the raw image information from the specified stream.
- ///
- /// The specialized decoder options.
- /// The containing image data.
- /// The token to monitor for cancellation requests.
- /// The object.
- /// Thrown if the encoded image contains errors.
- public abstract IImageInfo IdentifySpecialized(T options, Stream stream, CancellationToken cancellationToken);
-
- ///
- /// Decodes the image from the specified stream to an of a specific pixel type.
- ///
- /// 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 abstract Image DecodeSpecialized(T options, Stream stream, CancellationToken cancellationToken)
- where TPixel : unmanaged, IPixel;
-
- ///
- /// Decodes the image from the specified stream to an of a specific pixel type.
- ///
- /// The specialized decoder options.
- /// The containing image data.
- /// The token to monitor for cancellation requests.
- /// The .
- /// Thrown if the encoded image contains errors.
- public abstract Image DecodeSpecialized(T 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 = KnownResamplers.Box,
- 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;
- }
- }
-}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
index 1675fd6d74..a655acbce0 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
@@ -10,38 +10,45 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
/// Decoder for generating an image out of a jpeg encoded stream.
///
- public sealed class JpegDecoder : ImageDecoder
+ public sealed class JpegDecoder : ImageDecoder, IImageDecoderSpecialized
{
///
- ///
- /// Unlike , when
- /// is passed, the codec may not be able to scale efficiently to
- /// the exact scale factor requested, so returns a size that approximates that scale.
- /// Upscaling is not supported, so the original size will be returned.
- ///
- public override Image DecodeSpecialized(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
- using JpegDecoderCore decoder = new(options);
- return decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
+ Guard.NotNull(stream, nameof(stream));
+
+ using JpegDecoderCore decoder = new(new() { GeneralOptions = options });
+ return decoder.Identify(options.Configuration, stream, cancellationToken);
}
///
- ///
- /// Unlike , when
- /// is passed, the codec may not be able to scale efficiently to
- /// the exact scale factor requested, so returns a size that approximates that scale.
- /// Upscaling is not supported, so the original size will be returned.
- ///
- public override Image DecodeSpecialized(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
+
+ ///
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
///
- public override IImageInfo IdentifySpecialized(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public Image DecodeSpecialized(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ where TPixel : unmanaged, IPixel
{
+ Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
using JpegDecoderCore decoder = new(options);
- return decoder.Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
+ Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
+
+ if (options.ResizeMode != JpegDecoderResizeMode.IdctOnly)
+ {
+ Resize(options.GeneralOptions, image);
+ }
+
+ return image;
}
+
+ ///
+ public Image DecodeSpecialized(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(options, stream, cancellationToken);
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index 30af0b4e26..18201d49b3 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
@@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// Originally ported from
/// with additional fixes for both performance and common encoding errors.
///
- internal sealed class JpegDecoderCore : IRawJpegData, IImageDecoderInternals
+ internal sealed class JpegDecoderCore : IRawJpegData, IImageDecoderInternals
{
///
/// The only supported precision
@@ -125,19 +125,25 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
private readonly bool skipMetadata;
+ ///
+ /// The jpeg specific resize options.
+ ///
+ private readonly JpegDecoderResizeMode resizeMode;
+
///
/// Initializes a new instance of the class.
///
/// The decoder options.
public JpegDecoderCore(JpegDecoderOptions options)
{
- this.Options = options;
+ this.Options = options.GeneralOptions;
+ this.resizeMode = options.ResizeMode;
this.configuration = options.GeneralOptions.Configuration;
this.skipMetadata = options.GeneralOptions.SkipMetadata;
}
///
- public JpegDecoderOptions Options { get; }
+ public DecoderOptions Options { get; }
///
public Size Dimensions => this.Frame.PixelSize;
@@ -207,7 +213,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
public Image Decode(BufferedReadStream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel
{
- using var spectralConverter = new SpectralConverter(this.configuration, this.Options.GeneralOptions.TargetSize);
+ using var spectralConverter = new SpectralConverter(this.configuration, this.resizeMode == JpegDecoderResizeMode.ScaleOnly ? null : this.Options.TargetSize);
this.ParseStream(stream, spectralConverter, cancellationToken);
this.InitExifProfile();
this.InitIccProfile();
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderOptions.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderOptions.cs
index 80e680cd0e..95d1c81d23 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderOptions.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderOptions.cs
@@ -8,6 +8,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
public sealed class JpegDecoderOptions : ISpecializedDecoderOptions
{
+ ///
+ /// Gets or sets the resize mode.
+ ///
+ public JpegDecoderResizeMode ResizeMode { get; set; }
+
///
public DecoderOptions GeneralOptions { get; set; } = new();
}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderResizeMode.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderResizeMode.cs
new file mode 100644
index 0000000000..d99d522c5b
--- /dev/null
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderResizeMode.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Jpeg
+{
+ ///
+ /// Provides enumeration for resize modes taken during decoding.
+ /// Applicable only when has a value.
+ ///
+ public enum JpegDecoderResizeMode
+ {
+ ///
+ /// Both and .
+ ///
+ Combined,
+
+ ///
+ /// IDCT-only to nearest block scale.
+ ///
+ IdctOnly,
+
+ ///
+ /// Opt-out the IDCT part and only Resize. Can be useful in case of quality concerns.
+ ///
+ ScaleOnly
+ }
+}
diff --git a/src/ImageSharp/Formats/Pbm/PbmDecoder.cs b/src/ImageSharp/Formats/Pbm/PbmDecoder.cs
index 34dca4ca4e..1127f8e090 100644
--- a/src/ImageSharp/Formats/Pbm/PbmDecoder.cs
+++ b/src/ImageSharp/Formats/Pbm/PbmDecoder.cs
@@ -26,29 +26,33 @@ namespace SixLabors.ImageSharp.Formats.Pbm
///
/// The specification of these images is found at .
///
- public sealed class PbmDecoder : ImageDecoder
+ public sealed class PbmDecoder : ImageDecoder
{
- ///
- public override Image DecodeSpecialized(PbmDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ ///
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
- PbmDecoderCore decoder = new(options);
- Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
-
- Resize(options.GeneralOptions, image);
+ Guard.NotNull(options, nameof(options));
+ Guard.NotNull(stream, nameof(stream));
- return image;
+ return new PbmDecoderCore(options).Identify(options.Configuration, stream, cancellationToken);
}
///
- public override Image DecodeSpecialized(PbmDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
-
- ///
- public override IImageInfo IdentifySpecialized(PbmDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
+ Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
- return new PbmDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
+ PbmDecoderCore decoder = new(options);
+ Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
+
+ Resize(options, image);
+
+ return image;
}
+
+ ///
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
}
diff --git a/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs b/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs
index cac1a9c640..05f06deaae 100644
--- a/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs
+++ b/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm
///
/// Performs the PBM decoding operation.
///
- internal sealed class PbmDecoderCore : IImageDecoderInternals
+ internal sealed class PbmDecoderCore : IImageDecoderInternals
{
private int maxPixelValue;
@@ -52,14 +52,14 @@ namespace SixLabors.ImageSharp.Formats.Pbm
/// Initializes a new instance of the class.
///
/// The decoder options.
- public PbmDecoderCore(PbmDecoderOptions options)
+ public PbmDecoderCore(DecoderOptions options)
{
this.Options = options;
- this.configuration = options.GeneralOptions.Configuration;
+ this.configuration = options.Configuration;
}
///
- public PbmDecoderOptions Options { get; }
+ public DecoderOptions Options { get; }
///
public Size Dimensions => this.pixelSize;
diff --git a/src/ImageSharp/Formats/Pbm/PbmDecoderOptions.cs b/src/ImageSharp/Formats/Pbm/PbmDecoderOptions.cs
deleted file mode 100644
index 1253d72b39..0000000000
--- a/src/ImageSharp/Formats/Pbm/PbmDecoderOptions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-namespace SixLabors.ImageSharp.Formats.Pbm
-{
- ///
- /// Configuration options for decoding Pbm images.
- ///
- public sealed class PbmDecoderOptions : ISpecializedDecoderOptions
- {
- ///
- public DecoderOptions GeneralOptions { get; set; } = new();
- }
-}
diff --git a/src/ImageSharp/Formats/Png/PngDecoder.cs b/src/ImageSharp/Formats/Png/PngDecoder.cs
index 5771e5b09a..9f23982d09 100644
--- a/src/ImageSharp/Formats/Png/PngDecoder.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoder.cs
@@ -10,24 +10,39 @@ namespace SixLabors.ImageSharp.Formats.Png
///
/// Decoder for generating an image out of a png encoded stream.
///
- public sealed class PngDecoder : ImageDecoder
+ public sealed class PngDecoder : ImageDecoder
{
///
- public override Image DecodeSpecialized(PngDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
+ Guard.NotNull(options, nameof(options));
+ Guard.NotNull(stream, nameof(stream));
+
+ return new PngDecoderCore(options).Identify(options.Configuration, stream, cancellationToken);
+ }
+
+ ///
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ {
+ Guard.NotNull(options, nameof(options));
+ Guard.NotNull(stream, nameof(stream));
+
PngDecoderCore decoder = new(options);
- Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
+ Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
- Resize(options.GeneralOptions, image);
+ Resize(options, image);
return image;
}
///
- public override Image DecodeSpecialized(PngDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
+ Guard.NotNull(options, nameof(options));
+ Guard.NotNull(stream, nameof(stream));
+
PngDecoderCore decoder = new(options, true);
- IImageInfo info = decoder.Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
+ IImageInfo info = decoder.Identify(options.Configuration, stream, cancellationToken);
stream.Position = 0;
PngMetadata meta = info.Metadata.GetPngMetadata();
@@ -39,50 +54,42 @@ namespace SixLabors.ImageSharp.Formats.Png
if (bits == PngBitDepth.Bit16)
{
return !meta.HasTransparency
- ? this.DecodeSpecialized(options, stream, cancellationToken)
- : this.DecodeSpecialized(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
}
return !meta.HasTransparency
- ? this.DecodeSpecialized(options, stream, cancellationToken)
- : this.DecodeSpecialized(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
case PngColorType.Rgb:
if (bits == PngBitDepth.Bit16)
{
return !meta.HasTransparency
- ? this.DecodeSpecialized(options, stream, cancellationToken)
- : this.DecodeSpecialized(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
}
return !meta.HasTransparency
- ? this.DecodeSpecialized(options, stream, cancellationToken)
- : this.DecodeSpecialized(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
case PngColorType.Palette:
- return this.DecodeSpecialized(options, stream, cancellationToken);
+ return this.Decode(options, stream, cancellationToken);
case PngColorType.GrayscaleWithAlpha:
return (bits == PngBitDepth.Bit16)
- ? this.DecodeSpecialized(options, stream, cancellationToken)
- : this.DecodeSpecialized(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
case PngColorType.RgbWithAlpha:
return (bits == PngBitDepth.Bit16)
- ? this.DecodeSpecialized(options, stream, cancellationToken)
- : this.DecodeSpecialized(options, stream, cancellationToken);
+ ? this.Decode(options, stream, cancellationToken)
+ : this.Decode(options, stream, cancellationToken);
default:
- return this.DecodeSpecialized(options, stream, cancellationToken);
+ return this.Decode(options, stream, cancellationToken);
}
}
-
- ///
- public override IImageInfo IdentifySpecialized(PngDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- {
- Guard.NotNull(stream, nameof(stream));
-
- return new PngDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
- }
}
}
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index 8d6a1719e4..0ec937a207 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Formats.Png
///
/// Performs the png decoding operation.
///
- internal sealed class PngDecoderCore : IImageDecoderInternals
+ internal sealed class PngDecoderCore : IImageDecoderInternals
{
///
/// Reusable buffer.
@@ -123,25 +123,25 @@ namespace SixLabors.ImageSharp.Formats.Png
/// Initializes a new instance of the class.
///
/// The decoder options.
- public PngDecoderCore(PngDecoderOptions options)
+ public PngDecoderCore(DecoderOptions options)
{
this.Options = options;
- this.configuration = options.GeneralOptions.Configuration;
- this.skipMetadata = options.GeneralOptions.SkipMetadata;
+ this.configuration = options.Configuration;
+ this.skipMetadata = options.SkipMetadata;
this.memoryAllocator = this.configuration.MemoryAllocator;
}
- internal PngDecoderCore(PngDecoderOptions options, bool colorMetadataOnly)
+ internal PngDecoderCore(DecoderOptions options, bool colorMetadataOnly)
{
this.Options = options;
this.colorMetadataOnly = colorMetadataOnly;
this.skipMetadata = true;
- this.configuration = options.GeneralOptions.Configuration;
+ this.configuration = options.Configuration;
this.memoryAllocator = this.configuration.MemoryAllocator;
}
///
- public PngDecoderOptions Options { get; }
+ public DecoderOptions Options { get; }
///
public Size Dimensions => new(this.header.Width, this.header.Height);
diff --git a/src/ImageSharp/Formats/Png/PngDecoderOptions.cs b/src/ImageSharp/Formats/Png/PngDecoderOptions.cs
deleted file mode 100644
index 722d803254..0000000000
--- a/src/ImageSharp/Formats/Png/PngDecoderOptions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-namespace SixLabors.ImageSharp.Formats.Png
-{
- ///
- /// Configuration options for decoding Png images.
- ///
- public sealed class PngDecoderOptions : ISpecializedDecoderOptions
- {
- ///
- public DecoderOptions GeneralOptions { get; set; } = new();
- }
-}
diff --git a/src/ImageSharp/Formats/Tga/TgaDecoder.cs b/src/ImageSharp/Formats/Tga/TgaDecoder.cs
index ca4d9a5f55..2ad845adb1 100644
--- a/src/ImageSharp/Formats/Tga/TgaDecoder.cs
+++ b/src/ImageSharp/Formats/Tga/TgaDecoder.cs
@@ -10,29 +10,33 @@ namespace SixLabors.ImageSharp.Formats.Tga
///
/// Image decoder for Truevision TGA images.
///
- public sealed class TgaDecoder : ImageDecoder
+ public sealed class TgaDecoder : ImageDecoder
{
///
- public override Image DecodeSpecialized(TgaDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
- TgaDecoderCore decoder = new(options);
- Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
-
- Resize(options.GeneralOptions, image);
+ Guard.NotNull(options, nameof(options));
+ Guard.NotNull(stream, nameof(stream));
- return image;
+ return new TgaDecoderCore(options).Identify(options.Configuration, stream, cancellationToken);
}
///
- public override Image DecodeSpecialized(TgaDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
-
- ///
- public override IImageInfo IdentifySpecialized(TgaDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
+ Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
- return new TgaDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
+ TgaDecoderCore decoder = new(options);
+ Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
+
+ Resize(options, image);
+
+ return image;
}
+
+ ///
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
}
diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
index 056aa9e840..830f2cc3df 100644
--- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
+++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
@@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
///
/// Performs the tga decoding operation.
///
- internal sealed class TgaDecoderCore : IImageDecoderInternals
+ internal sealed class TgaDecoderCore : IImageDecoderInternals
{
///
/// A scratch buffer to reduce allocations.
@@ -61,15 +61,15 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// Initializes a new instance of the class.
///
/// The options.
- public TgaDecoderCore(TgaDecoderOptions options)
+ public TgaDecoderCore(DecoderOptions options)
{
this.Options = options;
- this.configuration = options.GeneralOptions.Configuration;
+ this.configuration = options.Configuration;
this.memoryAllocator = this.configuration.MemoryAllocator;
}
///
- public TgaDecoderOptions Options { get; }
+ public DecoderOptions Options { get; }
///
public Size Dimensions => new(this.fileHeader.Width, this.fileHeader.Height);
diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderOptions.cs b/src/ImageSharp/Formats/Tga/TgaDecoderOptions.cs
deleted file mode 100644
index 89ec90430d..0000000000
--- a/src/ImageSharp/Formats/Tga/TgaDecoderOptions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-namespace SixLabors.ImageSharp.Formats.Tga
-{
- ///
- /// Configuration options for decoding Tga images.
- ///
- public sealed class TgaDecoderOptions : ISpecializedDecoderOptions
- {
- ///
- public DecoderOptions GeneralOptions { get; set; } = new();
- }
-}
diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffJpegSpectralConverter{TPixel}.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffJpegSpectralConverter{TPixel}.cs
index ced6b9027c..5d09bd7905 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffJpegSpectralConverter{TPixel}.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffJpegSpectralConverter{TPixel}.cs
@@ -35,10 +35,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
return JpegColorConverterBase.GetConverter(colorSpace, frame.Precision);
}
- ///
+ ///
/// This converter must be used only for RGB and YCbCr color spaces for performance reasons.
/// For grayscale images must be used.
- ///
+ ///
private static JpegColorSpace GetJpegColorSpaceFromPhotometricInterpretation(TiffPhotometricInterpretation interpretation)
=> interpretation switch
{
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs
index 68d27262f8..012adc5863 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs
@@ -10,29 +10,33 @@ namespace SixLabors.ImageSharp.Formats.Tiff
///
/// Image decoder for generating an image out of a TIFF stream.
///
- public class TiffDecoder : ImageDecoder
+ public class TiffDecoder : ImageDecoder
{
///
- public override Image DecodeSpecialized(TiffDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
- TiffDecoderCore decoder = new(options);
- Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
-
- Resize(options.GeneralOptions, image);
+ Guard.NotNull(options, nameof(options));
+ Guard.NotNull(stream, nameof(stream));
- return image;
+ return new TiffDecoderCore(options).Identify(options.Configuration, stream, cancellationToken);
}
///
- public override Image DecodeSpecialized(TiffDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
-
- ///
- public override IImageInfo IdentifySpecialized(TiffDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
+ Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
- return new TiffDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
+ TiffDecoderCore decoder = new(options);
+ Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
+
+ Resize(options, image);
+
+ return image;
}
+
+ ///
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
}
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
index 6b3abbc9e7..8e3f8c16b7 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
@@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
///
/// Performs the tiff decoding operation.
///
- internal class TiffDecoderCore : IImageDecoderInternals
+ internal class TiffDecoderCore : IImageDecoderInternals
{
///
/// General configuration options.
@@ -61,12 +61,12 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// Initializes a new instance of the class.
///
/// The decoder options.
- public TiffDecoderCore(TiffDecoderOptions options)
+ public TiffDecoderCore(DecoderOptions options)
{
this.Options = options;
- this.configuration = options.GeneralOptions.Configuration;
- this.skipMetadata = options.GeneralOptions.SkipMetadata;
- this.maxFrames = options.GeneralOptions.MaxFrames;
+ this.configuration = options.Configuration;
+ this.skipMetadata = options.SkipMetadata;
+ this.maxFrames = options.MaxFrames;
this.memoryAllocator = this.configuration.MemoryAllocator;
}
@@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
public TiffPredictor Predictor { get; set; }
///
- public TiffDecoderOptions Options { get; }
+ public DecoderOptions Options { get; }
///
public Size Dimensions { get; private set; }
@@ -373,7 +373,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
}
using TiffBaseDecompressor decompressor = TiffDecompressorsFactory.Create(
- this.Options.GeneralOptions,
+ this.Options,
this.CompressionType,
this.memoryAllocator,
this.PhotometricInterpretation,
@@ -454,7 +454,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
Buffer2D pixels = frame.PixelBuffer;
using TiffBaseDecompressor decompressor = TiffDecompressorsFactory.Create(
- this.Options.GeneralOptions,
+ this.Options,
this.CompressionType,
this.memoryAllocator,
this.PhotometricInterpretation,
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptions.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptions.cs
deleted file mode 100644
index b22cf001e1..0000000000
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-namespace SixLabors.ImageSharp.Formats.Tiff
-{
- ///
- /// Configuration options for decoding Tiff images.
- ///
- public sealed class TiffDecoderOptions : ISpecializedDecoderOptions
- {
- ///
- public DecoderOptions GeneralOptions { get; set; } = new();
- }
-}
diff --git a/src/ImageSharp/Formats/Webp/WebpDecoder.cs b/src/ImageSharp/Formats/Webp/WebpDecoder.cs
index dc653705d2..b2dbbcba98 100644
--- a/src/ImageSharp/Formats/Webp/WebpDecoder.cs
+++ b/src/ImageSharp/Formats/Webp/WebpDecoder.cs
@@ -10,29 +10,34 @@ namespace SixLabors.ImageSharp.Formats.Webp
///
/// Image decoder for generating an image out of a webp stream.
///
- public sealed class WebpDecoder : ImageDecoder
+ public sealed class WebpDecoder : ImageDecoder
{
///
- public override Image DecodeSpecialized(WebpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
- WebpDecoderCore decoder = new(options);
- Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
-
- Resize(options.GeneralOptions, image);
+ Guard.NotNull(options, nameof(options));
+ Guard.NotNull(stream, nameof(stream));
- return image;
+ using WebpDecoderCore decoder = new(options);
+ return decoder.Identify(options.Configuration, stream, cancellationToken);
}
///
- public override Image DecodeSpecialized(WebpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
-
- ///
- public override IImageInfo IdentifySpecialized(WebpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
+ Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream));
- return new WebpDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
+ using WebpDecoderCore decoder = new(options);
+ Image image = decoder.Decode(options.Configuration, stream, cancellationToken);
+
+ Resize(options, image);
+
+ return image;
}
+
+ ///
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
}
diff --git a/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs b/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs
index ecb7b1b87d..75f5f88f8b 100644
--- a/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs
+++ b/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs
@@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Formats.Webp
///
/// Performs the webp decoding operation.
///
- internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
+ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
{
///
/// Reusable buffer.
@@ -76,17 +76,17 @@ namespace SixLabors.ImageSharp.Formats.Webp
/// Initializes a new instance of the class.
///
/// The decoder options.
- public WebpDecoderCore(WebpDecoderOptions options)
+ public WebpDecoderCore(DecoderOptions options)
{
this.Options = options;
- this.configuration = options.GeneralOptions.Configuration;
- this.skipMetadata = options.GeneralOptions.SkipMetadata;
- this.maxFrames = options.GeneralOptions.MaxFrames;
+ this.configuration = options.Configuration;
+ this.skipMetadata = options.SkipMetadata;
+ this.maxFrames = options.MaxFrames;
this.memoryAllocator = this.configuration.MemoryAllocator;
}
///
- public WebpDecoderOptions Options { get; }
+ public DecoderOptions Options { get; }
///
public Size Dimensions => new((int)this.webImageInfo.Width, (int)this.webImageInfo.Height);
diff --git a/src/ImageSharp/Formats/Webp/WebpDecoderOptions.cs b/src/ImageSharp/Formats/Webp/WebpDecoderOptions.cs
deleted file mode 100644
index 8e8218472f..0000000000
--- a/src/ImageSharp/Formats/Webp/WebpDecoderOptions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-namespace SixLabors.ImageSharp.Formats.Webp
-{
- ///
- /// Configuration options for decoding Webp images.
- ///
- public sealed class WebpDecoderOptions : ISpecializedDecoderOptions
- {
- ///
- public DecoderOptions GeneralOptions { get; set; } = new();
- }
-}
diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs
index f7ff9966d5..5c73590aa1 100644
--- a/src/ImageSharp/Image.FromStream.cs
+++ b/src/ImageSharp/Image.FromStream.cs
@@ -521,7 +521,7 @@ namespace SixLabors.ImageSharp
/// The input stream.
/// The action to perform.
/// The .
- private static T WithSeekableStream(
+ internal static T WithSeekableStream(
DecoderOptions options,
Stream stream,
Func action)
@@ -562,7 +562,7 @@ namespace SixLabors.ImageSharp
/// The action to perform.
/// The cancellation token.
/// The .
- private static async Task WithSeekableStreamAsync(
+ internal static async Task WithSeekableStreamAsync(
DecoderOptions options,
Stream stream,
Func action,
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs
index 1c8977f5e3..5df2267703 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs
@@ -65,7 +65,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
}
}
-
/*
BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19042.1348 (20H2/October2020Update)
Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
diff --git a/tests/ImageSharp.Tests/TestFormat.cs b/tests/ImageSharp.Tests/TestFormat.cs
index eecdb4bb97..96fcb6afd1 100644
--- a/tests/ImageSharp.Tests/TestFormat.cs
+++ b/tests/ImageSharp.Tests/TestFormat.cs
@@ -194,7 +194,7 @@ namespace SixLabors.ImageSharp.Tests
public TestHeader(TestFormat testFormat) => this.testFormat = testFormat;
}
- public class TestDecoder : ImageDecoder
+ public class TestDecoder : ImageDecoder, IImageDecoderSpecialized
{
private readonly TestFormat testFormat;
@@ -208,10 +208,17 @@ namespace SixLabors.ImageSharp.Tests
public bool IsSupportedFileFormat(Span header) => this.testFormat.IsSupportedFileFormat(header);
- public override IImageInfo IdentifySpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
+
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
- public override Image DecodeSpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
+
+ public Image DecodeSpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ where TPixel : unmanaged, IPixel
{
Configuration configuration = options.GeneralOptions.Configuration;
var ms = new MemoryStream();
@@ -228,7 +235,7 @@ namespace SixLabors.ImageSharp.Tests
return this.testFormat.Sample();
}
- public override Image DecodeSpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public Image DecodeSpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
=> this.DecodeSpecialized(options, stream, cancellationToken);
}
diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs
index 1fc0100a69..6cc96dedeb 100644
--- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs
@@ -220,7 +220,7 @@ namespace SixLabors.ImageSharp.Tests
return Task.FromResult(decoder.Decode(options, stream, default));
}
- public override Image GetImage(ImageDecoder decoder, T options)
+ public override Image GetImage(IImageDecoderSpecialized decoder, T options)
{
Guard.NotNull(decoder, nameof(decoder));
Guard.NotNull(options, nameof(options));
@@ -243,7 +243,7 @@ namespace SixLabors.ImageSharp.Tests
return cachedImage.Clone(this.Configuration);
}
- public override Task> GetImageAsync(ImageDecoder decoder, T options)
+ public override Task> GetImageAsync(IImageDecoderSpecialized decoder, T options)
{
Guard.NotNull(decoder, nameof(decoder));
Guard.NotNull(options, nameof(options));
@@ -279,7 +279,7 @@ namespace SixLabors.ImageSharp.Tests
return decoder.Decode(options, stream, default);
}
- private Image DecodeImage(ImageDecoder decoder, T options)
+ private Image DecodeImage(IImageDecoderSpecialized decoder, T options)
where T : class, ISpecializedDecoderOptions, new()
{
options.GeneralOptions.Configuration = this.Configuration;
diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs
index 8d186bdab0..bb0e196499 100644
--- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs
@@ -101,11 +101,11 @@ namespace SixLabors.ImageSharp.Tests
public virtual Task> GetImageAsync(IImageDecoder decoder, DecoderOptions options)
=> throw new NotSupportedException($"Decoder specific GetImageAsync() is not supported with {this.GetType().Name}!");
- public virtual Image GetImage(ImageDecoder decoder, T options)
+ public virtual Image GetImage(IImageDecoderSpecialized decoder, T options)
where T : class, ISpecializedDecoderOptions, new()
=> throw new NotSupportedException($"Decoder specific GetImage() is not supported with {this.GetType().Name}!");
- public virtual Task> GetImageAsync(ImageDecoder decoder, T options)
+ public virtual Task> GetImageAsync(IImageDecoderSpecialized decoder, T options)
where T : class, ISpecializedDecoderOptions, new()
=> throw new NotSupportedException($"Decoder specific GetImageAsync() is not supported with {this.GetType().Name}!");
diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
index 02abbbb430..92b7aeac9b 100644
--- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
@@ -15,7 +15,7 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
{
- public class MagickReferenceDecoder : ImageDecoder
+ public class MagickReferenceDecoder : ImageDecoder
{
private readonly bool validate;
@@ -28,9 +28,9 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
public static MagickReferenceDecoder Instance { get; } = new();
- public override Image DecodeSpecialized(MagickReferenceDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
- Configuration configuration = options.GeneralOptions.Configuration;
+ Configuration configuration = options.Configuration;
var bmpReadDefines = new BmpReadDefines
{
IgnoreFileSize = !this.validate
@@ -70,11 +70,11 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
return new Image(configuration, new ImageMetadata(), framesList);
}
- public override Image DecodeSpecialized(MagickReferenceDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
- public override IImageInfo IdentifySpecialized(MagickReferenceDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
private static void FromRgba32Bytes(Configuration configuration, Span rgbaBytes, IMemoryGroup destinationGroup)
where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel
@@ -106,9 +106,4 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
}
}
}
-
- public class MagickReferenceDecoderOptions : ISpecializedDecoderOptions
- {
- public DecoderOptions GeneralOptions { get; set; } = new();
- }
}
diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs
index 21f0fd8650..ddf09ebddc 100644
--- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs
@@ -11,18 +11,18 @@ using SDImage = System.Drawing.Image;
namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
{
- public class SystemDrawingReferenceDecoder : ImageDecoder
+ public class SystemDrawingReferenceDecoder : ImageDecoder
{
public static SystemDrawingReferenceDecoder Instance { get; } = new SystemDrawingReferenceDecoder();
- public override IImageInfo IdentifySpecialized(SystemDrawingReferenceDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
using var sourceBitmap = new SDBitmap(stream);
PixelTypeInfo pixelType = new(SDImage.GetPixelFormatSize(sourceBitmap.PixelFormat));
return new ImageInfo(pixelType, sourceBitmap.Width, sourceBitmap.Height, new ImageMetadata());
}
- public override Image DecodeSpecialized(SystemDrawingReferenceDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
using var sourceBitmap = new SDBitmap(stream);
if (sourceBitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb)
@@ -47,12 +47,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
return SystemDrawingBridge.From32bppArgbSystemDrawingBitmap(convertedBitmap);
}
- public override Image DecodeSpecialized(SystemDrawingReferenceDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
- }
-
- public class SystemDrawingReferenceDecoderOptions : ISpecializedDecoderOptions
- {
- public DecoderOptions GeneralOptions { get; set; } = new();
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.Decode(options, stream, cancellationToken);
}
}
diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
index d75ac21dca..9255d5d9fa 100644
--- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
@@ -351,7 +351,7 @@ namespace SixLabors.ImageSharp.Tests
}
}
- private class TestDecoder : ImageDecoder
+ private class TestDecoder : ImageDecoder, IImageDecoderSpecialized
{
// Couldn't make xUnit happy without this hackery:
private static readonly ConcurrentDictionary InvocationCounts = new();
@@ -368,16 +368,23 @@ namespace SixLabors.ImageSharp.Tests
}
}
- public override IImageInfo IdentifySpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
+
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
+
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
- public override Image DecodeSpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public Image DecodeSpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ where TPixel : unmanaged, IPixel
{
InvocationCounts[this.callerName]++;
return new Image(42, 42);
}
- public override Image DecodeSpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ public Image DecodeSpecialized(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken)
=> this.DecodeSpecialized(options, stream, cancellationToken);
internal static int GetInvocationCount(string callerName) => InvocationCounts[callerName];
@@ -389,7 +396,7 @@ namespace SixLabors.ImageSharp.Tests
}
}
- private class TestDecoderWithParameters : ImageDecoder
+ private class TestDecoderWithParameters : ImageDecoder, IImageDecoderSpecialized
{
private static readonly ConcurrentDictionary InvocationCounts = new();
@@ -405,16 +412,23 @@ namespace SixLabors.ImageSharp.Tests
}
}
- public override IImageInfo IdentifySpecialized(TestDecoderWithParametersOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
+ public override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
+
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
+
+ public override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(new() { GeneralOptions = options }, stream, cancellationToken);
- public override Image DecodeSpecialized(TestDecoderWithParametersOptions options, Stream stream, CancellationToken cancellationToken)
+ public Image DecodeSpecialized(TestDecoderWithParametersOptions options, Stream stream, CancellationToken cancellationToken)
+ where TPixel : unmanaged, IPixel
{
InvocationCounts[this.callerName]++;
return new Image(42, 42);
}
- public override Image DecodeSpecialized(TestDecoderWithParametersOptions options, Stream stream, CancellationToken cancellationToken)
+ public Image DecodeSpecialized(TestDecoderWithParametersOptions options, Stream stream, CancellationToken cancellationToken)
=> this.DecodeSpecialized(options, stream, cancellationToken);
internal static int GetInvocationCount(string callerName) => InvocationCounts[callerName];