diff --git a/src/ImageSharp/Formats/DecoderOptions.cs b/src/ImageSharp/Formats/DecoderOptions.cs index 6b35e2614d..6ed66db92c 100644 --- a/src/ImageSharp/Formats/DecoderOptions.cs +++ b/src/ImageSharp/Formats/DecoderOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. +using System; + namespace SixLabors.ImageSharp.Formats { /// @@ -8,6 +10,8 @@ namespace SixLabors.ImageSharp.Formats /// public sealed class DecoderOptions { + private uint maxFrames = uint.MaxValue; + /// /// Gets or sets a custom Configuration instance to be used by the image processing pipeline. /// @@ -26,6 +30,6 @@ namespace SixLabors.ImageSharp.Formats /// /// Gets or sets the maximum number of image frames to decode, inclusive. /// - public int MaxFrames { get; set; } = int.MaxValue; + public uint MaxFrames { get => this.maxFrames; set => this.maxFrames = Math.Min(Math.Max(value, 1), uint.MaxValue); } } } diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index c084f57cea..938a8f3603 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// /// The maximum number of frames to decode. Inclusive. /// - private readonly int maxFrames; + private readonly uint maxFrames; /// /// Whether to skip metadata during decode. @@ -109,7 +109,7 @@ namespace SixLabors.ImageSharp.Formats.Gif public Image Decode(BufferedReadStream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - int frameCount = 0; + uint frameCount = 0; Image image = null; ImageFrame previousFrame = null; try @@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.Formats.Gif { if (nextFlag == GifConstants.ImageLabel) { - if (previousFrame != null && frameCount++ <= this.maxFrames) + if (previousFrame != null && frameCount++ > this.maxFrames) { break; } diff --git a/src/ImageSharp/Formats/Png/PngDecoderOptions.cs b/src/ImageSharp/Formats/Png/PngDecoderOptions.cs index f8b3364bb5..9619bbe7f7 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderOptions.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderOptions.cs @@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// Configuration options for decoding Png images. /// - public class PngDecoderOptions : ISpecializedDecoderOptions + public sealed class PngDecoderOptions : ISpecializedDecoderOptions { /// public DecoderOptions GeneralOptions { get; set; } = new(); diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderOptions.cs b/src/ImageSharp/Formats/Tga/TgaDecoderOptions.cs index f5c0fb128e..7483618c47 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoderOptions.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoderOptions.cs @@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Tga /// /// Configuration options for decoding Tga images. /// - public class TgaDecoderOptions : ISpecializedDecoderOptions + public sealed class TgaDecoderOptions : ISpecializedDecoderOptions { /// public DecoderOptions GeneralOptions { get; set; } = new(); diff --git a/src/ImageSharp/Formats/Tiff/ITiffDecoderOptions.cs b/src/ImageSharp/Formats/Tiff/ITiffDecoderOptions.cs deleted file mode 100644 index d6d1bb8a4c..0000000000 --- a/src/ImageSharp/Formats/Tiff/ITiffDecoderOptions.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Apache License, Version 2.0. - -using SixLabors.ImageSharp.Metadata; - -namespace SixLabors.ImageSharp.Formats.Tiff -{ - /// - /// Encapsulates the options for the . - /// - internal interface ITiffDecoderOptions - { - /// - /// Gets a value indicating whether the metadata should be ignored when the image is being decoded. - /// - bool IgnoreMetadata { get; } - - /// - /// Gets the decoding mode for multi-frame images. - /// - FrameDecodingMode DecodingMode { get; } - } -} diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index 0bb01fcdce..1f644fa82f 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -33,14 +33,14 @@ namespace SixLabors.ImageSharp.Formats.Tiff private readonly MemoryAllocator memoryAllocator; /// - /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. + /// A value indicating whether the metadata should be ignored when the image is being decoded. /// private readonly bool skipMetadata; /// /// The maximum number of frames to decode. Inclusive. /// - private readonly int maxFrames; + private readonly uint maxFrames; /// /// The stream to decode from. @@ -170,14 +170,14 @@ namespace SixLabors.ImageSharp.Formats.Tiff this.byteOrder = reader.ByteOrder; this.isBigTiff = reader.IsBigTiff; - int frameCount = 0; + uint frameCount = 0; foreach (ExifProfile ifd in directories) { cancellationToken.ThrowIfCancellationRequested(); ImageFrame frame = this.DecodeFrame(ifd, cancellationToken); frames.Add(frame); - if (frameCount++ <= this.maxFrames) + if (frameCount++ > this.maxFrames) { break; } diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptions.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptions.cs index ac01952510..ec3b437971 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptions.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptions.cs @@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// /// Configuration options for decoding Tiff images. /// - public class TiffDecoderOptions : ISpecializedDecoderOptions + public sealed class TiffDecoderOptions : ISpecializedDecoderOptions { /// public DecoderOptions GeneralOptions { get; set; } = new(); diff --git a/src/ImageSharp/Formats/Webp/IWebpDecoderOptions.cs b/src/ImageSharp/Formats/Webp/IWebpDecoderOptions.cs deleted file mode 100644 index cf607ef69f..0000000000 --- a/src/ImageSharp/Formats/Webp/IWebpDecoderOptions.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Apache License, Version 2.0. - -using SixLabors.ImageSharp.Metadata; - -namespace SixLabors.ImageSharp.Formats.Webp -{ - /// - /// Image decoder options for generating an image out of a webp stream. - /// - internal interface IWebpDecoderOptions - { - /// - /// Gets a value indicating whether the metadata should be ignored when the image is being decoded. - /// - bool IgnoreMetadata { get; } - - /// - /// Gets the decoding mode for multi-frame images. - /// - FrameDecodingMode DecodingMode { get; } - } -} diff --git a/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs b/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs index 09653fd4cd..8e69673118 100644 --- a/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs +++ b/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs @@ -33,6 +33,11 @@ namespace SixLabors.ImageSharp.Formats.Webp /// private readonly Configuration configuration; + /// + /// The maximum number of frames to decode. Inclusive. + /// + private readonly uint maxFrames; + /// /// The area to restore. /// @@ -48,29 +53,24 @@ namespace SixLabors.ImageSharp.Formats.Webp /// private WebpMetadata webpMetadata; + /// + /// The alpha data, if an ALPH chunk is present. + /// + private IMemoryOwner alphaData; + /// /// Initializes a new instance of the class. /// /// The memory allocator. /// The global configuration. - /// The frame decoding mode. - public WebpAnimationDecoder(MemoryAllocator memoryAllocator, Configuration configuration, FrameDecodingMode decodingMode) + /// The maximum number of frames to decode. Inclusive. + public WebpAnimationDecoder(MemoryAllocator memoryAllocator, Configuration configuration, uint maxFrames) { this.memoryAllocator = memoryAllocator; this.configuration = configuration; - this.DecodingMode = decodingMode; + this.maxFrames = maxFrames; } - /// - /// Gets or sets the alpha data, if an ALPH chunk is present. - /// - public IMemoryOwner AlphaData { get; set; } - - /// - /// Gets the decoding mode for multi-frame images. - /// - public FrameDecodingMode DecodingMode { get; } - /// /// Decodes the animated webp image from the specified stream. /// @@ -90,6 +90,7 @@ namespace SixLabors.ImageSharp.Formats.Webp this.webpMetadata = this.metadata.GetWebpMetadata(); this.webpMetadata.AnimationLoopCount = features.AnimationLoopCount; + uint frameCount = 0; int remainingBytes = (int)completeDataSize; while (remainingBytes > 0) { @@ -110,7 +111,7 @@ namespace SixLabors.ImageSharp.Formats.Webp break; } - if (stream.Position == stream.Length || this.DecodingMode is FrameDecodingMode.First) + if (stream.Position == stream.Length || frameCount++ > this.maxFrames) { break; } @@ -224,14 +225,14 @@ namespace SixLabors.ImageSharp.Formats.Webp /// The stream to read from. private byte ReadAlphaData(BufferedReadStream stream) { - this.AlphaData?.Dispose(); + this.alphaData?.Dispose(); uint alphaChunkSize = WebpChunkParsingUtils.ReadChunkSize(stream, this.buffer); int alphaDataSize = (int)(alphaChunkSize - 1); - this.AlphaData = this.memoryAllocator.Allocate(alphaDataSize); + this.alphaData = this.memoryAllocator.Allocate(alphaDataSize); byte alphaChunkHeader = (byte)stream.ReadByte(); - Span alphaData = this.AlphaData.GetSpan(); + Span alphaData = this.alphaData.GetSpan(); stream.Read(alphaData, 0, alphaDataSize); return alphaChunkHeader; @@ -260,7 +261,7 @@ namespace SixLabors.ImageSharp.Formats.Webp else { var lossyDecoder = new WebpLossyDecoder(webpInfo.Vp8BitReader, this.memoryAllocator, this.configuration); - lossyDecoder.Decode(pixelBufferDecoded, (int)webpInfo.Width, (int)webpInfo.Height, webpInfo, this.AlphaData); + lossyDecoder.Decode(pixelBufferDecoded, (int)webpInfo.Width, (int)webpInfo.Height, webpInfo, this.alphaData); } return pixelBufferDecoded; @@ -381,6 +382,6 @@ namespace SixLabors.ImageSharp.Formats.Webp } /// - public void Dispose() => this.AlphaData?.Dispose(); + public void Dispose() => this.alphaData?.Dispose(); } } diff --git a/src/ImageSharp/Formats/Webp/WebpDecoder.cs b/src/ImageSharp/Formats/Webp/WebpDecoder.cs index 2f6b593eef..64544c5e69 100644 --- a/src/ImageSharp/Formats/Webp/WebpDecoder.cs +++ b/src/ImageSharp/Formats/Webp/WebpDecoder.cs @@ -3,8 +3,6 @@ using System.IO; using System.Threading; -using SixLabors.ImageSharp.Memory; -using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Formats.Webp @@ -12,49 +10,29 @@ namespace SixLabors.ImageSharp.Formats.Webp /// /// Image decoder for generating an image out of a webp stream. /// - public sealed class WebpDecoder : IImageDecoder, IWebpDecoderOptions, IImageInfoDetector + public sealed class WebpDecoder : ImageDecoder { - /// - /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. - /// - public bool IgnoreMetadata { get; set; } - - /// - /// Gets or sets the decoding mode for multi-frame images. - /// Defaults to All. - /// - public FrameDecodingMode DecodingMode { get; set; } = FrameDecodingMode.All; - /// - public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken) - where TPixel : unmanaged, IPixel + public override Image DecodeSpecialized(WebpDecoderOptions options, Stream stream, CancellationToken cancellationToken) { - Guard.NotNull(stream, nameof(stream)); + WebpDecoderCore decoder = new(options); + Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken); - using var decoder = new WebpDecoderCore(configuration, this); + Resize(options.GeneralOptions, image); - try - { - return decoder.Decode(configuration, stream, cancellationToken); - } - catch (InvalidMemoryOperationException ex) - { - Size dims = decoder.Dimensions; - - throw new InvalidImageContentException($"Cannot decode image. Failed to allocate buffers for possibly degenerate dimensions: {dims.Width}x{dims.Height}.", ex); - } + return image; } - /// - public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken) - => this.Decode(configuration, stream, cancellationToken); + /// + public override Image DecodeSpecialized(WebpDecoderOptions options, Stream stream, CancellationToken cancellationToken) + => this.DecodeSpecialized(options, stream, cancellationToken); /// - public IImageInfo Identify(Configuration configuration, Stream stream, CancellationToken cancellationToken) + public override IImageInfo IdentifySpecialized(WebpDecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(stream, nameof(stream)); - return new WebpDecoderCore(configuration, this).Identify(configuration, stream, cancellationToken); + return new WebpDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken); } } } diff --git a/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs b/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs index 979ac55825..70ca6900b9 100644 --- a/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs +++ b/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs @@ -4,7 +4,6 @@ using System; using System.Buffers; using System.Buffers.Binary; -using System.IO; using System.Threading; using SixLabors.ImageSharp.Formats.Webp.Lossless; using SixLabors.ImageSharp.Formats.Webp.Lossy; @@ -21,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. @@ -29,65 +28,68 @@ namespace SixLabors.ImageSharp.Formats.Webp private readonly byte[] buffer = new byte[4]; /// - /// Used for allocating memory during the decoding operations. + /// General configuration options. /// - private readonly MemoryAllocator memoryAllocator; + private readonly Configuration configuration; /// - /// The stream to decode from. + /// A value indicating whether the metadata should be ignored when the image is being decoded. /// - private BufferedReadStream currentStream; + private readonly bool skipMetadata; /// - /// The webp specific metadata. + /// The maximum number of frames to decode. Inclusive. /// - private WebpMetadata webpMetadata; + private readonly uint maxFrames; /// - /// Information about the webp image. + /// Gets the decoded by this decoder instance. /// - private WebpImageInfo webImageInfo; + private ImageMetadata metadata; /// - /// Initializes a new instance of the class. + /// Gets or sets the alpha data, if an ALPH chunk is present. /// - /// The configuration. - /// The options. - public WebpDecoderCore(Configuration configuration, IWebpDecoderOptions options) - { - this.Configuration = configuration; - this.DecodingMode = options.DecodingMode; - this.memoryAllocator = configuration.MemoryAllocator; - this.IgnoreMetadata = options.IgnoreMetadata; - } - - /// - public Configuration Configuration { get; } + private IMemoryOwner alphaData; /// - /// Gets the decoding mode for multi-frame images. + /// Used for allocating memory during the decoding operations. /// - public FrameDecodingMode DecodingMode { get; } + private readonly MemoryAllocator memoryAllocator; /// - /// Gets a value indicating whether the metadata should be ignored when the image is being decoded. + /// The stream to decode from. /// - public bool IgnoreMetadata { get; } + private BufferedReadStream currentStream; /// - /// Gets the decoded by this decoder instance. + /// The webp specific metadata. /// - public ImageMetadata Metadata { get; private set; } + private WebpMetadata webpMetadata; /// - /// Gets the dimensions of the image. + /// Information about the webp image. /// - public Size Dimensions => new((int)this.webImageInfo.Width, (int)this.webImageInfo.Height); + private WebpImageInfo webImageInfo; /// - /// Gets or sets the alpha data, if an ALPH chunk is present. + /// Initializes a new instance of the class. /// - public IMemoryOwner AlphaData { get; set; } + /// The decoder options. + public WebpDecoderCore(WebpDecoderOptions options) + { + this.Options = options; + this.configuration = options.GeneralOptions.Configuration; + this.skipMetadata = options.GeneralOptions.SkipMetadata; + this.maxFrames = options.GeneralOptions.MaxFrames; + this.memoryAllocator = this.configuration.MemoryAllocator; + } + + /// + public WebpDecoderOptions Options { get; } + + /// + public Size Dimensions => new((int)this.webImageInfo.Width, (int)this.webImageInfo.Height); /// public Image Decode(BufferedReadStream stream, CancellationToken cancellationToken) @@ -96,7 +98,7 @@ namespace SixLabors.ImageSharp.Formats.Webp Image image = null; try { - this.Metadata = new ImageMetadata(); + this.metadata = new ImageMetadata(); this.currentStream = stream; uint fileSize = this.ReadImageHeader(); @@ -105,7 +107,7 @@ namespace SixLabors.ImageSharp.Formats.Webp { if (this.webImageInfo.Features is { Animation: true }) { - using var animationDecoder = new WebpAnimationDecoder(this.memoryAllocator, this.Configuration, this.DecodingMode); + using var animationDecoder = new WebpAnimationDecoder(this.memoryAllocator, this.configuration, this.maxFrames); return animationDecoder.Decode(stream, this.webImageInfo.Features, this.webImageInfo.Width, this.webImageInfo.Height, fileSize); } @@ -114,17 +116,17 @@ namespace SixLabors.ImageSharp.Formats.Webp WebpThrowHelper.ThrowNotSupportedException("Animations are not supported"); } - image = new Image(this.Configuration, (int)this.webImageInfo.Width, (int)this.webImageInfo.Height, this.Metadata); + image = new Image(this.configuration, (int)this.webImageInfo.Width, (int)this.webImageInfo.Height, this.metadata); Buffer2D pixels = image.GetRootFramePixelBuffer(); if (this.webImageInfo.IsLossless) { - var losslessDecoder = new WebpLosslessDecoder(this.webImageInfo.Vp8LBitReader, this.memoryAllocator, this.Configuration); + var losslessDecoder = new WebpLosslessDecoder(this.webImageInfo.Vp8LBitReader, this.memoryAllocator, this.configuration); losslessDecoder.Decode(pixels, image.Width, image.Height); } else { - var lossyDecoder = new WebpLossyDecoder(this.webImageInfo.Vp8BitReader, this.memoryAllocator, this.Configuration); - lossyDecoder.Decode(pixels, image.Width, image.Height, this.webImageInfo, this.AlphaData); + var lossyDecoder = new WebpLossyDecoder(this.webImageInfo.Vp8BitReader, this.memoryAllocator, this.configuration); + lossyDecoder.Decode(pixels, image.Width, image.Height, this.webImageInfo, this.alphaData); } // There can be optional chunks after the image data, like EXIF and XMP. @@ -151,7 +153,7 @@ namespace SixLabors.ImageSharp.Formats.Webp this.ReadImageHeader(); using (this.webImageInfo = this.ReadVp8Info(true)) { - return new ImageInfo(new PixelTypeInfo((int)this.webImageInfo.BitsPerPixel), (int)this.webImageInfo.Width, (int)this.webImageInfo.Height, this.Metadata); + return new ImageInfo(new PixelTypeInfo((int)this.webImageInfo.BitsPerPixel), (int)this.webImageInfo.Width, (int)this.webImageInfo.Height, this.metadata); } } @@ -182,8 +184,8 @@ namespace SixLabors.ImageSharp.Formats.Webp /// Information about the webp image. private WebpImageInfo ReadVp8Info(bool ignoreAlpha = false) { - this.Metadata = new ImageMetadata(); - this.webpMetadata = this.Metadata.GetFormatMetadata(WebpFormat.Instance); + this.metadata = new ImageMetadata(); + this.webpMetadata = this.metadata.GetFormatMetadata(WebpFormat.Instance); WebpChunkType chunkType = WebpChunkParsingUtils.ReadChunkType(this.currentStream, this.buffer); @@ -277,7 +279,7 @@ namespace SixLabors.ImageSharp.Formats.Webp /// The webp features. private void ParseOptionalChunks(WebpFeatures features) { - if (this.IgnoreMetadata || (features.ExifProfile == false && features.XmpMetaData == false)) + if (this.skipMetadata || (features.ExifProfile == false && features.XmpMetaData == false)) { return; } @@ -287,11 +289,11 @@ namespace SixLabors.ImageSharp.Formats.Webp { // Read chunk header. WebpChunkType chunkType = this.ReadChunkType(); - if (chunkType == WebpChunkType.Exif && this.Metadata.ExifProfile == null) + if (chunkType == WebpChunkType.Exif && this.metadata.ExifProfile == null) { this.ReadExifProfile(); } - else if (chunkType == WebpChunkType.Xmp && this.Metadata.XmpProfile == null) + else if (chunkType == WebpChunkType.Xmp && this.metadata.XmpProfile == null) { this.ReadXmpProfile(); } @@ -310,7 +312,7 @@ namespace SixLabors.ImageSharp.Formats.Webp private void ReadExifProfile() { uint exifChunkSize = this.ReadChunkSize(); - if (this.IgnoreMetadata) + if (this.skipMetadata) { this.currentStream.Skip((int)exifChunkSize); } @@ -325,7 +327,7 @@ namespace SixLabors.ImageSharp.Formats.Webp } var profile = new ExifProfile(exifData); - this.Metadata.ExifProfile = profile; + this.metadata.ExifProfile = profile; } } @@ -335,7 +337,7 @@ namespace SixLabors.ImageSharp.Formats.Webp private void ReadXmpProfile() { uint xmpChunkSize = this.ReadChunkSize(); - if (this.IgnoreMetadata) + if (this.skipMetadata) { this.currentStream.Skip((int)xmpChunkSize); } @@ -350,7 +352,7 @@ namespace SixLabors.ImageSharp.Formats.Webp } var profile = new XmpProfile(xmpData); - this.Metadata.XmpProfile = profile; + this.metadata.XmpProfile = profile; } } @@ -360,7 +362,7 @@ namespace SixLabors.ImageSharp.Formats.Webp private void ReadIccProfile() { uint iccpChunkSize = this.ReadChunkSize(); - if (this.IgnoreMetadata) + if (this.skipMetadata) { this.currentStream.Skip((int)iccpChunkSize); } @@ -376,7 +378,7 @@ namespace SixLabors.ImageSharp.Formats.Webp var profile = new IccProfile(iccpData); if (profile.CheckIsValid()) { - this.Metadata.IccProfile = profile; + this.metadata.IccProfile = profile; } } } @@ -419,8 +421,8 @@ namespace SixLabors.ImageSharp.Formats.Webp features.AlphaChunkHeader = (byte)this.currentStream.ReadByte(); int alphaDataSize = (int)(alphaChunkSize - 1); - this.AlphaData = this.memoryAllocator.Allocate(alphaDataSize); - Span alphaData = this.AlphaData.GetSpan(); + this.alphaData = this.memoryAllocator.Allocate(alphaDataSize); + Span alphaData = this.alphaData.GetSpan(); int bytesRead = this.currentStream.Read(alphaData, 0, alphaDataSize); if (bytesRead != alphaDataSize) { @@ -462,6 +464,6 @@ namespace SixLabors.ImageSharp.Formats.Webp } /// - public void Dispose() => this.AlphaData?.Dispose(); + public void Dispose() => this.alphaData?.Dispose(); } } diff --git a/src/ImageSharp/Formats/Webp/WebpDecoderOptions.cs b/src/ImageSharp/Formats/Webp/WebpDecoderOptions.cs new file mode 100644 index 0000000000..e574b0c72f --- /dev/null +++ b/src/ImageSharp/Formats/Webp/WebpDecoderOptions.cs @@ -0,0 +1,14 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp.Formats.Webp +{ + /// + /// Configuration options for decoding Webp images. + /// + public sealed class WebpDecoderOptions : ISpecializedDecoderOptions + { + /// + public DecoderOptions GeneralOptions { get; set; } = new(); + } +}