diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
index e76448938..326ba0b74 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors.
+// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.IO;
@@ -10,43 +10,31 @@ namespace SixLabors.ImageSharp.Formats.Bmp
///
/// Image decoder for generating an image out of a Windows bitmap stream.
///
- ///
- /// Does not support the following formats at the moment:
- ///
- /// - JPG
- /// - PNG
- /// - Some OS/2 specific subtypes like: Bitmap Array, Color Icon, Color Pointer, Icon, Pointer.
- ///
- /// Formats will be supported in a later releases. We advise always
- /// to use only 24 Bit Windows bitmaps.
- ///
- public sealed class BmpDecoder : IImageDecoder, IBmpDecoderOptions, IImageInfoDetector
+ public class BmpDecoder : ImageDecoder
{
- ///
- /// Gets or sets a value indicating how to deal with skipped pixels, which can occur during decoding run length encoded bitmaps.
- ///
- public RleSkippedPixelHandling RleSkippedPixelHandling { get; set; } = RleSkippedPixelHandling.Black;
-
///
- public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken)
- where TPixel : unmanaged, IPixel
+ public override Image DecodeSpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(stream, nameof(stream));
- var decoder = new BmpDecoderCore(configuration, this);
- return decoder.Decode(configuration, stream, cancellationToken);
+ BmpDecoderCore decoder = new(options);
+ Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
+
+ Resize(options.GeneralOptions, image);
+
+ return image;
}
- ///
- public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken)
- => this.Decode(configuration, stream, cancellationToken);
+ ///
+ public override Image DecodeSpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(options, stream, cancellationToken);
///
- public IImageInfo Identify(Configuration configuration, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo IdentifySpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(stream, nameof(stream));
- return new BmpDecoderCore(configuration, this).Identify(configuration, stream, cancellationToken);
+ return new BmpDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
}
}
}
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoder2.cs b/src/ImageSharp/Formats/Bmp/BmpDecoder2.cs
deleted file mode 100644
index 97439182d..000000000
--- a/src/ImageSharp/Formats/Bmp/BmpDecoder2.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.IO;
-using System.Threading;
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp.Formats.Bmp
-{
- ///
- /// Image decoder for generating an image out of a Windows bitmap stream.
- ///
- public class BmpDecoder2 : ImageDecoder
- {
- ///
- public override Image DecodeSpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- {
- throw new NotImplementedException();
- }
-
- ///
- public override Image DecodeSpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => this.DecodeSpecialized(options, stream, cancellationToken);
-
- ///
- public override IImageInfo IdentifySpecialized(BmpDecoderOptions options, Stream stream, CancellationToken cancellationToken)
- => throw new NotImplementedException();
- }
-}
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
index 26687ff16..f00d4cd03 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.
@@ -90,33 +90,30 @@ namespace SixLabors.ImageSharp.Formats.Bmp
private BmpInfoHeader infoHeader;
///
- /// Used for allocating memory during processing operations.
+ /// The global configuration.
///
- private readonly MemoryAllocator memoryAllocator;
+ private readonly Configuration configuration;
///
- /// The bitmap decoder options.
+ /// Used for allocating memory during processing operations.
///
- private readonly IBmpDecoderOptions options;
+ private readonly MemoryAllocator memoryAllocator;
///
/// Initializes a new instance of the class.
///
- /// The configuration.
/// The options.
- public BmpDecoderCore(Configuration configuration, IBmpDecoderOptions options)
+ public BmpDecoderCore(BmpDecoderOptions options)
{
- this.Configuration = configuration;
- this.memoryAllocator = configuration.MemoryAllocator;
- this.options = options;
+ this.configuration = options.GeneralOptions.Configuration;
+ this.memoryAllocator = this.configuration.MemoryAllocator;
+ this.Options = options;
}
///
- public Configuration Configuration { get; }
+ public BmpDecoderOptions Options { get; }
- ///
- /// Gets the dimensions of the image.
- ///
+ ///
public Size Dimensions => new(this.infoHeader.Width, this.infoHeader.Height);
///
@@ -128,7 +125,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
{
int bytesPerColorMapEntry = this.ReadImageHeaders(stream, out bool inverted, out byte[] palette);
- image = new Image(this.Configuration, this.infoHeader.Width, this.infoHeader.Height, this.metadata);
+ image = new Image(this.configuration, this.infoHeader.Width, this.infoHeader.Height, this.metadata);
Buffer2D pixels = image.GetRootFramePixelBuffer();
@@ -325,7 +322,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
byte colorIdx = bufferRow[x];
if (undefinedPixelsSpan[rowStartIdx + x])
{
- switch (this.options.RleSkippedPixelHandling)
+ switch (this.Options.RleSkippedPixelHandling)
{
case RleSkippedPixelHandling.FirstColorOfPalette:
color.FromBgr24(Unsafe.As(ref colors[colorIdx * 4]));
@@ -397,7 +394,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
int idx = rowStartIdx + (x * 3);
if (undefinedPixelsSpan[yMulWidth + x])
{
- switch (this.options.RleSkippedPixelHandling)
+ switch (this.Options.RleSkippedPixelHandling)
{
case RleSkippedPixelHandling.FirstColorOfPalette:
color.FromBgr24(Unsafe.As(ref bufferSpan[idx]));
@@ -943,7 +940,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
int newY = Invert(y, height, inverted);
Span pixelSpan = pixels.DangerousGetRowSpan(newY);
PixelOperations.Instance.FromBgr24Bytes(
- this.Configuration,
+ this.configuration,
rowSpan,
pixelSpan,
width);
@@ -971,7 +968,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
int newY = Invert(y, height, inverted);
Span pixelSpan = pixels.DangerousGetRowSpan(newY);
PixelOperations.Instance.FromBgra32Bytes(
- this.Configuration,
+ this.configuration,
rowSpan,
pixelSpan,
width);
@@ -1006,7 +1003,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
this.stream.Read(rowSpan);
PixelOperations.Instance.FromBgra32Bytes(
- this.Configuration,
+ this.configuration,
rowSpan,
bgraRowSpan,
width);
@@ -1042,7 +1039,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
Span pixelSpan = pixels.DangerousGetRowSpan(newY);
PixelOperations.Instance.FromBgra32Bytes(
- this.Configuration,
+ this.configuration,
rowSpan,
pixelSpan,
width);
@@ -1056,7 +1053,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
{
this.stream.Read(rowSpan);
PixelOperations.Instance.FromBgra32Bytes(
- this.Configuration,
+ this.configuration,
rowSpan,
bgraRowSpan,
width);
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderOptions.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderOptions.cs
index 74509d68f..535f819d2 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoderOptions.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoderOptions.cs
@@ -4,7 +4,7 @@
namespace SixLabors.ImageSharp.Formats.Bmp
{
///
- /// Image decoder options for decoding Windows bitmap streams.
+ /// Configuration options for decoding Windows Bitmap images.
///
public sealed class BmpDecoderOptions : ISpecializedDecoderOptions
{
diff --git a/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs b/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs
deleted file mode 100644
index ff88d15a3..000000000
--- a/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Apache License, Version 2.0.
-
-namespace SixLabors.ImageSharp.Formats.Bmp
-{
- ///
- /// Image decoder options for decoding Windows bitmap streams.
- ///
- internal interface IBmpDecoderOptions
- {
- ///
- /// Gets the value indicating how to deal with skipped pixels, which can occur during decoding run length encoded bitmaps.
- ///
- RleSkippedPixelHandling RleSkippedPixelHandling { get; }
- }
-}
diff --git a/src/ImageSharp/Formats/DecoderOptions.cs b/src/ImageSharp/Formats/DecoderOptions.cs
index a690b0607..6b35e2614 100644
--- a/src/ImageSharp/Formats/DecoderOptions.cs
+++ b/src/ImageSharp/Formats/DecoderOptions.cs
@@ -24,10 +24,8 @@ namespace SixLabors.ImageSharp.Formats
public bool SkipMetadata { get; set; } = false;
///
- /// Gets or sets the number of image frames to decode.
- /// Leave to decode all frames.
+ /// Gets or sets the maximum number of image frames to decode, inclusive.
///
- // supported decoders may handle this internally but we will fallback to removeing additional frames after decode.
- public int? MaxFrames { get; set; } = null;
+ public int MaxFrames { get; set; } = int.MaxValue;
}
}
diff --git a/src/ImageSharp/Formats/Gif/GifDecoder.cs b/src/ImageSharp/Formats/Gif/GifDecoder.cs
index 6d6cfc079..5550c419e 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoder.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoder.cs
@@ -3,7 +3,6 @@
using System.IO;
using System.Threading;
-using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Gif
@@ -11,37 +10,29 @@ namespace SixLabors.ImageSharp.Formats.Gif
///
/// Decoder for generating an image out of a gif encoded stream.
///
- public sealed class GifDecoder : IImageDecoder, IGifDecoderOptions, IImageInfoDetector
+ public sealed class GifDecoder : ImageDecoder
{
- ///
- /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
- ///
- public bool IgnoreMetadata { get; set; } = false;
-
- ///
- /// Gets or sets the decoding mode for multi-frame images
- ///
- public FrameDecodingMode DecodingMode { get; set; } = FrameDecodingMode.All;
-
///
- public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken)
- where TPixel : unmanaged, IPixel
+ public override Image DecodeSpecialized(GifDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
- var decoder = new GifDecoderCore(configuration, this);
- return decoder.Decode(configuration, stream, cancellationToken);
+ GifDecoderCore decoder = new(options);
+ Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken);
+
+ Resize(options.GeneralOptions, image);
+
+ return image;
}
- ///
- public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken)
- => this.Decode(configuration, stream, cancellationToken);
+ ///
+ public override Image DecodeSpecialized(GifDecoderOptions options, Stream stream, CancellationToken cancellationToken)
+ => this.DecodeSpecialized(options, stream, cancellationToken);
///
- public IImageInfo Identify(Configuration configuration, Stream stream, CancellationToken cancellationToken)
+ public override IImageInfo IdentifySpecialized(GifDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
Guard.NotNull(stream, nameof(stream));
- var decoder = new GifDecoderCore(configuration, this);
- return decoder.Identify(configuration, stream, cancellationToken);
+ return new GifDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
}
}
}
diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
index 2932cafe2..c63a3e08e 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.
@@ -56,6 +56,26 @@ namespace SixLabors.ImageSharp.Formats.Gif
///
private GifImageDescriptor imageDescriptor;
+ ///
+ /// The global configuration.
+ ///
+ private readonly Configuration configuration;
+
+ ///
+ /// Used for allocating memory during processing operations.
+ ///
+ private readonly MemoryAllocator memoryAllocator;
+
+ ///
+ /// The maximum number of frames to decode.
+ ///
+ private readonly int maxFrames;
+
+ ///
+ /// Whether to skip metadata during decode.
+ ///
+ private readonly bool skipMetadata;
+
///
/// The abstract metadata.
///
@@ -69,39 +89,26 @@ namespace SixLabors.ImageSharp.Formats.Gif
///
/// Initializes a new instance of the class.
///
- /// The configuration.
/// The decoder options.
- public GifDecoderCore(Configuration configuration, IGifDecoderOptions options)
+ public GifDecoderCore(GifDecoderOptions options)
{
- this.IgnoreMetadata = options.IgnoreMetadata;
- this.DecodingMode = options.DecodingMode;
- this.Configuration = configuration ?? Configuration.Default;
+ this.skipMetadata = options.GeneralOptions.SkipMetadata;
+ this.configuration = options.GeneralOptions.Configuration;
+ this.memoryAllocator = this.configuration.MemoryAllocator;
+ this.maxFrames = options.GeneralOptions.MaxFrames;
}
///
- public Configuration Configuration { get; }
-
- ///
- /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
- ///
- public bool IgnoreMetadata { get; internal set; }
+ public GifDecoderOptions Options { get; }
- ///
- /// Gets the decoding mode for multi-frame images.
- ///
- public FrameDecodingMode DecodingMode { get; }
-
- ///
- /// Gets the dimensions of the image.
- ///
+ ///
public Size Dimensions => new(this.imageDescriptor.Width, this.imageDescriptor.Height);
- private MemoryAllocator MemoryAllocator => this.Configuration.MemoryAllocator;
-
///
public Image Decode(BufferedReadStream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel
{
+ int frameCount = 0;
Image image = null;
ImageFrame previousFrame = null;
try
@@ -114,7 +121,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
{
if (nextFlag == GifConstants.ImageLabel)
{
- if (previousFrame != null && this.DecodingMode == FrameDecodingMode.First)
+ if (previousFrame != null && frameCount++ <= this.maxFrames)
{
break;
}
@@ -277,9 +284,9 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.stream.Read(this.buffer, 0, GifConstants.ApplicationBlockSize);
bool isXmp = this.buffer.AsSpan().StartsWith(GifConstants.XmpApplicationIdentificationBytes);
- if (isXmp && !this.IgnoreMetadata)
+ if (isXmp && !this.skipMetadata)
{
- var extension = GifXmpApplicationExtension.Read(this.stream, this.MemoryAllocator);
+ var extension = GifXmpApplicationExtension.Read(this.stream, this.memoryAllocator);
if (extension.Data.Length > 0)
{
this.metadata.XmpProfile = new XmpProfile(extension.Data);
@@ -346,13 +353,13 @@ namespace SixLabors.ImageSharp.Formats.Gif
GifThrowHelper.ThrowInvalidImageContentException($"Gif comment length '{length}' exceeds max '{GifConstants.MaxCommentSubBlockLength}' of a comment data block");
}
- if (this.IgnoreMetadata)
+ if (this.skipMetadata)
{
this.stream.Seek(length, SeekOrigin.Current);
continue;
}
- using IMemoryOwner commentsBuffer = this.MemoryAllocator.Allocate(length);
+ using IMemoryOwner commentsBuffer = this.memoryAllocator.Allocate(length);
Span commentsSpan = commentsBuffer.GetSpan();
this.stream.Read(commentsSpan);
@@ -385,11 +392,11 @@ namespace SixLabors.ImageSharp.Formats.Gif
if (this.imageDescriptor.LocalColorTableFlag)
{
int length = this.imageDescriptor.LocalColorTableSize * 3;
- localColorTable = this.Configuration.MemoryAllocator.Allocate(length, AllocationOptions.Clean);
+ localColorTable = this.configuration.MemoryAllocator.Allocate(length, AllocationOptions.Clean);
this.stream.Read(localColorTable.GetSpan());
}
- indices = this.Configuration.MemoryAllocator.Allocate2D(this.imageDescriptor.Width, this.imageDescriptor.Height, AllocationOptions.Clean);
+ indices = this.configuration.MemoryAllocator.Allocate2D(this.imageDescriptor.Width, this.imageDescriptor.Height, AllocationOptions.Clean);
this.ReadFrameIndices(indices);
Span rawColorTable = default;
@@ -423,7 +430,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
private void ReadFrameIndices(Buffer2D indices)
{
int minCodeSize = this.stream.ReadByte();
- using var lzwDecoder = new LzwDecoder(this.Configuration.MemoryAllocator, this.stream);
+ using var lzwDecoder = new LzwDecoder(this.configuration.MemoryAllocator, this.stream);
lzwDecoder.DecodePixels(minCodeSize, indices);
}
@@ -451,12 +458,12 @@ namespace SixLabors.ImageSharp.Formats.Gif
{
if (!transFlag)
{
- image = new Image(this.Configuration, imageWidth, imageHeight, Color.Black.ToPixel(), this.metadata);
+ image = new Image(this.configuration, imageWidth, imageHeight, Color.Black.ToPixel(), this.metadata);
}
else
{
// This initializes the image to become fully transparent because the alpha channel is zero.
- image = new Image(this.Configuration, imageWidth, imageHeight, this.metadata);
+ image = new Image(this.configuration, imageWidth, imageHeight, this.metadata);
}
this.SetFrameMetadata(image.Frames.RootFrame.Metadata);
@@ -675,7 +682,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
if (globalColorTableLength > 0)
{
- this.globalColorTable = this.MemoryAllocator.Allocate(globalColorTableLength, AllocationOptions.Clean);
+ this.globalColorTable = this.memoryAllocator.Allocate(globalColorTableLength, AllocationOptions.Clean);
// Read the global color table data from the stream
stream.Read(this.globalColorTable.GetSpan());
diff --git a/src/ImageSharp/Formats/Gif/GifDecoderOptions.cs b/src/ImageSharp/Formats/Gif/GifDecoderOptions.cs
new file mode 100644
index 000000000..429c1fee1
--- /dev/null
+++ b/src/ImageSharp/Formats/Gif/GifDecoderOptions.cs
@@ -0,0 +1,14 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+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/IImageDecoderInternals.cs b/src/ImageSharp/Formats/IImageDecoderInternals{T}.cs
similarity index 87%
rename from src/ImageSharp/Formats/IImageDecoderInternals.cs
rename to src/ImageSharp/Formats/IImageDecoderInternals{T}.cs
index e190f7add..ffc839d34 100644
--- a/src/ImageSharp/Formats/IImageDecoderInternals.cs
+++ b/src/ImageSharp/Formats/IImageDecoderInternals{T}.cs
@@ -9,14 +9,16 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats
{
///
- /// Abstraction for shared internals for ***DecoderCore implementations to be used with .
+ /// Abstraction for shared internals for XXXDecoderCore implementations to be used with .
///
- internal interface IImageDecoderInternals
+ /// The type of specialized decoder options.
+ internal interface IImageDecoderInternals
+ where T : ISpecializedDecoderOptions
{
///
- /// Gets the associated configuration.
+ /// Gets the specialized decoder options.
///
- Configuration Configuration { get; }
+ T Options { get; }
///
/// Gets the dimensions of the image being decoded.
diff --git a/src/ImageSharp/Formats/ImageDecoderUtilities.cs b/src/ImageSharp/Formats/ImageDecoderUtilities.cs
index 71ecda893..fc78f14b3 100644
--- a/src/ImageSharp/Formats/ImageDecoderUtilities.cs
+++ b/src/ImageSharp/Formats/ImageDecoderUtilities.cs
@@ -12,11 +12,12 @@ 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);
@@ -30,20 +31,22 @@ 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);